4 |
5 | > Permission is hereby granted, free of charge, to any person obtaining a copy
6 | > of this software and associated documentation files (the "Software"), to deal
7 | > in the Software without restriction, including without limitation the rights
8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | > copies of the Software, and to permit persons to whom the Software is
10 | > furnished to do so, subject to the following conditions:
11 | >
12 | > The above copyright notice and this permission notice shall be included in
13 | > all copies or substantial portions of the Software.
14 | >
15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | > THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/config/cloudinary.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | return [
13 |
14 | /*
15 | |--------------------------------------------------------------------------
16 | | Cloudinary Configuration
17 | |--------------------------------------------------------------------------
18 | |
19 | | An HTTP or HTTPS URL to notify your application (a webhook) when the process of uploads, deletes, and any API
20 | | that accepts notification_url has completed.
21 | |
22 | |
23 | */
24 | 'notification_url' => env('CLOUDINARY_NOTIFICATION_URL'),
25 |
26 |
27 | /*
28 | |--------------------------------------------------------------------------
29 | | Cloudinary Configuration
30 | |--------------------------------------------------------------------------
31 | |
32 | | Here you may configure your Cloudinary settings. Cloudinary is a cloud hosted
33 | | media management service for all file uploads, storage, delivery and transformation needs.
34 | |
35 | |
36 | */
37 | 'cloud_url' => env('CLOUDINARY_URL'),
38 |
39 | /**
40 | * Upload Preset From Cloudinary Dashboard
41 | *
42 | */
43 | 'upload_preset' => env('CLOUDINARY_UPLOAD_PRESET')
44 | ];
45 |
--------------------------------------------------------------------------------
/contributing.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Contributions are **welcome** and will be fully **credited**.
4 |
5 | We accept contributions via Pull Requests on [Github](https://github.com/unicodeveloper/laravel-cloudinary).
6 |
7 |
8 | ## Pull Requests
9 |
10 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer).
11 |
12 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests.
13 |
14 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date.
15 |
16 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option.
17 |
18 | - **Create feature branches** - Don't ask us to pull from your master branch.
19 |
20 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
21 |
22 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting.
23 |
24 |
25 | ## Running Tests
26 |
27 | ``` bash
28 | $ composer test
29 | ```
30 |
31 |
32 | **Happy coding**!
33 |
34 |
35 | Daniel Alabuja
--------------------------------------------------------------------------------
/src/Commands/DeleteFilesCommand.php:
--------------------------------------------------------------------------------
1 | warn('Please ensure your Cloudinary credentials are set before continuing.');
38 |
39 | return;
40 | }
41 |
42 | $publicId = $this->argument('publicId');
43 |
44 | $this->info("About to delete {$publicId} file on Cloudinary...");
45 |
46 | try {
47 | $engine->destroy($publicId);
48 |
49 | $this->info('File deleted!');
50 | } catch (Exception $exception) {
51 | $this->warn("Deletion of files on Cloudinary failed because: {$exception->getMessage()}.");
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "unicodeveloper/laravel-cloudinary",
3 | "description": "A Laravel Cloudinary Package",
4 | "license": "MIT",
5 | "authors": [
6 | {
7 | "name": "Prosper Otemuyiwa",
8 | "email": "prosperotemuyiwa@gmail.com",
9 | "homepage": "https://github.com/unicodeveloper"
10 | }
11 | ],
12 | "homepage": "https://github.com/unicodeveloper/laravel-cloudinary",
13 | "keywords": ["Laravel", "laravel-cloudinary"],
14 | "require": {
15 | "php": "^7.0",
16 | "illuminate/support": "~5|~6|~7",
17 | "cloudinary/cloudinary_php": "2.0.0-beta6",
18 | "ext-json": "*"
19 | },
20 | "require-dev": {
21 | "phpunit/phpunit": "^8.0",
22 | "mockery/mockery": "^1.1",
23 | "orchestra/testbench": "~3|~4",
24 | "sempro/phpunit-pretty-print": "^1.0"
25 | },
26 | "autoload": {
27 | "psr-4": {
28 | "Unicodeveloper\\Cloudinary\\": "src/"
29 | },
30 | "files": [
31 | "src/Support/helpers.php"
32 | ]
33 | },
34 | "autoload-dev": {
35 | "psr-4": {
36 | "Unicodeveloper\\Cloudinary\\Tests\\": "tests"
37 | }
38 | },
39 | "extra": {
40 | "laravel": {
41 | "providers": [
42 | "Unicodeveloper\\Cloudinary\\CloudinaryServiceProvider"
43 | ],
44 | "aliases": {
45 | "Cloudinary": "Unicodeveloper\\Cloudinary\\Facades\\Cloudinary"
46 | }
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Model/Media.php:
--------------------------------------------------------------------------------
1 | morphTo();
26 | }
27 |
28 | /**
29 | * Get the file url / path of a Media File
30 | * @return string
31 | */
32 | public function getSecurePath()
33 | {
34 | return $this->file_url;
35 | }
36 |
37 | /**
38 | * Get the file name of a Media File
39 | * @return string
40 | */
41 | public function getFileName()
42 | {
43 | return $this->file_name;
44 | }
45 |
46 | /**
47 | * Get the mime type of a Media File
48 | * @return string
49 | */
50 | public function getFileType()
51 | {
52 | return $this->file_type;
53 | }
54 |
55 | /**
56 | * Get the Size of a Media File
57 | * @return Integer
58 | */
59 | public function getSize()
60 | {
61 | return $this->size;
62 | }
63 |
64 | /**
65 | * Get the Readable Size of a Media File
66 | * @return string
67 | */
68 | public function getReadableSize()
69 | {
70 | return resolve(CloudinaryEngine::class)->getHumanReadableSize($this->size);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Commands/FetchFilesCommand.php:
--------------------------------------------------------------------------------
1 | warn('Please ensure your Cloudinary credentials are set before continuing.');
38 |
39 | return;
40 | }
41 |
42 | $publicId = $this->argument('publicId');
43 |
44 | if (!is_string($publicId)) {
45 | $this->warn("Please ensure a valid public Id is passed as an argument.");
46 |
47 | return;
48 | }
49 |
50 | $this->info("Fetching file...");
51 |
52 | try {
53 | $url = $engine->getImage($publicId)->toUrl();
54 | $this->info("File: {$url}");
55 | } catch (Exception $exception) {
56 | $this->warn("Renaming of file on Cloudinary failed because: {$exception->getMessage()}.");
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Commands/RenameFilesCommand.php:
--------------------------------------------------------------------------------
1 | warn('Please ensure your Cloudinary credentials are set before continuing.');
38 |
39 | return;
40 | }
41 |
42 | $fromPublicId = $this->argument('fromPublicId');
43 | $toPublicId = $this->argument('toPublicId');
44 |
45 | if (!is_string($fromPublicId) || !is_string($toPublicId)) {
46 | $this->warn("Please ensure a valid public Id is passed as an argument.");
47 |
48 | return;
49 | }
50 |
51 | $this->info("About to rename {$fromPublicId} file to {$toPublicId} on Cloudinary...");
52 |
53 | try {
54 | $engine->rename($fromPublicId, $toPublicId);
55 |
56 | $this->info('File renamed successfully on Cloudinary!');
57 | } catch (Exception $exception) {
58 | $this->warn("Renaming of file on Cloudinary failed because: {$exception->getMessage()}.");
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/Commands/UploadFileCommand.php:
--------------------------------------------------------------------------------
1 | warn('Please ensure your Cloudinary credentials are set before continuing.');
39 |
40 | return;
41 | }
42 |
43 | if (is_numeric($this->argument('remote-url'))) {
44 | $this->warn('This is a number, not a valid remote file url. Please try again with a valid URL.');
45 |
46 | return;
47 | }
48 |
49 | if (!filter_var($this->argument('remote-url'), FILTER_VALIDATE_URL)) {
50 | $this->warn('Please add a valid remote file url as an argument.');
51 |
52 | return;
53 | }
54 |
55 | $remoteUrl = $this->argument('remote-url');
56 |
57 | $this->info('Extracting remote file...');
58 |
59 | try {
60 | $engine->uploadFile($remoteUrl);
61 | $this->info('Uploading in progress...');
62 |
63 | $this->info('Upload to Cloudinary completed!');
64 | } catch (Exception $exception) {
65 | $this->warn("Backup of files to Cloudinary failed because: {$exception->getMessage()}.");
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/Commands/GenerateArchiveCommand.php:
--------------------------------------------------------------------------------
1 | warn('Please ensure your Cloudinary credentials are set before continuing.');
40 |
41 | return;
42 | }
43 |
44 | if (!$this->option('tags') && !$this->option('public_ids')) {
45 | $this->warn(
46 | 'Please ensure you pass in at least a tag with --tags, or at least a public_id with --public_ids'
47 | );
48 |
49 | return;
50 | }
51 |
52 | $this->info('Generating Archive...');
53 |
54 | try {
55 | $response = $engine->createArchive(
56 | [
57 | 'tags' => $this->option('tags') ?? null,
58 | 'public_ids' => $this->option('public_ids') ?? null
59 | ]
60 | )['secure_url'];
61 |
62 | $this->info("Archive: {$response}");
63 | } catch (Exception $exception) {
64 | $this->warn("Backup of files to Cloudinary failed because: {$exception->getMessage()}.");
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Commands/BackupFilesCommand.php:
--------------------------------------------------------------------------------
1 | getFiles();
40 | $folder = null;
41 |
42 | if (!$files) {
43 | $this->warn(
44 | 'There are no files in the storage/app/public directory. Use --location flag to specify the name of the directory (if there are files in there) within the storage/app directory.'
45 | );
46 |
47 | return;
48 | }
49 |
50 | if (!config('cloudinary.cloud_url')) {
51 | $this->warn('Please ensure your Cloudinary credentials are set before continuing.');
52 |
53 | return;
54 | }
55 |
56 | if ($this->option('folder') && is_string($this->option('folder'))) {
57 | $folder = $this->option('folder');
58 | }
59 |
60 | if ($this->option('location') && is_string($this->option('location'))) {
61 | $files = $this->getFiles($this->option('location'));
62 | }
63 |
64 | $this->info('Starting backup to Cloudinary...');
65 |
66 | try {
67 | foreach ($files as $file) {
68 | $engine->uploadFile($file->getRealPath(), $folder ? ['folder' => $folder] : []);
69 | $this->info('Uploading in progress...');
70 | }
71 |
72 | $this->info('Backup to Cloudinary completed!');
73 | } catch (Exception $exception) {
74 | $this->warn("Backup of files to Cloudinary failed because: {$exception->getMessage()}.");
75 | }
76 | }
77 |
78 | public function getFiles($location = 'public')
79 | {
80 | return File::allFiles(storage_path("app/{$location}"));
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/MediaAlly.php:
--------------------------------------------------------------------------------
1 | morphMany(Media::class, 'medially');
26 | }
27 |
28 |
29 | /**
30 | * Attach Media Files to a Model
31 | */
32 | public function attachMedia($file)
33 | {
34 | if(! file_exists($file)) {
35 | throw new Exception('Please pass in a file that exists');
36 | }
37 |
38 | $response = resolve(CloudinaryEngine::class)->uploadFile($file->getRealPath());
39 |
40 | $media = new Media();
41 | $media->file_name = $response->getFileName();
42 | $media->file_url = $response->getSecurePath();
43 | $media->size = $response->getSize();
44 | $media->file_type = $response->getFileType();
45 |
46 | $this->medially()->save($media);
47 | }
48 |
49 | /**
50 | * Attach Remote Media Files to a Model
51 | */
52 | public function attachRemoteMedia($remoteFile)
53 | {
54 | $response = resolve(CloudinaryEngine::class)->uploadFile($remoteFile);
55 |
56 | $media = new Media();
57 | $media->file_name = $response->getFileName();
58 | $media->file_url = $response->getSecurePath();
59 | $media->size = $response->getSize();
60 | $media->file_type = $response->getFileType();
61 |
62 | $this->medially()->save($media);
63 | }
64 |
65 | /**
66 | * Get all the Media files relating to a particular Model record
67 | */
68 | public function fetchAllMedia()
69 | {
70 | return $this->medially()->get();
71 | }
72 |
73 | /**
74 | * Get the first Media file relating to a particular Model record
75 | */
76 | public function fetchFirstMedia()
77 | {
78 | return $this->medially()->first();
79 | }
80 |
81 | /**
82 | * Delete all files associated with a particular Model record
83 | */
84 | public function detachMedia()
85 | {
86 |
87 | $items = $this->medially()->get();
88 |
89 | foreach($items as $item) {
90 | resolve(CloudinaryEngine::class)->destroy($item->getFileName());
91 | }
92 |
93 | return $this->medially()->delete();
94 | }
95 |
96 | /**
97 | * Get the last Media file relating to a particular Model record
98 | */
99 | public function fetchLastMedia()
100 | {
101 | return $this->medially()->get()->last();
102 | }
103 |
104 | /**
105 | * Update the Media files relating to a particular Model record
106 | */
107 | public function updateMedia($file)
108 | {
109 | $this->detachMedia();
110 | $this->attachMedia($file);
111 | }
112 |
113 | /**
114 | * Update the Media files relating to a particular Model record (Specificially existing remote files)
115 | */
116 | public function updateRemoteMedia($file)
117 | {
118 | $this->detachMedia();
119 | $this->attachRemoteMedia($file);
120 | }
121 |
122 | }
--------------------------------------------------------------------------------
/src/CloudinaryServiceProvider.php:
--------------------------------------------------------------------------------
1 | bootMacros();
32 | $this->bootResources();
33 | $this->bootDirectives();
34 | $this->bootComponents();
35 | $this->bootCommands();
36 | $this->bootPublishing();
37 | $this->bootCloudinaryDriver();
38 | }
39 |
40 | /**
41 | * Boot the package macros that extends Laravel Uploaded File API.
42 | *
43 | * @return void
44 | */
45 | protected function bootMacros()
46 | {
47 | UploadedFile::macro(
48 | 'storeOnCloudinary',
49 | function ($folder = null) {
50 | return resolve(CloudinaryEngine::class)->uploadFile($this->getRealPath(), ['folder' => $folder]);
51 | }
52 | );
53 |
54 | UploadedFile::macro(
55 | 'storeOnCloudinaryAs',
56 | function ($folder = null, $publicId = null) {
57 | return resolve(CloudinaryEngine::class)->uploadFile(
58 | $this->getRealPath(),
59 | ['folder' => $folder, 'public_id' => $publicId]
60 | );
61 | }
62 | );
63 | }
64 |
65 | /**
66 | * Boot the package resources.
67 | *
68 | * @return void
69 | */
70 | protected function bootResources()
71 | {
72 | $this->loadViewsFrom(__DIR__ . '/../resources/views', 'cloudinary');
73 | }
74 |
75 | /**
76 | * Boot the package directives.
77 | *
78 | * @return void
79 | */
80 | protected function bootDirectives()
81 | {
82 | Blade::directive(
83 | 'cloudinaryJS',
84 | function () {
85 | return "";
86 | }
87 | );
88 | }
89 |
90 | /**
91 | * Boot the package components.
92 | *
93 | * @return void
94 | */
95 | protected function bootComponents()
96 | {
97 | Blade::component('cloudinary::components.button', 'cld-upload-button');
98 | Blade::component('cloudinary::components.image', 'cld-image');
99 | Blade::component('cloudinary::components.video', 'cld-video');
100 | }
101 |
102 | protected function bootCommands()
103 | {
104 | /**
105 | * Register Laravel Cloudinary Artisan commands
106 | */
107 | if ($this->app->runningInConsole()) {
108 | $this->commands(
109 | [
110 | BackupFilesCommand::class,
111 | UploadFileCommand::class,
112 | FetchFilesCommand::class,
113 | RenameFilesCommand::class,
114 | GenerateArchiveCommand::class,
115 | DeleteFilesCommand::class
116 | ]
117 | );
118 | }
119 | }
120 |
121 | /**
122 | * Boot the package's publishable resources.
123 | *
124 | * @return void
125 | */
126 | protected function bootPublishing()
127 | {
128 | if ($this->app->runningInConsole()) {
129 | $config = dirname(__DIR__) . '/config/cloudinary.php';
130 |
131 | $this->publishes(
132 | [
133 | $config => $this->app->configPath('cloudinary.php'),
134 | ],
135 | 'laravel-cloudinary-config'
136 | );
137 |
138 | $this->publishes(
139 | [
140 | __DIR__.'/../database/migrations' => $this->app->databasePath('migrations'),
141 | ],
142 | 'laravel-cloudinary-migration'
143 | );
144 | }
145 | }
146 |
147 | protected function bootCloudinaryDriver()
148 | {
149 | $this->app['config']['filesystems.disks.cloudinary'] = ['driver' => 'cloudinary'];
150 |
151 | Storage::extend(
152 | 'cloudinary',
153 | function ($app, $config) {
154 | return new Filesystem(new CloudinaryAdapter(config('cloudinary.cloud_url')));
155 | }
156 | );
157 | }
158 |
159 | /**
160 | * Register any package services.
161 | *
162 | * @return void
163 | */
164 | public function register()
165 | {
166 | // Register the service the package provides.
167 | $this->app->singleton(
168 | CloudinaryEngine::class,
169 | function ($app) {
170 | return new CloudinaryEngine();
171 | }
172 | );
173 | }
174 | }
--------------------------------------------------------------------------------
/src/CloudinaryAdapter.php:
--------------------------------------------------------------------------------
1 | cloudinary = new Cloudinary($config);
31 | }
32 |
33 | /**
34 | * Update a file.
35 | * Cloudinary has no specific update method. Overwrite instead.
36 | *
37 | * @param string $path
38 | * @param string $contents
39 | * @param Config $options Config object
40 | *
41 | * @return array|false false on failure file meta data on success
42 | */
43 | public function update($path, $contents, Config $options)
44 | {
45 | return $this->write($path, $contents, $options);
46 | }
47 |
48 | /**
49 | * Write a new file.
50 | * Create temporary stream with content.
51 | * Pass to writeStream.
52 | *
53 | * @param string $path
54 | * @param string $contents
55 | * @param Config $options Config object
56 | *
57 | * @return array|false false on failure file meta data on success
58 | */
59 | public function write($path, $contents, Config $options)
60 | {
61 | $tempFile = tmpfile();
62 |
63 | fwrite($tempFile, $contents);
64 |
65 | return $this->writeStream($path, $tempFile, $options);
66 | }
67 |
68 | /**
69 | * Write a new file using a stream.
70 | *
71 | * @param string $path
72 | * @param resource $resource
73 | * @param Config $options Config object
74 | *
75 | * @return array|false false on failure file meta data on success
76 | */
77 | public function writeStream($path, $resource, Config $options)
78 | {
79 | $publicId = $options->has('public_id') ? $options->get('public_id') : $path;
80 |
81 | $resourceType = $options->has('resource_type') ? $options->get('resource_type') : 'auto';
82 |
83 | $fileExtension = pathinfo($publicId, PATHINFO_EXTENSION);
84 |
85 | $newPublicId = $fileExtension ? substr($publicId, 0, - (strlen($fileExtension) + 1)) : $publicId;
86 |
87 | $uploadOptions = [
88 | 'public_id' => $newPublicId,
89 | 'resource_type' => $resourceType
90 | ];
91 |
92 | $resourceMetadata = stream_get_meta_data($resource);
93 |
94 | $result = resolve(CloudinaryEngine::class)->upload($resourceMetadata['uri'], $uploadOptions);
95 |
96 | return $result;
97 | }
98 |
99 | /**
100 | * Update a file using a stream.
101 | * Cloudinary has no specific update method. Overwrite instead.
102 | *
103 | * @param string $path
104 | * @param resource $resource
105 | * @param Config $options Config object
106 | *
107 | * @return array|false false on failure file meta data on success
108 | */
109 | public function updateStream($path, $resource, Config $options)
110 | {
111 | return $this->writeStream($path, $resource, $options);
112 | }
113 |
114 |
115 | /**
116 | * Rename a file.
117 | * Paths without extensions.
118 | *
119 | * @param string $path
120 | * @param string $newpath
121 | *
122 | * @return bool
123 | */
124 | public function rename($path, $newpath)
125 | {
126 | $pathInfo = pathinfo($path);
127 | $newPathInfo = pathinfo($newpath);
128 |
129 | $remotePath = ($pathInfo['dirname'] != '.') ? pathInfo['dirname'] . '/' . $pathInfo['filename'] : $pathInfo['filename'];
130 |
131 | $remoteNewPath = ($pathInfo['dirname'] != '.') ? $newPathInfo['dirname'] . '/' . $newPathInfo['filename'] : $newPathInfo['filename'];
132 |
133 | $result = $this->uploadApi()->rename($remotePath, $remoteNewPath);
134 |
135 | return $result['public_id'] == $newPathInfo['filename'];
136 | }
137 |
138 | /**
139 | * Expose the Cloudinary v2 Upload Functionality
140 | *
141 | */
142 | protected function uploadApi()
143 | {
144 | return $this->cloudinary->uploadApi();
145 | }
146 |
147 | /**
148 | * Copy a file.
149 | * Copy content from existing url.
150 | *
151 | * @param string $path
152 | * @param string $newpath
153 | *
154 | * @return bool
155 | */
156 | public function copy($path, $newpath)
157 | {
158 | $result = $this->uploadApi()->upload($path, ['public_id' => $newpath]);
159 |
160 | return is_array($result) ? $result['public_id'] == $newpath : false;
161 | }
162 |
163 | /**
164 | * Delete a file.
165 | *
166 | * @param string $path
167 | *
168 | * @return bool
169 | */
170 | public function delete($path)
171 | {
172 | $result = $this->uploadApi()->destroy($path);
173 |
174 | return is_array($result) ? $result['result'] == 'ok' : false;
175 | }
176 |
177 | /**
178 | * Delete a directory.
179 | * Delete Files using directory as a prefix.
180 | *
181 | * @param string $dirname
182 | *
183 | * @return bool
184 | *
185 | * @throws ApiError
186 | */
187 | public function deleteDir($dirname)
188 | {
189 | $this->adminApi()->deleteResourcesByPrefix($dirname);
190 |
191 | return true;
192 | }
193 |
194 | /**
195 | * Expose the Cloudinary v2 Upload Functionality
196 | *
197 | */
198 | protected function adminApi()
199 | {
200 | return $this->cloudinary->adminApi();
201 | }
202 |
203 | /**
204 | * Create a directory.
205 | *
206 | * @param string $dirname directory name
207 | * @param Config $options
208 | *
209 | * @return bool
210 | *
211 | * @throws ApiError
212 | */
213 | public function createDir($dirname, Config $options)
214 | {
215 | $this->adminApi()->createFolder($dirname);
216 |
217 | return true;
218 | }
219 |
220 | /**
221 | * Check whether a file exists.
222 | *
223 | * @param string $path
224 | *
225 | * @return array|bool|null
226 | */
227 | public function has($path)
228 | {
229 | return file_exists($path);
230 | }
231 |
232 | /**
233 | * Read a file.
234 | *
235 | * @param string $path
236 | *
237 | * @return array|false
238 | */
239 | public function read($path)
240 | {
241 | $resource = (array)$this->adminApi()->resource($path);
242 | $contents = file_get_contents($resource['secure_url']);
243 |
244 | return compact('contents', 'path');
245 | }
246 |
247 | /**
248 | * Read a file as a stream.
249 | *
250 | * @param string $path
251 | *
252 | * @return array|false
253 | */
254 | public function readStream($path)
255 | {
256 | $resource = (array)$this->adminApi()->resource($path);
257 |
258 | $stream = fopen($resource['secure_url'], 'rb');
259 |
260 | return compact('stream', 'path');
261 | }
262 |
263 | /**
264 | * List contents of a directory.
265 | *
266 | * @param string $directory
267 | * @param bool $hasR ecursive
268 | *
269 | * @return array
270 | */
271 | public function listContents($directory = '', $hasRecursive = false)
272 | {
273 | $resources = [];
274 |
275 | // get resources array
276 | $response = null;
277 | do {
278 | $response = (array)$this->adminApi()->resources(
279 | [
280 | 'type' => 'upload',
281 | 'prefix' => $directory,
282 | 'max_results' => 500,
283 | 'next_cursor' => isset($response['next_cursor']) ? $response['next_cursor'] : null,
284 | ]
285 | );
286 | $resources = array_merge($resources, $response['resources']);
287 | } while (array_key_exists('next_cursor', $response));
288 |
289 | // parse resourses
290 | foreach ($resources as $i => $resource) {
291 | $resources[$i] = $this->prepareResourceMetadata($resource);
292 | }
293 | return $resources;
294 | }
295 |
296 | /**
297 | * Prepare apropriate metadata for resource metadata given from cloudinary.
298 | * @param array $resource
299 | * @return array
300 | */
301 | protected function prepareResourceMetadata($resource)
302 | {
303 | $resource['type'] = 'file';
304 | $resource['path'] = $resource['public_id'];
305 | $resource = array_merge($resource, $this->prepareSize($resource));
306 | $resource = array_merge($resource, $this->prepareTimestamp($resource));
307 | $resource = array_merge($resource, $this->prepareMimetype($resource));
308 | return $resource;
309 | }
310 |
311 | /**
312 | * prepare size response
313 | *
314 | * @param array $resource
315 | *
316 | * @return array
317 | */
318 | protected function prepareSize($resource)
319 | {
320 | $size = $resource['bytes'];
321 | return compact('size');
322 | }
323 |
324 | /**
325 | * prepare timestamp response
326 | *
327 | * @param array $resource
328 | *
329 | * @return array
330 | */
331 | protected function prepareTimestamp($resource)
332 | {
333 | $timestamp = strtotime($resource['created_at']);
334 | return compact('timestamp');
335 | }
336 |
337 | /**
338 | * prepare mimetype response
339 | *
340 | * @param array $resource
341 | *
342 | * @return array
343 | */
344 | protected function prepareMimetype($resource)
345 | {
346 | $mimetype = $resource['resource_type'];
347 | return compact('mimetype');
348 | }
349 |
350 | /**
351 | * Get all the meta data of a file or directory.
352 | *
353 | * @param string $path
354 | *
355 | * @return array|false
356 | */
357 | public function getMetadata($path)
358 | {
359 | return $this->prepareResourceMetadata($this->getResource($path));
360 | }
361 |
362 | /**
363 | * Get Resource data
364 | * @param string $path
365 | * @return array
366 | */
367 | public function getResource($path)
368 | {
369 | return (array)$this->adminApi()->resource($path);
370 | }
371 |
372 | /**
373 | * Get all the meta data of a file or directory.
374 | *
375 | * @param string $path
376 | *
377 | * @return array|false
378 | */
379 | public function getSize($path)
380 | {
381 | return $this->prepareSize($this->getResource($path));
382 | }
383 |
384 | /**
385 | * Get the mimetype of a file.
386 | *
387 | * @param string $path
388 | *
389 | * @return array|false
390 | */
391 | public function getMimetype($path)
392 | {
393 | return $this->prepareMimetype($this->getResource($path));
394 | }
395 |
396 | /**
397 | * Get the timestamp of a file.
398 | *
399 | * @param string $path
400 | *
401 | * @return array|false
402 | */
403 | public function getTimestamp($path)
404 | {
405 | return $this->prepareTimestamp($this->getResource($path));
406 | }
407 | }
408 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
Laravel Cloudinary (DEPRECATED)
3 |
4 |
5 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | > A Laravel Package for uploading, optimizing, transforming and delivering media files with Cloudinary. Furthermore, it provides a fluent and expressive API to easily attach your media files to Eloquent models.
22 |
23 |
24 | ## Usage
25 |
26 | **Upload** a file (_Image_, _Video_ or any type of _File_) to **Cloudinary**:
27 |
28 | ```php
29 |
30 | /**
31 | * Using the Cloudinary Facade
32 | */
33 |
34 | // Upload an Image File to Cloudinary with One line of Code
35 | $uploadedFileUrl = Cloudinary::upload($request->file('file')->getRealPath())->getSecurePath();
36 |
37 | // Upload a Video File to Cloudinary with One line of Code
38 | $uploadedFileUrl = Cloudinary::uploadVideo($request->file('file')->getRealPath())->getSecurePath();
39 |
40 | // Upload any File to Cloudinary with One line of Code
41 | $uploadedFileUrl = Cloudinary::uploadFile($request->file('file')->getRealPath())->getSecurePath();
42 |
43 | /**
44 | * This package also exposes a helper function you can use if you are not a fan of Facades
45 | * Shorter, expressive, fluent using the
46 | * cloudinary() function
47 | */
48 |
49 | // Upload an Image File to Cloudinary with One line of Code
50 | $uploadedFileUrl = cloudinary()->upload($request->file('file')->getRealPath())->getSecurePath();
51 |
52 | // Upload a Video File to Cloudinary with One line of Code
53 | $uploadedFileUrl = cloudinary()->uploadVideo($request->file('file')->getRealPath())->getSecurePath();
54 |
55 | // Upload any File to Cloudinary with One line of Code
56 | $uploadedFileUrl = cloudinary()->uploadFile($request->file('file')->getRealPath())->getSecurePath();
57 |
58 |
59 |
60 | /**
61 | * You can also skip the Cloudinary Facade or helper method and laravel-ize your uploads by simply calling the
62 | * storeOnCloudinary() method on the file itself
63 | */
64 |
65 | // Store the uploaded file in the "lambogini" directory on Cloudinary
66 | $result = $request->file('image')->store('lambogini', 'cloudinary');
67 |
68 | // Store the uploaded file on Cloudinary
69 | $result = $request->file('file')->storeOnCloudinary();
70 |
71 | // Store the uploaded file on Cloudinary
72 | $result = $request->file->storeOnCloudinary();
73 |
74 | // Store the uploaded file in the "lambogini" directory on Cloudinary
75 | $result = $request->file->storeOnCloudinary('lambogini');
76 |
77 | // Store the uploaded file in the "lambogini" directory on Cloudinary with the filename "prosper"
78 | $result = $request->file->storeOnCloudinaryAs('lambogini', 'prosper');
79 |
80 |
81 | $result->getPath(); // Get the url of the uploaded file; http
82 | $result->getSecurePath(); // Get the url of the uploaded file; https
83 | $result->getSize(); // Get the size of the uploaded file in bytes
84 | $result->getReadableSize(); // Get the size of the uploaded file in bytes, megabytes, gigabytes or terabytes. E.g 1.8 MB
85 | $result->getFileType(); // Get the type of the uploaded file
86 | $result->getFileName(); // Get the file name of the uploaded file
87 | $result->getOriginalFileName(); // Get the file name of the file before it was uploaded to Cloudinary
88 | $result->getPublicId(); // Get the public_id of the uploaded file
89 | $result->getExtension(); // Get the extension of the uploaded file
90 | $result->getWidth(); // Get the width of the uploaded file
91 | $result->getHeight(); // Get the height of the uploaded file
92 | $result->getTimeUploaded(); // Get the time the file was uploaded
93 | ```
94 |
95 | **Attach Files to Laravel Eloquent Models**:
96 |
97 | First, import the `Unicodeveloper\Cloudinary\MediaAlly` trait into your Model like so:
98 |
99 | ```php
100 | request->input());
130 | $page->attachMedia($file); // Example of $file is $request->file('file');
131 |
132 | /**
133 | * How to attach an existing remote file to a Model by model creation
134 | */
135 | $page = Page::create($this->request->input());
136 | $page->attachRemoteMedia($remoteFileUrl); // Example of $remoteFileUrl is https://miro.medium.com/max/4096/1*V1TmCz1GeAQ4T7EWRTWebA.jpeg
137 |
138 | /**
139 | * How to attach a file to a Model by retreiving model records
140 | */
141 | $page = Page::find(2);
142 | $page->attachMedia($file); // Example of $file is $request->file('file');
143 |
144 | /**
145 | * How to attach a remote file to a Model by retreiving model records
146 | */
147 | $page = Page::find(2);
148 | $page->attachRemoteMedia($remoteFileUrl); // Example of $remoteFileUrl is https://miro.medium.com/max/4096/1*V1TmCz1GeAQ4T7EWRTWebA.jpeg
149 |
150 | /**
151 | * How to retrieve files that were attached to a Model
152 | */
153 | $filesBelongingToSecondPage = Page::find(2)->fetchAllMedia();
154 |
155 | /**
156 | * How to retrieve the first file that was attached to a Model
157 | */
158 | $fileBelongingToSecondPage = Page::find(2)->fetchFirstMedia();
159 |
160 | /**
161 | * How to retrieve the last file that was attached to a Model
162 | */
163 | $fileBelongingToSecondPage = Page::find(2)->fetchLastMedia();
164 |
165 | /**
166 | * How to replace/update files attached to a Model
167 | */
168 | $page = Page::find(2);
169 | $page->updateMedia($file); // Example of $file is $request->file('file');
170 |
171 | /**
172 | * How to detach a file from a Model
173 | */
174 | $page = Page::find(2);
175 | $page->detachMedia($file) // Example of $file is $request->file('file');
176 | ```
177 |
178 | **Upload Files Via An Upload Widget**:
179 |
180 | Use the `x-cld-upload-button` Blade upload button component that ships with this Package like so:
181 | ```
182 |
183 |
184 |
185 | ...
186 | @cloudinaryJS
187 |
188 |
189 |
190 | Upload Files
191 |
192 |
193 |
194 | ````
195 |
196 | Other Blade components you can use are:
197 |
198 | ```php
199 | // Blade Image Component for displaying images
200 |
201 | // Blade Video Component for displaying videos
202 | ```
203 |
204 | **Media Management via The Command Line**:
205 |
206 | ```bash
207 | /**
208 | * Back up Files on Cloudinary
209 | */
210 | php artisan cloudinary:backup
211 |
212 | /**
213 | * Delete a File on Cloudinary
214 | */
215 | php artisan cloudinary:delete
216 |
217 | /**
218 | * Fetch a File from Cloudinary
219 | */
220 | php artisan cloudinary:fetch
221 |
222 | /**
223 | * Rename a File from Cloudinary
224 | */
225 | php artisan cloudinary:rename
226 |
227 | /**
228 | * Upload a File to Cloudinary
229 | */
230 | php artisan cloudinary:upload
231 |
232 | /**
233 | * Generate an archive of a group of files and get the zipped downloadable url
234 | */
235 | php artisan cloudinary:archive
236 | ```
237 |
238 |
239 | ## Installation
240 |
241 | [PHP](https://php.net) 7.0+, and [Composer](https://getcomposer.org) are required.
242 |
243 | To get the latest version of Laravel Cloudinary, simply require it:
244 |
245 | ```bash
246 | composer require unicodeveloper/laravel-cloudinary
247 | ```
248 |
249 | Or add the following line to the require block of your `composer.json` file.
250 |
251 | ```
252 | "unicodeveloper/laravel-cloudinary": "1.0.0-beta"
253 | ```
254 |
255 | You'll then need to run `composer install` or `composer update` to download it and have the autoloader updated.
256 |
257 |
258 | Once Laravel Cloudinary is installed, you need to register the service provider. Open up `config/app.php` and add the following to the `providers` key.
259 |
260 | ```php
261 | 'providers' => [
262 | ...
263 | Unicodeveloper\Cloudinary\CloudinaryServiceProvider::class,
264 | ...
265 | ]
266 | ```
267 |
268 | > Note: If you use **Laravel >= 5.5** you can skip this step (adding the code above to the providers key) and go to [**`configuration`**](https://github.com/unicodeveloper/laravel-cloudinary#configuration)
269 |
270 | Also, register the Cloudinary Facade like so:
271 |
272 | ```php
273 | 'aliases' => [
274 | ...
275 | 'Cloudinary' => Unicodeveloper\Cloudinary\Facades\Cloudinary::class,
276 | ...
277 | ]
278 | ```
279 |
280 | ## Configuration
281 |
282 | You can publish the configuration file using this command:
283 |
284 | ```bash
285 | php artisan vendor:publish --provider="Unicodeveloper\Cloudinary\CloudinaryServiceProvider" --tag="laravel-cloudinary-config"
286 | ```
287 |
288 | A configuration-file named `cloudinary.php` with some sensible defaults will be placed in your `config` directory:
289 |
290 | ```php
291 | env('CLOUDINARY_NOTIFICATION_URL'),
304 |
305 |
306 | /*
307 | |--------------------------------------------------------------------------
308 | | Cloudinary Configuration
309 | |--------------------------------------------------------------------------
310 | |
311 | | Here you may configure your Cloudinary settings. Cloudinary is a cloud hosted
312 | | media management service for all file uploads, storage, delivery and transformation needs.
313 | |
314 | |
315 | */
316 | 'cloud_url' => env('CLOUDINARY_URL'),
317 |
318 | /**
319 | * Upload Preset From Cloudinary Dashboard
320 | *
321 | */
322 | 'upload_preset' => env('CLOUDINARY_UPLOAD_PRESET')
323 | ];
324 | ```
325 |
326 | ### API Keys
327 | Open your `.env` file and add your API Environment variable, upload_preset (this is optional, until you need to use the widget) like so:
328 |
329 | ```php
330 | CLOUDINARY_URL=xxxxxxxxxxxxx
331 | CLOUDINARY_UPLOAD_PRESET=xxxxxxxxxxxxx
332 | CLOUDINARY_NOTIFICATION_URL=
333 | ```
334 |
335 | ***Note:** You need to get these credentials from your [Cloudinary Dashboard](https://cloudinary.com/console)*
336 |
337 | *If you are using a hosting service like heroku,forge,digital ocean, etc, please ensure to add the above details to your configuration variables.*
338 |
339 | ### Cloudinary JS
340 |
341 | Cloudinary relies on its own JavaScript library to initiate the Cloudinary Upload Widget. You can load the JavaScript library by placing the @cloudinaryJS directive right before your application layout's closing tag:
342 |
343 | ```html
344 |
345 | ...
346 |
347 | @cloudinaryJS
348 |
349 | ```
350 |
351 | ***Note:** ONLY LOAD THIS IF YOU HAVE DECIDED TO USE THE UPLOAD WIDGET. IF YOU ARE USING THIS PACKAGE FOR A LARAVEL API BACKEND, YOU DON'T NEED TO DO THIS!*
352 |
353 | ## License
354 |
355 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
356 |
--------------------------------------------------------------------------------
/src/CloudinaryEngine.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Unicodeveloper\Cloudinary;
13 |
14 | use Cloudinary\Api\ApiResponse;
15 | use Cloudinary\Api\Exception\ApiError;
16 | use Cloudinary\Cloudinary;
17 | use Cloudinary\Tag\ImageTag;
18 | use Cloudinary\Tag\VideoTag;
19 | use GuzzleHttp\Promise\PromiseInterface;
20 | use Unicodeveloper\Cloudinary\Exceptions\IsNullException;
21 |
22 | /**
23 | * Class CloudinaryEngine
24 | * @package Unicodeveloper\Cloudinary
25 | */
26 | class CloudinaryEngine
27 | {
28 |
29 | /**
30 | *
31 | */
32 | public const ASSET_ID = 'asset_id';
33 | public const PUBLIC_ID = 'public_id';
34 | public const VERSION = 'version';
35 | public const VERSION_ID = 'version_id';
36 | public const SIGNATURE = 'signature';
37 | public const WIDTH = 'width';
38 | public const HEIGHT = 'height';
39 | public const FORMAT = 'format';
40 | public const RESOURCE_TYPE = 'resource_type';
41 | public const CREATED_AT = 'created_at';
42 | public const TAGS = 'tags';
43 | public const PAGES = 'pages';
44 | public const BYTES = 'bytes';
45 | public const TYPE = 'type';
46 | public const ETAG = 'etag';
47 | public const PLACEHOLDER = 'placeholder';
48 | public const URL = 'url';
49 | public const SECURE_URL = 'secure_url';
50 | public const PHASH = 'phash';
51 | public const ORIGINAL_FILENAME = 'original_filename';
52 |
53 | /**
54 | * Instance of Cloudinary
55 | * @var Cloudinary
56 | */
57 | protected $cloudinary;
58 |
59 | /**
60 | * Instance of Cloudinary Config
61 | * @var Configuration
62 | */
63 | protected $cloudinaryConfig;
64 |
65 | /**
66 | * Response from Cloudinary
67 | * @var Array
68 | */
69 | protected $response;
70 |
71 | public function __construct()
72 | {
73 | $this->setCloudinaryConfig();
74 | $this->bootCloudinary();
75 | }
76 |
77 | /**
78 | * Create a Cloudinary Config Instance
79 | *
80 | */
81 | public function setCloudinaryConfig()
82 | {
83 | $config = config('cloudinary.cloud_url');
84 | $this->cloudinaryConfig = $config;
85 | }
86 |
87 | /**
88 | * Create a Cloudinary Instance
89 | *
90 | */
91 | public function bootCloudinary()
92 | {
93 | $this->cloudinary = new Cloudinary($this->cloudinaryConfig);
94 | }
95 |
96 | /**
97 | * Expose the Cloudinary Admin Functionality
98 | *
99 | */
100 | public function admin()
101 | {
102 | return $this->cloudinary->adminApi();
103 | }
104 |
105 | /**
106 | * Expose the Cloudinary Search Functionality
107 | *
108 | */
109 | public function search()
110 | {
111 | return $this->cloudinary->searchApi();
112 | }
113 |
114 | /**
115 | * Uploads an asset to a Cloudinary account.
116 | *
117 | * The asset can be:
118 | * * a local file path
119 | * * the actual data (byte array buffer)
120 | * * the Data URI (Base64 encoded), max ~60 MB (62,910,000 chars)
121 | * * the remote FTP, HTTP or HTTPS URL address of an existing file
122 | * * a private storage bucket (S3 or Google Storage) URL of a whitelisted bucket
123 | *
124 | * @param string $file The asset to upload.
125 | * @param array $options The optional parameters. See the upload API documentation.
126 | *
127 | * @return ApiResponse
128 | *
129 | * @throws ApiError
130 | *
131 | * @see https://cloudinary.com/documentation/image_upload_api_reference#upload_method
132 | */
133 | public function upload($file, $options = [])
134 | {
135 | $this->response = $this->uploadApi()->upload($file, $options);
136 |
137 | return $this;
138 | }
139 |
140 | /**
141 | * Expose the Cloudinary Upload Functionality
142 | *
143 | */
144 | public function uploadApi()
145 | {
146 | return $this->cloudinary->uploadApi();
147 | }
148 |
149 | /**
150 | * Uploads an asset to a Cloudinary account.
151 | *
152 | * The asset can be:
153 | * * a local file path
154 | * * the actual data (byte array buffer)
155 | * * the Data URI (Base64 encoded), max ~60 MB (62,910,000 chars)
156 | * * the remote FTP, HTTP or HTTPS URL address of an existing file
157 | * * a private storage bucket (S3 or Google Storage) URL of a whitelisted bucket
158 | *
159 | * This is asynchronous
160 | */
161 | public function uploadAsync($file, $options = [])
162 | {
163 | return $this->uploadApi()->uploadAsync($file, $options);
164 | }
165 |
166 | /**
167 | * Uploads an asset to a Cloudinary account.
168 | *
169 | * The upload is not signed so an upload preset is required.
170 | *
171 | * @param string $file The asset to upload.
172 | * @param string $uploadPreset The name of an upload preset.
173 | * @param array $options The optional parameters. See the upload API documentation.
174 | *
175 | * @return ApiResponse
176 | *
177 | * @throws ApiError
178 | *
179 | * @see https://cloudinary.com/documentation/image_upload_api_reference#unsigned_upload_syntax
180 | */
181 | public function unsignedUpload($file, $uploadPreset, $options = [])
182 | {
183 | $this->response = $this->uploadApi()->unsignedUpload($file, $uploadPreset, $options);
184 |
185 | return $this;
186 | }
187 |
188 | /**
189 | * Uploads an asset to a Cloudinary account.
190 | *
191 | * The upload is not signed so an upload preset is required.
192 | *
193 | * This is asynchronous
194 | */
195 | public function unsignedUploadAsync($file, $uploadPreset, $options = [])
196 | {
197 | return $this->uploadApi()->unsignedUploadAsync($file, $uploadPreset, $options);
198 | }
199 |
200 | /**
201 | * @param $file
202 | * @param array $options
203 | * @return $this
204 | * @throws ApiError
205 | */
206 | public function uploadFile($file, $options = [])
207 | {
208 | $uploadOptions = array_merge($options, ['resource_type' => 'auto']);
209 |
210 | $this->response = $this->uploadApi()->upload($file, $uploadOptions);
211 |
212 | return $this;
213 | }
214 |
215 | /**
216 | * @param $file
217 | * @param array $options
218 | * @return $this
219 | * @throws ApiError
220 | */
221 | public function uploadVideo($file, $options = [])
222 | {
223 | $videoUploadOptions = array_merge($options, ['resource_type' => 'video']);
224 |
225 | $this->response = $this->uploadApi()->upload($file, $videoUploadOptions);
226 |
227 | return $this;
228 | }
229 |
230 | /**
231 | * @return Array
232 | */
233 | public function getResponse()
234 | {
235 | return $this->response;
236 | }
237 |
238 | /**
239 | * @return mixed
240 | */
241 | public function getAssetId()
242 | {
243 | return $this->response[self::ASSET_ID];
244 | }
245 |
246 | /**
247 | * Get the name of the file after it has been uploaded to Cloudinary
248 | * @return string
249 | */
250 | public function getFileName()
251 | {
252 | return $this->response[self::PUBLIC_ID];
253 | }
254 |
255 | /**
256 | * Get the public id of the file (also known as the name of the file) after it has been uploaded to Cloudinary
257 | * @return string
258 | */
259 | public function getPublicId()
260 | {
261 | return $this->response[self::PUBLIC_ID];
262 | }
263 |
264 | /**
265 | * Get the name of the file before it was uploaded to Cloudinary
266 | * @return string
267 | */
268 | public function getOriginalFileName()
269 | {
270 | return $this->response[self::ORIGINAL_FILENAME];
271 | }
272 |
273 | /**
274 | * @return mixed
275 | */
276 | public function getVersion()
277 | {
278 | return $this->response[self::VERSION];
279 | }
280 |
281 | /**
282 | * @return mixed
283 | */
284 | public function getVersionId()
285 | {
286 | return $this->response[self::VERSION_ID];
287 | }
288 |
289 | /**
290 | * @return mixed
291 | */
292 | public function getSignature()
293 | {
294 | return $this->response[self::SIGNATURE];
295 | }
296 |
297 | /**
298 | * @return mixed
299 | */
300 | public function getWidth()
301 | {
302 | return $this->response[self::WIDTH];
303 | }
304 |
305 | /**
306 | * @return mixed
307 | */
308 | public function getHeight()
309 | {
310 | return $this->response[self::HEIGHT];
311 | }
312 |
313 | /**
314 | * @return mixed
315 | */
316 | public function getExtension()
317 | {
318 | return $this->response[self::FORMAT];
319 | }
320 |
321 | /**
322 | * @return mixed
323 | */
324 | public function getFileType()
325 | {
326 | return $this->response[self::RESOURCE_TYPE];
327 | }
328 |
329 | /**
330 | * @return mixed
331 | */
332 | public function getTimeUploaded()
333 | {
334 | return $this->response[self::CREATED_AT];
335 | }
336 |
337 | /**
338 | * @return mixed
339 | */
340 | public function getTags()
341 | {
342 | return $this->response[self::TAGS];
343 | }
344 |
345 | /**
346 | * @return mixed
347 | */
348 | public function getPages()
349 | {
350 | return $this->response[self::PAGES];
351 | }
352 |
353 | /**
354 | * @return string
355 | */
356 | public function getReadableSize()
357 | {
358 | return $this->getHumanReadableSize($this->getSize());
359 | }
360 |
361 | /**
362 | * Formats filesize in the way every human understands
363 | *
364 | * @param file $file
365 | * @return string Formatted Filesize, e.g. "113.24 MB".
366 | */
367 | private function getHumanReadableSize($sizeInBytes)
368 | {
369 | if ($sizeInBytes >= 1073741824) {
370 | return number_format($bytes / 1073741824, 2) . ' GB';
371 | } elseif ($sizeInBytes >= 1048576) {
372 | return number_format($bytes / 1048576, 2) . ' MB';
373 | } elseif ($sizeInBytes >= 1024) {
374 | return number_format($bytes / 1024, 2) . ' KB';
375 | } elseif ($sizeInBytes > 1) {
376 | return $sizeInBytes . ' bytes';
377 | } elseif ($sizeInBytes == 1) {
378 | return '1 byte';
379 | } else {
380 | return '0 bytes';
381 | }
382 | }
383 |
384 | /**
385 | * @return mixed
386 | */
387 | public function getSize()
388 | {
389 | return $this->response[self::BYTES];
390 | }
391 |
392 | /**
393 | * @return mixed
394 | */
395 | public function getPlaceHolder()
396 | {
397 | return $this->response[self::PLACEHOLDER];
398 | }
399 |
400 | /**
401 | * @return mixed
402 | */
403 | public function getPath()
404 | {
405 | return $this->response[self::URL];
406 | }
407 |
408 | /**
409 | * @return mixed
410 | */
411 | public function getSecurePath()
412 | {
413 | return $this->response[self::SECURE_URL];
414 | }
415 |
416 | /**
417 | * @return mixed
418 | */
419 | public function getPhash()
420 | {
421 | return $this->response[self::PHASH];
422 | }
423 |
424 | /**
425 | * Fetches a new Image with current instance configuration.
426 | *
427 | * @param string $publicId The public ID of the image.
428 | *
429 | * @return Image
430 | */
431 | public function getImage($publicId)
432 | {
433 | return $this->cloudinary->image($publicId);
434 | }
435 |
436 | /**
437 | * Fetches a new Video with current instance configuration.
438 | *
439 | * @param string|mixed $publicId The public ID of the video.
440 | *
441 | * @return Video
442 | */
443 | public function getVideo($publicId)
444 | {
445 | return $this->cloudinary->video($publicId);
446 | }
447 |
448 | /**
449 | * Fetches a raw file with current instance configuration.
450 | *
451 | * @param string|mixed $publicId The public ID of the file.
452 | *
453 | * @return File
454 | */
455 | public function getFile($publicId)
456 | {
457 | return $this->cloudinary->raw($publicId);
458 | }
459 |
460 | /**
461 | * @param $publicId
462 | * @return ImageTag
463 | */
464 | public function getImageTag($publicId)
465 | {
466 | return $this->cloudinary->imageTag($publicId);
467 | }
468 |
469 | /**
470 | * @param $publicId
471 | * @return VideoTag
472 | */
473 | public function getVideoTag($publicId)
474 | {
475 | return $this->cloudinary->videoTag($publicId);
476 | }
477 |
478 | /*
479 | |--------------------------------------------------------------------------
480 | | Cloudinary Tags
481 | |--------------------------------------------------------------------------
482 | */
483 |
484 | /**
485 | * Adds a tag to the assets specified.
486 | *
487 | * @param string $tag The name of the tag to add.
488 | * @param array $publicIds The public IDs of the assets to add the tag to.
489 | * @param array $options The optional parameters. See the upload API documentation.
490 | *
491 | * @return ApiResponse
492 | *
493 | * @see https://cloudinary.com/documentation/image_upload_api_reference#tags_method
494 | */
495 | public function addTag($tag, $publicIds = [], $options = [])
496 | {
497 | return $this->uploadApi()->addTag($tag, $publicIds, $options);
498 | }
499 |
500 | /**
501 | * Adds a tag to the assets specified.
502 | *
503 | * This is an asynchronous function.
504 | */
505 | public function addTagAsync($tag, $publicIds = [], $options = [])
506 | {
507 | return $this->uploadApi()->addTagAsync($tag, $publicIds, $options);
508 | }
509 |
510 | /**
511 | * Removes a tag from the assets specified.
512 | *
513 | * @param string $tag The name of the tag to remove.
514 | * @param array|string $publicIds The public IDs of the assets to remove the tags from.
515 | * @param array $options The optional parameters. See the upload API documentation.
516 | *
517 | * @return ApiResponse
518 | *
519 | * @see https://cloudinary.com/documentation/image_upload_api_reference#tags_method
520 | */
521 | public function removeTag($tag, $publicIds = [], $options = [])
522 | {
523 | return $this->uploadApi()->removeTag($tag, $publicIds, $options);
524 | }
525 |
526 | /**
527 | * Removes a tag from the assets specified.
528 | *
529 | * This is an asynchronous function.
530 | *
531 | */
532 | public function removeTagAsync($tag, $publicIds = [], $options = [])
533 | {
534 | return $this->uploadApi()->removeTagAsync($tag, $publicIds, $options);
535 | }
536 |
537 | /**
538 | * Removes all tags from the assets specified.
539 | *
540 | * @param array $publicIds The public IDs of the assets to remove all tags from.
541 | * @param array $options The optional parameters. See the upload API documentation.
542 | *
543 | * @return ApiResponse
544 | *
545 | * @see https://cloudinary.com/documentation/image_upload_api_reference#tags_method
546 | */
547 | public function removeAllTags($publicIds = [], $options = [])
548 | {
549 | return $this->uploadApi()->removeAllTags($publicIds, $options);
550 | }
551 |
552 | /**
553 | * Removes all tags from the assets specified.
554 | *
555 | * This is an asynchronous function.
556 | *
557 | */
558 | public function removeAllTagsAsync($publicIds = [], $options = [])
559 | {
560 | return $this->uploadApi()->removeAllTagsAsync($publicIds, $options);
561 | }
562 |
563 | /**
564 | * Replaces all existing tags on the assets specified with the tag specified.
565 | *
566 | * @param string $tag The new tag with which to replace the existing tags.
567 | * @param array|string $publicIds The public IDs of the assets to replace the tags of.
568 | * @param array $options The optional parameters. See the upload API documentation.
569 | *
570 | * @return ApiResponse
571 | *
572 | * @see https://cloudinary.com/documentation/image_upload_api_reference#tags_method
573 | */
574 | public function replaceTag($tag, $publicIds = [], $options = [])
575 | {
576 | return $this->uploadApi()->replaceTag($tag, $publicIds, $options);
577 | }
578 |
579 | /**
580 | * Replaces all existing tags on the assets specified with the tag specified.
581 | *
582 | * This is an asynchronous function.
583 | *
584 | */
585 | public function replaceTagAsync($tag, $publicIds = [], $options = [])
586 | {
587 | return $this->uploadApi()->replaceTagAsync($tag, $publicIds, $options);
588 | }
589 |
590 | /*
591 | |--------------------------------------------------------------------------
592 | | Cloudinary Sprite & Image Generation
593 | |--------------------------------------------------------------------------
594 | */
595 |
596 | /**
597 | * Creates a sprite from all images that have been assigned a specified tag.
598 | *
599 | * The process produces two files:
600 | * * A single image file containing all the images with the specified tag (PNG by default).
601 | * * A CSS file that includes the style class names and the location of the individual images in the sprite.
602 | *
603 | * @param string $tag The tag that indicates which images to include in the sprite.
604 | * @param array $options The optional parameters. See the upload API documentation.
605 | *
606 | * @return ApiResponse
607 | *
608 | * @see https://cloudinary.com/documentation/image_upload_api_reference#sprite_method
609 | */
610 | public function generateSprite($tag, $options = [])
611 | {
612 | return $this->uploadApi()->generateSprite($tag, $options);
613 | }
614 |
615 | /**
616 | * Creates a sprite from all images that have been assigned a specified tag.
617 | *
618 | * This is an asynchronous function.
619 | */
620 | public function generateSpriteAsync($tag, $options = [])
621 | {
622 | return $this->uploadApi()->generateSpriteAsync($tag, $options);
623 | }
624 |
625 | /**
626 | * Creates a PDF file from images in your media library that have been assigned a specific tag.
627 | *
628 | * Important note for free accounts:
629 | * By default, while you can use this method to generate PDF files, free Cloudinary accounts are blocked from delivering
630 | * files in PDF format for security reasons.
631 | *For details or to request that this limitation be removed for your free account, see Media delivery.
632 | *
633 | * @see https://cloudinary.com/documentation/paged_and_layered_media#creating_pdf_files_from_images
634 | */
635 | public function generatePDF($tag, $options = [])
636 | {
637 | $pdfOptions = array_merge($options, ['async' => false, 'format' => 'pdf']);
638 |
639 | return $this->uploadApi()->multi($tag, $pdfOptions);
640 | }
641 |
642 | /**
643 | * @param $tag
644 | * @param array $options
645 | * @return ApiResponse
646 | */
647 | public function generatePDFAsync($tag, $options = [])
648 | {
649 | $pdfOptions = array_merge($options, ['async' => true, 'format' => 'pdf']);
650 |
651 | return $this->uploadApi()->multi($tag, $pdfOptions);
652 | }
653 |
654 | /**
655 | * @param $tag
656 | * @param array $options
657 | * @return ApiResponse
658 | */
659 | public function generateAnimatedGIF($tag, $options = [])
660 | {
661 | $gifOptions = array_merge($options, ['async' => false, 'format' => 'gif']);
662 |
663 | return $this->uploadApi()->multi($tag, $gifOptions);
664 | }
665 |
666 | /**
667 | * @param $tag
668 | * @param array $options
669 | * @return ApiResponse
670 | */
671 | public function generateAnimatedPNG($tag, $options = [])
672 | {
673 | $pngOptions = array_merge($options, ['async' => false, 'format' => 'png']);
674 |
675 | return $this->uploadApi()->multi($tag, $pngOptions);
676 | }
677 |
678 | /**
679 | * @param $tag
680 | * @param array $options
681 | * @return ApiResponse
682 | */
683 | public function generateAnimatedPNGAsync($tag, $options = [])
684 | {
685 | $pngOptions = array_merge($options, ['async' => true, 'format' => 'png']);
686 |
687 | return $this->uploadApi()->multi($tag, $pngOptions);
688 | }
689 |
690 | /**
691 | * @param $tag
692 | * @param array $options
693 | * @return ApiResponse
694 | */
695 | public function generateAnimatedWEBP($tag, $options = [])
696 | {
697 | $webpOptions = array_merge($options, ['async' => false, 'format' => 'webp']);
698 |
699 | return $this->uploadApi()->multi($tag, $webpOptions);
700 | }
701 |
702 | /**
703 | * @param $tag
704 | * @param array $options
705 | * @return ApiResponse
706 | */
707 | public function generateAnimatedWEBPAsync($tag, $options = [])
708 | {
709 | $webpOptions = array_merge($options, ['async' => true, 'format' => 'webp']);
710 |
711 | return $this->uploadApi()->multi($tag, $webpOptions);
712 | }
713 |
714 | /**
715 | * @param $tag
716 | * @param array $options
717 | * @return ApiResponse
718 | */
719 | public function generateAnimatedMP4($tag, $options = [])
720 | {
721 | $mp4Options = array_merge($options, ['async' => false, 'format' => 'mp4']);
722 |
723 | return $this->uploadApi()->multi($tag, $mp4Options);
724 | }
725 |
726 | /**
727 | * @param $tag
728 | * @param array $options
729 | * @return ApiResponse
730 | */
731 | public function generateAnimatedMP4Async($tag, $options = [])
732 | {
733 | $mp4Options = array_merge($options, ['async' => true, 'format' => 'mp4']);
734 |
735 | return $this->uploadApi()->multi($tag, $mp4Options);
736 | }
737 |
738 | /**
739 | * @param $tag
740 | * @param array $options
741 | * @return ApiResponse
742 | */
743 | public function generateAnimatedWEBM($tag, $options = [])
744 | {
745 | $webmOptions = array_merge($options, ['async' => false, 'format' => 'webm']);
746 |
747 | return $this->uploadApi()->multi($tag, $webmOptions);
748 | }
749 |
750 | /**
751 | * @param $tag
752 | * @param array $options
753 | * @return ApiResponse
754 | */
755 | public function generateAnimatedWEBMAsync($tag, $options = [])
756 | {
757 | $webmOptions = array_merge($options, ['async' => true, 'format' => 'webm']);
758 |
759 | return $this->uploadApi()->multi($tag, $webmOptions);
760 | }
761 |
762 | /**
763 | * @param $tag
764 | * @param array $options
765 | * @return ApiResponse
766 | */
767 | public function multi($tag, $options = [])
768 | {
769 | return $this->uploadApi()->multi($tag, $options);
770 | }
771 |
772 | /**
773 | * @param $tag
774 | * @param array $options
775 | * @return PromiseInterface
776 | */
777 | public function multiAsync($tag, $options = [])
778 | {
779 | return $this->uploadApi()->multiAsync($tag, $options);
780 | }
781 |
782 | /**
783 | * @param $publicId
784 | * @param array $options
785 | * @return ApiResponse
786 | */
787 | public function explode($publicId, $options = [])
788 | {
789 | return $this->uploadApi()->explode($publicId, $options);
790 | }
791 |
792 | /**
793 | * @param $publicId
794 | * @param array $options
795 | * @return PromiseInterface
796 | */
797 | public function explodeAsync($publicId, $options = [])
798 | {
799 | return $this->uploadApi()->explodeAsync($publicId, $options);
800 | }
801 |
802 | /**
803 | * Dynamically generates an image from a given textual string.
804 | *
805 | * @param string $text The text string to generate an image for.
806 | * @param array $options The optional parameters. See the upload API documentation.
807 | *
808 | * @return ApiResponse
809 | *
810 | * @see https://cloudinary.com/documentation/image_upload_api_reference#text_method
811 | */
812 | public function generateImageFromText($text, $options = [])
813 | {
814 | $this->response = $this->uploadApi()->text($text, $options);
815 |
816 | return $this;
817 | }
818 |
819 | /**
820 | * @param $text
821 | * @param array $options
822 | * @return PromiseInterface
823 | */
824 | public function generateImageFromTextAsync($text, $options = [])
825 | {
826 | return $this->uploadApi()->textAsync($text, $options);
827 | }
828 |
829 | /*
830 | |--------------------------------------------------------------------------
831 | | Cloudinary Zip & Archives
832 | |--------------------------------------------------------------------------
833 | */
834 |
835 | /**
836 | * @param array $options
837 | * @param null $targetFormat
838 | * @return ApiResponse
839 | */
840 | public function createArchive($options = [], $targetFormat = null)
841 | {
842 | return $this->uploadApi()->createArchive($options, $targetFormat);
843 | }
844 |
845 | /**
846 | * @param array $options
847 | * @param null $targetFormat
848 | * @return PromiseInterface
849 | */
850 | public function createArchiveAsync($options = [], $targetFormat = null)
851 | {
852 | return $this->uploadApi()->createArchiveAsync($options, $targetFormat);
853 | }
854 |
855 | /**
856 | * @param array $options
857 | * @return ApiResponse
858 | */
859 | public function createZip($options = [])
860 | {
861 | return $this->uploadApi()->createZip($options);
862 | }
863 |
864 | /**
865 | * @param array $options
866 | * @return PromiseInterface
867 | */
868 | public function createZipAsync($options = [])
869 | {
870 | return $this->uploadApi()->createZipAsync($options);
871 | }
872 |
873 | /**
874 | * @param array $options
875 | * @return string
876 | */
877 | public function downloadZipUrl($options = [])
878 | {
879 | return $this->uploadApi()->downloadZipUrl($options);
880 | }
881 |
882 | /**
883 | * @param array $options
884 | * @return string
885 | */
886 | public function downloadArchiveUrl($options = [])
887 | {
888 | return $this->uploadApi()->downloadArchiveUrl($options);
889 | }
890 |
891 | /*
892 | |--------------------------------------------------------------------------
893 | | Cloudinary Context
894 | |--------------------------------------------------------------------------
895 | */
896 |
897 | /**
898 | * @param $context
899 | * @param array $publicIds
900 | * @param array $options
901 | * @return ApiResponse
902 | */
903 | public function addContext($context, $publicIds = [], $options = [])
904 | {
905 | return $this->uploadApi()->addContext($context, $publicIds, $options);
906 | }
907 |
908 | /**
909 | * @param $context
910 | * @param array $publicIds
911 | * @param array $options
912 | * @return PromiseInterface
913 | */
914 | public function addContextAsync($context, $publicIds = [], $options = [])
915 | {
916 | return $this->uploadApi()->addContextAsync($context, $publicIds, $options);
917 | }
918 |
919 | /**
920 | * @param array $publicIds
921 | * @param array $options
922 | * @return ApiResponse
923 | */
924 | public function removeAllContext($publicIds = [], $options = [])
925 | {
926 | return $this->uploadApi()->removeAllContext($publicIds, $options);
927 | }
928 |
929 | /**
930 | * @param array $publicIds
931 | * @param array $options
932 | * @return PromiseInterface
933 | */
934 | public function removeAllContextAsync($publicIds = [], $options = [])
935 | {
936 | return $this->uploadApi()->removeAllContextAsync($publicIds, $options);
937 | }
938 |
939 | /*
940 | |--------------------------------------------------------------------------
941 | | Cloudinary Delete & Rename Assets
942 | |--------------------------------------------------------------------------
943 | */
944 |
945 | /**
946 | * @param $publicId
947 | * @param array $options
948 | * @return ApiResponse
949 | */
950 | public function destroy($publicId, $options = [])
951 | {
952 | return $this->uploadApi()->destroy($publicId, $options);
953 | }
954 |
955 | /**
956 | * @param $publicId
957 | * @param array $options
958 | * @return PromiseInterface
959 | */
960 | public function destroyAsync($publicId, $options = [])
961 | {
962 | return $this->uploadApi()->destroyAsync($publicId, $options);
963 | }
964 |
965 | /**
966 | * @param $from
967 | * @param $to
968 | * @param array $options
969 | * @return mixed
970 | */
971 | public function rename($from, $to, $options = [])
972 | {
973 | return $this->uploadApi()->rename($from, $to, $options);
974 | }
975 |
976 | /**
977 | * @param $from
978 | * @param $to
979 | * @param array $options
980 | * @return PromiseInterface
981 | */
982 | public function renameAsync($from, $to, $options = [])
983 | {
984 | return $this->uploadApi()->renameAsync($from, $to, $options);
985 | }
986 |
987 | /**
988 | * @param $publicId
989 | * @param array $options
990 | * @return mixed
991 | */
992 | public function explicit($publicId, $options = [])
993 | {
994 | return $this->uploadApi()->explicit($publicId, $options);
995 | }
996 |
997 | /**
998 | * @param $publicId
999 | * @param array $options
1000 | * @return PromiseInterface
1001 | */
1002 | public function explicitAsync($publicId, $options = [])
1003 | {
1004 | return $this->uploadApi()->explicitAsync($publicId, $options);
1005 | }
1006 | }
1007 |
--------------------------------------------------------------------------------