Add APIv4 and pseudoconstants for RelationshipCache
[civicrm-core.git] / Civi / Api4 / Generic / AbstractEntity.php
CommitLineData
19b53e5b 1<?php
380f3545
TO
2
3/*
4 +--------------------------------------------------------------------+
41498ac5 5 | Copyright CiviCRM LLC. All rights reserved. |
380f3545 6 | |
41498ac5
TO
7 | This work is published under the GNU AGPLv3 license with some |
8 | permitted exceptions and without any warranty. For full license |
9 | and copyright information, see https://civicrm.org/licensing |
380f3545
TO
10 +--------------------------------------------------------------------+
11 */
12
13/**
14 *
15 * @package CRM
ca5cec67 16 * @copyright CiviCRM LLC https://civicrm.org/licensing
380f3545
TO
17 */
18
19b53e5b
C
19namespace Civi\Api4\Generic;
20
21use Civi\API\Exception\NotImplementedException;
449c4e6b 22use Civi\Api4\Utils\ReflectionUtils;
19b53e5b
C
23
24/**
25 * Base class for all api entities.
26 *
27 * When adding your own api from an extension, extend this class only
28 * if your entity does not have an associated DAO. Otherwise extend DAOEntity.
29 *
30 * The recommended way to create a non-DAO-based api is to extend this class
31 * and then add a getFields function and any other actions you wish, e.g.
c2adedc1
CW
32 * - a get() function which returns BasicGetAction using your custom getter callback.
33 * - a create() function which returns BasicCreateAction using your custom setter callback.
34 * - a save() function which returns BasicSaveAction using your custom setter callback.
35 * - an update() function which returns BasicUpdateAction using your custom setter callback.
36 * - a delete() function which returns BasicBatchAction using your custom delete callback.
19b53e5b 37 * - a replace() function which returns BasicReplaceAction (no callback needed but
c2adedc1 38 * depends on the existence of get, save & delete actions).
19b53e5b
C
39 *
40 * Note that you can use the same setter callback function for update as create -
41 * that function can distinguish between new & existing records by checking if the
42 * unique identifier has been set (identifier field defaults to "id" but you can change
c2adedc1
CW
43 * that when constructing BasicUpdateAction).
44 *
45 * @see https://lab.civicrm.org/extensions/api4example
19b53e5b
C
46 */
47abstract class AbstractEntity {
48
49 /**
6764a9d3 50 * @param bool $checkPermissions
19b53e5b
C
51 * @return \Civi\Api4\Action\GetActions
52 */
6764a9d3
CW
53 public static function getActions($checkPermissions = TRUE) {
54 return (new \Civi\Api4\Action\GetActions(self::getEntityName(), __FUNCTION__))
55 ->setCheckPermissions($checkPermissions);
19b53e5b
C
56 }
57
58 /**
c0c668ce 59 * @return \Civi\Api4\Generic\BasicGetFieldsAction
19b53e5b 60 */
c0c668ce 61 abstract public static function getFields();
19b53e5b
C
62
63 /**
64 * Returns a list of permissions needed to access the various actions in this api.
65 *
66 * @return array
67 */
68 public static function permissions() {
69 $permissions = \CRM_Core_Permission::getEntityActionPermissions();
70
71 // For legacy reasons the permissions are keyed by lowercase entity name
74c303ca 72 $lcentity = \CRM_Core_DAO_AllCoreTables::convertEntityNameToLower(self::getEntityName());
19b53e5b 73 // Merge permissions for this entity with the defaults
74c303ca 74 return ($permissions[$lcentity] ?? []) + $permissions['default'];
19b53e5b
C
75 }
76
77 /**
78 * Get entity name from called class
79 *
80 * @return string
81 */
82 protected static function getEntityName() {
83 return substr(static::class, strrpos(static::class, '\\') + 1);
84 }
85
449c4e6b
CW
86 /**
87 * Overridable function to return a localized title for this entity.
88 *
89 * @return string
90 */
91 protected static function getEntityTitle() {
92 return static::getEntityName();
93 }
94
19b53e5b
C
95 /**
96 * Magic method to return the action object for an api.
97 *
98 * @param string $action
6764a9d3 99 * @param array $args
19b53e5b
C
100 * @return AbstractAction
101 * @throws NotImplementedException
102 */
103 public static function __callStatic($action, $args) {
104 $entity = self::getEntityName();
105 // Find class for this action
106 $entityAction = "\\Civi\\Api4\\Action\\$entity\\" . ucfirst($action);
107 if (class_exists($entityAction)) {
108 $actionObject = new $entityAction($entity, $action);
6764a9d3
CW
109 if (isset($args[0]) && $args[0] === FALSE) {
110 $actionObject->setCheckPermissions(FALSE);
111 }
19b53e5b
C
112 }
113 else {
114 throw new NotImplementedException("Api $entity $action version 4 does not exist.");
115 }
116 return $actionObject;
117 }
118
449c4e6b
CW
119 /**
120 * Reflection function called by Entity::get()
121 *
122 * @see \Civi\Api4\Action\Entity\Get
123 * @return array
124 */
125 public static function getInfo() {
126 $info = [
127 'name' => static::getEntityName(),
128 'title' => static::getEntityTitle(),
129 ];
130 $reflection = new \ReflectionClass(static::class);
131 $info += ReflectionUtils::getCodeDocs($reflection, NULL, ['entity' => $info['name']]);
132 unset($info['package'], $info['method']);
133 return $info;
134 }
135
19b53e5b 136}