/**
* Get a list of all installed modules, including enabled and disabled ones
*
- * @return array
- * CRM_Core_Module
+ * @return CRM_Core_Module[]
*/
public function getModules() {
$result = [];
$fields = $this->entityFields();
foreach ($records as &$values) {
foreach ($this->entityFields() as $field) {
+ $values += [$field['name'] => NULL];
if (!empty($field['options'])) {
foreach (FormattingUtil::$pseudoConstantSuffixes as $suffix) {
$pseudofield = $field['name'] . ':' . $suffix;
$mapper = CRM_Extension_System::singleton()->getMapper();
foreach ($mapper->getModules() as $module) {
- /** @var $module CRM_Core_Module */
try {
if ($module->is_active) {
- $this->appendFilePaths($paths, dirname($mapper->keyToPath($module->name)) . DIRECTORY_SEPARATOR . 'ang', 20);
+ $this->appendFilePaths($paths, dirname($mapper->keyToPath($module->name)) . DIRECTORY_SEPARATOR . 'ang', $module->name);
}
}
catch (CRM_Extension_Exception_MissingException $e) {
}
}
- $this->appendFilePaths($paths, $this->getSiteLocalPath(), 10);
+ $this->appendFilePaths($paths, $this->getSiteLocalPath(), '');
$this->cache->set('afformAllPaths', $paths);
return $paths;
}
/**
- * Adds has_local & has_base to an afform metadata record
+ * Adds base_module, has_local & has_base to an afform metadata record
*
* @param array $record
*/
public function addComputedFields(&$record) {
$name = $record['name'];
- // Ex: $allPaths['viewIndividual'][0] == '/var/www/foo/afform/view-individual'].
+ // Ex: $allPaths['viewIndividual']['org.civicrm.foo'] == '/var/www/foo/afform/view-individual'].
$allPaths = $this->findFilePaths()[$name] ?? [];
- // $activeLayoutPath = $this->findFilePath($name, self::LAYOUT_FILE);
- // $activeMetaPath = $this->findFilePath($name, self::METADATA_FILE);
- $localLayoutPath = $this->createSiteLocalPath($name, self::LAYOUT_FILE);
- $localMetaPath = $this->createSiteLocalPath($name, self::METADATA_FILE);
-
- $record['has_local'] = file_exists($localLayoutPath) || file_exists($localMetaPath);
+ // Empty string key refers to the site local path
+ $record['has_local'] = isset($allPaths['']);
if (!isset($record['has_base'])) {
- $record['has_base'] = ($record['has_local'] && count($allPaths) > 1)
- || (!$record['has_local'] && count($allPaths) > 0);
+ $record['base_module'] = \CRM_Utils_Array::first(array_filter(array_keys($allPaths)));
+ $record['has_base'] = !empty($record['base_module']);
}
}
* Ex: ['foo' => [0 => '/var/www/org.example.foobar/ang']]
* @param string $parent
* Ex: '/var/www/org.example.foobar/afform/'
- * @param int $priority
- * Lower priority files override higher priority files.
+ * @param string $module
+ * Name of module or '' empty string for local files.
*/
- private function appendFilePaths(&$formPaths, $parent, $priority) {
+ private function appendFilePaths(&$formPaths, $parent, $module) {
$files = preg_grep(self::FILE_REGEXP, (array) glob("$parent/*"));
foreach ($files as $file) {
$fileBase = preg_replace(self::FILE_REGEXP, '', $file);
$name = basename($fileBase);
- $formPaths[$name][$priority] = $fileBase;
+ $formPaths[$name][$module] = $fileBase;
+ // Local files get top priority
ksort($formPaths[$name]);
}
}
public function getRecords() {
/** @var \CRM_Afform_AfformScanner $scanner */
$scanner = \Civi::service('afform_scanner');
- $getComputed = $this->_isFieldSelected('has_local', 'has_base');
+ $getComputed = $this->_isFieldSelected('has_local', 'has_base', 'base_module');
$getLayout = $this->_isFieldSelected('layout');
$getSearchDisplays = $this->_isFieldSelected('search_displays');
$values = [];
namespace Civi\Api4;
use Civi\Api4\Generic\BasicBatchAction;
+use Civi\Api4\Generic\BasicGetFieldsAction;
/**
* User-configurable forms.
* @return Generic\BasicGetFieldsAction
*/
public static function getFields($checkPermissions = TRUE) {
- return (new Generic\BasicGetFieldsAction('Afform', __FUNCTION__, function($self) {
+ return (new Generic\BasicGetFieldsAction('Afform', __FUNCTION__, function(BasicGetFieldsAction $self) {
$fields = [
[
'name' => 'name',
'name' => 'has_local',
'type' => 'Extra',
'data_type' => 'Boolean',
+ 'description' => 'Whether a local copy is saved on site',
'readonly' => TRUE,
];
$fields[] = [
'name' => 'has_base',
'type' => 'Extra',
'data_type' => 'Boolean',
+ 'description' => 'Is provided by an extension',
'readonly' => TRUE,
];
+ $fields[] = [
+ 'name' => 'base_module',
+ 'type' => 'Extra',
+ 'data_type' => 'String',
+ 'description' => 'Name of extension which provides this form',
+ 'readonly' => TRUE,
+ 'options' => $self->getLoadOptions() ? \CRM_Core_PseudoConstant::getExtensions() : TRUE,
+ ];
$fields[] = [
'name' => 'search_displays',
'type' => 'Extra',
$this->assertEquals($this->formName, $result['name']);
$this->assertFalse($result['has_base']);
$this->assertArrayNotHasKey('has_local', $result);
+ $this->assertArrayNotHasKey('base_module', $result);
}
public function testGetSearchDisplays() {
$message = 'The initial Afform.get should return default data';
$result = Civi\Api4\Afform::get()
- ->addSelect('*', 'has_base', 'has_local')
+ ->addSelect('*', 'has_base', 'has_local', 'base_module')
->addWhere('name', '=', $formName)->execute();
$this->assertEquals($formName, $result[0]['name'], $message);
$this->assertEquals($get($originalMetadata, 'title'), $get($result[0], 'title'), $message);
$this->assertTrue(is_array($result[0]['layout']), $message);
$this->assertEquals(TRUE, $get($result[0], 'has_base'), $message);
$this->assertEquals(FALSE, $get($result[0], 'has_local'), $message);
+ $this->assertEquals('org.civicrm.afform-mock', $get($result[0], 'base_module'), $message);
$message = 'After updating with Afform.create, the revised data should be returned';
$result = Civi\Api4\Afform::update()
$message = 'After updating, the Afform.get API should return blended data';
$result = Civi\Api4\Afform::get()
- ->addSelect('*', 'has_base', 'has_local')
+ ->addSelect('*', 'has_base', 'has_local', 'base_module')
->addWhere('name', '=', $formName)->execute();
$this->assertEquals($formName, $result[0]['name'], $message);
$this->assertEquals($get($originalMetadata, 'title'), $get($result[0], 'title'), $message);
$this->assertTrue(is_array($result[0]['layout']), $message);
$this->assertEquals(TRUE, $get($result[0], 'has_base'), $message);
$this->assertEquals(TRUE, $get($result[0], 'has_local'), $message);
+ $this->assertEquals('org.civicrm.afform-mock', $get($result[0], 'base_module'), $message);
Civi\Api4\Afform::revert()->addWhere('name', '=', $formName)->execute();
$message = 'After reverting, the final Afform.get should return default data';
$result = Civi\Api4\Afform::get()
- ->addSelect('*', 'has_base', 'has_local')
+ ->addSelect('*', 'has_base', 'has_local', 'base_module')
->addWhere('name', '=', $formName)->execute();
$this->assertEquals($formName, $result[0]['name'], $message);
$this->assertEquals($get($originalMetadata, 'title'), $get($result[0], 'title'), $message);
$this->assertTrue(is_array($result[0]['layout']), $message);
$this->assertEquals(TRUE, $get($result[0], 'has_base'), $message);
$this->assertEquals(FALSE, $get($result[0], 'has_local'), $message);
+ $this->assertEquals('org.civicrm.afform-mock', $get($result[0], 'base_module'), $message);
}
public function getFormatExamples() {
foreach (MockBasicEntity::get()->addSelect('*')->execute() as $result) {
ksort($result);
- $this->assertEquals(['color', 'group', 'identifier', 'shape', 'size', 'weight'], array_keys($result));
+ $this->assertEquals(['color', 'foo', 'fruit', 'group', 'identifier', 'shape', 'size', 'weight'], array_keys($result));
}
$result = MockBasicEntity::get()
],
[
'field1' => 3,
+ 'field3' => NULL,
],
[
'field1' => 4,