Browse Source

Initial commit

master
dimti 2 years ago
commit
e3e7af347b
  1. 1
      .env.example
  2. 3
      .gitignore
  3. 23
      composer.json
  4. 845
      composer.lock
  5. 10
      config/logger.php
  6. BIN
      plugin.png
  7. 113
      plugin.svg
  8. 37
      src/Actions/Convert.php
  9. 33
      src/Actions/Convert/Attachment.php
  10. 115
      src/Actions/Convert/Replacer/PostAttachmentReplacer.php
  11. 100
      src/Actions/Convert/ReplacerService.php
  12. 6
      src/Exceptions/LoggerException.php
  13. 6
      src/Exceptions/ViewNotFoundException.php
  14. 6
      src/Exceptions/WpstudioMediaCloudTransformException.php
  15. 81
      src/Logger.php
  16. 68
      src/Models/PostAttachment.php
  17. 6
      src/Pages/Converter.php
  18. 55
      src/Pages/Page.php
  19. 10
      src/Support/Counters.php
  20. 46
      src/Support/Http.php
  21. 5
      views/converter.html
  22. 49
      wpstudio-media-cloud-transform.php

1
.env.example

@ -0,0 +1 @@
LOG_TYPE=html

3
.gitignore

@ -0,0 +1,3 @@
/.idea
/.env
/vendor

23
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"
}

845
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"
}

10
config/logger.php

@ -0,0 +1,10 @@
<?php
return [
/**
* Available logging types: html, error_log, both
* default: html
*/
'log_type' => $_ENV['LOG_TYPE'] ?? 'html',
];

BIN
plugin.png

After

Width: 26  |  Height: 20  |  Size: 861 B

113
plugin.svg

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
style="enable-background:new 0 0 499.978 391.973;"
version="1.1"
viewBox="0 0 499.978 391.973"
xml:space="preserve"
id="svg69"
sodipodi:docname="plugin.svg"
inkscape:export-filename="/home/dimti/PhpstormProjects/onhillsport.ru/wp-content/plugins/wpstudio-media-cloud-transform/plugin.png"
inkscape:export-xdpi="4.9922199"
inkscape:export-ydpi="4.9922199"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs73" /><sodipodi:namedview
id="namedview71"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:snap-global="false"
inkscape:zoom="1.3385443"
inkscape:cx="134.1009"
inkscape:cy="238.31859"
inkscape:window-width="1680"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg69" /><g
id="cloud-photo-camera"
style="fill:#9ca2a7;fill-opacity:0.99944663"
inkscape:export-filename="/home/dimti/PhpstormProjects/onhillsport.ru/wp-content/plugins/wpstudio-media-cloud-transform/plugin.png"
inkscape:export-xdpi="4.8983092"
inkscape:export-ydpi="4.8983092"><g
id="cloud-photo-camera_1_"
style="fill:#9ca2a7;fill-opacity:0.99944663"><path
d="M404.157,119.447c-4.323,0-8.528,0.386-12.679,0.938C387.821,53.285,332.257,0,264.272,0 c-55.532,0-97.805,40.413-115.28,89.943c-9.31-2.435-24.017-8.662-34.1-8.662C51.434,81.281,0,132.716,0,196.185 c0,56.818,41.276,103.871,95.445,113.128v25.663c0.054,31.386,25.626,56.948,57.034,56.996H347.51 c31.397-0.048,56.958-25.615,57.001-57.023v-23.888c52.743-0.182,95.467-42.987,95.467-95.8 C499.978,162.342,457.072,119.447,404.157,119.447z M347.478,373.791H152.479c-21.432-0.032-38.809-17.42-38.852-38.841v-23.931 v-99.485c0.043-21.416,17.42-38.814,38.852-38.835h151.611v-4.387c0-5.975,4.88-10.856,10.845-10.856h36.18 c5.964,0,10.845,4.88,10.845,10.856v7.241c0,0.005,0,0.01,0,0.015c14.245,5.771,24.36,19.672,24.371,35.966v99.549v23.867h0.01 C386.297,356.371,368.91,373.759,347.478,373.791z"
style="fill:#9ca2a7;stroke:none;fill-opacity:0.99944663"
id="path58" /><path
d="M347.478,190.978H152.479c-11.23,0.015-20.541,9.316-20.563,20.557v99.549v23.867 c0.022,11.247,9.333,20.541,20.563,20.563h194.999c11.253-0.022,20.563-9.317,20.585-20.563v-23.867v-99.549 C368.041,200.293,358.731,190.993,347.478,190.978z M333.04,338.758c-6.748,0-12.218-5.46-12.218-12.186 c0-6.742,5.47-12.197,12.218-12.197c6.704,0,12.164,5.455,12.164,12.197C345.204,333.298,339.744,338.758,333.04,338.758z M249.984,345.612c-25.412-0.006-47.519-13.929-59.244-34.529c-5.652-9.938-8.936-21.399-8.936-33.649 c0-37.662,30.528-68.185,68.179-68.185c37.661,0,68.178,30.523,68.178,68.185c0,12.249-3.282,23.71-8.936,33.649 C297.502,331.684,275.395,345.607,249.984,345.612z"
style="fill:#9ca2a7;fill-opacity:0.99944663"
id="path60" /><path
d="M249.984,222.964c-30.067,0.054-54.416,24.387-54.438,54.47 c0.011,12.716,4.409,24.381,11.713,33.649c9.955,12.642,25.369,20.783,42.725,20.805c17.366-0.022,32.748-8.163,42.735-20.805 c7.304-9.267,11.702-20.932,11.745-33.649C304.389,247.351,280.072,223.018,249.984,222.964z M271.694,311.083 c-6.275,4.039-13.697,6.452-21.71,6.452c-8.002,0-15.447-2.413-21.689-6.452c-11.071-7.148-18.407-19.511-18.407-33.649 c0-22.15,17.946-40.102,40.096-40.102c22.16,0,40.117,17.951,40.117,40.102C290.101,291.572,282.732,303.934,271.694,311.083z"
style="fill:#9ca2a7;fill-opacity:0.99944663"
id="path62" /><path
d="M249.984,248.644c-15.908,0.015-28.758,12.893-28.79,28.79c0.021,12.4,7.873,22.863,18.878,26.918 c3.101,1.142,6.415,1.867,9.912,1.872c3.496-0.004,6.822-0.729,9.9-1.872c10.995-4.054,18.868-14.518,18.9-26.918 C278.752,261.537,265.891,248.659,249.984,248.644z"
style="fill:#9ca2a7;fill-opacity:0.99944663"
id="path64" /></g></g><g
id="Layer_1"
style="fill:#9ca2a7;fill-opacity:0.99944663"
inkscape:export-filename="/home/dimti/PhpstormProjects/onhillsport.ru/wp-content/plugins/wpstudio-media-cloud-transform/plugin.png"
inkscape:export-xdpi="4.8983092"
inkscape:export-ydpi="4.8983092" /><path
style="fill:#9ca2a7;stroke:none;stroke-width:0.528265;fill-opacity:0.99944663"
d="m 147.12194,391.40068 c -21.58092,-1.82537 -41.41176,-17.51089 -48.365119,-38.25519 -2.481892,-7.40434 -2.837985,-10.88767 -2.862206,-27.99808 l -0.02245,-15.84796 -7.787917,-1.90651 C 66.904118,302.20796 49.064868,292.21289 33.82749,276.99367 -1.1897132,242.0182 -9.7128094,188.66603 12.658314,144.48061 31.809527,106.65487 70.74156,82.131814 112.25642,81.744358 c 9.32416,-0.08702 11.70255,0.458402 36.24519,8.311888 0.32382,0.103619 1.47416,-2.102534 2.56437,-4.918052 16.38881,-42.324824 50.18944,-73.498244 89.0924,-82.1675387 8.71628,-1.9423715 14.34641,-2.50886974 24.76677,-2.49200788 27.65155,0.0447446 53.05887,8.51357878 75.54196,25.17983958 6.90694,5.119973 20.21557,18.364859 25.25287,25.131918 14.12388,18.973848 22.48087,40.181478 24.94964,63.314945 l 0.64833,6.07505 h 12.47763 c 14.01893,0 19.22489,0.73516 30.08672,4.24869 7.26365,2.3496 19.05803,8.27606 25.44455,12.7854 6.5051,4.59307 18.25689,16.34486 22.84996,22.84996 4.50934,6.38651 10.4358,18.1809 12.7854,25.44454 3.49052,10.7907 4.24869,16.10116 4.24869,29.7592 0,13.6943 -0.77231,19.07622 -4.26942,29.75194 -12.01165,36.66831 -46.39396,63.43659 -84.02739,65.41937 l -6.41566,0.33803 -0.26095,15.90132 c -0.2011,12.25378 -0.46488,16.7975 -1.14994,19.80815 -4.89596,21.51615 -20.78701,38.08704 -41.62716,43.40801 -2.32049,0.59247 -6.62637,1.29439 -9.56864,1.55981 -6.57286,0.59296 -197.71686,0.54241 -204.7698,-0.0541 z m 207.96758,-18.21752 c 8.34994,-1.72473 14.88871,-5.41764 20.89206,-11.79924 4.55887,-4.8461 7.77759,-10.72878 9.39537,-17.17138 1.0193,-4.05925 1.04916,-6.0805 1.04556,-70.78758 -0.004,-64.50625 -0.0367,-66.74644 -1.04732,-70.9621 -2.58513,-10.78299 -9.80946,-20.07395 -19.61555,-25.2269 l -3.51361,-1.84635 -0.20439,-5.52153 c -0.18912,-5.10905 -0.32186,-5.6883 -1.77688,-7.75409 -0.86486,-1.22791 -2.62018,-2.78568 -3.9007,-3.46172 -2.32401,-1.22693 -2.36606,-1.22915 -23.29266,-1.22915 -20.92661,0 -20.96865,0.002 -23.29267,1.22915 -1.28051,0.67604 -3.03751,2.2362 -3.90442,3.46702 -1.33323,1.89287 -1.60667,2.84097 -1.77377,6.1501 l -0.19756,3.91224 -78.52259,0.15592 -78.52258,0.15593 -4.11346,1.16455 c -14.05989,3.98046 -24.91362,15.12292 -28.43935,29.19592 -0.59945,2.3927 -0.72792,14.8389 -0.72792,70.52345 0,75.8362 -0.28481,70.13618 3.9329,78.71155 5.50064,11.18379 16.35279,19.34375 28.43044,21.37743 1.3762,0.23173 48.09492,0.44928 103.81937,0.48346 90.14101,0.0553 101.7598,-0.0293 105.32973,-0.76668 z"
id="path718"
inkscape:export-filename="/home/dimti/PhpstormProjects/onhillsport.ru/wp-content/plugins/wpstudio-media-cloud-transform/plugin.png"
inkscape:export-xdpi="4.8983092"
inkscape:export-ydpi="4.8983092" /><path
style="fill:#9ca2a7;stroke:none;stroke-width:1.05653;fill-opacity:0.99944663"
d="m 144.09383,352.97314 c -4.75687,-2.16018 -8.95112,-7.06684 -10.82501,-12.66368 -1.70634,-5.0964 -1.68654,-127.20156 0.0217,-133.9857 1.58262,-6.28512 7.34722,-12.15329 13.6407,-13.88575 3.56854,-0.98235 28.70057,-1.21598 105.75321,-0.9831 l 101.07225,0.30547 4.49973,3.16959 c 2.47486,1.74328 5.60598,5.26499 6.95805,7.82602 l 2.45831,4.65644 v 65.37268 c 0,56.6149 -0.21906,65.89697 -1.63523,69.28631 -2.18139,5.22081 -5.40023,8.56554 -10.51488,10.92611 -4.01577,1.85339 -9.2747,1.95048 -105.6531,1.95048 -96.80559,0 -101.62512,-0.09 -105.77575,-1.97487 z m 122.68025,-9.17157 c 23.72342,-5.64 43.62151,-25.65923 49.78284,-50.08595 2.22746,-8.83084 2.22746,-23.92163 0,-32.75246 -3.22105,-12.76991 -8.48999,-21.80336 -18.50315,-31.7232 -14.23438,-14.10171 -28.47106,-20.01559 -48.18419,-20.01559 -18.89295,0 -33.79972,5.93799 -47.37262,18.8705 -13.6677,13.02283 -20.7424,29.81887 -20.7424,49.24452 0,19.6179 6.00302,34.02164 20.04286,48.09113 18.14849,18.18682 39.89244,24.33455 64.97666,18.37105 z m 72.40695,-6.2578 c 5.89103,-3.04636 8.05983,-11.47617 4.5021,-17.49893 -1.96984,-3.33466 -7.12949,-6.25741 -11.03554,-6.25118 -5.84996,0.009 -12.5187,7.22251 -12.5187,13.54077 0,2.8025 4.32162,8.88883 7.42744,10.46039 3.51958,1.78093 7.87728,1.68682 11.6247,-0.25105 z"
id="path1609"
inkscape:export-filename="/home/dimti/PhpstormProjects/onhillsport.ru/wp-content/plugins/wpstudio-media-cloud-transform/plugin.png"
inkscape:export-xdpi="4.8983092"
inkscape:export-ydpi="4.8983092" /><path
style="fill:#9ca2a7;stroke:none;stroke-width:1.05653;fill-opacity:0.99944663"
d="m 142.99215,390.83263 c -16.83553,-2.86517 -32.14545,-13.968 -40.26375,-29.19949 -5.368839,-10.07298 -6.584079,-16.61057 -6.584079,-35.42019 0,-12.48037 -0.334622,-16.80492 -1.320664,-17.06786 C 72.832423,303.28084 63.874267,299.5852 51.359347,291.2141 -9.5764166,250.45484 -17.131913,164.67596 35.741348,113.90021 54.817595,95.580732 76.093994,85.561642 102.822,82.311833 c 11.78772,-1.433248 18.00965,-0.696408 33.36575,3.951392 6.62495,2.00516 12.40499,3.265803 12.84452,2.801429 0.43953,-0.464373 2.07348,-3.934669 3.63099,-7.711767 16.83033,-40.815009 50.13704,-70.089002 89.7743,-78.904606 10.37679,-2.30787226 33.31177,-2.28570539 45.22929,0.043715 48.87394,9.552984 87.02559,45.270423 99.52812,93.177865 1.37256,5.259419 2.82759,12.932069 3.23339,17.050329 l 0.73783,7.48775 12.81764,-0.0252 c 16.2877,-0.032 27.89519,2.62323 42.40052,9.69937 24.32207,11.86502 43.24291,35.12136 50.34284,61.87829 3.30131,12.44143 3.31297,34.61155 0.0247,47.01563 -10.2804,38.78005 -44.67691,68.19294 -83.53726,71.43377 l -8.24888,0.68793 -0.60596,17.09132 c -0.65285,18.41364 -2.29802,25.79246 -7.90213,35.44218 -6.49971,11.19187 -19.05152,21.29126 -31.87827,25.64978 l -6.94366,2.35945 -104.59657,0.1599 c -57.52811,0.0879 -107.04927,-0.25752 -110.04702,-0.7677 z m 220.45451,-20.61841 c 8.72802,-4.15527 15.29066,-10.71792 19.44593,-19.44593 l 3.26949,-6.86745 v -70.78758 -70.78757 l -2.81081,-5.99598 c -3.33361,-7.1112 -10.13973,-14.80457 -16.28135,-18.40382 -4.22388,-2.47535 -4.44445,-2.85913 -4.9168,-8.55509 -0.41827,-5.04382 -1.01095,-6.42488 -3.84329,-8.95558 l -3.34875,-2.9921 h -22.05875 -22.05875 l -3.28132,3.06522 c -2.63234,2.45897 -3.28133,3.91664 -3.28133,7.37005 v 4.30484 l -80.03223,0.28979 -80.03222,0.2898 -6.33918,2.54887 c -8.69973,3.498 -18.27894,13.08961 -21.7232,21.75134 l -2.52073,6.33919 -0.36602,62.46264 c -0.38871,66.33226 0.17891,78.47513 4.02033,86.00493 4.71376,9.23973 14.51752,17.46866 24.58968,20.63969 3.59318,1.13124 24.73501,1.36238 109.57702,1.19796 l 105.12483,-0.20373 z"
id="path1648"
inkscape:export-filename="/home/dimti/PhpstormProjects/onhillsport.ru/wp-content/plugins/wpstudio-media-cloud-transform/plugin.png"
inkscape:export-xdpi="4.8983092"
inkscape:export-ydpi="4.8983092" /><path
style="fill:#9ca2a7;stroke:none;stroke-width:1.05653;fill-opacity:0.99944663"
d="m 241.69561,330.65954 c -17.39078,-2.92832 -31.92399,-13.68197 -39.93345,-29.54821 -3.63574,-7.20216 -5.221,-14.42287 -5.23485,-23.84431 -0.0215,-14.59585 4.72472,-26.35289 14.92774,-36.97828 10.82867,-11.27693 22.85297,-16.31704 38.84406,-16.28188 12.31408,0.0271 20.96904,2.71946 30.71239,9.55403 11.29316,7.9217 18.72199,19.31402 21.67006,33.23162 1.95029,9.20719 1.95067,11.8766 0.003,21.11219 -4.56281,21.63583 -20.61401,37.68703 -42.24984,42.2497 -8.06281,1.70033 -11.14749,1.78348 -18.73928,0.50514 z m 20.47692,-14.76164 c 19.88381,-6.27176 31.92553,-27.16186 27.27598,-47.31864 -3.752,-16.26574 -16.06355,-27.85135 -32.89141,-30.952 -26.68536,-4.91697 -51.328,19.65252 -46.42109,46.2833 4.57263,24.81655 28.37777,39.4498 52.03652,31.98734 z"
id="path1687"
inkscape:export-filename="/home/dimti/PhpstormProjects/onhillsport.ru/wp-content/plugins/wpstudio-media-cloud-transform/plugin.png"
inkscape:export-xdpi="4.8983092"
inkscape:export-ydpi="4.8983092" /><path
style="fill:#9ca2a7;stroke:none;stroke-width:1.05653;fill-opacity:0.99944663"
d="m 238.24774,302.8516 c -19.37202,-9.04019 -22.05103,-34.85597 -4.9692,-47.88472 17.92343,-13.67066 44.47433,-0.72961 44.56591,21.72166 0.0329,8.06507 -1.82106,13.25462 -6.72583,18.82672 -8.42842,9.5752 -21.71759,12.54116 -32.87088,7.33634 z"
id="path1726"
inkscape:export-filename="/home/dimti/PhpstormProjects/onhillsport.ru/wp-content/plugins/wpstudio-media-cloud-transform/plugin.png"
inkscape:export-xdpi="4.8983092"
inkscape:export-ydpi="4.8983092" /><path
style="fill:#9ca2a7;stroke:none;stroke-width:1.05653;fill-opacity:0.99944663"
d="m 143.58994,390.8611 c -21.77369,-3.25632 -40.18948,-20.07428 -45.87235,-41.89228 -1.058699,-4.06462 -1.573269,-11.28147 -1.573269,-22.06508 0,-11.59576 -0.36502,-16.29428 -1.320664,-16.99954 -0.726365,-0.53606 -5.124175,-2.05745 -9.772912,-3.38087 C 71.948011,302.79317 61.726407,298.14851 51.359347,291.2141 -9.6082519,250.43355 -17.159536,164.70249 35.741348,113.90021 53.796846,96.560989 73.91708,86.547171 97.991627,82.918323 c 16.562243,-2.496488 22.048503,-1.932548 41.819803,4.298712 4.55033,1.434113 8.6399,2.380925 9.08793,2.104025 0.44804,-0.276899 1.66828,-2.777314 2.71165,-5.556477 6.12615,-16.317786 18.50282,-35.233558 31.66844,-48.400198 24.69278,-24.694668 56.42877,-37.1392071 88.77728,-34.81195917 23.79018,1.71153707 44.05009,8.66475467 63.92013,21.93745017 10.61589,7.091157 26.67269,23.449351 34.27707,34.920469 10.67579,16.104296 18.39788,37.280644 20.17641,55.329845 l 0.73596,7.46883 12.81759,0.01 c 15.15481,0.0111 24.93587,1.86607 36.73317,6.96654 13.14628,5.68368 19.55193,9.96178 29.45653,19.67289 13.53526,13.27086 20.50011,24.76191 25.98573,42.87288 2.55926,8.44957 2.85384,11.06618 2.84512,25.27337 -0.0115,18.79532 -1.88401,27.31182 -9.29631,42.282 -13.61185,27.49084 -40.60079,47.55417 -70.26532,52.23445 -3.7771,0.59591 -8.5774,1.08708 -10.66733,1.09148 l -3.79988,0.008 -0.62516,17.16863 c -0.72253,19.84245 -2.53708,27.34591 -9.02475,37.31892 -7.17842,11.03483 -17.20035,18.93722 -30.37866,23.95386 l -6.25476,2.38103 -104.59657,0.15114 c -57.52811,0.0831 -107.2557,-0.24654 -110.50576,-0.7326 z m 219.03059,-20.20896 c 8.43626,-3.95407 15.9928,-11.37312 20.11704,-19.751 l 3.42451,-6.95649 v -70.80949 -70.80947 l -2.75762,-5.81092 c -3.44841,-7.26657 -10.29194,-15.04767 -16.36443,-18.60639 -4.06506,-2.38228 -4.6499,-3.18177 -4.6499,-6.35642 0,-4.8321 -2.37541,-10.28316 -5.40613,-12.40597 -2.08175,-1.4581 -5.82076,-1.72287 -24.33055,-1.72287 h -21.87079 l -3.25087,3.25086 c -2.52526,2.52527 -3.25086,4.17601 -3.25086,7.39572 v 4.14485 h -77.43305 c -86.3835,0 -85.16883,-0.0908 -95.79994,7.15762 -3.17505,2.16478 -7.56786,6.31315 -9.76178,9.21861 -7.54738,9.99515 -7.36628,8.35505 -7.93321,71.84411 -0.59913,67.09215 0.16988,83.264 4.3673,91.84322 3.09259,6.32104 11.11357,14.23788 17.98879,17.75523 2.35472,1.20468 6.89623,2.53601 10.09224,2.95854 3.196,0.42252 51.9285,0.70604 108.29442,0.63002 l 102.48351,-0.13819 z"
id="path1802"
inkscape:export-filename="/home/dimti/PhpstormProjects/onhillsport.ru/wp-content/plugins/wpstudio-media-cloud-transform/plugin.png"
inkscape:export-xdpi="4.8983092"
inkscape:export-ydpi="4.8983092" /><path
style="fill:#9ca2a7;stroke:none;stroke-width:1.05653;fill-opacity:0.99944663"
d="m 143.43823,390.8818 c -17.71869,-2.98353 -33.26499,-14.31643 -41.20063,-30.03432 -4.968319,-9.8406 -5.270636,-11.43528 -5.974823,-31.51631 -0.491878,-14.02667 -1.019214,-19.01834 -2.078314,-19.6729 -0.780559,-0.48241 -5.294439,-1.93134 -10.030847,-3.21984 C 58.40627,299.43408 34.084555,281.70989 19.278328,259.16124 -6.2217447,220.32677 -6.025304,171.928 19.793792,132.16182 25.502013,123.3701 44.651975,104.77417 53.883081,99.058765 69.641888,89.301762 88.980795,83.015161 107.04488,81.777178 c 10.02349,-0.686939 15.07119,0.161172 34.84758,5.855056 6.70062,1.929196 7.22752,1.947512 7.8193,0.271815 0.34901,-0.988225 2.89152,-6.637375 5.65002,-12.553667 13.37758,-28.69145 36.50836,-52.578188 62.88237,-64.937468 30.67929,-14.3767984 68.44946,-13.3445274 101.49226,2.773817 38.39717,18.730214 64.33521,54.515828 70.4574,97.207109 l 1.36166,9.49513 13.67954,0.19158 c 16.18374,0.22665 26.04408,2.44116 39.48887,8.8687 26.45053,12.64521 44.81808,35.04039 52.45464,63.95689 2.88449,10.92239 2.65082,34.96177 -0.45101,46.39813 -6.03123,22.237 -20.32356,42.31406 -39.24959,55.13565 -13.73489,9.30481 -34.18157,16.18019 -48.11821,16.18019 h -4.41235 l -0.57247,17.16863 c -0.6596,19.78188 -2.44106,27.14334 -9.03108,37.31893 -8.08951,12.49093 -23.64146,23.32197 -37.05988,25.81008 -6.82925,1.26631 -207.31102,1.23278 -214.8457,-0.0359 z m 219.23532,-20.25393 c 7.82011,-3.66454 16.44563,-12.31551 20.32784,-20.38784 l 3.04871,-6.33919 0.003,-70.78758 0.003,-70.78757 -2.82305,-5.8503 c -3.64531,-7.55426 -8.92209,-13.66171 -15.38898,-17.8115 -4.83586,-3.10317 -5.20464,-3.65683 -5.80347,-8.71303 -0.74816,-6.31708 -2.93471,-10.10873 -6.64233,-11.51836 -1.46013,-0.55517 -11.94246,-1.00938 -23.29404,-1.00938 H 311.465 l -3.59221,3.5922 c -2.72582,2.72582 -3.5922,4.49 -3.5922,7.31463 v 3.72241 l -80.03223,0.34524 -80.03222,0.34522 -7.07951,3.35385 c -8.337,3.94957 -15.40156,10.63202 -19.53325,18.47672 l -2.97011,5.63923 -0.65776,30.11114 c -1.10556,50.6104 -0.27346,108.26912 1.66702,115.51332 2.79699,10.44168 10.12054,19.03833 20.64963,24.23928 6.88531,3.40107 14.8328,3.62575 124.14239,3.50956 l 96.14432,-0.10217 6.09434,-2.85584 z"
id="path1917"
inkscape:export-filename="/home/dimti/PhpstormProjects/onhillsport.ru/wp-content/plugins/wpstudio-media-cloud-transform/plugin.png"
inkscape:export-xdpi="4.8983092"
inkscape:export-ydpi="4.8983092" /><path
style="fill:#9ca2a7;stroke:none;stroke-width:1.05653;fill-opacity:0.99944663"
d="m 168.51669,354.06915 c -14.50393,-0.41154 -24.0382,-1.11963 -25.35674,-1.88318 -2.98095,-1.72624 -6.29491,-5.54993 -8.55418,-9.86993 -1.81425,-3.46905 -1.93185,-7.71819 -1.90059,-68.67451 0.0303,-59.07885 0.19827,-65.35675 1.85061,-69.16412 2.32252,-5.3516 4.47818,-7.69938 9.35447,-10.18813 3.76727,-1.92274 7.93677,-2.00064 107.08586,-2.00064 h 103.16595 l 4.12801,3.26945 c 2.2704,1.79819 5.37644,5.39972 6.90229,8.00339 l 2.77428,4.73396 -0.52762,65.16137 c -0.57581,71.11137 -0.42831,69.46805 -6.76771,75.39534 -1.66957,1.56103 -4.46189,3.3778 -6.20517,4.03725 -3.63948,1.37677 -146.96026,2.28606 -185.94946,1.17975 z m 93.2689,-8.97193 c 5.71595,-0.76034 12.91247,-2.89429 12.91247,-3.82885 0,-0.39227 0.70504,-0.71322 1.56675,-0.71322 2.06868,0 8.99856,-3.75884 8.99856,-4.8809 0,-0.48325 0.4788,-0.58271 1.06399,-0.22104 0.5852,0.36166 1.34818,-0.0829 1.69551,-0.98811 0.34732,-0.90514 1.04158,-1.39227 1.54278,-1.0825 0.5012,0.30975 1.51662,-0.40614 2.25649,-1.59087 0.73988,-1.18473 1.89478,-2.15406 2.56643,-2.15406 0.67167,0 2.7091,-1.7829 4.52763,-3.96199 1.81852,-2.1791 4.00725,-4.71503 4.86384,-5.63542 0.85658,-0.92039 1.55742,-2.22784 1.55742,-2.90546 0,-0.67762 0.47544,-1.23203 1.05653,-1.23203 0.58109,0 1.05653,-0.71316 1.05653,-1.5848 0,-0.87164 0.40324,-1.58479 0.89608,-1.58479 1.00952,0 5.05949,-8.49179 4.65071,-9.75142 -0.14528,-0.44764 0.14865,-0.81389 0.65317,-0.81389 1.99822,0 4.65643,-13.76697 4.69203,-24.30022 0.0352,-10.42392 -2.59555,-25.35674 -4.46719,-25.35674 -0.38086,0 -0.7627,-0.93227 -0.84853,-2.0717 -0.19453,-2.58247 -5.43686,-11.6632 -6.73319,-11.6632 -0.52588,0 -0.95614,-0.49381 -0.95614,-1.09736 0,-2.4207 -19.6877,-20.39677 -21.26872,-19.41965 -0.50514,0.31219 -0.91843,0.0962 -0.91843,-0.48006 0,-0.97559 -2.63465,-2.25349 -4.52799,-2.19625 -0.45658,0.0138 -1.58762,-0.73238 -2.51342,-1.65819 -0.92582,-0.92581 -2.33516,-1.43315 -3.13187,-1.12742 -0.79671,0.30572 -1.44856,0.0445 -1.44856,-0.58055 0,-0.62502 -0.69794,-0.86858 -1.55096,-0.54125 -0.85303,0.32734 -1.81327,0.17074 -2.13388,-0.34799 -0.69479,-1.12422 -0.8974,-1.14415 -16.38925,-1.61224 -12.79746,-0.38668 -25.11384,1.49918 -27.88423,4.26956 -0.7959,0.7959 -1.7414,1.15277 -2.10113,0.79305 -0.35972,-0.35973 -0.65404,-0.0713 -0.65404,0.64093 0,0.71223 -0.47544,1.00113 -1.05653,0.642 -0.58109,-0.35914 -1.05653,-0.22871 -1.05653,0.28982 0,0.51854 -0.60895,0.9428 -1.35323,0.9428 -1.79389,0 -7.09902,3.51219 -7.09902,4.69981 0,0.51426 -0.38828,0.81616 -0.86284,0.67089 -1.12658,-0.34487 -14.5376,13.06615 -14.19273,14.19273 0.14527,0.47456 -0.15662,0.86283 -0.67088,0.86283 -1.18763,0 -4.69982,5.30514 -4.69982,7.09903 0,0.74427 -0.42426,1.35322 -0.94279,1.35322 -0.51854,0 -0.64896,0.47544 -0.28983,1.05653 0.35914,0.5811 0.12142,1.05653 -0.52826,1.05653 -0.64968,0 -0.9125,0.43484 -0.58404,0.9663 0.32846,0.53146 0.13255,1.12576 -0.43536,1.32066 -0.56791,0.1949 -1.21135,1.30525 -1.42988,2.46743 -0.21854,1.16219 -1.00085,3.53938 -1.73848,5.28266 -2.87244,6.78858 -1.93031,40.67644 1.13086,40.67644 0.48264,0 0.62738,0.65186 0.32165,1.44857 -0.30573,0.79671 0.16199,2.16643 1.03938,3.04381 0.87738,0.87739 1.30093,1.88958 0.9412,2.24929 -0.35972,0.35973 -0.0713,0.65405 0.64093,0.65405 0.71224,0 1.00114,0.47544 0.642,1.05653 -0.35913,0.58109 -0.12141,1.05653 0.52827,1.05653 0.64968,0 0.8874,0.47544 0.52826,1.05653 -0.35913,0.58109 -0.14947,1.05653 0.46592,1.05653 0.61538,0 1.00002,0.44686 0.85475,0.99303 -0.74405,2.79728 22.54424,26.14047 24.73079,24.78911 0.48955,-0.30255 0.89008,-0.10428 0.89008,0.4406 0,1.00555 5.64924,3.74523 6.96815,3.3793 0.39577,-0.10981 1.03125,0.30463 1.41216,0.92096 0.38092,0.61634 1.86039,1.25124 3.28772,1.41091 1.42733,0.15966 2.88185,0.68073 3.23227,1.15794 0.35042,0.47721 2.633,1.01651 5.0724,1.19845 2.43939,0.18193 4.76759,0.66736 5.17379,1.07871 0.73104,0.74035 11.32114,0.26926 20.05025,-0.8919 z m 80.14521,-9.31142 c 3.70515,-3.70513 4.32736,-11.71449 1.29715,-16.69727 -1.14527,-1.88324 -2.35101,-3.15538 -2.67941,-2.82696 -0.32841,0.32841 -1.23128,-0.0371 -2.00636,-0.81215 -1.63727,-1.63725 -9.96104,-2.03386 -9.96104,-0.4746 0,0.57895 -0.40567,0.80195 -0.90147,0.49551 -1.43314,-0.88572 -7.55078,8.41473 -7.55078,11.47919 0,2.87331 0.67438,3.98313 5.48201,9.02185 2.45649,2.57456 3.56489,2.95068 8.19513,2.78099 4.21201,-0.15436 5.94552,-0.7873 8.12477,-2.96656 z"
id="path1993"
inkscape:export-filename="/home/dimti/PhpstormProjects/onhillsport.ru/wp-content/plugins/wpstudio-media-cloud-transform/plugin.png"
inkscape:export-xdpi="4.8983092"
inkscape:export-ydpi="4.8983092" /><path
style="fill:#9ca2a7;stroke:none;stroke-width:0.528265;fill-opacity:0.99944663"
d="m 244.05866,304.51191 c -10.00262,-2.16018 -18.87419,-10.70336 -21.08556,-20.30507 -0.30113,-1.30746 -0.55331,-4.4141 -0.56041,-6.90364 -0.022,-7.72627 2.15997,-13.08717 7.73015,-18.99185 8.59405,-9.11015 20.98529,-11.21594 32.42409,-5.51022 10.61463,5.29462 16.07583,15.79258 14.71897,28.29403 -0.97658,8.9977 -6.63445,16.75358 -15.3188,20.9992 -6.41788,3.13757 -11.437,3.81513 -17.90844,2.41755 z"
id="path2071"
inkscape:export-filename="/home/dimti/PhpstormProjects/onhillsport.ru/wp-content/plugins/wpstudio-media-cloud-transform/plugin.png"
inkscape:export-xdpi="4.8983092"
inkscape:export-ydpi="4.8983092" /></svg>

37
src/Actions/Convert.php

@ -0,0 +1,37 @@
<?php namespace WpsMcloud\Actions;
use WpsMcloud\Actions\Convert\Attachment;
use WpsMcloud\Actions\Convert\ReplacerService;
use WpsMcloud\Support\Counters;
class Convert
{
private Attachment $attachment;
private ReplacerService $replacer;
public static int $countProcessedImages = 0;
public static int $countImagesNotFound = 0;
public function __construct()
{
$this->attachment = new Attachment();
$this->replacer = new ReplacerService();
}
public function run()
{
$images = $this->attachment->getImagesWithoutS3MetaData();
echo sprintf('Count for the processing: %d<br>', count($images));
foreach ($images as $post) {
$this->replacer->processImage($post);
}
echo sprintf('Processed: %d<br>', Counters::$processedImages);
echo sprintf('Not found: %d<br>', Counters::$imagesNotFound);
}
}

33
src/Actions/Convert/Attachment.php

@ -0,0 +1,33 @@
<?php namespace WpsMcloud\Actions\Convert;
use WpsMcloud\Models\PostAttachment;
class Attachment
{
public function getImagesWithoutS3MetaData(): array
{
global $wpdb;
$query = <<<EOF
SELECT $wpdb->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"') . '%',
]
)));
}
}

115
src/Actions/Convert/Replacer/PostAttachmentReplacer.php

@ -0,0 +1,115 @@
<?php namespace WpsMcloud\Actions\Convert\Replacer;
use WpsMcloud\Actions\Convert\ReplacerService;
use WpsMcloud\Models\PostAttachment;
class PostAttachmentReplacer
{
private PostAttachment $post;
private ReplacerService $replacer;
public string $mcloudPostUrl;
public string $mcloudPostBaseUrl;
public string $localPostBaseUrl;
/**
* @var string
* @desc Filename with prepend parts after "wp-content/uploads/"
*/
public string $key;
/**
* @var string Only prepends parts without filename
*/
public string $baseKey;
public function __construct(PostAttachment $post, ReplacerService $replacer)
{
$this->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;
}
}

100
src/Actions/Convert/ReplacerService.php

@ -0,0 +1,100 @@
<?php namespace WpsMcloud\Actions\Convert;
use WpsMcloud\Actions\Convert;
use WpsMcloud\Models\PostAttachment;
use WpsMcloud\Support\Counters;
use WpsMcloud\Support\Http;
class ReplacerService
{
const S3_ACL = 'public-read';
private string $uploadsDirBaseUrl;
private string $mcloudEndPoint;
private string $bucket;
private string $mcloudBaseUrl;
public function __construct()
{
$this->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;
}
}

6
src/Exceptions/LoggerException.php

@ -0,0 +1,6 @@
<?php namespace WpsMcloud\Exceptions;
class LoggerException extends WpstudioMediaCloudTransformException
{
}

6
src/Exceptions/ViewNotFoundException.php

@ -0,0 +1,6 @@
<?php namespace WpsMcloud\Exceptions;
class ViewNotFoundException extends WpstudioMediaCloudTransformException
{
}

6
src/Exceptions/WpstudioMediaCloudTransformException.php

@ -0,0 +1,6 @@
<?php namespace WpsMcloud\Exceptions;
abstract class WpstudioMediaCloudTransformException extends \Exception
{
}

81
src/Logger.php

@ -0,0 +1,81 @@
<?php namespace WpsMcloud;
use WpsMcloud\Exceptions\LoggerException;
class Logger
{
const LOG_TYPE_HTML = 'html';
const LOG_TYPE_ERROR_LOG = 'error_log';
const LOG_TYPE_BOTH = 'both';
private static array $logTypes = [
self::LOG_TYPE_HTML,
self::LOG_TYPE_ERROR_LOG,
self::LOG_TYPE_BOTH,
];
private string $logType;
/**
* @param string $logType
* @throws LoggerException
*/
public function __construct(string $logType)
{
$this->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 '<pre>';
}
public function closePreformating()
{
echo '</pre>';
}
}

68
src/Models/PostAttachment.php

@ -0,0 +1,68 @@
<?php namespace WpsMcloud\Models;
use JetBrains\PhpStorm\Pure;
class PostAttachment
{
const META_KEY_FLAGGED_AS_404 = '_wp_media_cloud_transform_404';
const META_KEY_ATTACHMENT_METADATA = '_wp_attachment_metadata';
public int $id;
public string $meta_value;
public ?array $meta;
public string $guid;
public string $post_mime_type;
public function __construct($post)
{
$this->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);
}
}

6
src/Pages/Converter.php

@ -0,0 +1,6 @@
<?php namespace WpsMcloud\Pages;
class Converter extends Page
{
}

55
src/Pages/Page.php

@ -0,0 +1,55 @@
<?php namespace WpsMcloud\Pages;
use WpsMcloud\Exceptions\ViewNotFoundException;
abstract class Page
{
private static string $viewsDir = 'views';
/**
* @throws ViewNotFoundException
*/
public function render(): void
{
$this->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;
}
}

10
src/Support/Counters.php

@ -0,0 +1,10 @@
<?php namespace WpsMcloud\Support;
class Counters
{
/**
* @desc Convert action
*/
public static $imagesNotFound = 0;
public static $processedImages = 0;
}

46
src/Support/Http.php

@ -0,0 +1,46 @@
<?php namespace WpsMcloud\Support;
use Guzzle\Http\Client;
use Guzzle\Http\Exception\ClientErrorResponseException;
class Http
{
private static Client $guzzle;
private static function getGuzzle(): Client
{
if (!isset(static::$guzzle)) {
static::$guzzle = new Client();
}
return static::$guzzle;
}
public static function fileExists(string $url, ?\Closure $successCallback = null, ?\Closure $errorCallback = null): bool
{
try {
$res = self::getGuzzle()->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;
}
}

5
views/converter.html

@ -0,0 +1,5 @@
<p>&nbsp;</p>
<form method="post">
<img src="/wp-content/plugins/wpstudio-media-cloud-transform/plugin.png">
<input type="submit" value="Convert local images to media cloud S3">
</form>

49
wpstudio-media-cloud-transform.php

@ -0,0 +1,49 @@
<?php
/**
* Plugin Name: Wpstudio Media Cloud Transform
* Plugin URI: PLUGIN SITE HERE
* Description: PLUGIN DESCRIPTION HERE
* Author: YOUR NAME HERE
* Author URI: YOUR SITE HERE
* Text Domain: wpstudio-media-cloud-transform
* Domain Path: /languages
* Version: 0.1.0
*
* @package Wpstudio_Media_Cloud_Transform
*/
use WpsMcloud\Actions;
use WpsMcloud\Pages;
use WpsMcloud\Logger;
define('WPSTUDIO_MEDIA_CLOUD_TRANFORM_BASE_PATH', dirname(__FILE__));
add_action('admin_menu', fn () => 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 '<pre>';
(new Actions\Convert())->run();
echo '</pre>';
}
(new Pages\Converter())->render();
},
6
), 99);
Loading…
Cancel
Save