diff --git a/app/src/View/Helper/FieeldHelper.php b/app/src/View/Helper/FieeldHelper.php index 8882e2354..6ca565231 100644 --- a/app/src/View/Helper/FieeldHelper.php +++ b/app/src/View/Helper/FieeldHelper.php @@ -81,6 +81,93 @@ public function initialize(array $config): void $this->fieldTypes = $this->getView()->get('vv_field_types'); } + /** + * We autogenerate field labels and descriptions from the field name. + * + * @param string $fieldName + * + * @return array + */ + public function calculateLabelAndDescription(string $fieldName): array + { + $desc = null; + $label = null; + + // First, try to autogenerate the field label (if we weren't given one). + $pluginDomain = (!empty($this->getPluginName()) + ? Inflector::underscore($this->getPluginName()) + : null); + + $modelName = $this->getModelName(); + // We try to automagically determine if a description for the field exists by + // looking for the corresponding .desc language translation. + // We autogenerate field labels and descriptions from the field name. + + // We loop over the field generation logic twice, first for a plugin + // context (if set) and then generally (if no plugin localization was found). + + // We use $core as the variable for this loop, so the rest of the code + // is easier to read (!$core = plugin) + for($core = 0;$core < 2;$core++) { + if(!$core && empty($this->pluginName)) { + // No plugin set, go to the core field checks + continue; + } + + // Is there a model specific key? For plugins, this will be in field.Model.Field + + $key = (!$core ? 'field.' : '') . "$modelName.$fieldName"; + $label = __d(($core ? 'field' : $pluginDomain), $key); + + if($label === $key) { + // Model-specific label isn't found, try again for a general label + + $f = null; + + if(preg_match('/^(.*?)_id$/', $fieldName, $f)) { + // Map foreign keys (foo_id) to the controller label + $key = (!$core ? 'controller.' : '') . Inflector::camelize(Inflector::pluralize($f[1])); + $label = __d(($core ? 'controller' : $pluginDomain), $key, [1]); + + if($key !== $label) { + break; + } + } + + // Look up the key + $key = (!$core ? 'field.' : '') . $fieldName; + $label = __d(($core ? 'field' : $pluginDomain), $key); + + if($key !== $label) { + break; + } + } else { + // If we found a key, break the loop + break; + } + } + // We try to automagically determine if a description for the field exists by + // looking for the corresponding .desc language translation. + + for($core = 0;$core < 2;$core++) { + if(!$core && empty($this->pluginName)) { + // No plugin set, just go to the core field checks + continue; + } + + $key = (!$core ? 'field.' : '') . "$modelName.$fieldName.desc"; + $desc = __d(($core ? 'field' : $pluginDomain), $key); + + // If the description is the literal key we just generated, there is no description + if($desc === $key) { + $desc = null; + } else { + break; + } + } + + return [$label, $desc]; + } /** * Emit a date/time form control. @@ -91,7 +178,7 @@ public function initialize(array $config): void * @param array|null $queryParams Request Query parameters used by the filtering Blocks to get the date values * @param string|null $label * - * @return array HTML for control + * @return string HTML element * @since COmanage Registry v5.0.0 */ @@ -126,7 +213,7 @@ public function dateField(string $fieldName, // ACTION VIEW if($this->action == 'view') { // return the date as plaintext - $element = $this->notSetElement(); + $element = $this->getView()->element('form/notSetDiv'); if ($date_object !== null) { // Adjust the time back to the user's timezone $element = ''; @@ -188,19 +275,19 @@ public function dateField(string $fieldName, * * @param string $fieldName Form field * @param array|null $options FormHelper control options - * By setting the options you are requesting a select field * @param string|null $labelText * @param string $prefix Field prefix - used for API Usernames * @param string|null $fieldType * - * @return string HTML for control + * @return string HTML element * @since COmanage Registry v5.0.0 */ public function formField(string $fieldName, array $options = null, string $labelText = null, string $prefix = '', // api user - string $fieldType = null): string { + string $fieldType = null): string + { $fieldArgs = $options ?? []; $fieldArgs['label'] = $options['label'] ?? false; $fieldArgs['readonly'] = !$this->editable @@ -209,7 +296,7 @@ public function formField(string $fieldName, // Selects, Checkboxes, and Radio Buttons use "disabled" $fieldArgs['disabled'] = $fieldArgs['readonly']; - $fieldArgs['required'] = (bool)$this->getReqField($fieldName); + $fieldArgs['required'] = (bool)$this->isReqField($fieldName); // Get the field type from the map of fields (e.g. 'boolean', 'string', 'timestamp') $fieldType = $fieldType ?? $this->getFieldType($fieldName); @@ -223,12 +310,14 @@ public function formField(string $fieldName, $this->getView()->set('vv_obj', $vv_obj); } - if($fieldName !== 'status' - && !isset($options['empty']) - && (!isset($options['suppressBlank']) || !$options['suppressBlank'])) { - // Cause any select (except status) to render with a blank option, even - // if the field is required. This makes it clear when a value needs to be set. - // Note this will be ignored for non-select controls. + // Cause any select (except status) to render with a blank option, even + // if the field is required. This makes it clear when a value needs to be set. + // Note this will be ignored for non-select controls. + if($fieldName === 'status') { + $fieldArgs['empty'] = false; + } elseif(isset($options['empty'])) { + $fieldArgs['empty'] = $options['empty']; + } else { $fieldArgs['empty'] = true; } @@ -248,93 +337,48 @@ public function formField(string $fieldName, } - /** - * We autogenerate field labels and descriptions from the field name. + * Emit a source control for an MVEA that has a source_foo_id field pointing + * to an External Identity attribute. * - * @param string $fieldName + * @param Entity $entity Entity to emit control for * - * @return array + * @return string Source Link + * @since COmanage Registry v5.0.0 */ - public function calculateLabelAndDescription(string $fieldName): array + public function sourceLink($entity): string { - $desc = null; - $label = null; - - // First, try to autogenerate the field label (if we weren't given one). - $pluginDomain = (!empty($this->getPluginName()) - ? Inflector::underscore($this->getPluginName()) - : null); - - $modelName = $this->getModelName(); - // We try to automagically determine if a description for the field exists by - // looking for the corresponding .desc language translation. - // We autogenerate field labels and descriptions from the field name. - - // We loop over the field generation logic twice, first for a plugin - // context (if set) and then generally (if no plugin localization was found). - - // We use $core as the variable for this loop, so the rest of the code - // is easier to read (!$core = plugin) - for($core = 0;$core < 2;$core++) { - if(!$core && empty($this->pluginName)) { - // No plugin set, go to the core field checks - continue; - } - - // Is there a model specific key? For plugins, this will be in field.Model.Field - - $key = (!$core ? 'field.' : '') . "$modelName.$fieldName"; - $label = __d(($core ? 'field' : $pluginDomain), $key); - - if($label === $key) { - // Model-specific label isn't found, try again for a general label - - $f = null; - - if(preg_match('/^(.*?)_id$/', $fieldName, $f)) { - // Map foreign keys (foo_id) to the controller label - $key = (!$core ? 'controller.' : '') . Inflector::camelize(Inflector::pluralize($f[1])); - $label = __d(($core ? 'controller' : $pluginDomain), $key, [1]); - - if($key !== $label) { - break; - } - } - - // Look up the key - $key = (!$core ? 'field.' : '') . $fieldName; - $label = __d(($core ? 'field' : $pluginDomain), $key); - - if($key !== $label) { - break; - } - } else { - // If we found a key, break the loop - break; - } + // eg: Identifiers + // eg: source_identifier_id, or source_external_identity_role_id + $sourceFK = $this->getView()->get('vv_source_fk'); + // e.g.: source_identifier - we need to construct this from the $sourceFK + $sourceEntityName = substr($sourceFK, 0, strlen($sourceFK) - 3); + // In most cases, $sourceModelName = $modelName, but not for PersonRoles + $sourceModelName = substr(StringUtilities::foreignKeyToClassName($sourceFK), 6); + + $link = ''; + if (!empty($entity->$sourceFK)) { + $link .= $this->Html->Link( + title: __d('controller', $sourceModelName, [1]), + url: [ + 'controller' => $sourceModelName, + 'action' => 'view', + $entity->$sourceFK + ] + ); } - // We try to automagically determine if a description for the field exists by - // looking for the corresponding .desc language translation. - - for($core = 0;$core < 2;$core++) { - if(!$core && empty($this->pluginName)) { - // No plugin set, just go to the core field checks - continue; - } - - $key = (!$core ? 'field.' : '') . "$modelName.$fieldName.desc"; - $desc = __d(($core ? 'field' : $pluginDomain), $key); - // If the description is the literal key we just generated, there is no description - if($desc === $key) { - $desc = null; - } else { - break; - } + if (!empty($entity->$sourceEntityName)) { + $link .= ', ' . $this->Html->Link( + title: __d('controller', 'ExternalIdentities', [1]), + url: [ + 'controller' => 'external_identities', + 'action' => 'view', + $entity->$sourceEntityName->external_identity_id + ] + ); } - - return [$label, $desc]; + return $link; } /** @@ -380,11 +424,11 @@ public function getReqFields(): array /** * @param string $field * - * @return string|null + * @return bool */ - public function getReqField(string $field): ?string + public function isReqField(string $field): bool { - return $this->reqFields[$field] ?? null; + return \in_array($field, $this->reqFields, true); }