Skip to content

Commit

Permalink
Split schemaEntity into storage and metadata classes
Browse files Browse the repository at this point in the history
  • Loading branch information
colemanw committed Feb 27, 2024
1 parent e67c46c commit 66cbee6
Show file tree
Hide file tree
Showing 12 changed files with 289 additions and 181 deletions.
22 changes: 4 additions & 18 deletions Civi.php
Original file line number Diff line number Diff line change
Expand Up @@ -304,27 +304,13 @@ public static function url(?string $logicalUri = NULL, ?string $flags = NULL): \
}

/**
* Gets an entity by name
* Get the canonical entityProvider for a given entity type.
*
* @param string $entityName
* @return \Civi\Schema\EntityInterface
* @return \Civi\Schema\EntityProvider
*/
public static function entity(string $entityName): \Civi\Schema\EntityInterface {
if (isset(\Civi\Schema\EntityRepository::getEntities()[$entityName]['fields'])) {
return new \Civi\Schema\SqlEntity($entityName);
}
return new \Civi\Schema\LegacySqlEntity($entityName);
}

/**
* Gets an entity by table name
*
* @param string $tableName
* @return \Civi\Schema\EntityInterface
*/
public static function table(string $tableName): \Civi\Schema\EntityInterface {
$entityName = \Civi\Schema\EntityRepository::getTableIndex()[$tableName];
return self::Entity($entityName);
public static function entity(string $entityName): \Civi\Schema\EntityProvider {
return new \Civi\Schema\EntityProvider($entityName);
}

}
29 changes: 29 additions & 0 deletions Civi/Schema/EntityMetadataBase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
/*
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC. All rights reserved. |
| |
| This work is published under the GNU AGPLv3 license with some |
| permitted exceptions and without any warranty. For full license |
| and copyright information, see https://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/

namespace Civi\Schema;

abstract class EntityMetadataBase implements EntityMetadataInterface {

/**
* @var string
*/
protected string $entityName;

public function __construct(string $entityName) {
$this->entityName = $entityName;
}

protected function getEntity(): array {
return EntityRepository::getEntity($this->entityName);
}

}
22 changes: 22 additions & 0 deletions Civi/Schema/EntityMetadataInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/*
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC. All rights reserved. |
| |
| This work is published under the GNU AGPLv3 license with some |
| permitted exceptions and without any warranty. For full license |
| and copyright information, see https://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/

namespace Civi\Schema;

interface EntityMetadataInterface {

public function getProperty(string $propertyName);

public function getFields(): array;

public function getOptions(string $fieldName, array $values = NULL): ?array;

}
90 changes: 90 additions & 0 deletions Civi/Schema/EntityProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
/*
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC. All rights reserved. |
| |
| This work is published under the GNU AGPLv3 license with some |
| permitted exceptions and without any warranty. For full license |
| and copyright information, see https://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/

namespace Civi\Schema;

final class EntityProvider {

/**
* @var string
*/
private string $entityName;

/**
* @var EntityMetadataInterface
*/
private $meta;

/**
* @var EntityStorageInterface
*/
private $storage;

public function __construct(string $entityName) {
$this->entityName = $entityName;
}

public function getMeta(string $property) {
return $this->getMetaProvider()->getProperty($property);
}

public function getFields(): array {
return $this->getMetaProvider()->getFields();
}

public function getField(string $fieldName): ?array {
return $this->getFields()[$fieldName] ?? NULL;
}

public function getOptions(string $fieldName, array $values = NULL): ?array {
return $this->getMetaProvider()->getOptions($fieldName, $values);
}

public function writeRecords(array $records): array {
return $this->getStorageProvider()->writeRecords($records);
}

public function deleteRecords(array $records): array {
return $this->getStorageProvider()->deleteRecords($records);
}

private function getMetaProvider(): EntityMetadataInterface {
if (!isset($this->meta)) {
$entity = EntityRepository::getEntity($this->entityName);
if (isset($entity['metaProvider'])) {
return new $entity['metaProvider']($this->entityName);
}
if (isset($entity['fields'])) {
return new SqlEntityMetadata($this->entityName);
}
if (isset($entity['table'])) {
return new LegacySqlEntityMetadata($this->entityName);
}
throw new \CRM_Core_Exception("Unknown entity $this->entityName");
}
return $this->meta;
}

private function getStorageProvider(): EntityStorageInterface {
if (!isset($this->storage)) {
$entity = EntityRepository::getEntity($this->entityName);
if (isset($entity['storageProvider'])) {
return new $entity['storageProvider']($this->entityName);
}
if (isset($entity['table'])) {
return new SqlEntityStorage($this->entityName);
}
throw new \CRM_Core_Exception("Unknown entity $this->entityName");
}
return $this->storage;
}

}
9 changes: 9 additions & 0 deletions Civi/Schema/EntityRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ public static function getEntities(): array {
return self::$entities;
}

/**
* @internal
* @return array
*/
public static function getEntity(string $entityName): ?array {
self::loadAll();
return self::$entities[$entityName] ?? NULL;
}

/**
* @internal
* @return array
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,7 @@

namespace Civi\Schema;

interface EntityInterface {

public function getEntityName(): string;

public function getTableName(): string;

public function getClassName(): string;

public function getTitle(bool $plural = FALSE): string;

public function getIcon(): ?string;

public function getDescription(): ?string;

public function getLabelField(): ?string;

public function getPrimaryKey(): array;

public function getPaths(): ?array;

public function getFields(): array;

public function getField(string $fieldName): ?array;

public function getRecords(array $criteria): ?array;
interface EntityStorageInterface {

public function writeRecords(array $records): array;

Expand Down
44 changes: 0 additions & 44 deletions Civi/Schema/LegacySqlEntity.php

This file was deleted.

63 changes: 63 additions & 0 deletions Civi/Schema/LegacySqlEntityMetadata.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php
/*
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC. All rights reserved. |
| |
| This work is published under the GNU AGPLv3 license with some |
| permitted exceptions and without any warranty. For full license |
| and copyright information, see https://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/

namespace Civi\Schema;

/**
* Supports older extensions that created dao-based entities with
* `civix generate:entity-boilerplate`.
*/
class LegacySqlEntityMetadata extends EntityMetadataBase {

/**
* @return string|\CRM_Core_DAO
*/
public function getClassName(): string {
return $this->getEntity()['class'];
}

public function getProperty(string $propertyName) {
switch ($propertyName) {
case 'title':
return $this->getClassName()::getEntityTitle();

case 'titlePlural':
return $this->getClassName()::getEntityTitle(TRUE);

case 'icon':
return $this->getClassName()::$_icon ?? NULL;

case 'paths':
return $this->getClassName()::getEntityPaths();

case 'labelField':
return $this->getClassName()::$_labelField;

case 'primaryKey':
return $this->getClassName()::$_primaryKey ?? ['id'];

case 'description':
return $this->getClassName()::getEntityDescription();

default:
return $this->getEntity()[$propertyName] ?? NULL;
}
}

public function getFields(): array {
return $this->getClassName()::fields();
}

public function getOptions(string $fieldName, array $values = NULL): ?array {
// TODO: Implement getOptions() method.
}

}
Loading

0 comments on commit 66cbee6

Please sign in to comment.