*/
class CRM_Afform_AfformScanner {
- const METADATA_FILE = 'meta.json';
+ const METADATA_FILE = 'aff.json';
const DEFAULT_REQUIRES = 'afformCore';
'group' => md5('afform_' . CRM_Core_Config_Runtime::getId() . $this->getSiteLocalPath()),
'prefetch' => FALSE,
]);
+ // $this->cache = new CRM_Utils_Cache_Arraycache([]);
}
/**
foreach ($mapper->getModules() as $module) {
/** @var $module CRM_Core_Module */
if ($module->is_active) {
- $this->appendFilePaths($paths, dirname($mapper->keyToPath($module->name)) . DIRECTORY_SEPARATOR . 'afform', 20);
+ $this->appendFilePaths($paths, dirname($mapper->keyToPath($module->name)) . DIRECTORY_SEPARATOR . 'ang', 20);
}
}
*
* @param string $formName
* Ex: 'view-individual'
- * @param string $subFile
- * Ex: 'meta.json'
+ * @param string $suffix
+ * Ex: 'aff.json'
* @return string|NULL
- * Ex: '/var/www/sites/default/files/civicrm/afform/view-individual'
+ * Ex: '/var/www/sites/default/files/civicrm/afform/view-individual.aff.json'
*/
- public function findFilePath($formName, $subFile) {
+ public function findFilePath($formName, $suffix) {
$paths = $this->findFilePaths();
if (isset($paths[$formName])) {
foreach ($paths[$formName] as $path) {
- if (file_exists($path . DIRECTORY_SEPARATOR . $subFile)) {
- return $path . DIRECTORY_SEPARATOR . $subFile;
+ if (file_exists($path . '.' . $suffix)) {
+ return $path . '.' . $suffix;
}
}
}
* @param string $formName
* Ex: 'view-individual'
* @param string $file
- * Ex: 'meta.json'
+ * Ex: 'aff.json'
* @return string|NULL
- * Ex: '/var/www/sites/default/files/civicrm/afform/view-individual'
+ * Ex: '/var/www/sites/default/files/civicrm/afform/view-individual.aff.json'
*/
public function createSiteLocalPath($formName, $file) {
- return $this->getSiteLocalPath() . DIRECTORY_SEPARATOR . $formName . DIRECTORY_SEPARATOR . $file;
+ return $this->getSiteLocalPath() . DIRECTORY_SEPARATOR . $formName . '.' . $file;
}
public function clear() {
* Ex: 'view-individual'
* @return array
* An array with some mix of the following keys: name, title, description, client_route, server_route, requires.
- * NOTE: This is only data available in meta.json. It does *NOT* include layout.
+ * NOTE: This is only data available in *.aff.json. It does *NOT* include layout.
* Ex: [
* 'name' => 'view-individual',
* 'title' => 'View an individual contact',
*
* @return array
* A list of all forms, keyed by form name.
- * NOTE: This is only data available in meta.json. It does *NOT* include layout.
+ * NOTE: This is only data available in *.aff.json. It does *NOT* include layout.
* Ex: ['view-individual' => ['title' => 'View an individual contact', ...]]
*/
public function getMetas() {
/**
* @param array $formPaths
* List of all form paths.
- * Ex: ['foo' => [0 => '/var/www/org.example.foobar/afform//foo']]
+ * 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.
*/
private function appendFilePaths(&$formPaths, $parent, $priority) {
- $parent = CRM_Utils_File::addTrailingSlash($parent);
- if (is_dir($parent) && $handle = opendir($parent)) {
- while (FALSE !== ($entry = readdir($handle))) {
- if ($entry{0} !== '.' && is_dir($parent . $entry)) {
- $formPaths[$entry][$priority] = $parent . $entry;
- ksort($formPaths[$entry]);
- }
- }
+ $files = (array) glob("$parent/*." . self::METADATA_FILE);
+ foreach ($files as $file) {
+ $name = _afform_angular_module_name(preg_replace('/\.aff\.json$/', '', basename($file)));
+ $formPaths[$name][$priority] = preg_replace('/\.aff\.json$/', '', $file);
+ ksort($formPaths[$name]);
}
}
private function getSiteLocalPath() {
// TODO Allow a setting override.
// return Civi::paths()->getPath(Civi::settings()->get('afformPath'));
- return Civi::paths()->getPath('[civicrm.files]/afform');
+ return Civi::paths()->getPath('[civicrm.files]/ang');
}
}
parent::_run($result);
- $files = [\CRM_Afform_AfformScanner::METADATA_FILE, 'layout.html'];
+ $files = [\CRM_Afform_AfformScanner::METADATA_FILE, 'aff.html'];
foreach ($result as $afform) {
foreach ($files as $file) {
$values = [];
foreach ($names as $name) {
$record = $scanner->getMeta($name);
- $layout = $scanner->findFilePath($name, 'layout.html');
+ $layout = $scanner->findFilePath($name, 'aff.html');
if ($layout) {
// FIXME check for file existence+substance+validity
$record['layout'] = $converter->convertHtmlToArray(file_get_contents($layout));
// FIXME validate all field data.
$updates = _afform_fields_filter($record);
- // Create or update layout.html.
+ // Create or update aff.html.
if (isset($updates['layout'])) {
- $layoutPath = $scanner->createSiteLocalPath($name, 'layout.html');
+ $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 meta.json.
+ // Create or update *.aff.json.
$orig = \Civi\Api4\Afform::get()
->setCheckPermissions($this->getCheckPermissions())
->addWhere('name', '=', $name)
$names = array_keys($scanner->findFilePaths());
foreach ($names as $name) {
$meta = $scanner->getMeta($name);
- $angularModules[_afform_angular_module_name($name)] = [
+ $angularModules[_afform_angular_module_name($name, 'camel')] = [
'ext' => E::LONG_NAME,
'js' => ['assetBuilder://afform.js?name=' . urlencode($name)],
'requires' => $meta['requires'],
$smarty = CRM_Core_Smarty::singleton();
$smarty->assign('afform', [
- 'camel' => _afform_angular_module_name($name),
+ 'camel' => _afform_angular_module_name($name, 'camel'),
'meta' => $meta,
'metaJson' => json_encode($meta),
- 'layout' => file_get_contents($scanner->findFilePath($name, 'layout.html'))
+ 'layout' => file_get_contents($scanner->findFilePath($name, 'aff.html'))
]);
$mimeType = 'text/javascript';
$content = $smarty->fetch('afform/AfformAngularModule.tpl');
}
/**
- * @param string $name
- * Ex: fooBar
+ * @param string $fileBaseName
+ * Ex: foo-bar
* @param string $format
* 'camel' or 'dash'.
* @return string
* Ex: 'FooBar' or 'foo-bar'.
*/
-function _afform_angular_module_name($name, $format = 'camel') {
+function _afform_angular_module_name($fileBaseName, $format = 'camel') {
switch ($format) {
case 'camel':
- return 'afform' . strtoupper($name{0}) . substr($name, 1);
+ $camelCase = '';
+ foreach (explode('-', $fileBaseName) as $shortNamePart) {
+ $camelCase .= ucfirst($shortNamePart);
+ }
+ return strtolower($camelCase{0}) . substr($camelCase, 1);
case 'dash':
- $camel = _afform_angular_module_name($name, 'camel');
- return strtolower(implode('-', array_filter(preg_split('/(?=[A-Z])/', $camel))));
+ return strtolower(implode('-', array_filter(preg_split('/(?=[A-Z])/', $fileBaseName))));
default:
throw new \Exception("Unrecognized format");
--- /dev/null
+<?php
+
+use Civi\Test\HeadlessInterface;
+use Civi\Test\TransactionalInterface;
+
+/**
+ * @group headless
+ */
+class CRM_Afform_UtilTest extends \PHPUnit_Framework_TestCase implements HeadlessInterface, TransactionalInterface {
+
+ /**
+ * Civi\Test has many helpers, like install(), uninstall(), sql(), and sqlFile().
+ * See: https://github.com/civicrm/org.civicrm.testapalooza/blob/master/civi-test.md
+ */
+ public function setUpHeadless() {
+ return \Civi\Test::headless()
+ ->installMe(__DIR__)
+ ->install(['org.civicrm.api4'])
+ ->apply();
+ }
+
+ public function getNameExamples() {
+ $exs = [];
+ $exs[] = ['ab-cd-ef', 'camel', 'abCdEf'];
+ $exs[] = ['abCd', 'camel', 'abCd'];
+ $exs[] = ['AbCd', 'camel', 'abCd'];
+ $exs[] = ['ab-cd', 'dash', 'ab-cd'];
+ $exs[] = ['abCd', 'dash', 'ab-cd'];
+ $exs[] = ['AbCd', 'dash', 'ab-cd'];
+
+ $exs[] = ['ab-cd-ef23', 'camel', 'abCdEf23'];
+ $exs[] = ['abCd23', 'camel', 'abCd23'];
+ $exs[] = ['AbCd23', 'camel', 'abCd23'];
+ $exs[] = ['ab-cd23', 'dash', 'ab-cd23'];
+ $exs[] = ['abCd23', 'dash', 'ab-cd23'];
+ $exs[] = ['AbCd23', 'dash', 'ab-cd23'];
+
+ return $exs;
+ }
+
+ /**
+ * @param $inputFileName
+ * @param $toFormat
+ * @param $expected
+ * @dataProvider getNameExamples
+ */
+ public function testNameConversion($inputFileName, $toFormat, $expected) {
+ $actual = _afform_angular_module_name($inputFileName, $toFormat);
+ $this->assertEquals($expected, $actual);
+ }
+
+}