diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..1c4b2b4
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,15 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+indent_style = tab
+indent_size = 4
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[*.{yml,yaml,json}]
+indent_size = 2
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..81ad3f0
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,8 @@
+# Ignore all test and documentation with "export-ignore".
+/.gitattributes export-ignore
+/.github export-ignore
+/.gitignore export-ignore
+/phpunit.xml.dist export-ignore
+/phpcs.xml export-ignore
+/tests export-ignore
+/.editorconfig export-ignore
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 0000000..aa990a0
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,42 @@
+name: tests
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ test:
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ php: [8.2, 8.1, 8.0]
+ laravel: ["^10.0", "^9.0"]
+ dependency-version: [prefer-lowest, prefer-stable]
+ exclude:
+ - laravel: "^10.0"
+ php: 8.0
+ name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }}
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ - name: Cache dependencies
+ uses: actions/cache@v4
+ with:
+ path: ~/.composer/cache/files
+ key: dependencies-laravel-${{ matrix.laravel }}-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, mysql, mysqli, pdo_mysql, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo
+ coverage: none
+
+ - name: Install dependencies
+ uses: ramsey/composer-install@v2
+
+ - name: Execute tests
+ run: composer test
\ No newline at end of file
diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml
new file mode 100644
index 0000000..298072a
--- /dev/null
+++ b/.github/workflows/update-changelog.yml
@@ -0,0 +1,28 @@
+name: "Update Changelog"
+
+on:
+ release:
+ types: [released]
+
+jobs:
+ update:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+ with:
+ ref: master
+
+ - name: Update Changelog
+ uses: stefanzweifel/changelog-updater-action@v1
+ with:
+ latest-version: ${{ github.event.release.name }}
+ release-notes: ${{ github.event.release.body }}
+
+ - name: Commit updated CHANGELOG
+ uses: stefanzweifel/git-auto-commit-action@v4.15.4
+ with:
+ branch: master
+ commit_message: Update CHANGELOG
+ file_pattern: CHANGELOG.md
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fdb5924
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+vendor
+.idea
+composer.lock
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..d4cca36
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,7 @@
+# Changelog
+
+All notable changes to `syberisle/laravel-castable-archive` will be documented in this file
+
+## 0.0.0 - 2024-03-17
+
+Initial Release
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..368890b
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,17 @@
+# Contributing
+
+Contributions are **welcome** and will be fully **credited**.
+
+We accept contributions via Pull Requests on [Github](https://github.com/syberisle/laravel-castable-archive).
+
+## Pull Requests
+
+- **[SyberIsle Coding Standard](https://github.com/SyberIsle/coding-standards)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer).
+
+- **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date.
+
+- **Consider our release cycle** - We try to follow [SemVer v2.0.0](https://semver.org/).
+
+- **Create feature branches** - Don't ask us to pull from your master branch.
+
+- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..246be92
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2024 SyberIsle, LLC.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e97c709
--- /dev/null
+++ b/README.md
@@ -0,0 +1,49 @@
+# Laravel Model attribute to de/compress the value
+
+[![Latest Version on Packagist](https://img.shields.io/packagist/v/syberisle/laravel-castable-archive.svg?style=flat-square)](https://packagist.org/packages/syberisle/laravel-castable-archive)
+[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/syberisle/laravel-castable-archive/run-tests.yml?branch=main&label=Tests)](https://github.com/syberisle/laravel-castable-archive/actions/workflows/tests.yml)
+[![Total Downloads](https://img.shields.io/packagist/dt/syberisle/laravel-castable-archive.svg?style=flat-square)](https://packagist.org/packages/syberisle/laravel-castable-archive)
+
+This package allows you to cast a model attribute as a compressed value using either gzip or bzip.
+
+Available Casts:
+- `SyberIsle\Laravel\Cast\Archive\BzArchive`
+- `SyberIsle\Laravel\Cast\Archive\GzArchive`
+
+## Installation
+
+```shell
+composer install syberisle/laravel-castable-archive
+```
+
+## Usage
+
+```php
+use SyberIsle\Laravel\Cast\Archive;
+
+class MyModel
+{
+ protected $casts = [
+ 'field_name' => Archive\GzArchive::class
+ ];
+}
+
+$model->field_name = 'kakaw' // raw attribute = b"ËNÌN,\x07\x00"
+$value = $model->field_name; // = 'kakaw'
+```
+
+## Changelog
+
+Please see [CHANGELOG](CHANGELOG.md) for more information about recent changes.
+
+## Contributing
+
+Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
+
+## Security
+
+If you've found a bug regarding security please report it via the security tab of this repository.
+
+## License
+
+The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
\ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..40a0675
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,53 @@
+{
+ "name": "syberisle/laravel-castable-archive",
+ "description": "Tool for casting a model field as bzip or gzip",
+ "license": "MIT",
+ "keywords": [
+ "laravel",
+ "model cast",
+ "gzip",
+ "bzip"
+ ],
+ "authors": [
+ {
+ "name": "David Lundgren",
+ "email": "dlundgren@syberisle.com",
+ "role": "Developer"
+ }
+ ],
+ "homepage": "https://github.com/syberisle/laravel-castable-archive",
+ "require": {
+ "php": "^8.0",
+ "ext-bz2": "*",
+ "ext-zlib": "*",
+ "illuminate/contracts": "^9.28 || ^10.0 || ^11.0"
+ },
+ "require-dev": {
+ "nunomaduro/collision": "^6.2",
+ "orchestra/testbench": "^7.7 || ^8.0",
+ "phpstan/phpstan": "^1.8",
+ "phpunit/phpunit": "^9.5.24",
+ "squizlabs/php_codesniffer": "^3.9",
+ "syberisle/coding-standards": "^2.0"
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true,
+ "autoload": {
+ "psr-4": {
+ "SyberIsle\\Laravel\\Cast\\Archive\\": "src"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "SyberIsle\\Laravel\\Cast\\Archive\\Test\\": "tests"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "scripts": {
+ "sniff": "@php vendor/bin/phpcs",
+ "stan": "vendor/bin/phpstan analyse --level 6 src",
+ "test": "vendor/bin/testbench package:test"
+ }
+}
diff --git a/phpcs.xml b/phpcs.xml
new file mode 100644
index 0000000..3a4f4ae
--- /dev/null
+++ b/phpcs.xml
@@ -0,0 +1,15 @@
+
+
+ Coding standard for this project
+
+
+
+ src
+ tests
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..c13d1b4
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,20 @@
+
+
+
+
+ ./tests
+
+
+
+
+ ./app
+ ./src
+
+
+
\ No newline at end of file
diff --git a/src/BzArchive.php b/src/BzArchive.php
new file mode 100644
index 0000000..e782780
--- /dev/null
+++ b/src/BzArchive.php
@@ -0,0 +1,41 @@
+
+ */
+class BzArchive
+ implements CastsAttributes
+{
+ /**
+ * @param Model $model
+ * @param string $key
+ * @param mixed $value
+ * @param mixed[] $attributes
+ *
+ * @return false|string|null
+ */
+ public function get($model, string $key, $value, array $attributes): mixed
+ {
+ return bzdecompress($value);
+ }
+
+ /**
+ * @param Model $model
+ * @param string $key
+ * @param mixed $value
+ * @param mixed[] $attributes
+ *
+ * @return false|string|null
+ */
+ public function set($model, string $key, $value, array $attributes)
+ {
+ return bzcompress($value);
+ }
+}
\ No newline at end of file
diff --git a/src/GzArchive.php b/src/GzArchive.php
new file mode 100644
index 0000000..73bf638
--- /dev/null
+++ b/src/GzArchive.php
@@ -0,0 +1,41 @@
+
+ */
+class GzArchive
+ implements CastsAttributes
+{
+ /**
+ * @param Model $model
+ * @param string $key
+ * @param mixed $value
+ * @param mixed[] $attributes
+ *
+ * @return false|string|null
+ */
+ public function get($model, string $key, $value, array $attributes): mixed
+ {
+ return gzinflate($value);
+ }
+
+ /**
+ * @param Model $model
+ * @param string $key
+ * @param mixed $value
+ * @param mixed[] $attributes
+ *
+ * @return false|string|null
+ */
+ public function set($model, string $key, $value, array $attributes): mixed
+ {
+ return gzdeflate($value);
+ }
+}
\ No newline at end of file
diff --git a/tests/BzArchiveTest.php b/tests/BzArchiveTest.php
new file mode 100644
index 0000000..e062126
--- /dev/null
+++ b/tests/BzArchiveTest.php
@@ -0,0 +1,42 @@
+ BzArchive::class
+ ];
+
+ public function getRawAttribute(string $key): mixed
+ {
+ return $this->attributes[$key];
+ }
+ };
+ }
+
+ public function testGetDecompresses()
+ {
+ $model = $this->buildModel();
+ $model->setRawAttributes(['test' => bzcompress('kakaw')]);
+
+ self::assertEquals('kakaw', $model->test);
+ }
+
+ public function testSetCompresses()
+ {
+ $model = $this->buildModel();
+ $model->test = 'kakaw';
+
+ self::assertEquals($model->getRawAttribute('test'), bzcompress('kakaw'));
+ }
+}
\ No newline at end of file
diff --git a/tests/GzArchiveTest.php b/tests/GzArchiveTest.php
new file mode 100644
index 0000000..f9bfe63
--- /dev/null
+++ b/tests/GzArchiveTest.php
@@ -0,0 +1,42 @@
+ GzArchive::class
+ ];
+
+ public function getRawAttribute(string $key): mixed
+ {
+ return $this->attributes[$key];
+ }
+ };
+ }
+
+ public function testGetDecompresses()
+ {
+ $model = $this->buildModel();
+ $model->setRawAttributes(['test' => gzdeflate('kakaw')]);
+
+ self::assertEquals('kakaw', $model->test);
+ }
+
+ public function testSetCompresses()
+ {
+ $model = $this->buildModel();
+ $model->test = 'kakaw';
+
+ self::assertEquals($model->getRawAttribute('test'), gzdeflate('kakaw'));
+ }
+}
\ No newline at end of file