5 use Civi\Api4\Generic\AbstractEntity
;
6 use Civi\Api4\Generic\BasicBatchAction
;
7 use Civi\Api4\Generic\BasicGetAction
;
8 use Civi\Api4\Generic\BasicGetFieldsAction
;
9 use Civi\Api4\Generic\BasicUpdateAction
;
15 class Afform
extends AbstractEntity
{
18 * @return BasicGetAction
20 public static function get() {
21 return new BasicGetAction('Afform', __FUNCTION__
, function(BasicGetAction
$action) {
22 /** @var \CRM_Afform_AfformScanner $scanner */
23 $scanner = \Civi
::service('afform_scanner');
24 $converter = new \
CRM_Afform_ArrayHtml();
26 $where = $action->getWhere();
27 if (count($where) === 1 && $where[0][0] === 'name' && $where[0][1] == '=') {
28 $names = [$where[0][2]];
31 $names = array_keys($scanner->findFilePaths());
35 foreach ($names as $name) {
36 $record = $scanner->getMeta($name);
37 $layout = $scanner->findFilePath($name, 'aff.html');
39 // FIXME check for file existence+substance+validity
40 $record['layout'] = $converter->convertHtmlToArray(file_get_contents($layout));
50 * @return BasicBatchAction
52 public static function revert() {
53 return new BasicBatchAction('Afform', __FUNCTION__
, ['name'], function($item, BasicBatchAction
$action) {
54 $scanner = \Civi
::service('afform_scanner');
56 \CRM_Afform_AfformScanner
::METADATA_FILE
,
57 \CRM_Afform_AfformScanner
::LAYOUT_FILE
60 foreach ($files as $file) {
61 $metaPath = $scanner->createSiteLocalPath($item['name'], $file);
62 if (file_exists($metaPath)) {
63 if (!@unlink
($metaPath)) {
64 throw new \
API_Exception("Failed to remove afform overrides in $file");
69 // We may have changed list of files covered by the cache.
72 // FIXME if `server_route` changes, then flush the menu cache.
73 // FIXME if asset-caching is enabled, then flush the asset cache
80 * @return BasicUpdateAction
82 public static function update() {
83 $save = function ($item, BasicUpdateAction
$action) {
84 /** @var \CRM_Afform_AfformScanner $scanner */
85 $scanner = \Civi
::service('afform_scanner');
86 $converter = new \
CRM_Afform_ArrayHtml();
88 if (empty($item['name']) ||
!preg_match('/^[a-zA-Z][a-zA-Z0-9\-]*$/', $item['name'])) {
89 throw new \
API_Exception("Afform.create: name is a mandatory field. It should use alphanumerics and dashes.");
91 $name = $item['name'];
93 // FIXME validate all field data.
94 $updates = _afform_fields_filter($item);
96 // Create or update aff.html.
97 if (isset($updates['layout'])) {
98 $layoutPath = $scanner->createSiteLocalPath($name, 'aff.html');
99 \ CRM_Utils_File
::createDir(dirname($layoutPath));
100 file_put_contents($layoutPath, $converter->convertArrayToHtml($updates['layout']));
101 // FIXME check for writability then success. Report errors.
104 // Create or update *.aff.json.
105 $orig = \Civi\Api4\Afform
::get()
106 ->setCheckPermissions($action->getCheckPermissions())
107 ->addWhere('name', '=', $name)
110 if (isset($orig[0])) {
111 $meta = _afform_fields_filter(array_merge($orig[0], $updates));
116 unset($meta['layout']);
117 unset($meta['name']);
119 $metaPath = $scanner->createSiteLocalPath($name, \CRM_Afform_AfformScanner
::METADATA_FILE
);
120 // printf("[%s] Update meta %s: %s\n", $name, $metaPath, print_R(['updates'=>$updates, 'meta'=>$meta], 1));
121 \CRM_Utils_File
::createDir(dirname($metaPath));
122 file_put_contents($metaPath, json_encode($meta, JSON_PRETTY_PRINT
));
123 // FIXME check for writability then success. Report errors.
126 // We may have changed list of files covered by the cache.
129 // FIXME if `server_route` changes, then flush the menu cache.
130 // FIXME if asset-caching is enabled, then flush the asset cache.
134 return new BasicUpdateAction('Afform', __FUNCTION__
, $save, 'name');
137 public static function getFields() {
138 return new BasicGetFieldsAction('Afform', __FUNCTION__
, function() {
144 'name' => 'requires',
150 'name' => 'description',
153 'name' => 'is_public',
154 'data_type' => 'Boolean',
157 'name' => 'server_route',
169 public static function permissions() {
171 "meta" => ["access CiviCRM"],
172 "default" => ["administer CiviCRM"],