--- /dev/null
+<?php
+
+namespace Civi\Api4\Action\Afform;
+
+use Civi\Api4\Generic\AbstractAction;
+use Civi\Api4\Generic\Result;
+
+/**
+ * Convert afform layouts between different representations, e.g. from
+ * a deep array to HTML.
+ *
+ * @method setLayout(mixed $layout)
+ * @method getLayout(): mixed
+ * @method setFrom(string $layoutFormat)
+ * @method getFrom(): string
+ * @method setTo(string $layoutFormat)
+ * @method getTo(): string
+ * @method setFormatWhitespace(string $layoutFormat)
+ * @method getFormatWhitespace(): string
+ *
+ * @package Civi\Api4\Action\Afform
+ */
+class Convert extends AbstractAction {
+
+ /**
+ * @var string|array
+ */
+ protected $layout;
+
+ /**
+ * How is the input `$layout` formatted?
+ *
+ * @var string
+ * @options html,shallow,deep
+ */
+ protected $from = NULL;
+
+ /**
+ * How should the `$layout` be returned?
+ *
+ * @var string
+ * @options html,shallow,deep
+ */
+ protected $to = NULL;
+
+ /**
+ * Normalize whitespace?
+ *
+ * @var bool
+ */
+ protected $formatWhitespace = FALSE;
+
+ public function _run(Result $result) {
+ // Normalize to HTML
+ if ($this->from === 'html') {
+ $interimHtml = $this->layout;
+ }
+ else {
+ $converter = new \CRM_Afform_ArrayHtml($this->from !== 'shallow', $this->formatWhitespace);
+ $interimHtml = $converter->convertTreeToHtml($this->layout);
+ }
+
+ // And go to preferred format
+ if ($this->to === 'html') {
+ $final = $interimHtml;
+ }
+ else {
+ $converter = new \CRM_Afform_ArrayHtml($this->to !== 'shallow', $this->formatWhitespace);
+ $final = $converter->convertHtmlToArray($interimHtml);
+ }
+
+ $result[] = [
+ 'layout' => $final,
+ ];
+ }
+
+}
->setCheckPermissions($checkPermissions);
}
+ /**
+ * @param bool $checkPermissions
+ * @return Action\Afform\Convert
+ */
+ public static function convert($checkPermissions = TRUE) {
+ return (new Action\Afform\Convert('Afform', __FUNCTION__))
+ ->setCheckPermissions($checkPermissions);
+ }
+
/**
* @param bool $checkPermissions
* @return Action\Afform\Prefill
return $ex;
}
+ /**
+ * In this test, we receive a layout
+ *
+ * @param string $formName
+ * The symbolic name of the form.
+ * @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.
+ * @param string $exampleName
+ * (For debug messages) A symbolic name of the example data-set being tested.
+ * @dataProvider getFormatExamples
+ */
+ public function testBasicConvert($formName, $updateFormat, $updateLayout, $readFormat, $readLayout, $exampleName) {
+ $actual = Civi\Api4\Afform::convert()->setLayout($updateLayout)
+ ->setFrom($updateFormat)
+ ->setTo($readFormat)
+ ->execute();
+
+ $cb = function($m) {
+ return '<' . rtrim($m[1]) . '/>';
+ };
+ $norm = function($layout) use ($cb, &$norm) {
+ if (is_string($layout)) {
+ return preg_replace_callback(';<((br|img)[^>]*)/>;', $cb, $layout);
+ }
+ elseif (is_array($layout)) {
+ foreach ($layout as &$item) {
+ $item = $norm($item);
+ }
+ }
+ };
+
+ $this->assertEquals($norm($readLayout), $norm($actual->single()['layout']), "Based on \"$exampleName\", writing content as \"$updateFormat\" and reading back as \"$readFormat\".");
+ }
+
/**
* In this test, we update the layout and in one format and then read it back
* in another format.