Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional database storage #185

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Then publish the publishables from the service provider:
```
php artisan vendor:publish --provider="WithCandour\AardvarkSeo\ServiceProvider"
```
This publishes a configuration file and an optional database migration for using the database storage driver.

#### Install via CP
Or alternatively search for us in the `Tools > Addons` section of the Statamic control panel.
Expand Down Expand Up @@ -50,6 +51,23 @@ Aardvark SEO integrates with the [Statamic Git functionality](https://statamic.d
!/addons/aardvark-seo
```

### Database storage

If you plan to store Aardvark SEO data in a database you should publish and run the optional `create_aardvark_seo_storage` migration.

Then ensure your `config/aardvark-seo.php` configuration file includes the following keys:

```
'storage_driver' => env('AARDVARK_SEO_STORAGE_DRIVER', 'file'),
'database_connection' => env('AARDVARK_SEO_DATABASE_CONNECTION', null),
```

You can enable database storage by setting the `AARDVARK_SEO_STORAGE_DRIVER` environment variable to `database`.

If you wish to use a database connection other than the application default, you can optionally specify
the connection name using the `AARDVARK_SEO_DATABASE_CONNECTION` environment variable.


## Permissions

Aardvark SEO now has a set of permissions which can be applied to user roles, head to the permissions section of the control panel to take a look, non-super users will now need permission to view and update the global settings. There are additional permissions for creating and updating redirects.
Expand Down
6 changes: 4 additions & 2 deletions config/aardvark-seo.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<?php

return [
'asset_container' => 'assets',
'asset_folder' => 'seo',
'asset_container' => env('AARDVARK_SEO_ASSET_CONTAINER', 'assets'),
'asset_folder' => env('AARDVARK_SEO_ASSET_FOLDER', 'seo'),
'custom_socials' => [],
'excluded_collections' => [],
'excluded_taxonomies' => [],
'storage_driver' => env('AARDVARK_SEO_STORAGE_DRIVER', 'file'),
'database_connection' => env('AARDVARK_SEO_DATABASE_CONNECTION', null),
];
27 changes: 27 additions & 0 deletions database/migrations/create_aardvark_seo_storage_table.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('aardvark_seo_storage', function (Blueprint $table) {
$table->string('handle')->unique();
$table->text('yaml');
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('aardvark_seo_storage');
}
};
12 changes: 11 additions & 1 deletion src/Facades/AardvarkStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

namespace WithCandour\AardvarkSeo\Facades;

use Illuminate\Support\Facades\Config;
use WithCandour\AardvarkSeo\Storage\GlobalsStorage;
use Illuminate\Support\Facades\Facade;
use WithCandour\AardvarkSeo\Storage\DatabaseStorage;
use WithCandour\AardvarkSeo\Storage\FileStorage;

class AardvarkStorage extends Facade
{
Expand All @@ -12,6 +15,13 @@ class AardvarkStorage extends Facade
*/
protected static function getFacadeAccessor()
{
return GlobalsStorage::class;
$driver = Config::get('aardvark-seo.storage_driver', 'file');

switch ($driver) {
case 'database':
return DatabaseStorage::class;
default:
return FileStorage::class;
}
}
}
4 changes: 4 additions & 0 deletions src/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ public function boot()
__DIR__ . '/../config/aardvark-seo.php' => config_path('aardvark-seo.php'),
], 'config');

$this->publishes([
__DIR__ . '/../database/migrations/create_aardvark_seo_storage_table.stub' => database_path('migrations/2024_10_15_10000_create_aardvark_seo_storage_table.php'),
], 'aardvark-seo-migrations');

// Set up permissions
$this->bootPermissions();

Expand Down
109 changes: 109 additions & 0 deletions src/Storage/DatabaseStorage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php

namespace WithCandour\AardvarkSeo\Storage;

use Illuminate\Contracts\Database\Query\Builder;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Statamic\Sites\Site as SiteObject;
use Statamic\Facades\File;
use Statamic\Facades\Site;
use Statamic\Facades\YAML;

class DatabaseStorage implements Storage
{
const TABLE = 'aardvark_seo_storage';

/**
* Retrieve YAML data from storage
*
* @param string $handle
* @param Site $site
* @param bool $returnCollection
*
* @return array|Collection
*/
public static function getYaml(string $handle, SiteObject $site, bool $returnCollection = false)
{
$record = self::query()
->where('handle', $handle)
->first();

$data = YAML::parse($record?->yaml);

$site_data = collect($data)->get($site->handle());

if ($returnCollection) {
return collect($site_data);
}

return collect($site_data)->toArray() ?: [];
}

/**
* Retrieve YAML data from storage but back up using the default site
*
* @param string $handle
* @param Site $site
* @param bool $returnCollection
*
* @return array
*/
public function getYamlWithBackup(string $handle, SiteObject $site, bool $returnCollection = false)
{
$storage = self::getYaml($handle, $site, true);

if (Site::hasMultiple() && $site !== Site::default()) {
$default_storage = self::getYaml($handle, Site::default(), true);
$storage = $default_storage->merge($storage);
}

if ($returnCollection) {
return $storage;
}

return $storage->toArray() ?: [];
}

/**
* Put YAML data into storage
*
* @param string $handle
* @param Site $site
* @param array $data
*
* @return void
*/
public static function putYaml(string $handle, SiteObject $site, array $data)
{
$record = self::query()
->where('handle', $site->handle())
->first();

$existing = collect(YAML::parse($record?->yaml));

$combined_data = $existing->merge([
"{$site->handle()}" => $data,
])->toArray();

DB::table(self::TABLE)->updateOrInsert([
'handle' => $handle,
], [
'yaml' => YAML::dump($combined_data),
]);
}

/**
* @return Builder
*/
protected static function query(): Builder
{
$connection = Config::get(
'aardvark-seo.database_connection',
Config::get('database.default')
);

return DB::connection($connection)->table(self::TABLE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use Statamic\Facades\Site;
use Statamic\Facades\YAML;

class GlobalsStorage implements Storage
class FileStorage implements Storage
{
const prefix = 'aardvark';

Expand Down