PHP code example of tobento / service-repository-storage
1. Go to this page and download the library: Download tobento/service-repository-storage library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
tobento / service-repository-storage example snippets
use Tobento\Service\Repository\RepositoryInterface;
use Tobento\Service\Repository\ReadRepositoryInterface;
use Tobento\Service\Repository\WriteRepositoryInterface;
use Tobento\Service\Repository\Storage\StorageRepository;
use Tobento\Service\Repository\Storage\StorageEntityFactoryInterface;
use Tobento\Service\Storage\InMemoryStorage;
use Tobento\Service\Storage\Tables\Tables;
class ProductRepository extends StorageRepository
{
//
}
$repository = new ProductRepository(
storage: new InMemoryStorage(
items: [],
tables: new Tables()->add('products', ['id', 'sku', 'price'], 'id')
),
table: 'products', // specify which storage table should be used.
entityFactory: null, // null|StorageEntityFactoryInterface
);
var_dump($repository instanceof RepositoryInterface);
// bool(true)
var_dump($repository instanceof ReadRepositoryInterface);
// bool(true)
var_dump($repository instanceof WriteRepositoryInterface);
// bool(true)
use Tobento\Service\Repository\ReadRepositoryInterface;
use Tobento\Service\Repository\Storage\StorageReadRepository;
use Tobento\Service\Repository\Storage\StorageEntityFactoryInterface;
use Tobento\Service\Storage\InMemoryStorage;
use Tobento\Service\Storage\Tables\Tables;
class ProductReadRepository extends StorageReadRepository
{
// adding custom find methods
}
$repository = new ProductReadRepository(
storage: new InMemoryStorage(
items: [
'products' => [
1 => ['id' => 1, 'sku' => 'paper', 'price' => 1.2],
2 => ['id' => 2, 'sku' => 'pen', 'price' => 1.8],
3 => ['id' => 3, 'sku' => 'pencil', 'price' => 1.5],
],
],
tables: new Tables()->add('products', ['id', 'sku', 'price'], 'id')
),
table: 'products',
entityFactory: null, // null|StorageEntityFactoryInterface
);
var_dump($repository instanceof ReadRepositoryInterface);
// bool(true)
use Tobento\Service\Repository\Storage\EntityFactory;
use Tobento\Service\Repository\Storage\StorageEntityFactoryInterface;
use Tobento\Service\Repository\EntityFactoryInterface;
use Tobento\Service\Storage\ItemInterface;
class ProductFactory extends EntityFactory
{
public function createEntityFromArray(array $attributes): Product
{
// Process the columns reading:
$attributes = $this->columns->processReading($attributes);
// Create entity:
return new Product(
id: $attributes['id'] ?? 0,
sku: $attributes['sku'] ?? '',
);
}
}
class Product
{
public function __construct(
public readonly int $id,
public readonly string $sku,
) {}
}
$productFactory = new ProductFactory();
$productFactory->setColumns([]); // will be set by the storage
var_dump($productFactory instanceof StorageEntityFactoryInterface);
// bool(true)
var_dump($productFactory instanceof EntityFactoryInterface);
// bool(true)
$product = $productFactory->createEntityFromArray([
'id' => 1,
'sku' => 'pen',
]);
var_dump($product);
// object(Product)#4 (2) { ["id"]=> int(1) ["sku"]=> string(3) "pen" }
use Tobento\Service\Repository\Storage\StorageRepository;
use Tobento\Service\Repository\Storage\Column;
use Tobento\Service\Storage\InMemoryStorage;
class ProductRepository extends StorageRepository
{
//
}
$repository = new ProductRepository(
storage: new InMemoryStorage(items: []),
table: 'products',
// specify the columns:
columns: [
new Column\Id(),
new Column\Text('sku'),
new Column\Text('title')
->read(fn (string $value, array $attributes): string => ucfirst($value))
->write(fn (string $value, array $attributes, string $action): string => ucfirst($value)),
new Column\Boolean('active'),
],
);
use Tobento\Service\Repository\Storage\StorageRepository;
use Tobento\Service\Repository\Storage\Column\ColumnsInterface;
use Tobento\Service\Repository\Storage\Column\ColumnInterface;
use Tobento\Service\Repository\Storage\Column;
use Tobento\Service\Storage\InMemoryStorage;
class ProductRepository extends StorageRepository
{
/**
* Returns the configured columns.
*
* @return iterable<ColumnInterface>|ColumnsInterface
*/
protected function configureColumns(): iterable|ColumnsInterface
{
return [
new Column\Id(),
new Column\Text('sku'),
new Column\Text('title')
->read(fn (string $value, array $attributes): string => ucfirst($value))
->write(fn (string $value, array $attributes, string $action): string => ucfirst($value)),
new Column\Boolean('active'),
];
}
}
$repository = new ProductRepository(
storage: new InMemoryStorage(items: []),
table: 'products',
);
use Tobento\Service\Repository\Storage\Column\Text;
$column = new Text(name: 'name')
->read(fn (string $value, array $attributes): string => ucfirst($value));
use Tobento\Service\Repository\Storage\Column\Text;
$column = new Text(name: 'name')
->write(fn (string $value, array $attributes, string $action): string => ucfirst($value));
// $action = the action name processed such as 'create' or 'update'
use Tobento\Service\Repository\Storage\Column\Text;
$column = new Text(name: 'name')
->storable(false);
use Tobento\Service\Repository\Storage\Column\Boolean;
$column = new Boolean(name: 'active');
$column = new Boolean(name: 'active')
->type(default: true);
use Tobento\Service\Repository\Storage\Column\Datetime;
$column = new Datetime(name: 'created_at');
// with datetime type (default):
$column = new Datetime(name: 'created_at', type: 'datetime')
->type(nullable: true);
// with date type:
$column = new Datetime(name: 'created_at', type: 'date')
->type(nullable: true);
// with time type:
$column = new Datetime(name: 'created_time', type: 'time')
->type(nullable: true);
// with timestamp type:
$column = new Datetime(name: 'created_ts', type: 'timestamp')
->type(nullable: true);
use Tobento\Service\Repository\Storage\Column\Datetime;
use Tobento\Service\Dater\DateFormatter;
use DateTimeImmutable;
$column = new Datetime(name: 'created_at');
$read = fn (mixed $value, array $attributes, DateFormatter $df)
: DateTimeImmutable => $df->toDateTime(value: $value);
$column = new Datetime(name: 'created_at')->read($read);
use Tobento\Service\Repository\Storage\Column\Datetime;
use Tobento\Service\Dater\DateFormatter;
$column = new Datetime(name: 'created_at');
$write = fn (mixed $value, array $attributes, string $action, DateFormatter $df)
: string => $df->format(value: $value, format: 'H:i:s');
$column = new Datetime(name: 'created_at')->read($read);
use Tobento\Service\Repository\Storage\Column\Datetime;
$column = new Datetime(name: 'created_at')->autoCreate();
use Tobento\Service\Repository\Storage\Column\Datetime;
$column = new Datetime(name: 'updated_at')->autoUpdate();
use Tobento\Service\Repository\Storage\Column\FloatCol;
$column = new FloatCol(name: 'name');
// with float type (default):
$column = new FloatCol(name: 'name', type: 'float')
->type(nullable: false, default: 0.5);
// with double type:
$column = new FloatCol(name: 'name', type: 'double')
->type(nullable: false, default: 0.5);
// with decimal type:
$column = new FloatCol(name: 'name', type: 'decimal')
->type(nullable: false, default: 0.5, precision: 10, scale: 0);
use Tobento\Service\Repository\Storage\Column\Id;
$column = new Id();
// with name (default is id):
$column = new Id(name: 'some_id');
// with bigPrimary type (default):
$column = new Id(type: 'bigPrimary')
->type(
length: 18,
unsigned: true,
index: ['name' => 'index_name', 'primary' => true],
);
// with primary:
$column = new Id(type: 'primary')
->type(
length: 5,
unsigned: true,
index: ['name' => 'index_name', 'primary' => true],
);
use Tobento\Service\Repository\Storage\Column\Integer;
$column = new Integer(name: 'name');
// with int type (default):
$column = new Integer(name: 'name', type: 'int')
->type(length: 11, unsigned: true, nullable: false, default: 0);
// with tinyInt type:
$column = new Integer(name: 'name', type: 'tinyInt')
->type(length: 5, unsigned: true, nullable: false, default: 0);
// with bigInt type:
$column = new Integer(name: 'name', type: 'bigInt')
->type(length: 200, unsigned: true, nullable: false, default: 0);
use Tobento\Service\Repository\Storage\Column\Json;
$column = new Json(name: 'name');
$column = new Json(name: 'name')
->type(nullable: false, default: ['foo', 'bar']);
use Tobento\Service\Repository\Storage\Column\Text;
$column = new Text(name: 'sku');
// with string type (default):
$column = new Text(name: 'sku', type: 'string')
->type(length: 100, nullable: false, default: '');
// with char type:
$column = new Text(name: 'locale', type: 'char')
->type(length: 5, nullable: false, default: 'en');
// with text type:
$column = new Text(name: 'desc', type: 'text')
->type(nullable: false, default: 'lorem ipsum');
use Tobento\Service\Repository\Storage\Attribute\StringTranslations;
$repository->locale('en');
$repository->locales('en', 'de', 'fr');
$repository->localeFallbacks(['de' => 'en']);
$entity = $repository->findById(id: 2);
var_dump($entity->get('title') instanceof StringTranslations);
// bool(true)
// The title on the current locale set on the repository:
$title = (string)$entity->get('title');
// or:
$title = $entity->get('title')->get();
// specific locale:
$title = $entity->get('title')->get(locale: 'de');
// specific locale with default value
// if fallback locale value does not exist:
$title = $entity->get('title')->get(locale: 'fr', default: 'title');
// check if translation exists:
var_dump($entity->get('title')->has(locale: 'de'));
// bool(true)
// returns all translations:
var_dump($entity->get('title')->all();
// array(2) {["en"]=> string(5) "Title" ["de"]=> string(5) "Titel"}
use Tobento\Service\Repository\Storage\Attribute\ArrayTranslations;
$repository->locale('en');
$repository->locales('en', 'de', 'fr');
$repository->localeFallbacks(['de' => 'en']);
$entity = $repository->findById(id: 2);
var_dump($entity->get('meta') instanceof ArrayTranslations);
// bool(true)
// The meta on the current locale set on the repository:
$meta = $entity->get('meta')->get();
// array(1) {["color"]=> string(3) "red"}
// specific locale:
$meta = $entity->get('meta')->get(locale: 'de');
// array(1) {["color"]=> string(3) "rot"}
// specific locale with default value
// if fallback locale value does not exist:
$meta = $entity->get('meta')->get(locale: 'fr', default: ['color' => 'rot']);
// array(1) {["color"]=> string(3) "red"}
// check if translation exists:
var_dump($entity->get('title')->has(locale: 'de'));
// bool(true)
// returns all translations:
var_dump($entity->get('meta')->all();
// array(2) {["en"]=> array(1) {["color"]=> string(3) "red"} ["de"]=> array(1) {["color"]=> string(3) "rot"}}
// The meta color on the current locale set on the repository:
$color = $entity->get('meta')->get(key: 'color');
// string(3) "red"
// specific locale:
$color = $entity->get('meta')->get(locale: 'de', key: 'color');
// string(3) "rot"
// specific locale with default value
// if fallback locale value does not exist:
$color = $entity->get('meta')->get(locale: 'fr', key: 'color', default: ['color' => 'rot']);
// string(3) "red"
// check if translation exists:
var_dump($entity->get('title')->has(locale: 'de', key: 'color'));
// bool(true)
// current locale:
$repository->locale('en');
// only the defined locales are used:
$repository->locales('en', 'de', 'fr');
// fallbacks:
$repository->localeFallbacks(['de' => 'en']);
$entities = $repository->findAll(where: [
// query current locale set on the repository:
'title' => ['like' => 'pe%'],
// query specific locale using json syntax:
'title->de' => ['like' => 'pe%'],
// Array translations:
// query current locale set on the repository:
'options->color' => 'red', // same as: options->en->color
// query specific locale using json syntax:
'options->de->color' => 'red',
]);
use Tobento\Service\Repository\Storage\Migration\RepositoryAction;
use Tobento\Service\Repository\Storage\Migration\RepositoryDeleteAction;
use Tobento\Service\Migration\MigrationInterface;
use Tobento\Service\Migration\ActionsInterface;
use Tobento\Service\Migration\Action;
use Tobento\Service\Migration\Actions;
class UserMigration implements MigrationInterface
{
public function __construct(
protected UserRepository $userRepository,
) {}
/**
* Return a description of the migration.
*
* @return string
*/
public function description(): string
{
return 'Users migration';
}
/**
* Return the actions to be processed on install.
*
* @return ActionsInterface
*/
public function install(): ActionsInterface
{
// you might check if repository is supported for the action:
if (RepositoryAction::isSupportedRepository($this->userRepository)) {
// create action
}
return new Actions(
new RepositoryAction(
repository: $this->userRepository,
description: 'User migration',
// you might set items to be migrated
items: [
['email' => '[email protected]'],
],
// you may set if items should be created using a boolean:
createItems: true, // default
// or using a closure:
createItems: fn ($repo): bool => is_null($repo->findOne()),
),
// you might use the newOrNull method
// if the defined repository is of any type.
// If it is an unsupported repository
// a Action\NullAction::class is created.
RepositoryAction::newOrNull(
repository: $this->userRepository,
description: 'User migration',
// you might set items to be migrated
items: [
['email' => '[email protected]'],
],
createItems: true, // default
),
// you might use the newOrFail method
// if the defined repository is of any type.
// If it is an unsupported repository
// a Action\Fail::class is created.
RepositoryAction::newOrFail(
repository: $this->userRepository,
description: 'User migration',
// you might set items to be migrated
items: [
['email' => '[email protected]'],
],
createItems: true, // default
),
);
}
/**
* Return the actions to be processed on uninstall.
*
* @return ActionsInterface
*/
public function uninstall(): ActionsInterface
{
// you might check if repository is supported for the action:
if (RepositoryDeleteAction::isSupportedRepository($this->userRepository)) {
// create action
}
return new Actions(
new RepositoryDeleteAction(
repository: $this->userRepository,
description: 'User migration',
),
// you might use the newOrNull method
// if the defined repository is of any type.
// If it is an unsupported repository
// a Action\NullAction::class is created.
RepositoryDeleteAction::newOrNull(
repository: $this->userRepository,
description: 'User migration',
),
// you might use the newOrFail method
// if the defined repository is of any type.
// If it is an unsupported repository
// a Action\Fail::class is created.
RepositoryDeleteAction::newOrFail(
repository: $this->userRepository,
description: 'User migration',
),
);
}
}
array
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.