Skip to content

Commit

Permalink
CachedDAOGetAction - generalise CustomGroup.get caching
Browse files Browse the repository at this point in the history
  • Loading branch information
ufundo committed Dec 4, 2024
1 parent d15c448 commit c0c5346
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 17 deletions.
9 changes: 6 additions & 3 deletions Civi/Api4/CustomGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
*/
namespace Civi\Api4;

use Civi\Api4\Generic\CachedDAOGetAction;

/**
* CustomGroup entity.
*
Expand All @@ -25,11 +27,12 @@ class CustomGroup extends Generic\DAOEntity {

/**
* @param bool $checkPermissions
* @return Action\CustomGroup\Get
* @return Generic\CachedDAOGetAction
*/
public static function get($checkPermissions = TRUE) {
return (new Action\CustomGroup\Get(__CLASS__, __FUNCTION__))
->setCheckPermissions($checkPermissions);
return (new CachedDAOGetAction(__CLASS__, __FUNCTION__, function (CachedDAOGetAction $action) {
return \CRM_Core_BAO_CustomGroup::getAll();
}))->setCheckPermissions($checkPermissions);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,17 @@
+--------------------------------------------------------------------+
*/

namespace Civi\Api4\Action\CustomGroup;
namespace Civi\Api4\Generic;

use Civi\Api4\Generic\Result;
use Civi\Api4\Generic\Traits\ArrayQueryActionTrait;
use Civi\Api4\Generic\Traits\PseudoconstantOutputTrait;
use Civi\API\Exception\NotImplementedException;

/**
* @inheritDoc
*
*/
class Get extends \Civi\Api4\Generic\DAOGetAction {
use ArrayQueryActionTrait;
use PseudoconstantOutputTrait;
class CachedDAOGetAction extends \Civi\Api4\Generic\DAOGetAction {
use Traits\ArrayQueryActionTrait;
use Traits\PseudoconstantOutputTrait;

/**
* @var bool
Expand All @@ -35,10 +33,33 @@ class Get extends \Civi\Api4\Generic\DAOGetAction {
*/
protected ?bool $useCache = NULL;

/**
* @var callable
* Function(BasicGetAction $thisAction): array[]
*/
private $cacheGetter;

/**
* Cached DAO Get constructor.
*
* Pass a function that returns the cached records
* The cache should contain all the fields in the
* EntityRepository schema for this entity. If not override
* this class and override getCachedFields as well
*
* @param string $entityName
* @param string $actionName
* @param callable $getter
*/
public function __construct($entityName, $actionName, $cacheGetter = NULL) {
parent::__construct($entityName, $actionName);
$this->cacheGetter = $cacheGetter;
}

/**
* @param \Civi\Api4\Generic\Result $result
*
* Use self::getFromCache or DAOGetAction::getObjects
* Decide whether to use self::getFromCache or DAOGetAction::getObjects
*/
protected function getObjects(Result $result): void {
if (is_null($this->useCache)) {
Expand All @@ -62,16 +83,17 @@ protected function needDatabase(): bool {
return TRUE;
}

$standardFields = \Civi::entity($this->getEntityName())->getFields();
$cachedFields = $this->getCachedFields();

foreach ($this->select as $field) {
[$field] = explode(':', $field);
if (!isset($standardFields[$field])) {
if (!isset($cachedFields[$field])) {
return TRUE;
}
}
foreach ($this->where as $clause) {
[$field] = explode(':', $clause[0] ?? '');
if (!$field || !isset($standardFields[$field])) {
if (!$field || !isset($cachedFields[$field])) {
return TRUE;
}
// ArrayQueryTrait doesn't yet support field-to-field comparisons
Expand All @@ -81,13 +103,26 @@ protected function needDatabase(): bool {
}
foreach ($this->orderBy as $field => $dir) {
[$field] = explode(':', $field);
if (!isset($standardFields[$field])) {
if (!isset($cachedFields[$field])) {
return TRUE;
}
}
return FALSE;
}

/**
* Which fields are included in the cache?
*
* By default, this is standard fields from the
* EntityRepository schema - but could be overridden
* in child classes.
*
* @return array with known fields as array *keys*
*/
protected function getCachedFields(): array {
return \Civi::entity($this->getEntityName())->getFields();
}

/**
* This works like BasicGetAction:
* - provide all the records upfront from the cache
Expand All @@ -100,8 +135,11 @@ protected function getFromCache($result): void {
$this->queryArray($values, $result);
}

protected function getCachedRecords() {
return \CRM_Core_BAO_CustomGroup::getAll();
protected function getCachedRecords(): array {
if (is_callable($this->cacheGetter)) {
return call_user_func($this->cacheGetter, $this);
}
throw new NotImplementedException('Cache getter function not found for api4 ' . $this->getEntityName() . '::' . $this->getActionName());
}

}

0 comments on commit c0c5346

Please sign in to comment.