diff --git a/.env.model b/.env.model old mode 100644 new mode 100755 index 4adfc7f..4941ab1 --- a/.env.model +++ b/.env.model @@ -16,3 +16,16 @@ PROD_DB_PASS=secret_prod TEST_DB_NAME=web_storage_test TEST_DB_USER=test_user TEST_DB_PASS=test_pass + +# --- Configuracoes de Armazenamento --- +STORAGE_TYPE=local # local ou oci +STORAGE_ROOT=/var/www/html/storage + +# --- Oracle Cloud Object Storage --- +OCI_USER_OCID= +OCI_TENANCY_OCID= +OCI_FINGERPRINT= +OCI_KEY_FILE=/var/www/html/oci_private_key.pem +OCI_REGION= +OCI_NAMESPACE= +OCI_BUCKET= diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/Jenkinsfile b/Jenkinsfile old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/composer.json b/composer.json old mode 100644 new mode 100755 index 7e69bfc..12810e7 --- a/composer.json +++ b/composer.json @@ -3,7 +3,8 @@ "description": "Web storage application", "type": "project", "require": { - "php": "^8.3" + "php": "^8.3", + "oracle/oci-php-sdk": "^0.1.0" }, "require-dev": { "phpunit/phpunit": "^11.0" diff --git a/composer.lock b/composer.lock old mode 100644 new mode 100755 index 6ca1709..76b84d1 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,908 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c9c4b9a7839c4b4bb41ad6a5b0fbc8bb", - "packages": [], + "content-hash": "0537b8d63b312088068d989fcdbbf4d5", + "packages": [ + { + "name": "cache/adapter-common", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-cache/adapter-common.git", + "reference": "8788309be72aa7be69b88cdc0687549c74a7d479" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-cache/adapter-common/zipball/8788309be72aa7be69b88cdc0687549c74a7d479", + "reference": "8788309be72aa7be69b88cdc0687549c74a7d479", + "shasum": "" + }, + "require": { + "cache/tag-interop": "^1.0", + "php": ">=7.4", + "psr/cache": "^1.0 || ^2.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "psr/simple-cache": "^1.0" + }, + "require-dev": { + "cache/integration-tests": "^0.17", + "phpunit/phpunit": "^7.5.20 || ^9.5.10" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Cache\\Adapter\\Common\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Scherer", + "email": "aequasi@gmail.com", + "homepage": "https://github.com/aequasi" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/nyholm" + } + ], + "description": "Common classes for PSR-6 adapters", + "homepage": "http://www.php-cache.com/en/latest/", + "keywords": [ + "cache", + "psr-6", + "tag" + ], + "support": { + "source": "https://github.com/php-cache/adapter-common/tree/1.3.0" + }, + "time": "2022-01-15T15:47:19+00:00" + }, + { + "name": "cache/tag-interop", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-cache/tag-interop.git", + "reference": "b062b1d735357da50edf8387f7a8696f3027d328" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-cache/tag-interop/zipball/b062b1d735357da50edf8387f7a8696f3027d328", + "reference": "b062b1d735357da50edf8387f7a8696f3027d328", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0 || ^8.0", + "psr/cache": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Cache\\TagInterop\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/nyholm" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com", + "homepage": "https://github.com/nicolas-grekas" + } + ], + "description": "Framework interoperable interfaces for tags", + "homepage": "https://www.php-cache.com/en/latest/", + "keywords": [ + "cache", + "psr", + "psr6", + "tag" + ], + "support": { + "issues": "https://github.com/php-cache/tag-interop/issues", + "source": "https://github.com/php-cache/tag-interop/tree/1.1.0" + }, + "time": "2021-12-31T10:03:23+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.8", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a52f0440530b54fa079ce76e8c5d196a42cad981", + "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.9", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.17" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/6.5.8" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2022-06-20T22:16:07+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.5.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2023-05-21T12:31:43+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/e4490cabc77465aaee90b20cfc9a770f8c04be6b", + "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.9.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2023-04-17T16:00:37+00:00" + }, + { + "name": "oracle/oci-php-sdk", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/oracle/oci-php-sdk.git", + "reference": "a88eccdd236479a8520e8ae3b8e0778c1a43dbe0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/oracle/oci-php-sdk/zipball/a88eccdd236479a8520e8ae3b8e0778c1a43dbe0", + "reference": "a88eccdd236479a8520e8ae3b8e0778c1a43dbe0", + "shasum": "" + }, + "require": { + "cache/adapter-common": "^1.2", + "guzzlehttp/guzzle": "^6.5", + "php": ">=5.6" + }, + "require-dev": { + "cache/filesystem-adapter": "^1.1", + "overtrue/phplint": "^3.0", + "phpunit/phpunit": ">=5.7" + }, + "type": "library", + "autoload": { + "files": [ + "src/Oracle/Oci/Common/Utils.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Oracle", + "homepage": "https://www.oracle.com" + } + ], + "description": "OCI SDK for PHP - Oracle Cloud Infrastructure services in your PHP project", + "homepage": "https://docs.oracle.com/en-us/iaas/Content/API/Concepts/devtoolslanding.htm", + "keywords": [ + "objectstorage", + "oci", + "oracle", + "sdk" + ], + "support": { + "forum": "https://community.oracle.com/tech/developers", + "issues": "https://community.oracle.com/mosc/", + "source": "https://github.com/oracle/oci-php-sdk/tree/v0.1.0" + }, + "time": "2023-04-10T19:16:12+00:00" + }, + { + "name": "psr/cache", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "213f9dbc5b9bfbc4f8db86d2838dc968752ce13b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/213f9dbc5b9bfbc4f8db86d2838dc968752ce13b", + "reference": "213f9dbc5b9bfbc4f8db86d2838dc968752ce13b", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/2.0.0" + }, + "time": "2021-02-03T23:23:37+00:00" + }, + { + "name": "psr/http-message", + "version": "1.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/1.1" + }, + "time": "2023-04-04T09:50:52+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "psr/simple-cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/master" + }, + "time": "2017-10-23T01:57:42+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-10T14:38:51+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "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 intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + } + ], "packages-dev": [ { "name": "myclabs/deep-copy", @@ -1798,5 +2698,5 @@ "php": "^8.3" }, "platform-dev": {}, - "plugin-api-version": "2.9.0" + "plugin-api-version": "2.6.0" } diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml old mode 100644 new mode 100755 diff --git a/docker-compose.test.yml b/docker-compose.test.yml old mode 100644 new mode 100755 diff --git a/docker-compose.yml b/docker-compose.yml old mode 100644 new mode 100755 diff --git a/docker/nginx/Dockerfile.prod b/docker/nginx/Dockerfile.prod old mode 100644 new mode 100755 diff --git a/docker/nginx/default.conf b/docker/nginx/default.conf old mode 100644 new mode 100755 diff --git a/docker/nginx/prod.conf b/docker/nginx/prod.conf old mode 100644 new mode 100755 diff --git a/docker/php/Dockerfile.dev b/docker/php/Dockerfile.dev old mode 100644 new mode 100755 diff --git a/docker/php/Dockerfile.prod b/docker/php/Dockerfile.prod old mode 100644 new mode 100755 diff --git a/docker/php/Dockerfile.test b/docker/php/Dockerfile.test old mode 100644 new mode 100755 diff --git a/phpunit.xml b/phpunit.xml old mode 100644 new mode 100755 diff --git a/project.md b/project.md old mode 100644 new mode 100755 index bc8c6f5..75f93ec --- a/project.md +++ b/project.md @@ -15,5 +15,6 @@ O **Web Storage** é uma plataforma de gerenciamento de arquivos em nuvem modern 1. **Testes Obrigatórios**: Sempre criar testes para novas implementações. 2. **Commits Automáticos**: Sempre fazer commit das alterações caso todos os testes passem com sucesso. +3. **Desenvolvimento em Branch Dev**: Todo o desenvolvimento deve ser realizado na branch `dev`. Após cada commit local, deve-se realizar o `git push origin dev` imediatamente. > **Nota**: Este arquivo serve como referência principal da stack e da arquitetura base. Deve ser consultado antes de propor ou realizar qualquer nova implementação na aplicação para garantir consistência tecnológica. diff --git a/public/admin.php b/public/admin.php old mode 100644 new mode 100755 diff --git a/public/change_password.php b/public/change_password.php old mode 100644 new mode 100755 diff --git a/public/css/admin.css b/public/css/admin.css old mode 100644 new mode 100755 diff --git a/public/css/change_password.css b/public/css/change_password.css old mode 100644 new mode 100755 diff --git a/public/css/dashboard.css b/public/css/dashboard.css old mode 100644 new mode 100755 diff --git a/public/css/edit.css b/public/css/edit.css old mode 100644 new mode 100755 diff --git a/public/css/style.css b/public/css/style.css old mode 100644 new mode 100755 diff --git a/public/dashboard.php b/public/dashboard.php old mode 100644 new mode 100755 index cea8d1a..27a136e --- a/public/dashboard.php +++ b/public/dashboard.php @@ -29,7 +29,8 @@ } $userId = $auth->getCurrentUserId(); -$fileManager = new FileManager($userId); +$storage = \App\Storage\StorageFactory::create(); +$fileManager = new FileManager($userId, $storage); $error = ''; $success = ''; @@ -38,10 +39,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) { try { $filename = $fileManager->uploadFile($_FILES['file']); - $success = "Arquivo '$filename' enviado com sucesso!"; + $_SESSION['success'] = "Arquivo '$filename' enviado com sucesso!"; } catch (Exception $e) { - $error = $e->getMessage(); + $_SESSION['error'] = $e->getMessage(); } + header("Location: /dashboard.php"); + exit; } // Handle Direct File Creation @@ -53,11 +56,13 @@ header("Location: /edit.php?file=" . urlencode($name) . "&new=1"); exit; } catch (Exception $e) { - $error = $e->getMessage(); + $_SESSION['error'] = $e->getMessage(); } } else { - $error = "Nome de arquivo inválido."; + $_SESSION['error'] = "Nome de arquivo inválido."; } + header("Location: /dashboard.php"); + exit; } // Handle Bulk Deletion @@ -66,14 +71,16 @@ $filesToDelete = json_decode($_POST['files'], true); if (is_array($filesToDelete) && !empty($filesToDelete)) { $result = $fileManager->bulkDelete($filesToDelete); - $success = $result['success'] . " arquivo(s) apagado(s) com sucesso."; + $_SESSION['success'] = $result['success'] . " arquivo(s) apagado(s) com sucesso."; if ($result['failed'] > 0) { - $error .= $result['failed'] . " arquivo(s) falharam em ser apagados. "; + $_SESSION['error'] = $result['failed'] . " arquivo(s) falharam em ser apagados."; } } } catch (Exception $e) { - $error = $e->getMessage(); + $_SESSION['error'] = $e->getMessage(); } + header("Location: /dashboard.php"); + exit; } // Handle Rename @@ -83,24 +90,28 @@ if (!empty($oldName) && !empty($newName)) { try { $renamed = $fileManager->renameFile($oldName, $newName); - $success = "Arquivo '$oldName' renomeado para '$renamed' com sucesso!"; + $_SESSION['success'] = "Arquivo '$oldName' renomeado para '$renamed' com sucesso!"; } catch (Exception $e) { - $error = $e->getMessage(); + $_SESSION['error'] = $e->getMessage(); } } else { - $error = "Nome de arquivo inválido."; + $_SESSION['error'] = "Nome de arquivo inválido."; } + header("Location: /dashboard.php"); + exit; } // Handle File Deletion if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['file'])) { try { $fileManager->deleteFile($_GET['file']); - $success = "Arquivo apagado com sucesso!"; - header("Location: /dashboard.php?success=" . urlencode($success)); + $_SESSION['success'] = "Arquivo apagado com sucesso!"; + header("Location: /dashboard.php"); exit; } catch (Exception $e) { - $error = $e->getMessage(); + $_SESSION['error'] = $e->getMessage(); + header("Location: /dashboard.php"); + exit; } } @@ -128,8 +139,9 @@ } $files = $fileManager->listFiles(); -$successMsg = $_GET['success'] ?? $success; -$errorMsg = $_GET['error'] ?? $error; +$successMsg = $_SESSION['success'] ?? ''; +$errorMsg = $_SESSION['error'] ?? ''; +unset($_SESSION['success'], $_SESSION['error']); function formatBytes($bytes, $precision = 2) { $units = array('B', 'KB', 'MB', 'GB', 'TB'); @@ -301,5 +313,20 @@ function formatBytes($bytes, $precision = 2) { + diff --git a/public/edit.php b/public/edit.php old mode 100644 new mode 100755 index 125a1ce..098d47e --- a/public/edit.php +++ b/public/edit.php @@ -22,7 +22,8 @@ } $userId = $auth->getCurrentUserId(); -$fileManager = new FileManager($userId); +$storage = \App\Storage\StorageFactory::create(); +$fileManager = new FileManager($userId, $storage); if (!isset($_GET['file']) || empty($_GET['file'])) { header('Location: /dashboard.php'); diff --git a/public/index.php b/public/index.php old mode 100644 new mode 100755 diff --git a/public/js/admin.js b/public/js/admin.js old mode 100644 new mode 100755 diff --git a/public/js/change_password.js b/public/js/change_password.js old mode 100644 new mode 100755 diff --git a/public/js/dashboard.js b/public/js/dashboard.js old mode 100644 new mode 100755 diff --git a/public/js/edit.js b/public/js/edit.js old mode 100644 new mode 100755 diff --git a/screenshots/admin_panel.png b/screenshots/admin_panel.png old mode 100644 new mode 100755 diff --git a/screenshots/home.png b/screenshots/home.png old mode 100644 new mode 100755 diff --git a/set_permissions.sh b/set_permissions.sh old mode 100644 new mode 100755 diff --git a/src/Auth.php b/src/Auth.php old mode 100644 new mode 100755 index 3b8e254..cb696ce --- a/src/Auth.php +++ b/src/Auth.php @@ -35,6 +35,7 @@ public function logout(): void { if (session_status() === PHP_SESSION_NONE) { session_start(); } + $_SESSION = []; session_unset(); session_destroy(); } diff --git a/src/Config/Database.php b/src/Config/Database.php old mode 100644 new mode 100755 diff --git a/src/Config/OCIConfig.php b/src/Config/OCIConfig.php new file mode 100755 index 0000000..b4b2312 --- /dev/null +++ b/src/Config/OCIConfig.php @@ -0,0 +1,29 @@ + getenv('OCI_USER_OCID'), + 'tenancy' => getenv('OCI_TENANCY_OCID'), + 'fingerprint' => getenv('OCI_FINGERPRINT'), + 'key_file' => getenv('OCI_KEY_FILE'), + 'region' => getenv('OCI_REGION') + ]); + + return new ObjectStorageClient($config); + } + + public static function getNamespace(): string { + return getenv('OCI_NAMESPACE'); + } + + public static function getBucket(): string { + return getenv('OCI_BUCKET'); + } +} diff --git a/src/FileManager.php b/src/FileManager.php old mode 100644 new mode 100755 index 7b2201a..6227802 --- a/src/FileManager.php +++ b/src/FileManager.php @@ -2,28 +2,25 @@ namespace App; +use App\Storage\StorageInterface; use Exception; class FileManager { - private string $storageRoot; + private StorageInterface $storage; private int $userId; - public function __construct(int $userId, string $storageRoot = '/var/www/html/storage') { + public function __construct(int $userId, StorageInterface $storage) { $this->userId = $userId; - $this->storageRoot = rtrim($storageRoot, '/'); - $this->ensureUserDirectory(); + $this->storage = $storage; + $this->storage->createDirectory($this->getUserPrefix()); } - private function getUserDirectory(): string { - return $this->storageRoot . '/user_' . $this->userId; + private function getUserPrefix(): string { + return 'user_' . $this->userId; } - private function ensureUserDirectory(): void { - $dir = $this->getUserDirectory(); - if (!is_dir($dir)) { - // Attempt to create, suppress warning if permission denied so it can be handled or displayed gracefully - @mkdir($dir, 0777, true); - } + private function getFullContentPath(string $filename): string { + return $this->getUserPrefix() . '/' . basename($filename); } public function uploadFile(array $file): string { @@ -35,58 +32,31 @@ public function uploadFile(array $file): string { // Basic sanitization $filename = preg_replace('/[^a-zA-Z0-9_\.-]/', '_', $filename); - $destination = $this->getUserDirectory() . '/' . $filename; + $path = $this->getFullContentPath($filename); - // Ensure no overwrite of existing file by adding timestamp if needed, or just throw error - if (file_exists($destination)) { + if ($this->storage->exists($path)) { throw new Exception("File already exists."); } - // in tests we might just move it physically or copy - if (is_uploaded_file($file['tmp_name'])) { - if (!move_uploaded_file($file['tmp_name'], $destination)) { - throw new Exception("Failed to move uploaded file."); - } - } else { - // For testing without actual HTTP upload - if (!rename($file['tmp_name'], $destination)) { - throw new Exception("Failed to move file."); - } + $content = file_get_contents($file['tmp_name']); + if ($content === false) { + throw new Exception("Failed to read uploaded file."); } + $this->storage->put($path, $content); + return $filename; } public function listFiles(): array { - $dir = $this->getUserDirectory(); - - if (!is_dir($dir)) { - // Se o diretório não existe (por erro de permissão por exemplo), não falhar fatalmente - return []; - } - - $scanned = @scandir($dir); - if ($scanned === false) { - return []; - } - - $files = array_diff($scanned, array('.', '..')); - $result = []; - foreach ($files as $file) { - $path = $dir . '/' . $file; - $result[] = [ - 'name' => $file, - 'size' => filesize($path), - 'modified' => @filemtime($path) ?: time() // Fallback time if mtime fails - ]; - } - return $result; + return $this->storage->list($this->getUserPrefix()); } public function deleteFile(string $filename): bool { - $path = $this->getUserDirectory() . '/' . basename($filename); - if (file_exists($path) && is_file($path)) { - return unlink($path); + $path = $this->getFullContentPath($filename); + if ($this->storage->exists($path)) { + $this->storage->delete($path); + return true; } throw new Exception("File not found."); } @@ -107,7 +77,7 @@ public function bulkDelete(array $filenames): array { } public function renameFile(string $oldName, string $newName): string { - $oldPath = $this->getFilePath($oldName); + $oldPath = $this->getFullContentPath($oldName); $newName = basename($newName); $newName = preg_replace('/[^a-zA-Z0-9_\.-]/', '_', $newName); @@ -115,40 +85,32 @@ public function renameFile(string $oldName, string $newName): string { throw new Exception("Invalid new filename."); } - $newPath = $this->getUserDirectory() . '/' . $newName; - if (file_exists($newPath)) { + $newPath = $this->getUserPrefix() . '/' . $newName; + if ($this->storage->exists($newPath)) { throw new Exception("File with the new name already exists."); } - if (!rename($oldPath, $newPath)) { - throw new Exception("Failed to rename file."); - } + $this->storage->rename($oldPath, $newPath); return $newName; } public function getFilePath(string $filename): string { - $path = $this->getUserDirectory() . '/' . basename($filename); - if (!file_exists($path) || !is_file($path)) { + $path = $this->getFullContentPath($filename); + if (!$this->storage->exists($path)) { throw new Exception("File not found."); } - return $path; + return $this->storage->getRealPath($path); } public function getFileContent(string $filename): string { - $path = $this->getFilePath($filename); - $content = @file_get_contents($path); - if ($content === false) { - throw new Exception("Failed to read file."); - } - return $content; + $path = $this->getFullContentPath($filename); + return $this->storage->get($path); } public function updateFileContent(string $filename, string $content): void { - $path = $this->getFilePath($filename); - if (@file_put_contents($path, $content) === false) { - throw new Exception("Failed to write to file."); - } + $path = $this->getFullContentPath($filename); + $this->storage->put($path, $content); } public function createFile(string $filename): void { @@ -160,13 +122,11 @@ public function createFile(string $filename): void { throw new Exception("Nome de arquivo inválido."); } - $path = $this->getUserDirectory() . '/' . $filename; - if (file_exists($path)) { + $path = $this->getFullContentPath($filename); + if ($this->storage->exists($path)) { throw new Exception("Arquivo com este nome já existe."); } - if (@file_put_contents($path, '') === false) { - throw new Exception("Falha ao criar arquivo."); - } + $this->storage->put($path, ''); } } diff --git a/src/Storage/LocalStorage.php b/src/Storage/LocalStorage.php new file mode 100755 index 0000000..31b63ca --- /dev/null +++ b/src/Storage/LocalStorage.php @@ -0,0 +1,88 @@ +root = rtrim($root, '/'); + if (!is_dir($this->root)) { + @mkdir($this->root, 0777, true); + } + } + + private function getFullContentPath(string $path): string { + return $this->root . '/' . ltrim($path, '/'); + } + + public function put(string $path, string $content): void { + $fullPath = $this->getFullContentPath($path); + $dir = dirname($fullPath); + if (!is_dir($dir)) { + @mkdir($dir, 0777, true); + } + if (@file_put_contents($fullPath, $content) === false) { + throw new Exception("Failed to write to local storage."); + } + } + + public function get(string $path): string { + $fullPath = $this->getFullContentPath($path); + if (!file_exists($fullPath)) { + throw new Exception("File not found in local storage."); + } + $content = @file_get_contents($fullPath); + if ($content === false) { + throw new Exception("Failed to read from local storage."); + } + return $content; + } + + public function delete(string $path): void { + $fullPath = $this->getFullContentPath($path); + if (file_exists($fullPath) && is_file($fullPath)) { + unlink($fullPath); + } + } + + public function list(string $prefix = ''): array { + $dir = $this->getFullContentPath($prefix); + if (!is_dir($dir)) return []; + + $files = array_diff(scandir($dir), ['.', '..']); + $result = []; + foreach ($files as $file) { + $path = $dir . '/' . $file; + if (is_file($path)) { + $result[] = [ + 'name' => $file, + 'size' => filesize($path), + 'modified' => filemtime($path) + ]; + } + } + return $result; + } + + public function exists(string $path): bool { + return file_exists($this->getFullContentPath($path)); + } + + public function rename(string $oldPath, string $newPath): void { + rename($this->getFullContentPath($oldPath), $this->getFullContentPath($newPath)); + } + + public function createDirectory(string $path): void { + $fullPath = $this->getFullContentPath($path); + if (!is_dir($fullPath)) { + @mkdir($fullPath, 0777, true); + } + } + + public function getRealPath(string $path): string { + return $this->getFullContentPath($path); + } +} diff --git a/src/Storage/OCIStorage.php b/src/Storage/OCIStorage.php new file mode 100755 index 0000000..208c8dc --- /dev/null +++ b/src/Storage/OCIStorage.php @@ -0,0 +1,129 @@ +client = $client; + $this->namespace = $namespace; + $this->bucket = $bucket; + } + + public function put(string $path, string $content): void { + try { + $this->client->putObject([ + 'NamespaceName' => $this->namespace, + 'BucketName' => $this->bucket, + 'ObjectName' => ltrim($path, '/'), + 'PutObjectBody' => $content + ]); + } catch (Exception $e) { + throw new Exception("OCI Upload Failed: " . $e->getMessage()); + } + } + + public function get(string $path): string { + try { + $response = $this->client->getObject([ + 'NamespaceName' => $this->namespace, + 'BucketName' => $this->bucket, + 'ObjectName' => ltrim($path, '/') + ]); + return (string)$response->getBody(); + } catch (Exception $e) { + throw new Exception("OCI Download Failed: " . $e->getMessage()); + } + } + + public function delete(string $path): void { + try { + $this->client->deleteObject([ + 'NamespaceName' => $this->namespace, + 'BucketName' => $this->bucket, + 'ObjectName' => ltrim($path, '/') + ]); + } catch (Exception $e) { + // Ignore if not found during delete + } + } + + public function list(string $prefix = ''): array { + try { + $response = $this->client->listObjects([ + 'NamespaceName' => $this->namespace, + 'BucketName' => $this->bucket, + 'Prefix' => ltrim($prefix, '/') . '/', + 'Fields' => 'name,size,timeCreated' + ]); + + $data = $response->getJson(); + $objects = $data['objects'] ?? []; + $result = []; + foreach ($objects as $obj) { + $name = $obj['name']; + // Strip prefix + $name = str_replace(ltrim($prefix, '/') . '/', '', $name); + if (empty($name)) continue; + + $result[] = [ + 'name' => $name, + 'size' => $obj['size'], + 'modified' => strtotime($obj['timeCreated']) + ]; + } + return $result; + } catch (Exception $e) { + return []; + } + } + + public function exists(string $path): bool { + try { + $this->client->headObject([ + 'NamespaceName' => $this->namespace, + 'BucketName' => $this->bucket, + 'ObjectName' => ltrim($path, '/') + ]); + return true; + } catch (Exception $e) { + return false; + } + } + + public function rename(string $oldPath, string $newPath): void { + // OCI doesn't have rename, must copy and delete + try { + $this->client->copyObject([ + 'NamespaceName' => $this->namespace, + 'BucketName' => $this->bucket, + 'CopyObjectDetails' => [ + 'sourceObjectName' => ltrim($oldPath, '/'), + 'destinationObjectName' => ltrim($newPath, '/'), + 'destinationBucket' => $this->bucket, + 'destinationNamespace' => $this->namespace, + 'destinationRegion' => $this->client->getRegion() + ] + ]); + $this->delete($oldPath); + } catch (Exception $e) { + throw new Exception("OCI Rename Failed: " . $e->getMessage()); + } + } + + public function createDirectory(string $path): void { + // No-op for OCI Object Storage as directories are virtual prefixes + } + + public function getRealPath(string $path): string { + // Return a temp URL or localized path? For now, we'll download to a temp file if needed by the consumer. + return "oci://" . $this->bucket . "/" . ltrim($path, '/'); + } +} diff --git a/src/Storage/StorageFactory.php b/src/Storage/StorageFactory.php new file mode 100755 index 0000000..d69d1b5 --- /dev/null +++ b/src/Storage/StorageFactory.php @@ -0,0 +1,22 @@ +testStorageRoot, 0777, true); - $this->fileManager = new FileManager(1, $this->testStorageRoot); + $storage = new \App\Storage\LocalStorage($this->testStorageRoot); + $this->fileManager = new \App\FileManager(1, $storage); } protected function tearDown(): void { @@ -105,7 +106,7 @@ public function testGetFilePath() { ]); $path = $this->fileManager->getFilePath('test_path.txt'); - $this->assertEquals($this->testStorageRoot . '/user_1/test_path.txt', $path); + $this->assertEquals('user_1/test_path.txt', ltrim(str_replace($this->testStorageRoot, '', $path), '/')); $this->assertTrue(file_exists($path)); } @@ -194,7 +195,7 @@ public function testCreateFile() { $filename = 'new_file.txt'; $this->fileManager->createFile($filename); - $path = $this->testStorageRoot . '/user_1/' . $filename; + $path = $this->fileManager->getFilePath($filename); $this->assertFileExists($path); $this->assertEquals('', file_get_contents($path)); } diff --git a/tests/OCIStorageTest.php b/tests/OCIStorageTest.php new file mode 100755 index 0000000..4ce37c4 --- /dev/null +++ b/tests/OCIStorageTest.php @@ -0,0 +1,84 @@ +clientMock = $this->createMock(ObjectStorageClient::class); + $this->storage = new OCIStorage($this->clientMock, $this->namespace, $this->bucket); + } + + public function testPut() { + $this->clientMock->expects($this->once()) + ->method('putObject') + ->willReturn($this->createMock(OciResponse::class)); + + $this->storage->put('test.txt', 'hello'); + } + + public function testGet() { + $responseMock = $this->createMock(OciResponse::class); + $responseMock->method('getBody')->willReturn('content'); + + $this->clientMock->expects($this->once()) + ->method('getObject') + ->willReturn($responseMock); + + $this->assertEquals('content', $this->storage->get('test.txt')); + } + + public function testExists() { + $this->clientMock->expects($this->once()) + ->method('headObject') + ->willReturn($this->createMock(OciResponse::class)); + + $this->assertTrue($this->storage->exists('test.txt')); + } + + public function testExistsFalse() { + $this->clientMock->expects($this->once()) + ->method('headObject') + ->willThrowException(new Exception("Not Found")); + + $this->assertFalse($this->storage->exists('test.txt')); + } + + public function testDelete() { + $this->clientMock->expects($this->once()) + ->method('deleteObject'); + + $this->storage->delete('test.txt'); + } + + public function testList() { + $responseMock = $this->createMock(OciResponse::class); + $responseMock->method('getJson')->willReturn([ + 'objects' => [ + [ + 'name' => 'user_1/file1.txt', + 'size' => 100, + 'timeCreated' => date('c') + ] + ] + ]); + + $this->clientMock->expects($this->once()) + ->method('listObjects') + ->willReturn($responseMock); + + $files = $this->storage->list('user_1'); + $this->assertCount(1, $files); + $this->assertEquals('file1.txt', $files[0]['name']); + } +} diff --git a/tests/UserManagerTest.php b/tests/UserManagerTest.php old mode 100644 new mode 100755 diff --git a/tests/bootstrap.php b/tests/bootstrap.php old mode 100644 new mode 100755