From 11e724f028a7c6235f9fb6db99ae71b554041d01 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Sat, 4 May 2019 16:00:50 -0700 Subject: [PATCH] Afform.{get,update} - Allow layout format to be array or string/HTML --- .../core/Civi/Api4/Action/Afform/Get.php | 43 ++++++++++ .../core/Civi/Api4/Action/Afform/Update.php | 67 +++++++++++++++ ext/afform/core/Civi/Api4/Afform.php | 85 +------------------ .../Civi/Api4/Utils/AfformFormatTrait.php | 59 +++++++++++++ .../mock/tests/phpunit/api/v4/AfformTest.php | 50 +++++++++++ 5 files changed, 223 insertions(+), 81 deletions(-) create mode 100644 ext/afform/core/Civi/Api4/Action/Afform/Get.php create mode 100644 ext/afform/core/Civi/Api4/Action/Afform/Update.php create mode 100644 ext/afform/core/Civi/Api4/Utils/AfformFormatTrait.php diff --git a/ext/afform/core/Civi/Api4/Action/Afform/Get.php b/ext/afform/core/Civi/Api4/Action/Afform/Get.php new file mode 100644 index 0000000000..867cdc0d78 --- /dev/null +++ b/ext/afform/core/Civi/Api4/Action/Afform/Get.php @@ -0,0 +1,43 @@ +getWhere(); + if (count($where) === 1 && $where[0][0] === 'name' && $where[0][1] == '=') { + $names = [$where[0][2]]; + } + else { + $names = array_keys($scanner->findFilePaths()); + } + + $values = []; + foreach ($names as $name) { + $record = $scanner->getMeta($name); + $layout = $scanner->findFilePath($name, 'aff.html'); + if ($layout) { + // FIXME check for file existence+substance+validity + $html = file_get_contents($layout); + $record['layout'] = $this->convertHtmlToOutput($html); + } + $values[] = $record; + } + + return $values; + } + +} diff --git a/ext/afform/core/Civi/Api4/Action/Afform/Update.php b/ext/afform/core/Civi/Api4/Action/Afform/Update.php new file mode 100644 index 0000000000..879b26a681 --- /dev/null +++ b/ext/afform/core/Civi/Api4/Action/Afform/Update.php @@ -0,0 +1,67 @@ +createSiteLocalPath($name, 'aff.html'); + \ CRM_Utils_File::createDir(dirname($layoutPath)); + file_put_contents($layoutPath, $this->convertInputToHtml($updates['layout'])); + // FIXME check for writability then success. Report errors. + } + + // Create or update *.aff.json. + $orig = \Civi\Api4\Afform::get() + ->setCheckPermissions($this->getCheckPermissions()) + ->addWhere('name', '=', $name) + ->execute(); + + if (isset($orig[0])) { + $meta = _afform_fields_filter(array_merge($orig[0], $updates)); + } + else { + $meta = $updates; + } + unset($meta['layout']); + unset($meta['name']); + if (!empty($meta)) { + $metaPath = $scanner->createSiteLocalPath($name, \CRM_Afform_AfformScanner::METADATA_FILE); + // printf("[%s] Update meta %s: %s\n", $name, $metaPath, print_R(['updates'=>$updates, 'meta'=>$meta], 1)); + \CRM_Utils_File::createDir(dirname($metaPath)); + file_put_contents($metaPath, json_encode($meta, JSON_PRETTY_PRINT)); + // FIXME check for writability then success. Report errors. + } + + // We may have changed list of files covered by the cache. + $scanner->clear(); + + // FIXME if `server_route` changes, then flush the menu cache. + // FIXME if asset-caching is enabled, then flush the asset cache. + + return $updates; + } + +} diff --git a/ext/afform/core/Civi/Api4/Afform.php b/ext/afform/core/Civi/Api4/Afform.php index d32fa0f60e..ecfffa0e80 100644 --- a/ext/afform/core/Civi/Api4/Afform.php +++ b/ext/afform/core/Civi/Api4/Afform.php @@ -4,9 +4,7 @@ namespace Civi\Api4; use Civi\Api4\Generic\AbstractEntity; use Civi\Api4\Generic\BasicBatchAction; -use Civi\Api4\Generic\BasicGetAction; use Civi\Api4\Generic\BasicGetFieldsAction; -use Civi\Api4\Generic\BasicUpdateAction; /** * Class Afform @@ -15,35 +13,10 @@ use Civi\Api4\Generic\BasicUpdateAction; class Afform extends AbstractEntity { /** - * @return \Civi\Api4\Generic\BasicGetAction + * @return \Civi\Api4\Action\Afform\Get */ public static function get() { - return new BasicGetAction('Afform', __FUNCTION__, function(BasicGetAction $action) { - /** @var \CRM_Afform_AfformScanner $scanner */ - $scanner = \Civi::service('afform_scanner'); - $converter = new \CRM_Afform_ArrayHtml(); - - $where = $action->getWhere(); - if (count($where) === 1 && $where[0][0] === 'name' && $where[0][1] == '=') { - $names = [$where[0][2]]; - } - else { - $names = array_keys($scanner->findFilePaths()); - } - - $values = []; - foreach ($names as $name) { - $record = $scanner->getMeta($name); - $layout = $scanner->findFilePath($name, 'aff.html'); - if ($layout) { - // FIXME check for file existence+substance+validity - $record['layout'] = $converter->convertHtmlToArray(file_get_contents($layout)); - } - $values[] = $record; - } - - return $values; - }); + return new \Civi\Api4\Action\Afform\Get('Afform', __FUNCTION__); } /** @@ -77,60 +50,10 @@ class Afform extends AbstractEntity { } /** - * @return \Civi\Api4\Generic\BasicUpdateAction + * @return \Civi\Api4\Action\Afform\Update */ public static function update() { - return new BasicUpdateAction('Afform', __FUNCTION__, 'name', function ($item, BasicUpdateAction $action) { - /** @var \CRM_Afform_AfformScanner $scanner */ - $scanner = \Civi::service('afform_scanner'); - $converter = new \CRM_Afform_ArrayHtml(); - - if (empty($item['name']) || !preg_match('/^[a-zA-Z][a-zA-Z0-9\-]*$/', $item['name'])) { - throw new \API_Exception("Afform.create: name is a mandatory field. It should use alphanumerics and dashes."); - } - $name = $item['name']; - - // FIXME validate all field data. - $updates = _afform_fields_filter($item); - - // Create or update aff.html. - if (isset($updates['layout'])) { - $layoutPath = $scanner->createSiteLocalPath($name, 'aff.html'); - \ CRM_Utils_File::createDir(dirname($layoutPath)); - file_put_contents($layoutPath, $converter->convertArrayToHtml($updates['layout'])); - // FIXME check for writability then success. Report errors. - } - - // Create or update *.aff.json. - $orig = \Civi\Api4\Afform::get() - ->setCheckPermissions($action->getCheckPermissions()) - ->addWhere('name', '=', $name) - ->execute(); - - if (isset($orig[0])) { - $meta = _afform_fields_filter(array_merge($orig[0], $updates)); - } - else { - $meta = $updates; - } - unset($meta['layout']); - unset($meta['name']); - if (!empty($meta)) { - $metaPath = $scanner->createSiteLocalPath($name, \CRM_Afform_AfformScanner::METADATA_FILE); - // printf("[%s] Update meta %s: %s\n", $name, $metaPath, print_R(['updates'=>$updates, 'meta'=>$meta], 1)); - \CRM_Utils_File::createDir(dirname($metaPath)); - file_put_contents($metaPath, json_encode($meta, JSON_PRETTY_PRINT)); - // FIXME check for writability then success. Report errors. - } - - // We may have changed list of files covered by the cache. - $scanner->clear(); - - // FIXME if `server_route` changes, then flush the menu cache. - // FIXME if asset-caching is enabled, then flush the asset cache. - - return $updates; - }); + return new \Civi\Api4\Action\Afform\Update('Afform', __FUNCTION__, 'name'); } public static function getFields() { diff --git a/ext/afform/core/Civi/Api4/Utils/AfformFormatTrait.php b/ext/afform/core/Civi/Api4/Utils/AfformFormatTrait.php new file mode 100644 index 0000000000..58110d74f0 --- /dev/null +++ b/ext/afform/core/Civi/Api4/Utils/AfformFormatTrait.php @@ -0,0 +1,59 @@ +layoutFormat) { + case 'html': + return $html; + + case 'array': + case NULL: + $converter = new \CRM_Afform_ArrayHtml(); + return $converter->convertHtmlToArray($html); + + default: + throw new \API_Exception("Requested format is unrecognized"); + } + } + + /** + * @param mixed $mixed + * @return string + * @throws \API_Exception + */ + protected function convertInputToHtml($mixed) { + switch ($this->layoutFormat) { + case 'html': + return $mixed; + + case 'array': + case NULL: + $converter = new \CRM_Afform_ArrayHtml(); + return $converter->convertArrayToHtml($mixed); + + default: + throw new \API_Exception("Requested format is unrecognized"); + } + } + +} diff --git a/ext/afform/mock/tests/phpunit/api/v4/AfformTest.php b/ext/afform/mock/tests/phpunit/api/v4/AfformTest.php index dcf29cca61..ad00a70e15 100644 --- a/ext/afform/mock/tests/phpunit/api/v4/AfformTest.php +++ b/ext/afform/mock/tests/phpunit/api/v4/AfformTest.php @@ -63,4 +63,54 @@ class api_v4_AfformTest extends api_v4_AfformTestCase { $this->assertTrue(is_array($result[0]['layout']), $message); } + public function getFormatExamples() { + $es = []; + + $asHtml = 'New text!'; + $asArray = ['#tag' => 'strong', '#children' => ['New text!']]; + + $es[] = ['fakelibBareFile', 'html', $asHtml, 'array', $asArray]; + $es[] = ['fakelibBareFile', 'array', $asArray, 'html', $asHtml]; + $es[] = ['fakelibBareFile', 'html', $asHtml, 'html', $asHtml]; + $es[] = ['fakelibBareFile', 'array', $asArray, 'array', $asArray]; + + return $es; + } + + /** + * In this test, we update the layout and in one format and then read it back + * in another format. + * + * @param string $directiveName + * @param string $updateFormat + * The format with which to write the data. + * 'html' or 'array' + * @param mixed $updateLayout + * The new value to set + * @param string $readFormat + * The format with which to read the data. + * 'html' or 'array' + * @param mixed $readLayout + * The value that we expect to read. + * @dataProvider getFormatExamples + */ + public function testUpdateAndGetFormat($directiveName, $updateFormat, $updateLayout, $readFormat, $readLayout) { + Civi\Api4\Afform::revert()->addWhere('name', '=', $directiveName)->execute(); + + Civi\Api4\Afform::update() + ->addWhere('name', '=', $directiveName) + ->setLayoutFormat($updateFormat) + ->setValues(['layout' => $updateLayout]) + ->execute(); + + $result = Civi\Api4\Afform::get() + ->addWhere('name', '=', $directiveName) + ->setLayoutFormat($readFormat) + ->execute(); + + $this->assertEquals($readLayout, $result[0]['layout']); + + Civi\Api4\Afform::revert()->addWhere('name', '=', $directiveName)->execute(); + } + } -- 2.25.1