commit e3e7af347bc6d874c0cac9a068d5867b1a84357f Author: dimti Date: Sun Jul 10 10:27:25 2022 +0300 Initial commit diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..5eabd88 --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +LOG_TYPE=html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a85490c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.idea +/.env +/vendor diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..164758e --- /dev/null +++ b/composer.json @@ -0,0 +1,23 @@ +{ + "name": "wpstudio/media-cloud-transform", + "description": "Convert attachment meta to compatible with Media Cloud S3", + "type": "library", + "require": { + "guzzle/http": "^3.7@dev", + "symfony/event-dispatcher": "4.4.x-dev", + "vlucas/phpdotenv": "5.4.x-dev" + }, + "license": "MIT", + "authors": [ + { + "name": "WP Studio", + "email": "info@wpstudio.ru" + } + ], + "autoload": { + "psr-4": { + "WpsMcloud\\": "src" + } + }, + "minimum-stability": "dev" +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..46365b0 --- /dev/null +++ b/composer.lock @@ -0,0 +1,845 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "55ed68dc29f8c2cfbb4655fc5e5d1abb", + "packages": [ + { + "name": "graham-campbell/result-type", + "version": "1.0.x-dev", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "ec4daa4b45faf6a683c9c0acf92fe1377d695a54" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/ec4daa4b45faf6a683c9c0acf92fe1377d695a54", + "reference": "ec4daa4b45faf6a683c9c0acf92fe1377d695a54", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "phpoption/phpoption": "^1.8" + }, + "require-dev": { + "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" + }, + "default-branch": true, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/1.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2022-02-07T10:52:05+00:00" + }, + { + "name": "guzzle/common", + "version": "v3.9.2", + "target-dir": "Guzzle/Common", + "source": { + "type": "git", + "url": "https://github.com/Guzzle3/common.git", + "reference": "2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Guzzle3/common/zipball/2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc", + "reference": "2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "symfony/event-dispatcher": ">=2.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle\\Common": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Common libraries used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "collection", + "common", + "event", + "exception" + ], + "abandoned": "guzzle/guzzle", + "time": "2014-08-11T04:32:36+00:00" + }, + { + "name": "guzzle/http", + "version": "v3.9.2", + "target-dir": "Guzzle/Http", + "source": { + "type": "git", + "url": "https://github.com/Guzzle3/http.git", + "reference": "1e8dd1e2ba9dc42332396f39fbfab950b2301dc5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Guzzle3/http/zipball/1e8dd1e2ba9dc42332396f39fbfab950b2301dc5", + "reference": "1e8dd1e2ba9dc42332396f39fbfab950b2301dc5", + "shasum": "" + }, + "require": { + "guzzle/common": "self.version", + "guzzle/parser": "self.version", + "guzzle/stream": "self.version", + "php": ">=5.3.2" + }, + "suggest": { + "ext-curl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle\\Http": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "HTTP libraries used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "client", + "curl", + "http", + "http client" + ], + "abandoned": "guzzle/guzzle", + "time": "2014-08-11T04:32:36+00:00" + }, + { + "name": "guzzle/parser", + "version": "v3.9.2", + "target-dir": "Guzzle/Parser", + "source": { + "type": "git", + "url": "https://github.com/Guzzle3/parser.git", + "reference": "6874d171318a8e93eb6d224cf85e4678490b625c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Guzzle3/parser/zipball/6874d171318a8e93eb6d224cf85e4678490b625c", + "reference": "6874d171318a8e93eb6d224cf85e4678490b625c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle\\Parser": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Interchangeable parsers used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "URI Template", + "cookie", + "http", + "message", + "url" + ], + "abandoned": "guzzle/guzzle", + "time": "2014-02-05T18:29:46+00:00" + }, + { + "name": "guzzle/stream", + "version": "v3.9.2", + "target-dir": "Guzzle/Stream", + "source": { + "type": "git", + "url": "https://github.com/Guzzle3/stream.git", + "reference": "60c7fed02e98d2c518dae8f97874c8f4622100f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Guzzle3/stream/zipball/60c7fed02e98d2c518dae8f97874c8f4622100f0", + "reference": "60c7fed02e98d2c518dae8f97874c8f4622100f0", + "shasum": "" + }, + "require": { + "guzzle/common": "self.version", + "php": ">=5.3.2" + }, + "suggest": { + "guzzle/http": "To convert Guzzle request objects to PHP streams" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle\\Stream": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle stream wrapper component", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "component", + "stream" + ], + "abandoned": "guzzle/guzzle", + "time": "2014-05-01T21:36:02+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "5f59b1b59025b3c66cf1ca0898247d9de39c6200" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/5f59b1b59025b3c66cf1ca0898247d9de39c6200", + "reference": "5f59b1b59025b3c66cf1ca0898247d9de39c6200", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/master" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2021-12-13T23:19:03+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "4.4.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "3ccfcfb96ecce1217d7b0875a0736976bc6e63dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3ccfcfb96ecce1217d7b0875a0736976bc6e63dc", + "reference": "3ccfcfb96ecce1217d7b0875a0736976bc6e63dc", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "symfony/event-dispatcher-contracts": "^1.1", + "symfony/polyfill-php80": "^1.16" + }, + "conflict": { + "symfony/dependency-injection": "<3.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "1.1" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/error-handler": "~3.4|~4.4", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/stopwatch": "^3.4|^4.0|^5.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:41:36+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "1.1.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "1d5cd762abaa6b2a4169d3e77610193a7157129e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/1d5cd762abaa6b2a4169d3e77610193a7157129e", + "reference": "1d5cd762abaa6b2a4169d3e77610193a7157129e", + "shasum": "" + }, + "require": { + "php": ">=7.1.3" + }, + "suggest": { + "psr/event-dispatcher": "", + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:41:36+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/main" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/main" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c", + "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-04T08:16:47+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "dd46c263f277573244c517bac125a78f67b83a98" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/dd46c263f277573244c517bac125a78f67b83a98", + "reference": "dd46c263f277573244c517bac125a78f67b83a98", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.0.2", + "php": "^7.1.3 || ^8.0", + "phpoption/phpoption": "^1.8", + "symfony/polyfill-ctype": "^1.23", + "symfony/polyfill-mbstring": "^1.23.1", + "symfony/polyfill-php80": "^1.23.1" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "ext-filter": "*", + "phpunit/phpunit": "^7.5.20 || ^8.5.21 || ^9.5.10" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.4-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/master" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2021-12-17T00:42:26+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": { + "guzzle/http": 20, + "symfony/event-dispatcher": 20, + "vlucas/phpdotenv": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/config/logger.php b/config/logger.php new file mode 100644 index 0000000..55589f9 --- /dev/null +++ b/config/logger.php @@ -0,0 +1,10 @@ + $_ENV['LOG_TYPE'] ?? 'html', +]; diff --git a/plugin.png b/plugin.png new file mode 100644 index 0000000..7b77275 Binary files /dev/null and b/plugin.png differ diff --git a/plugin.svg b/plugin.svg new file mode 100644 index 0000000..12716ef --- /dev/null +++ b/plugin.svg @@ -0,0 +1,113 @@ + + diff --git a/src/Actions/Convert.php b/src/Actions/Convert.php new file mode 100644 index 0000000..f2d8090 --- /dev/null +++ b/src/Actions/Convert.php @@ -0,0 +1,37 @@ +attachment = new Attachment(); + + $this->replacer = new ReplacerService(); + } + + public function run() + { + $images = $this->attachment->getImagesWithoutS3MetaData(); + + echo sprintf('Count for the processing: %d
', count($images)); + + foreach ($images as $post) { + $this->replacer->processImage($post); + } + + echo sprintf('Processed: %d
', Counters::$processedImages); + echo sprintf('Not found: %d
', Counters::$imagesNotFound); + } +} diff --git a/src/Actions/Convert/Attachment.php b/src/Actions/Convert/Attachment.php new file mode 100644 index 0000000..fb0d084 --- /dev/null +++ b/src/Actions/Convert/Attachment.php @@ -0,0 +1,33 @@ +posts.ID, $wpdb->posts.guid, $wpdb->posts.post_mime_type, $wpdb->postmeta.meta_id, $wpdb->postmeta.meta_value +FROM $wpdb->posts + JOIN $wpdb->postmeta ON $wpdb->posts.ID=$wpdb->postmeta.post_id + LEFT JOIN $wpdb->postmeta pm2 ON $wpdb->posts.ID=pm2.post_id AND pm2.meta_key = %s +WHERE + $wpdb->posts.post_type = %s and + $wpdb->postmeta.meta_key = %s and + $wpdb->postmeta.meta_value not like %s and + pm2.meta_id IS NULL +EOF; + + return PostAttachment::get($wpdb->get_results($wpdb->prepare( + $query, + [ + PostAttachment::META_KEY_FLAGGED_AS_404, + 'attachment', + '_wp_attachment_metadata', + '%' . $wpdb->esc_like('"s3"') . '%', + ] + ))); + } +} diff --git a/src/Actions/Convert/Replacer/PostAttachmentReplacer.php b/src/Actions/Convert/Replacer/PostAttachmentReplacer.php new file mode 100644 index 0000000..912f689 --- /dev/null +++ b/src/Actions/Convert/Replacer/PostAttachmentReplacer.php @@ -0,0 +1,115 @@ +post = $post; + + $this->replacer = $replacer; + + $this->mcloudPostUrl = str_replace( + $replacer->getUploadsDirBaseUrl(), + $replacer->getMcloudBaseUrl(), + $post->getUrl() + ); + + $this->mcloudPostBaseUrl = trailingslashit( + str_replace($this->post->getBasename(), '', $this->mcloudPostUrl) + ); + + $this->localPostBaseUrl = trailingslashit( + str_replace($this->post->getBasename(), '', $this->post->getUrl()) + ); + + $this->key = ltrim( + str_replace($replacer->getMcloudBaseUrl(), '', $this->mcloudPostUrl), + '/', + ); + + $this->baseKey = ltrim( + trailingslashit( + str_replace( + $this->post->getBasename(), + '', + $this->key + ) + ), + '/' + ); + } + + public function getGeneralS3Info(): array + { + return $this->getS3Info($this->getMcloudPostUrl(), $this->getKey()); + } + + public function getSizeS3Info(string $sizeFilename): array + { + return $this->getS3Info( + $this->getMcloudPostBaseUrl() . $sizeFilename, + $this->getBaseKey() . $sizeFilename + ); + } + + private function getS3Info(string $url, string $key): array + { + return [ + 'url' => $url, + 'bucket' => $this->replacer->getBucket(), + 'provider' => 's3', + 'privacy' => ReplacerService::S3_ACL, + 'v' => MEDIA_CLOUD_INFO_VERSION, + 'key' => $key, + 'options' => [], + 'mime-type' => $this->post->getPostMimeType(), + ]; + } + + public function getMcloudPostUrl(): string + { + return $this->mcloudPostUrl; + } + + public function getMcloudPostBaseUrl(): string + { + return $this->mcloudPostBaseUrl; + } + + public function getLocalPostBaseUrl(): string + { + return $this->localPostBaseUrl; + } + + public function getKey(): string + { + return $this->key; + } + + public function getBaseKey(): string + { + return $this->baseKey; + } +} diff --git a/src/Actions/Convert/ReplacerService.php b/src/Actions/Convert/ReplacerService.php new file mode 100644 index 0000000..838b68e --- /dev/null +++ b/src/Actions/Convert/ReplacerService.php @@ -0,0 +1,100 @@ +uploadsDirBaseUrl = trailingslashit(wp_get_upload_dir()['baseurl']); + $this->mcloudEndPoint = trailingslashit(get_option('mcloud-storage-s3-endpoint')); + $this->bucket = get_option('mcloud-storage-s3-bucket'); + + $this->mcloudBaseUrl = trailingslashit( $this->getMcloudEndPoint() . $this->bucket); + } + + public function processImage(PostAttachment $post): void + { + if (!Http::fileExists($post->getUrl())) { + $post->setFlaggedAs404(); + + echo sprintf('Not found image %d: %s', $post->getId(), $post->getUrl()); + + Counters::$imagesNotFound++; + + return; + } + + $postAttachmentReplacer = new Convert\Replacer\PostAttachmentReplacer($post, $this); + + $meta = $post->getMeta(); + + $meta['file'] = $postAttachmentReplacer->getKey(); + $meta['s3'] = $postAttachmentReplacer->getGeneralS3Info(); + + if (array_key_exists('sizes', $meta) && is_array($meta['sizes'])) { + $newSizes = []; + + foreach ($meta['sizes'] as $size => $sizeData) { + $sizeFilename = $sizeData['file']; + + $localSizeUrl = $postAttachmentReplacer->getLocalPostBaseUrl() . $sizeFilename; + + if (!Http::fileExists($localSizeUrl)) { + echo sprintf( + 'Not found size "%s" image %d: %s', + $sizeFilename, + $post->getId(), + $localSizeUrl + ) . PHP_EOL; + + Counters::$imagesNotFound++; + + continue; + } + + $sizeData['s3'] = $postAttachmentReplacer->getSizeS3Info($sizeFilename); + + $newSizes[$size] = $sizeData; + } + + $meta['sizes'] = $newSizes; + } + + update_post_meta( $post->getId(), '_wp_attachment_metadata', $meta ); + + Counters::$processedImages++; + } + + public function getUploadsDirBaseUrl(): string + { + return $this->uploadsDirBaseUrl; + } + + public function getMcloudEndPoint(): string + { + return $this->mcloudEndPoint; + } + + public function getBucket(): string + { + return $this->bucket; + } + + public function getMcloudBaseUrl(): string + { + return $this->mcloudBaseUrl; + } + +} diff --git a/src/Exceptions/LoggerException.php b/src/Exceptions/LoggerException.php new file mode 100644 index 0000000..5ed5608 --- /dev/null +++ b/src/Exceptions/LoggerException.php @@ -0,0 +1,6 @@ +validateLogType($logType); + + $this->logType = $logType; + } + + /** + * @param string $logType + * @throws LoggerException + */ + private function validateLogType(string $logType): void + { + if (!in_array($logType, self::$logTypes)) { + throw new LoggerException('Log type wrong: ' . $logType); + } + } + + public function log(string $message, bool $newLineAfter = true): void + { + switch ($this->logType) { + case self::LOG_TYPE_HTML: + $this->outputToDefaultStream($message, $newLineAfter); + break; + case self::LOG_TYPE_ERROR_LOG: + $this->outputToPhpErrorLog($message); + break; + case self::LOG_TYPE_BOTH: + $this->outputToDefaultStream($message, $newLineAfter); + + $this->outputToPhpErrorLog($message); + break; + } + } + + private function outputToDefaultStream(string $message, bool $newLineAfter): void + { + echo $message; + + if ($newLineAfter) { + echo PHP_EOL; + } + } + + private function outputToPhpErrorLog(string $message): void + { + error_log($message); + } + + public function openPreformating() + { + echo '
';
+    }
+
+    public function closePreformating()
+    {
+        echo '
'; + } +} diff --git a/src/Models/PostAttachment.php b/src/Models/PostAttachment.php new file mode 100644 index 0000000..f39d6a3 --- /dev/null +++ b/src/Models/PostAttachment.php @@ -0,0 +1,68 @@ +id = $post->ID; + $this->meta_value = $post->meta_value; + $this->guid = $post->guid; + $this->post_mime_type = $post->post_mime_type; + } + + public static function get(array $posts): array + { + return array_map(fn ($post) => new self($post), $posts); + } + + public function getId(): string + { + return $this->id; + } + + public function getMeta(): array + { + if (!isset($this->meta)) { + $this->meta = unserialize($this->meta_value); + } + + return $this->meta; + } + + public function getUrl(): string + { + return $this->guid; + } + + public function getBasename(): string + { + return basename($this->getUrl()); + } + + public function getPostMimeType(): string + { + return $this->post_mime_type; + } + + public function setAttachmentMetaData(array $meta) + { + + update_post_meta($this->getId(), self::META_KEY_ATTACHMENT_METADATA, $meta); + } + + public function setFlaggedAs404() + { + add_post_meta($this->getId(), self::META_KEY_FLAGGED_AS_404, 1); + } +} diff --git a/src/Pages/Converter.php b/src/Pages/Converter.php new file mode 100644 index 0000000..19ab5d6 --- /dev/null +++ b/src/Pages/Converter.php @@ -0,0 +1,6 @@ +renderView(); + } + + /** + * @throws ViewNotFoundException + */ + private function renderView(): void + { + $lowerCaseLastPartThisClassName = strtolower(array_reverse(explode('\\', get_class($this)))[0]); + + $filePathWithoutExtension = self::getViewsPath() . DIRECTORY_SEPARATOR .$lowerCaseLastPartThisClassName; + + $allowedExtensions = [ + 'html', + 'php' + ]; + + $fileIsFound = false; + + while (!$fileIsFound && $currentExtension = current($allowedExtensions)) { + if (file_exists($filePath = $filePathWithoutExtension . '.' . $currentExtension)) { + $fileIsFound = true; + + include $filePath; + } + } + + if (!$fileIsFound) { + throw new ViewNotFoundException(sprintf( + 'Not found any view file in view dir "%s" for this controller "%s" with these available extension: %s', + self::getViewsPath(), + $lowerCaseLastPartThisClassName, + implode(', ', $allowedExtensions) + )); + } + } + + private static function getViewsPath(): string + { + return WPSTUDIO_MEDIA_CLOUD_TRANFORM_BASE_PATH . DIRECTORY_SEPARATOR . self::$viewsDir; + } +} diff --git a/src/Support/Counters.php b/src/Support/Counters.php new file mode 100644 index 0000000..4bbb9e2 --- /dev/null +++ b/src/Support/Counters.php @@ -0,0 +1,10 @@ +createRequest('HEAD', $url, null, null, [ + 'allow_redirects' => true, + ])->send(); + + if ($res->getStatusCode() == 200) { + if ($successCallback !== null) { + $successCallback(); + } + + return true; + } + } catch (ClientErrorResponseException $e) { + if ($errorCallback !== null) { + throw $e; + } + } + + if ($errorCallback !== null) { + $errorCallback(); + } + + return false; + } +} diff --git a/views/converter.html b/views/converter.html new file mode 100644 index 0000000..0b8b69c --- /dev/null +++ b/views/converter.html @@ -0,0 +1,5 @@ +

 

+
+ + +
diff --git a/wpstudio-media-cloud-transform.php b/wpstudio-media-cloud-transform.php new file mode 100644 index 0000000..1c6f20f --- /dev/null +++ b/wpstudio-media-cloud-transform.php @@ -0,0 +1,49 @@ + add_submenu_page( + 'media-cloud', + 'Convert local to S3', + 'Convert local to S3', + 'manage_options', + 'convert_local_to_s3', + function () { +// $ilabLoader = require dirname(__FILE__) . '/../ilab-media-tools/vendor/autoload.php'; +// +// $ilabClassLoader = new Composer\Autoload\ClassLoader(); +// $ilabLoader->unregister(); + + include 'vendor/autoload.php'; + + $dotenv = Dotenv\Dotenv::createImmutable(__DIR__); + $dotenv->load(); + + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + $logger = new Logger(); + + echo '
';
+            (new Actions\Convert())->run();
+            echo '
'; + } + + (new Pages\Converter())->render(); + }, + 6 +), 99);