{"id":25507406,"url":"https://github.com/sausin/laravel-ovh","last_synced_at":"2025-04-07T13:04:14.115Z","repository":{"id":18704036,"uuid":"85194981","full_name":"sausin/laravel-ovh","owner":"sausin","description":"Wrapper for OVH Object Storage integration with laravel","archived":false,"fork":false,"pushed_at":"2025-03-15T12:11:01.000Z","size":233,"stargazers_count":37,"open_issues_count":0,"forks_count":13,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-31T12:03:28.715Z","etag":null,"topics":["auto-deletion","hacktoberfest","laravel","laravel-ovh","laravel-package","object-storage","openstack","ovh","php","storage","temporary-files"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sausin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-03-16T12:46:30.000Z","updated_at":"2025-03-15T12:11:05.000Z","dependencies_parsed_at":"2025-03-15T19:00:56.208Z","dependency_job_id":null,"html_url":"https://github.com/sausin/laravel-ovh","commit_stats":{"total_commits":167,"total_committers":9,"mean_commits":"18.555555555555557","dds":0.4730538922155688,"last_synced_commit":"f0b1d9426f720266dc1990651d42d23e5231f4ca"},"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sausin%2Flaravel-ovh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sausin%2Flaravel-ovh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sausin%2Flaravel-ovh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sausin%2Flaravel-ovh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sausin","download_url":"https://codeload.github.com/sausin/laravel-ovh/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247657275,"owners_count":20974344,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auto-deletion","hacktoberfest","laravel","laravel-ovh","laravel-package","object-storage","openstack","ovh","php","storage","temporary-files"],"created_at":"2025-02-19T07:31:32.663Z","updated_at":"2025-04-07T13:04:14.090Z","avatar_url":"https://github.com/sausin.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Laravel OVH Object Storage driver\n\n\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/sausin/laravel-ovh.svg?style=flat-square)](https://packagist.org/packages/sausin/laravel-ovh)\n[![Continuous Integration](https://github.com/sausin/laravel-ovh/workflows/CI%20laravel-ovh/badge.svg?branch=master)](https://github.com/sausin/laravel-ovh/actions?query=workflow%3A%22CI+laravel-ovh%22)\n[![Quality Score](https://img.shields.io/scrutinizer/g/sausin/laravel-ovh.svg?style=flat-square)](https://scrutinizer-ci.com/g/sausin/laravel-ovh)\n[![Total Downloads](https://img.shields.io/packagist/dt/sausin/laravel-ovh.svg?style=flat-square)](https://packagist.org/packages/sausin/laravel-ovh)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)\n\n\nLaravel `Storage` facade provides support for many different filesystems.\n\nThis is a wrapper to provide support in Laravel for [OVH Object Storage](https://www.ovh.ie/public-cloud/storage/object-storage/).\n\n# Installation\n\nInstall via composer:\n```\ncomposer require sausin/laravel-ovh\n```\n\nPlease see below for the details on various branches. You can choose the version of the package which is suitable for your development.\nAlso, take note of the upgrade.\n\n| Package version | PHP compatibility | Laravel versions | Special features of OVH                   | Status     |\n| --------------- | :---------------: | :--------------: | :---------------------------------------: | :--------- |\n| `1.2.x`         | `^7.0 - ^7.1`     | `\u003e=5.4`, `\u003c=5.8` | Temporary Url Support                     | Deprecated |\n| `2.x`           | `\u003e=7.1`           | `\u003e=5.4`, `\u003c=6.x` | Above + Expiring Objects + Custom Domains | Deprecated |\n| `3.x`           | `\u003e=7.1`           | `\u003e=5.4`, `\u003c=7.x` | Above + Keystone v3 API                   | Deprecated |\n| `4.x`           | `\u003e=7.2`           | `\u003e=5.4`          | Above + Set private key on container      | Deprecated |\n| `5.x`           | `\u003e=7.4`           | `\u003e=5.8`          | Above + Config-based Expiring Objects + Form Post Signature + Prefix     | Maintained     |\n| `6.x`           | `\u003e=7.4`           | `\u003e=7.x`          | PHP 8 support     | Active     |\n| `7.x`           | `\u003e=8.0`           | `\u003e=9.x`          | Laravel 9+ support     | Active     |\n\nIf you are using Laravel versions older than 5.5, add the service provider to the `providers` array in `config/app.php`:\n```php\nSausin\\LaravelOvh\\OVHServiceProvider::class\n```\n\nDefine the ovh driver in the `config/filesystems.php`\nas below\n```php\n'ovh' =\u003e [\n    'driver' =\u003e 'ovh',\n    'authUrl' =\u003e env('OS_AUTH_URL', 'https://auth.cloud.ovh.net/v3/'),\n    'projectId' =\u003e env('OS_PROJECT_ID'),\n    'region' =\u003e env('OS_REGION_NAME'),\n    'userDomain' =\u003e env('OS_USER_DOMAIN_NAME', 'Default'),\n    'username' =\u003e env('OS_USERNAME'),\n    'password' =\u003e env('OS_PASSWORD'),\n    'containerName' =\u003e env('OS_CONTAINER_NAME'),\n\n    // Since v1.2\n    // Optional variable and only if you are using temporary signed urls.\n    // You can also set a new key using the command 'php artisan ovh:set-temp-url-key'.\n    'tempUrlKey' =\u003e env('OS_TEMP_URL_KEY'),\n\n    // Since v2.1\n    // Optional variable and only if you have setup a custom endpoint.\n    'endpoint' =\u003e env('OS_CUSTOM_ENDPOINT'),\n\n    // Optional variables for handling large objects.\n    // Defaults below are 300MB threshold \u0026 100MB segments.\n    'swiftLargeObjectThreshold' =\u003e env('OS_LARGE_OBJECT_THRESHOLD', 300 * 1024 * 1024),\n    'swiftSegmentSize' =\u003e env('OS_SEGMENT_SIZE', 100 * 1024 * 1024),\n    'swiftSegmentContainer' =\u003e env('OS_SEGMENT_CONTAINER', null),\n\n    // Optional variable and only if you would like to DELETE all uploaded object by DEFAULT.\n    // This allows you to set an 'expiration' time for every new uploaded object to\n    // your container. This will not affect objects already in your container.\n    //\n    // If you're not willing to DELETE uploaded objects by DEFAULT, leave it empty.\n    // Really, if you don't know what you're doing, you should leave this empty as well.\n    'deleteAfter' =\u003e env('OS_DEFAULT_DELETE_AFTER', null),\n    \n    // Optional variable to cache your storage objects in memory\n    // You must require league/flysystem-cached-adapter to enable caching\n    // This option is not available on laravel-ovh \u003e= 7.0\n    'cache' =\u003e true, // Defaults to false\n    \n    // Optional variable to set a prefix on all paths\n    'prefix' =\u003e null,\n],\n```\nDefine the correct env variables above in your .env file (to correspond to the values above),\nand you should now have a working OVH Object Storage setup :smile:.\n\nThe environment variable `OS_AUTH_URL` is normally not going to be any different for OVH users and hence doesn't need to\nbe specified. To get the values for remaining variables (like `OS_USERNAME`, `OS_REGION_NAME`, `OS_CONTAINER_NAME`,\netc...), you can download the configuration file with details from OVH's Horizon or Control Panel:\n- **OVH Control Panel**: `Public cloud -\u003e Project Management -\u003e Users \u0026 Roles -\u003e Download Openstack's RC file`\n- **OVH Horizon**: `Project -\u003e API Access -\u003e Download OpenStack RC File -\u003e Identity API v3`\n\nBe sure to clear your app's config cache after finishing this library's configuration:\n```sh\nphp artisan config:cache\n```\n\n**NOTE**: Downloading your RC config file from **OVH Control Panel** will provide **Identity v2** variable names.\nHowever, for this package, the following variables are equivalent:\n\n| `laravel-ovh` variable name | OVH's RC variable name |\n| --------------------------- | ---------------------- |\n| `OS_PROJECT_ID`             | `OS_TENANT_ID`         |\n| `OS_PROJECT_NAME`           | `OS_TENANT_NAME`       |\n\nYou can safely place the values from the Identity v2 variables and place them in the corresponding variable for this package.\n\n## Upgrade Notes\n\n### From 3.x to 4.x\nStarting with `4.x` branch, the variables to be defined in the `.env` file\nhave been renamed to reflect the names used by OpenStack in their configuration file. This is to\nremove any discrepancy in understanding which variable should go where. This also means that\nthe package might fail to work unless the variable names in the `.env` file are updated.\n\n### From 4.x to 5.x\nStarting with `5.x` branch, the variables to be defined in the `config/filesystems.php`\nfile have been renamed to better correspond with the names used by OpenStack in their configuration file. This\nis intended to give the developer a better understanding of the contents of each configuration\nkey. If you're coming from `3.x`, updating the variable names in the `.env` might be essential to prevent failure.\n\n### From 5.x/6.x to 7.x\nStarting with `7.x` branch, only Laravel 9 and PHP 8 are supported. The `cache` option should be removed from\nyour config if you previously used it since Flysystem no longer supports \"cached adapters\".\n\n# Usage\n\nRefer to the extensive [Laravel Storage Documentation](https://laravel.com/docs/filesystem) for usage guidelines.\n\n**NOTE:** This package includes support for the following additional methods:\n```php\nStorage::url()\nStorage::temporaryUrl()\n```\n\nThe `temporaryUrl()` method is relevant for private containers where files are not publicly accessible\nunder normal conditions. This generates a temporary signed url. For more details, please refer\nto [OVH's Temporary URL Documentation](https://docs.ovh.com/gb/en/public-cloud/share_an_object_via_a_temporary_url/).\n\nRemember that this functionality requires the container to have a proper key stored.\nThe key in the header should match the `tempUrlKey` specified in `config/filesystems.php`.\nFor more details on how to set up the header on your OVH container, please refer to\n[Generate the temporary address (_tempurl_)](https://docs.ovh.com/gb/en/public-cloud/share_an_object_via_a_temporary_url/#generate-the-temporary-address-tempurl).\n\nAlternatively, since version 4.x you can use the following commands:\n```sh\n# Automatically generate a key\nphp artisan ovh:set-temp-url-key\n\n# Generate a key for a specific disk\nphp artisan ovh:set-temp-url-key --disk=\"other-ovh-disk\"\n\n# Set a specific key\nphp artisan ovh:set-temp-url-key --key=your-private-key\n```\nThe package will then set the relevant key on your container and present it to you. If a key\nhas already been set up previously, the package will warn you before overriding the existing\nkey. If you'd like to force a new key anyway, you may use the `--force` flag with the command.\n\nOnce you got your key configured in your container, you must add it to your `.env` file:\n```dotenv\nOS_TEMP_URL_KEY='your-private-key'\n``` \n\n## Configuring a Custom Domain Name (Custom Endpoint)\n\nOVH's Object Storage allows you to point a Custom Domain Name or Endpoint to an individual\ncontainer. For this, you must setup some records with your DNS provider, which will authorize\nthe forwarded requests coming from your Endpoint to OVH's servers.\n\nIn order to use a Custom Domain Name, you must specify it in your `.env` file:\n```dotenv\nOS_CUSTOM_ENDPOINT=\"http://my-endpoint.example.com\"\n```\n\nFor more information, please refer to [OVH's Custom Domain Documentation](https://docs.ovh.com/gb/en/storage/pcs/link-domain/).\n\n## Uploading Automatically Expiring Objects\n\nThis library allows you to add expiration time to uploaded objects. There are 2 ways to do it:\n\n1. Specifying expiration time programmatically:\n    - You can either specify the number of seconds after which the uploaded object should be deleted:\n        ```php\n        // Automatically expire after 1 hour of being uploaded.\n        Storage::disk('ovh')-\u003eput('path/to/file.jpg', $contents, ['deleteAfter' =\u003e 60*60]);\n        ```\n    - Or, you can also specify a timestamp after which the uploaded object should be deleted:\n        ```php\n        // Automatically delete at the beginning of next month.\n        Storage::disk('ovh')-\u003eput('path/to/file.jpg', $contents, ['deleteAt' =\u003e now()-\u003eaddMonth()-\u003estartOfMonth()])\n        ```\n\n2. Specifying default expiration time via `.env` file. This will set an expiration time (in seconds)\nto every newly uploaded object by default:\n    ```dotenv\n    # Delete every object after 3 days of being uploaded\n    OS_DELETE_AFTER=259200\n    ```\n\nFor more information about these variables,  please refer to\n[OVH's Automatic Object Deletion Documentation](https://docs.ovh.com/gb/en/storage/configure_automatic_object_deletion/)\n\n## Large Object Support\n\nThis library can help you optimize the upload speeds of large objects (such as videos or disk images)\nautomatically by detecting file size thresholds and splitting the file into lighter segments. This will\nimprove upload speeds by writing multiple segments into multiple Object Storage nodes simultaneously.\n\nBy default, the size threshold to detect a Large Object is set to 300MB, and the segment size to split\nthe file is set to 100MB. If you would like to change these values, you must specify the following\nvariables in your `.env` file (in Bytes):\n```dotenv\n# Set size threshold to 1GB\nOS_LARGE_OBJECT_THRESHOLD=1073741824\n# Set segment size to 200MB\nOS_SEGMENT_SIZE=209715200\n```\n\nIf you would like to use a separate container for storing your Large Object Segments,\nyou can do so by specifing the following variable in your `.env` file:\n```dotenv\nOS_SEGMENT_CONTAINER=\"large-object-container-name\"\n```\n\nUsing a separate container for storing the segments of your Large Objects can be beneficial in\nsome cases, to learn more about this, please refer to\n[OpenStack's Last Note on Using Swift for Large Objects](https://docs.openstack.org/swift/stein/overview_large_objects.html#using-swift)\n\nTo learn more about segmented uploads for large objects, please refer to:\n- [OVH's Optimizing Large Object Uploads Documentation](https://docs.ovh.com/gb/en/storage/optimised_method_for_uploading_files_to_object_storage/)\n- [OpenStack's Large Object Support Documentation](https://docs.openstack.org/swift/latest/overview_large_objects.html)\n\n## Form Post Middleware\n\nWhile this feature in not documented by the OVH team, it's explained in the\n[OpenStack's Documentation](https://docs.openstack.org/swift/latest/api/form_post_middleware.html).\n\nThis feature allows for uploading of files _directly_ to the OVH servers rather than going through the application servers\n(thus improving the efficiency in the upload cycle).\n\nYou must generate a valid FormPost signature, for which you can use the following function:\n```php\nStorage::disk('ovh')-\u003egetAdapter()-\u003egetFormPostSignature($path, $expiresAt, $redirect, $maxFileCount, $maxFileSize);\n```\nWhere:\n- `$path` is the directory path in which you would like to store the files.\n- `$expiresAt` is a `DateTimeInterface` object that specifies a date in which the FormPost signature will expire.\n- `$redirect` is the URL to which the user will be redirected once all files finish uploading. Defaults to `null` to prevent redirects.\n- `$maxFileCount` is the max quantity of files that the user will be able to upload using the signature. Defaults to `1` file.\n- `$maxFileSize` is the size limit that each uploaded file can have. Defaults to `25 MB` (`25*1024*1024`).\n\nAfter obtaining the signature, you need to pass the signature data to your HTML form:\n```blade\n\u003cform action=\"{{ $url }}\" method=\"POST\" enctype=\"multipart/form-data\"\u003e\n    \u003cinput type=\"hidden\" name=\"redirect\" value=\"{{ $redirect }}\"\u003e\n    \u003cinput type=\"hidden\" name=\"max_file_count\" value=\"{{ $maxFileCount }}\"\u003e\n    \u003cinput type=\"hidden\" name=\"max_file_size\" value=\"{{ $maxFileSize }}\"\u003e\n\n    \u003cinput type=\"hidden\" name=\"expires\" value=\"{{ $expiresAt-\u003egetTimestamp() }}\"\u003e\n    \u003cinput type=\"hidden\" name=\"signature\" value=\"{{ $signature }}\"\u003e\n\n    \u003cinput type=\"file\"\u003e\n\u003c/form\u003e\n```\n\n\u003e **NOTE**: The upload method in the form _must_ be type of `POST`.\n\n\u003e **NOTE**: As this will be a cross origin request, appropriate headers are needed on the container. See the use of command `php artisan ovh:set-cors-headers` further.\n\nThe `$url` variable refers to the path URL to your container, you can get it by passing the path to the adapter `getUrl`:\n```php\n$url = Storage::disk('ovh')-\u003egetAdapter()-\u003egetUrl($path);\n```\n\n\u003e **NOTE**: If you've setup a custom domain for your Object Storage container, you can use that domain (along with the corresponding path)\n\u003e to upload your files without exposing your OVH's URL scheme.\n\n### Examples\n\n```php\n// Generate a signature that allows an upload to the 'images' directory for the next 10 minutes.\nStorage::disk('ovh')-\u003egetAdapter()-\u003egetFormPostSignature('images', now()-\u003eaddMinutes(10));\n\n// Generate a signature that redirects to a url after successful file upload to the root of the container.\nStorage::disk('ovh')-\u003egetAdapter()-\u003egetFormPostSignature('', now()-\u003eaddMinutes(5), route('file-uploaded'));\n\n// Generate a signature that allows upload of 3 files until next day.\nStorage::disk('ovh')-\u003egetAdapter()-\u003egetFormPostSignature('', now()-\u003eaddDay(), null, 3);\n\n// Generate a signature that allows to upload 1 file of 1GB until the next hour.\nStorage::disk('ovh')-\u003egetAdapter()-\u003egetFormPostSignature('', now()-\u003eaddHour(), null, 1, 1 * 1024 * 1024 * 1024);\n```\n## Setting up Access Control headers on the container\nFor the setup above to work correctly, the container must have the correct headers set on it. This package provides a convenient way to set them up using the below command\n```php\nphp artisan ovh:set-cors-headers\n```\nBy default this will allow all origins to be able to upload on the container. However, if you would like to allow only specific origin(s) you may use the `--origins` flag.\n\nIf these headers were already set previously, the command will seek confirmation before overriding the existing headers.\n\n## Prefix \u0026 Multi-tenancy\n\nAs noted above, `prefix` parameter was introduced in release 5.3.0. This means that any path specified when using the package will be prefixed with the given string. Nothing is added by default (or if the parameter has not been set at all).\n\nFor example, when `prefix` has been set as `foo` in the config, the following command:\n```php\nStorage::disk('ovh')-\u003eurl('/');\n```\nwill generate a url as if it was requested with a path of `/foo` (i.e. the specified prefix has been used).\n\nThis is particularly powerful in a multi-tenant setup. The same container can be used for all tenants and yet each tenant can have its own folder, almost automatically. The middleware where the tenant is being set can be updated, and using the below command:\n```php\nConfig::set('filesystems.disks.ovh.prefix', 'someprefixvalue')\n```\na separate custom prefix will be set for each tenant!\n\nBoth examples above assume the disk has been named as `ovh` in the config. Replace with the correct name for your case.\n\n# Credits\n- ThePHPLeague for the awesome [Flysystem](https://github.com/thephpleague/flysystem)!\n- [Chris Harvey](https://github.com/chrisnharvey) for the [Flysystem OpenStack SwiftAdapter](https://github.com/nimbusoftltd/flysystem-openstack-swift).\n- Rackspace for maintaining the [PHP OpenStack Repo](https://github.com/php-opencloud/openstack).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsausin%2Flaravel-ovh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsausin%2Flaravel-ovh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsausin%2Flaravel-ovh/lists"}