diff --git a/.env.model b/.env.model index 4941ab1..b9b94ed 100755 --- a/.env.model +++ b/.env.model @@ -2,30 +2,49 @@ # Variaveis de Ambiente - Web Storage # ========================================== +DB_CONNECTION=pgsql +DB_PORT=5432 + # --- Ambiente Local de Desenvolvimento --- -DB_DATABASE=web_storage -DB_USERNAME=admin -DB_PASSWORD=secret +DEV_DB_HOST=db +DEV_DB_DATABASE=web_storage +DEV_DB_USERNAME=admin +DEV_DB_PASSWORD=secret + +DEV_POSTGRES_DB=web_storage +DEV_POSTGRES_USER=admin +DEV_POSTGRES_PASSWORD=secret # --- Ambiente de Producao --- -PROD_DB_NAME=web_storage_prod -PROD_DB_USER=admin_prod -PROD_DB_PASS=secret_prod +PROD_DB_HOST=10.0.0.110 +PROD_DB_DATABASE=web_storage_prod +PROD_DB_USERNAME=admin_prod +PROD_DB_PASSWORD=secret_prod + +PROD_POSTGRES_DB=web_storage_prod +PROD_POSTGRES_USER=admin_prod +PROD_POSTGRES_PASSWORD=secret_prod # --- Ambiente de Testes --- -TEST_DB_NAME=web_storage_test -TEST_DB_USER=test_user -TEST_DB_PASS=test_pass +TEST_DB_HOST=db_test +TEST_DB_DATABASE=web_storage_test +TEST_DB_USERNAME=test_user +TEST_DB_PASSWORD=test_pass + +TEST_POSTGRES_DB=web_storage_test +TEST_POSTGRES_USER=test_user +TEST_POSTGRES_PASSWORD=test_pass # --- Configuracoes de Armazenamento --- -STORAGE_TYPE=local # local ou oci +#STORAGE_TYPE=oci +STORAGE_TYPE=local 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_KEY_FILE=/var/www/html/.oci/key.pem OCI_REGION= OCI_NAMESPACE= OCI_BUCKET= diff --git a/.gitignore b/.gitignore index 65b1681..f5ec4d4 100755 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ docker/nginx/logs/* .phpunit.result.cache +.oci + # Ensure storage folder exists but ignore uploaded files /storage/* !/storage/.gitkeep diff --git a/README.md b/README.md index 9916ca7..2f35f97 100755 --- a/README.md +++ b/README.md @@ -10,11 +10,13 @@ Este projeto foi desenhado sob o conceito de "Glassmorphism" e possui design dar O Web Storage foi construído utilizando as melhores e mais robustas opções do ecossistema Web Open-Source: -- **Back-end**: PHP 8.3 (FPM) rodando dentro de containers estruturados. +- **Back-end**: PHP 8.4 (FPM) rodando dentro de containers estruturados. - **Servidor Web**: Nginx configurado com uploads expandidos (até 100MB por arquivo). - **Banco de Dados**: PostgreSQL, mantendo forte integridade relacional. +- **Armazenamento de Objetos**: Oracle Cloud Infrastructure (OCI) Object Storage ou Armazenamento Local. - **Front-end**: HTML5 semântico, CSS3 Moderno (CSS Grid/Flexbox) e Javascript (Vanilla ES6+). -- **Testes Unitários**: PHPUnit. +- **Testes Unitários**: PHPUnit 11. +- **CI/CD**: Jenkins & GitHub Actions. - **Virtualização**: Docker + Docker Compose (para ambientes Dev / Prod). ### 🤖 Powered by Antigravity AI @@ -22,13 +24,37 @@ Todo o desenvolvimento arquitetural inicial do projeto, refatoração de UI css/ --- +## 🏗️ Arquitetura e Abstração de Armazenamento + +O sistema utiliza uma **Arquitetura Híbrida de Persistência** com uma camada de abstração que permite alternar entre armazenamento local e na nuvem através da variável de ambiente `STORAGE_TYPE`: + +1. **Metadados (PostgreSQL)**: Todas as informações relacionais, como usuários, logs de auditoria e referências de arquivos, são armazenadas no banco de dados local. +2. **Arquivos Físicos (Abstraction Layer)**: + - **OCI Object Storage (`oci`)**: Integração nativa com o **Oracle Cloud (OCI)** para buckets escaláveis e duráveis. + - **Armazenamento Local (`local`)**: Persistência no sistema de arquivos do servidor/container (ideal para desenvolvimento ou infraestrutura on-premise). + +--- + +## ⚙️ CI/CD & Automação + +O fluxo de desenvolvimento e entrega é totalmente automatizado: + +- **GitHub Actions**: Executa a malha de testes unitários (`./run-tests.sh`) automaticamente em cada Pull Request para a branch `master` e em cada push para a branch `dev`, garantindo que nenhum código quebre as funcionalidades existentes. +- **Jenkins**: Atua como o orquestrador de Continuous Deployment (CD). Ele monitora mudanças, reconstrói as imagens de produção (`docker-compose.prod.yml`) e realiza o deploy seguro injetando as variáveis de ambiente necessárias via Jenkins Credentials. + +--- + ## 🛠️ Passo a Passo Prático (Como Usar) ### Configuração Inicial (Variáveis de Ambiente) Antes de tudo, garanta que o Docker e o `docker-compose` estejam instalados na sua máquina. Para proteger informações sensíveis, todas as credenciais do banco e configurações de ambiente foram extraídas dos arquivos do Docker e mapeadas externamente. Na raiz do projeto você encontrará um arquivo chamado `.env.model`. Copie-o (ou apenas renomeie-o) criando um novo arquivo estritamente chamado `.env`. -Dentro deste `.env`, você poderá personalizar livremente as senhas e nomes de banco de dados para os ambientes de Desenvolvimento (`docker-compose.yml`), Produção e Testes! Os containers do Docker lerão as variáveis automaticamente daqui. + +#### Configurações de Armazenamento: +- **`STORAGE_TYPE`**: Define o driver de armazenamento. Use `local` para disco local (padrão) ou `oci` para Oracle Cloud. +- **`STORAGE_ROOT`**: (Apenas para `local`) O caminho no container onde os arquivos serão salvos (ex: `/var/www/html/storage`). +- **Credenciais OCI**: Caso use `oci`, configure `OCI_USER_OCID`, `OCI_TENANCY_OCID`, `OCI_REGION`, `OCI_FINGERPRINT`, `OCI_KEY_FILE`, `OCI_NAMESPACE` e `OCI_BUCKET`. ### 1️⃣ Executando em Ambiente de Teste/Desenvolvimento Para inciar a aplicação via Docker Compose na porta 80 do seu localhost, execute: @@ -60,11 +86,18 @@ No diretório raiz do projeto, disponibilizamos dois scripts auxiliares BASH par ./set_permissions.sh ``` -### 4️⃣ Deploy para Produção Limitada -Você notará que existe um construtor otimizado exclusivo chamado `Dockerfile.prod`, além de configurações focadas no opcache. Para forçar um deploy fechado em ambiente de produção (mais veloz), monte usando: -```bash -docker compose -f docker-compose.prod.yml up --build -d -``` +--- + +## 📂 Estrutura do Projeto + +- `src/Config/`: Configurações de Banco de Dados e OCI. +- `src/Storage/`: Abstração e drivers de armazenamento (`LocalStorage`, `OCIStorage`). +- `src/Auth.php`: Gerenciamento de sessões e autenticação. +- `src/UserManager.php`: CRUD de usuários e permissões. +- `src/FileManager.php`: Lógica de gerenciamento de objetos na nuvem. +- `tests/`: Suíte de testes unitários. +- `.github/workflows/`: Automação de CI com GitHub Actions. +- `Jenkinsfile`: Pipeline de build e deploy contínuo. --- diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 48f6fcb..e64d29b 100755 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -5,13 +5,15 @@ services: dockerfile: docker/php/Dockerfile.prod container_name: web_storage_app_prod restart: unless-stopped + env_file: + - .env environment: - - DB_CONNECTION=pgsql + - DB_CONNECTION=${DB_CONNECTION:-pgsql} - DB_HOST=${PROD_DB_HOST:-10.0.0.110} - - DB_PORT=5432 - - DB_DATABASE=${WEB_STORAGE_PROD_DB_NAME:-web_storage_prod} - - DB_USERNAME=${WEB_STORAGE_PROD_DB_USER:-admin} - - DB_PASSWORD=${WEB_STORAGE_PROD_DB_PASS:-secret_prod} + - DB_PORT=${DB_PORT:-5432} + - DB_DATABASE=${PROD_DB_DATABASE:-web_storage_prod} + - DB_USERNAME=${PROD_DB_USERNAME:-admin_prod} + - DB_PASSWORD=${PROD_DB_PASSWORD:-secret_prod} volumes: - prod_storage:/var/www/html/storage networks: diff --git a/docker-compose.test.yml b/docker-compose.test.yml index 1e5f3d1..4febfd5 100755 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -5,13 +5,15 @@ services: dockerfile: docker/php/Dockerfile.test container_name: web_storage_app_test working_dir: /var/www/html + env_file: + - .env environment: - - DB_CONNECTION=pgsql - - DB_HOST=db_test - - DB_PORT=5432 - - DB_DATABASE=${TEST_DB_NAME:-web_storage_test} - - DB_USERNAME=${TEST_DB_USER:-test_user} - - DB_PASSWORD=${TEST_DB_PASS:-test_pass} + - DB_CONNECTION=${DB_CONNECTION:-pgsql} + - DB_HOST=${TEST_DB_HOST:-db_test} + - DB_PORT=${DB_PORT:-5432} + - DB_DATABASE=${TEST_DB_DATABASE:-web_storage_test} + - DB_USERNAME=${TEST_DB_USERNAME:-test_user} + - DB_PASSWORD=${TEST_DB_PASSWORD:-test_pass} depends_on: db_test: condition: service_healthy @@ -22,10 +24,12 @@ services: image: postgres:15-alpine container_name: web_storage_db_test command: postgres -p 5432 + env_file: + - .env environment: - POSTGRES_DB: ${TEST_DB_NAME:-web_storage_test} - POSTGRES_USER: ${TEST_DB_USER:-test_user} - POSTGRES_PASSWORD: ${TEST_DB_PASS:-test_pass} + POSTGRES_DB: ${TEST_POSTGRES_DB:-web_storage_test} + POSTGRES_USER: ${TEST_POSTGRES_USER:-test_user} + POSTGRES_PASSWORD: ${TEST_POSTGRES_PASSWORD:-test_pass} networks: - test_net healthcheck: diff --git a/docker-compose.yml b/docker-compose.yml index 294d827..985d5ca 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,33 +1,47 @@ +version: '3.8' + services: app: build: - context: . - dockerfile: docker/php/Dockerfile.dev - container_name: web_storage_app - restart: unless-stopped + context: ./ + dockerfile: docker/php/Dockerfile working_dir: /var/www/html volumes: - ./:/var/www/html + env_file: + - .env environment: - - DB_CONNECTION=pgsql - - DB_HOST=db - - DB_PORT=5432 - - DB_DATABASE=${DB_DATABASE:-web_storage} - - DB_USERNAME=${DB_USERNAME:-admin} - - DB_PASSWORD=${DB_PASSWORD:-secret} - command: /bin/bash -c "mkdir -p /var/www/html/storage && chmod -R 777 /var/www/html/storage && php-fpm" + - DB_CONNECTION=${DB_CONNECTION:-pgsql} + - DB_HOST=${DEV_DB_HOST:-db} + - DB_PORT=${DB_PORT:-5432} + - DB_DATABASE=${DEV_DB_DATABASE:-web_storage} + - DB_USERNAME=${DEV_DB_USERNAME:-admin} + - DB_PASSWORD=${DEV_DB_PASSWORD:-secret} + command: /bin/bash -c "chown -R www-data:www-data .oci && chmod 600 .oci/server1.pem && php src/init_db.php && mkdir -p /var/www/html/storage && chmod -R 777 /var/www/html/storage && php-fpm" depends_on: - - db + db: + condition: service_healthy networks: - dev_net + db: + image: postgres:15-alpine + environment: + - POSTGRES_DB=${DEV_DB_DATABASE:-web_storage} + - POSTGRES_USER=${DEV_DB_USERNAME:-admin} + - POSTGRES_PASSWORD=${DEV_DB_PASSWORD:-secret} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${DEV_DB_USERNAME:-admin} -d ${DEV_DB_DATABASE:-web_storage}"] + interval: 5s + timeout: 5s + retries: 5 + networks: + - dev_net - web: + nginx: image: nginx:alpine - container_name: web_storage_nginx - restart: unless-stopped ports: - - "8080:80" + - "80:80" volumes: - ./:/var/www/html - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf @@ -36,24 +50,6 @@ services: networks: - dev_net - db: - image: postgres:15-alpine - container_name: web_storage_db - restart: unless-stopped - environment: - POSTGRES_DB: ${DB_DATABASE:-web_storage} - POSTGRES_USER: ${DB_USERNAME:-admin} - POSTGRES_PASSWORD: ${DB_PASSWORD:-secret} - volumes: - - default_postgres_data:/var/lib/postgresql/data - ports: - - "5432:5432" - networks: - - dev_net - -volumes: - default_postgres_data: - networks: dev_net: driver: bridge diff --git a/docker/php/Dockerfile.dev b/docker/php/Dockerfile.dev index 91e6185..2fbb8ef 100755 --- a/docker/php/Dockerfile.dev +++ b/docker/php/Dockerfile.dev @@ -22,9 +22,10 @@ RUN pecl install xdebug \ RUN echo "xdebug.mode=coverage,debug" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \ && echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini -# Configure PHP Upload Limits +# Configure PHP Upload Limits and Error Reporting RUN echo "upload_max_filesize = 100M" > /usr/local/etc/php/conf.d/uploads.ini \ - && echo "post_max_size = 100M" >> /usr/local/etc/php/conf.d/uploads.ini + && echo "post_max_size = 100M" >> /usr/local/etc/php/conf.d/uploads.ini \ + && echo "error_reporting = E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED" > /usr/local/etc/php/conf.d/error_reporting.ini # Get latest Composer COPY --from=composer:latest /usr/bin/composer /usr/bin/composer diff --git a/docker/php/Dockerfile.prod b/docker/php/Dockerfile.prod index 31a9a45..feedf15 100755 --- a/docker/php/Dockerfile.prod +++ b/docker/php/Dockerfile.prod @@ -18,9 +18,10 @@ RUN echo "opcache.enable=1" >> /usr/local/etc/php/conf.d/opcache-recommended.ini && echo "opcache.revalidate_freq=2" >> /usr/local/etc/php/conf.d/opcache-recommended.ini \ && echo "opcache.fast_shutdown=1" >> /usr/local/etc/php/conf.d/opcache-recommended.ini -# Configure PHP Upload Limits +# Configure PHP Upload Limits and Error Reporting RUN echo "upload_max_filesize = 100M" > /usr/local/etc/php/conf.d/uploads.ini \ - && echo "post_max_size = 100M" >> /usr/local/etc/php/conf.d/uploads.ini + && echo "post_max_size = 100M" >> /usr/local/etc/php/conf.d/uploads.ini \ + && echo "error_reporting = E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED" > /usr/local/etc/php/conf.d/error_reporting.ini # Get latest Composer COPY --from=composer:latest /usr/bin/composer /usr/bin/composer diff --git a/docker/php/Dockerfile.test b/docker/php/Dockerfile.test index 0a6a1c7..f76f9ae 100755 --- a/docker/php/Dockerfile.test +++ b/docker/php/Dockerfile.test @@ -22,9 +22,10 @@ RUN pecl install xdebug \ RUN echo "xdebug.mode=coverage,debug" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \ && echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini -# Configure PHP Upload Limits +# Configure PHP Upload Limits and Error Reporting RUN echo "upload_max_filesize = 100M" > /usr/local/etc/php/conf.d/uploads.ini \ - && echo "post_max_size = 100M" >> /usr/local/etc/php/conf.d/uploads.ini + && echo "post_max_size = 100M" >> /usr/local/etc/php/conf.d/uploads.ini \ + && echo "error_reporting = E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED" > /usr/local/etc/php/conf.d/error_reporting.ini # Get latest Composer COPY --from=composer:latest /usr/bin/composer /usr/bin/composer diff --git a/project.md b/project.md index 75f93ec..a1597cf 100755 --- a/project.md +++ b/project.md @@ -1,20 +1,67 @@ -# Resumo do Projeto: Web Storage +# 🧩 Contexto do Projeto: Web Storage -O **Web Storage** é uma plataforma de gerenciamento de arquivos em nuvem moderna e segura. Ela fornece aos usuários um ambiente privado para realizar upload, download, edição, renomeação e exclusão de documentos e dados pessoais. A interface possui um design moderno baseado em "Glassmorphism" com suporte a dark/light mode. +O **Web Storage** é uma plataforma de gerenciamento de arquivos em nuvem moderna e segura. Este arquivo serve como a **Fonte da Verdade Técnica** para desenvolvedores e agentes de IA, detalhando a arquitetura, stack e regras de conduta do projeto. -## Tecnologias e Stack +--- -- **Back-end**: PHP 8.4 (FPM) executando dentro de containers. -- **Servidor Web**: Nginx (ambiente de desenvolvimento via porta 80; produção via porta 1234 com SSL habilitado). -- **Banco de Dados**: PostgreSQL. -- **Front-end**: HTML5 semântico, CSS3 Moderno (Grid/Flexbox) e Javascript (Vanilla ES6+). -- **Testes**: PHPUnit para testes unitários. -- **Infraestrutura/Virtualização**: Docker e Docker Compose (com suporte a ambientes de desenvolvimento, teste e produção). +## 🚀 Tecnologias e Stack Core -## Regras de Desenvolvimento +- **Linguagem**: PHP 8.4 (FPM) em containers Docker. +- **Servidor Web**: Nginx (Dev: porta 80; Prod: porta 1234 com SSL). +- **Banco de Dados**: PostgreSQL (Gestão de Metadados e Usuários). +- **Cloud Integration**: Oracle Cloud Infrastructure (OCI) Object Storage SDK. +- **Front-end**: HTML5 semântico, CSS3 Moderno (Glassmorphism) e Vanilla JS (ES6+). +- **Testes**: PHPUnit 11 (Unitário e Integração). +- **Infraestrutura**: Docker & Docker Compose (Ambientes Isolados Dev/Test/Prod). -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. +## 🏗️ Arquitetura e Padrões + +O projeto segue uma abordagem modular e orientada a interfaces para garantir flexibilidade de infraestrutura: + +1. **Abstração de Armazenamento**: + - `App\Storage\StorageInterface`: Contrato único para operações de arquivo. + - `App\Storage\StorageFactory`: Decide o driver via variável `STORAGE_TYPE` (`local` ou `oci`). + - `App\Storage\LocalStorage` & `App\Storage\OCIStorage`: Implementações concretas. +2. **Camada de Negócio (Managers)**: + - `App\Auth`: Autenticação, controle de sessões e política de troca de senha. + - `App\FileManager`: Orquestra operações de arquivos vinculadas ao contexto do usuário. + - `App\UserManager`: Gestão administrativa de membros e permissões. + +--- + +## 📂 Mapa do Projeto (Estrutura Crítica) + +- `public/`: Pontos de entrada web e recursos estáticos (CSS/JS). +- `src/Config/`: Classes de configuração (`Database.php`, `OCIConfig.php`). +- `src/Storage/`: Abstração e drivers de persistência. +- `src/`: Núcleo da lógica de negócio (`Auth.php`, `FileManager.php`, `UserManager.php`). +- `tests/`: Suíte completa de testes (Bootstrap isolado). +- `docker/`: Definições customizadas de Dockerfile (Dev vs Prod). +- `.github/workflows/`: Pipelines de CI (GitHub Actions). +- `Jenkinsfile`: Automação de CD (Deploy Contínuo). + +--- + +## ⚙️ Variáveis de Ambiente Essenciais + +- **`STORAGE_TYPE`**: Define o driver (`local` ou `oci`). +- **`STORAGE_ROOT`**: Diretório base para armazenamento local. +- **`OCI_*`**: Conjunto de credenciais para integração com Oracle Cloud. +- **`DB_*`**: Parâmetros de conexão com o PostgreSQL. + +--- + +## 🤖 Regras de Desenvolvimento e IA + +Para garantir a integridade do código e a eficiência na colaboração (Humano/IA), siga estas diretrizes: + +1. **Testes Obrigatórios**: Nenhuma funcionalidade é considerada "pronta" sem testes unitários correspondentes. Utilize `./run-tests.sh` para validação total. +2. **Commits Atômicos e Unitários**: Realize commits pequenos e focados em uma única funcionalidade ou correção. Evite commits massivos. +3. **Padronização de Código (PSR-12)**: Todo código PHP deve seguir rigorosamente os padrões PSR-12 para consistência estilística. +4. **Sincronização com Documentação**: Qualquer mudança na arquitetura, novas variáveis de ambiente ou novos diretórios **devem** ser refletidos imediatamente neste `project.md` e no `README.md`. +5. **Ciclo de Branch Dev**: O desenvolvimento ocorre na branch `dev`. O `git push origin dev` **só deve ser realizado após todos os testes passarem** com o comando `./run-tests.sh`. Caso algum teste falhe, as correções devem ser feitas localmente até a aprovação total antes de qualquer sincronização com o GitHub. +6. **Segurança Pró-ativa**: Nunca utilize credenciais hardcoded. Utilize sempre as abstrações em `src/Config/` que consomem variáveis do `.env`. + +> **Nota**: Consulte este arquivo antes de qualquer refatoração para garantir que os limites arquiteturais (como a abstração de storage) sejam respeitados. diff --git a/src/Config/OCIConfig.php b/src/Config/OCIConfig.php index b4b2312..adeb4fe 100755 --- a/src/Config/OCIConfig.php +++ b/src/Config/OCIConfig.php @@ -3,20 +3,23 @@ namespace App\Config; use Oracle\Oci\ObjectStorage\ObjectStorageClient; -use Oracle\Oci\Common\Config\Config; +use Oracle\Oci\Common\Auth\UserAuthProvider; class OCIConfig { public static function createClient(): ObjectStorageClient { - // Load from environment or home config - $config = new Config([ - 'user' => getenv('OCI_USER_OCID'), - 'tenancy' => getenv('OCI_TENANCY_OCID'), - 'fingerprint' => getenv('OCI_FINGERPRINT'), - 'key_file' => getenv('OCI_KEY_FILE'), - 'region' => getenv('OCI_REGION') - ]); + $keyFile = getenv('OCI_KEY_FILE'); + if (strpos($keyFile, 'file://') !== 0) { + $keyFile = 'file://' . $keyFile; + } - return new ObjectStorageClient($config); + $authProvider = new UserAuthProvider( + getenv('OCI_TENANCY_OCID'), + getenv('OCI_USER_OCID'), + getenv('OCI_FINGERPRINT'), + $keyFile + ); + + return new ObjectStorageClient($authProvider, getenv('OCI_REGION')); } public static function getNamespace(): string { diff --git a/src/Storage/OCIStorage.php b/src/Storage/OCIStorage.php index 208c8dc..4ddab9d 100755 --- a/src/Storage/OCIStorage.php +++ b/src/Storage/OCIStorage.php @@ -20,10 +20,10 @@ public function __construct(ObjectStorageClient $client, string $namespace, stri public function put(string $path, string $content): void { try { $this->client->putObject([ - 'NamespaceName' => $this->namespace, - 'BucketName' => $this->bucket, - 'ObjectName' => ltrim($path, '/'), - 'PutObjectBody' => $content + 'namespaceName' => $this->namespace, + 'bucketName' => $this->bucket, + 'objectName' => ltrim($path, '/'), + 'putObjectBody' => $content ]); } catch (Exception $e) { throw new Exception("OCI Upload Failed: " . $e->getMessage()); @@ -33,9 +33,9 @@ public function put(string $path, string $content): void { public function get(string $path): string { try { $response = $this->client->getObject([ - 'NamespaceName' => $this->namespace, - 'BucketName' => $this->bucket, - 'ObjectName' => ltrim($path, '/') + 'namespaceName' => $this->namespace, + 'bucketName' => $this->bucket, + 'objectName' => ltrim($path, '/') ]); return (string)$response->getBody(); } catch (Exception $e) { @@ -46,9 +46,9 @@ public function get(string $path): string { public function delete(string $path): void { try { $this->client->deleteObject([ - 'NamespaceName' => $this->namespace, - 'BucketName' => $this->bucket, - 'ObjectName' => ltrim($path, '/') + 'namespaceName' => $this->namespace, + 'bucketName' => $this->bucket, + 'objectName' => ltrim($path, '/') ]); } catch (Exception $e) { // Ignore if not found during delete @@ -58,25 +58,25 @@ public function delete(string $path): void { public function list(string $prefix = ''): array { try { $response = $this->client->listObjects([ - 'NamespaceName' => $this->namespace, - 'BucketName' => $this->bucket, - 'Prefix' => ltrim($prefix, '/') . '/', - 'Fields' => 'name,size,timeCreated' + 'namespaceName' => $this->namespace, + 'bucketName' => $this->bucket, + 'prefix' => ltrim($prefix, '/') . '/', + 'fields' => 'name,size,timeCreated' ]); $data = $response->getJson(); - $objects = $data['objects'] ?? []; + $objects = $data->objects ?? []; $result = []; foreach ($objects as $obj) { - $name = $obj['name']; + $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']) + 'size' => $obj->size, + 'modified' => strtotime($obj->timeCreated) ]; } return $result; @@ -88,9 +88,9 @@ public function list(string $prefix = ''): array { public function exists(string $path): bool { try { $this->client->headObject([ - 'NamespaceName' => $this->namespace, - 'BucketName' => $this->bucket, - 'ObjectName' => ltrim($path, '/') + 'namespaceName' => $this->namespace, + 'bucketName' => $this->bucket, + 'objectName' => ltrim($path, '/') ]); return true; } catch (Exception $e) { @@ -102,9 +102,9 @@ 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' => [ + 'namespaceName' => $this->namespace, + 'bucketName' => $this->bucket, + 'copyObjectDetails' => [ 'sourceObjectName' => ltrim($oldPath, '/'), 'destinationObjectName' => ltrim($newPath, '/'), 'destinationBucket' => $this->bucket, diff --git a/tests/OCIStorageTest.php b/tests/OCIStorageTest.php index 4ce37c4..027cf96 100755 --- a/tests/OCIStorageTest.php +++ b/tests/OCIStorageTest.php @@ -63,9 +63,9 @@ public function testDelete() { public function testList() { $responseMock = $this->createMock(OciResponse::class); - $responseMock->method('getJson')->willReturn([ + $responseMock->method('getJson')->willReturn((object)[ 'objects' => [ - [ + (object)[ 'name' => 'user_1/file1.txt', 'size' => 100, 'timeCreated' => date('c')