/** * The Config Class. * * @var Config * @since 3.2.0 */ protected Config $config; /** * The Power Class. * * @var Power * @since 3.2.0 */ protected Power $power; /** * The Language Class. * * @var Language * @since 3.2.0 */ protected Language $language; /** * The Placeholder Class. * * @var Placeholder * @since 3.2.0 */ protected Placeholder $placeholder; /** * The Layout Class. * * @var Layout * @since 3.2.0 */ protected Layout $layout; /** * The SiteFieldData Class. * * @var SiteFieldData * @since 3.2.0 */ protected SiteFieldData $sitefielddata; /** * The Tags Class. * * @var Tags * @since 3.2.0 */ protected Tags $tags; /** * The DatabaseTables Class. * * @var DatabaseTables * @since 3.2.0 */ protected DatabaseTables $databasetables; /** * The DatabaseUniqueKeys Class. * * @var DatabaseUniqueKeys * @since 3.2.0 */ protected DatabaseUniqueKeys $databaseuniquekeys; /** * The DatabaseKeys Class. * * @var DatabaseKeys * @since 3.2.0 */ protected DatabaseKeys $databasekeys; /** * The DatabaseUniqueGuid Class. * * @var DatabaseUniqueGuid * @since 3.2.0 */ protected DatabaseUniqueGuid $databaseuniqueguid; /** * The ListJoin Class. * * @var ListJoin * @since 3.2.0 */ protected ListJoin $listjoin; /** * The History Class. * * @var History * @since 3.2.0 */ protected History $history; /** * The Alias Class. * * @var Alias * @since 3.2.0 */ protected Alias $alias; /** * The Title Class. * * @var Title * @since 3.2.0 */ protected Title $title; /** * The CategoryOtherName Class. * * @var CategoryOtherName * @since 3.2.0 */ protected CategoryOtherName $categoryothername; /** * The Lists Class. * * @var Lists * @since 3.2.0 */ protected Lists $lists; /** * The CustomList Class. * * @var CustomList * @since 3.2.0 */ protected CustomList $customlist; /** * The FieldRelations Class. * * @var FieldRelations * @since 3.2.0 */ protected FieldRelations $fieldrelations; /** * The HiddenFields Class. * * @var HiddenFields * @since 3.2.0 */ protected HiddenFields $hiddenfields; /** * The IntegerFields Class. * * @var IntegerFields * @since 3.2.0 */ protected IntegerFields $integerfields; /** * The DynamicFields Class. * * @var DynamicFields * @since 3.2.0 */ protected DynamicFields $dynamicfields; /** * The MainTextField Class. * * @var MainTextField * @since 3.2.0 */ protected MainTextField $maintextfield; /** * The CustomField Class. * * @var CustomField * @since 3.2.0 */ protected CustomField $customfield; /** * The CustomFieldLinks Class. * * @var CustomFieldLinks * @since 3.2.0 */ protected CustomFieldLinks $customfieldlinks; /** * The ScriptUserSwitch Class. * * @var ScriptUserSwitch * @since 3.2.0 */ protected ScriptUserSwitch $scriptuserswitch; /** * The ScriptMediaSwitch Class. * * @var ScriptMediaSwitch * @since 3.2.0 */ protected ScriptMediaSwitch $scriptmediaswitch; /** * The Category Class. * * @var Category * @since 3.2.0 */ protected Category $category; /** * The CategoryCode Class. * * @var CategoryCode * @since 3.2.0 */ protected CategoryCode $categorycode; /** * The CheckBox Class. * * @var CheckBox * @since 3.2.0 */ protected CheckBox $checkbox; /** * The JsonString Class. * * @var JsonString * @since 3.2.0 */ protected JsonString $jsonstring; /** * The BaseSixFour Class. * * @var BaseSixFour * @since 3.2.0 */ protected BaseSixFour $basesixfour; /** * The ModelBasicField Class. * * @var ModelBasicField * @since 3.2.0 */ protected ModelBasicField $modelbasicfield; /** * The ModelWhmcsField Class. * * @var ModelWhmcsField * @since 3.2.0 */ protected ModelWhmcsField $modelwhmcsfield; /** * The ModelMediumField Class. * * @var ModelMediumField * @since 3.2.0 */ protected ModelMediumField $modelmediumfield; /** * The ModelExpertFieldInitiator Class. * * @var ModelExpertFieldInitiator * @since 3.2.0 */ protected ModelExpertFieldInitiator $modelexpertfieldinitiator; /** * The ModelExpertField Class. * * @var ModelExpertField * @since 3.2.0 */ protected ModelExpertField $modelexpertfield; /** * The JsonItem Class. * * @var JsonItem * @since 3.2.0 */ protected JsonItem $jsonitem; /** * The ItemsMethodListString Class. * * @var ItemsMethodListString * @since 3.2.0 */ protected ItemsMethodListString $itemsmethodliststring; /** * The JsonItemArray Class. * * @var JsonItemArray * @since 3.2.0 */ protected JsonItemArray $jsonitemarray; /** * The ItemsMethodEximportString Class. * * @var ItemsMethodEximportString * @since 3.2.0 */ protected ItemsMethodEximportString $itemsmethodeximportstring; /** * The SelectionTranslation Class. * * @var SelectionTranslation * @since 3.2.0 */ protected SelectionTranslation $selectiontranslation; /** * The AdminFilterType Class. * * @var AdminFilterType * @since 3.2.0 */ protected AdminFilterType $adminfiltertype; /** * The Sort Class. * * @var Sort * @since 3.2.0 */ protected Sort $sort; /** * The Search Class. * * @var Search * @since 3.2.0 */ protected Search $search; /** * The Filter Class. * * @var Filter * @since 3.2.0 */ protected Filter $filter; /** * The ComponentFields Class. * * @var ComponentFields * @since 3.2.0 */ protected ComponentFields $componentfields; /** * Application object. * * @var CMSApplication * @since 3.2.0 **/ protected CMSApplication $app; /** * Constructor. * * @param Config $config The Config Class. * @param Power $power The Power Class. * @param Language $language The Language Class. * @param Placeholder $placeholder The Placeholder Class. * @param Layout $layout The Layout Class. * @param SiteFieldData $sitefielddata The SiteFieldData Class. * @param Tags $tags The Tags Class. * @param DatabaseTables $databasetables The DatabaseTables Class. * @param DatabaseUniqueKeys $databaseuniquekeys The DatabaseUniqueKeys Class. * @param DatabaseKeys $databasekeys The DatabaseKeys Class. * @param DatabaseUniqueGuid $databaseuniqueguid The DatabaseUniqueGuid Class. * @param ListJoin $listjoin The ListJoin Class. * @param History $history The History Class. * @param Alias $alias The Alias Class. * @param Title $title The Title Class. * @param CategoryOtherName $categoryothername The CategoryOtherName Class. * @param Lists $lists The Lists Class. * @param CustomList $customlist The CustomList Class. * @param FieldRelations $fieldrelations The FieldRelations Class. * @param HiddenFields $hiddenfields The HiddenFields Class. * @param IntegerFields $integerfields The IntegerFields Class. * @param DynamicFields $dynamicfields The DynamicFields Class. * @param MainTextField $maintextfield The MainTextField Class. * @param CustomField $customfield The CustomField Class. * @param CustomFieldLinks $customfieldlinks The CustomFieldLinks Class. * @param ScriptUserSwitch $scriptuserswitch The ScriptUserSwitch Class. * @param ScriptMediaSwitch $scriptmediaswitch The ScriptMediaSwitch Class. * @param Category $category The Category Class. * @param CategoryCode $categorycode The CategoryCode Class. * @param CheckBox $checkbox The CheckBox Class. * @param JsonString $jsonstring The JsonString Class. * @param BaseSixFour $basesixfour The BaseSixFour Class. * @param ModelBasicField $modelbasicfield The ModelBasicField Class. * @param ModelWhmcsField $modelwhmcsfield The ModelWhmcsField Class. * @param ModelMediumField $modelmediumfield The ModelMediumField Class. * @param ModelExpertFieldInitiator $modelexpertfieldinitiator The ModelExpertFieldInitiator Class. * @param ModelExpertField $modelexpertfield The ModelExpertField Class. * @param JsonItem $jsonitem The JsonItem Class. * @param ItemsMethodListString $itemsmethodliststring The ItemsMethodListString Class. * @param JsonItemArray $jsonitemarray The JsonItemArray Class. * @param ItemsMethodEximportString $itemsmethodeximportstring The ItemsMethodEximportString Class. * @param SelectionTranslation $selectiontranslation The SelectionTranslation Class. * @param AdminFilterType $adminfiltertype The AdminFilterType Class. * @param Sort $sort The Sort Class. * @param Search $search The Search Class. * @param Filter $filter The Filter Class. * @param ComponentFields $componentfields The ComponentFields Class. * @param CMSApplication|null $app The app object. * * @since 3.2.0 */ public function __construct(Config $config, Power $power, Language $language, Placeholder $placeholder, Layout $layout, SiteFieldData $sitefielddata, Tags $tags, DatabaseTables $databasetables, DatabaseUniqueKeys $databaseuniquekeys, DatabaseKeys $databasekeys, DatabaseUniqueGuid $databaseuniqueguid, ListJoin $listjoin, History $history, Alias $alias, Title $title, CategoryOtherName $categoryothername, Lists $lists, CustomList $customlist, FieldRelations $fieldrelations, HiddenFields $hiddenfields, IntegerFields $integerfields, DynamicFields $dynamicfields, MainTextField $maintextfield, CustomField $customfield, CustomFieldLinks $customfieldlinks, ScriptUserSwitch $scriptuserswitch, ScriptMediaSwitch $scriptmediaswitch, Category $category, CategoryCode $categorycode, CheckBox $checkbox, JsonString $jsonstring, BaseSixFour $basesixfour, ModelBasicField $modelbasicfield, ModelWhmcsField $modelwhmcsfield, ModelMediumField $modelmediumfield, ModelExpertFieldInitiator $modelexpertfieldinitiator, ModelExpertField $modelexpertfield, JsonItem $jsonitem, ItemsMethodListString $itemsmethodliststring, JsonItemArray $jsonitemarray, ItemsMethodEximportString $itemsmethodeximportstring, SelectionTranslation $selectiontranslation, AdminFilterType $adminfiltertype, Sort $sort, Search $search, Filter $filter, ComponentFields $componentfields, ?CMSApplication $app = null) { $this->config = $config; $this->power = $power; $this->language = $language; $this->placeholder = $placeholder; $this->layout = $layout; $this->sitefielddata = $sitefielddata; $this->tags = $tags; $this->databasetables = $databasetables; $this->databaseuniquekeys = $databaseuniquekeys; $this->databasekeys = $databasekeys; $this->databaseuniqueguid = $databaseuniqueguid; $this->listjoin = $listjoin; $this->history = $history; $this->alias = $alias; $this->title = $title; $this->categoryothername = $categoryothername; $this->lists = $lists; $this->customlist = $customlist; $this->fieldrelations = $fieldrelations; $this->hiddenfields = $hiddenfields; $this->integerfields = $integerfields; $this->dynamicfields = $dynamicfields; $this->maintextfield = $maintextfield; $this->customfield = $customfield; $this->customfieldlinks = $customfieldlinks; $this->scriptuserswitch = $scriptuserswitch; $this->scriptmediaswitch = $scriptmediaswitch; $this->category = $category; $this->categorycode = $categorycode; $this->checkbox = $checkbox; $this->jsonstring = $jsonstring; $this->basesixfour = $basesixfour; $this->modelbasicfield = $modelbasicfield; $this->modelwhmcsfield = $modelwhmcsfield; $this->modelmediumfield = $modelmediumfield; $this->modelexpertfieldinitiator = $modelexpertfieldinitiator; $this->modelexpertfield = $modelexpertfield; $this->jsonitem = $jsonitem; $this->itemsmethodliststring = $itemsmethodliststring; $this->jsonitemarray = $jsonitemarray; $this->itemsmethodeximportstring = $itemsmethodeximportstring; $this->selectiontranslation = $selectiontranslation; $this->adminfiltertype = $adminfiltertype; $this->sort = $sort; $this->search = $search; $this->filter = $filter; $this->componentfields = $componentfields; $this->app = $app ?: Factory::getApplication(); } /** * set Builders * * @param string $langLabel The language string for field label * @param string $langView The language string of the view * @param string $nameSingleCode The single view name * @param string $nameListCode The list view name * @param string $name The field name * @param array $view The view data * @param array $field The field data * @param string $typeName The field type * @param bool $multiple The switch to set multiple selection option * @param array|null $custom The custom field switch * @param array|null $options The options switch * * @return void * @since 3.2.0 */ public function set(string $langLabel, string $langView, string $nameSingleCode, string $nameListCode, string $name, array $view, array $field, string $typeName, bool $multiple, ?array $custom = null, ?array $options = null): void { // check if this is a tag field if ($typeName === 'tag') { // set tags for this view but don't load to DB $this->tags->set($nameSingleCode, true); } // dbSwitch $dbSwitch = true; if (isset($field['list']) && $field['list'] == 2) { // do not add this field to the database $dbSwitch = false; } elseif (isset($field['settings']->datatype)) { // insure default not none if number type $numberKeys = array('INT', 'TINYINT', 'BIGINT', 'FLOAT', 'DECIMAL', 'DOUBLE'); // don't use these as index or uniqe keys $textKeys = array('TEXT', 'TINYTEXT', 'MEDIUMTEXT', 'LONGTEXT', 'BLOB', 'TINYBLOB', 'MEDIUMBLOB', 'LONGBLOB'); // build the query values $this->databasetables->set($nameSingleCode . '.' . $name . '.type', $field['settings']->datatype); // check if this is a number if (in_array($field['settings']->datatype, $numberKeys)) { if ($field['settings']->datadefault === 'Other') { // setup the checking $number_check = $field['settings']->datadefault_other; // Decimals in SQL needs some help if ('DECIMAL' === $field['settings']->datatype && !is_numeric($number_check)) { $number_check = str_replace( ',', '.', (string) $field['settings']->datadefault_other ); } // check if we have a valid number value if (!is_numeric($number_check)) { $field['settings']->datadefault_other = '0'; } } elseif (!is_numeric($field['settings']->datadefault)) { $field['settings']->datadefault = '0'; } } // check if this is not text if (!in_array($field['settings']->datatype, $textKeys)) { $this->databasetables->set($nameSingleCode . '.' . $name . '.lenght', $field['settings']->datalenght); $this->databasetables->set($nameSingleCode . '.' . $name . '.lenght_other', $field['settings']->datalenght_other); $this->databasetables->set($nameSingleCode . '.' . $name . '.default', $field['settings']->datadefault); $this->databasetables->set($nameSingleCode . '.' . $name . '.other', $field['settings']->datadefault_other); } // fall back unto EMPTY for text else { $this->databasetables->set($nameSingleCode . '.' . $name . '.default', 'EMPTY'); } // to identify the field $this->databasetables->set($nameSingleCode . '.' . $name . '.ID', $field['settings']->id); $this->databasetables->set($nameSingleCode . '.' . $name . '.null_switch', $field['settings']->null_switch); // set index types $_guid = true; if ($field['settings']->indexes == 1 && !in_array( $field['settings']->datatype, $textKeys )) { // build unique keys of this view for db $this->databaseuniquekeys->add($nameSingleCode, $name, true); // prevent guid from being added twice if ('guid' === $name) { $_guid = false; } } elseif (($field['settings']->indexes == 2 || (isset($field['alias']) && $field['alias']) || (isset($field['title']) && $field['title']) || $typeName === 'category') && !in_array($field['settings']->datatype, $textKeys)) { // build keys of this view for db $this->databasekeys->add($nameSingleCode, $name, true); } // special treatment for GUID if ('guid' === $name && $_guid) { $this->databaseuniqueguid->set($nameSingleCode, true); } } // set list switch $listSwitch = (isset($field['list']) && ($field['list'] == 1 || $field['list'] == 3 || $field['list'] == 4)); // set list join $listJoin = $this->listjoin->exists($nameListCode . '.' . (int) $field['field']); // add history to this view if (isset($view['history']) && $view['history']) { $this->history->set($nameSingleCode, true); } // set Alias (only one title per view) if ($dbSwitch && isset($field['alias']) && $field['alias'] && !$this->alias->get($nameSingleCode)) { $this->alias->set($nameSingleCode, $name); } // set Titles (only one title per view) if ($dbSwitch && isset($field['title']) && $field['title'] && !$this->title->get($nameSingleCode)) { $this->title->set($nameSingleCode, $name); } // category name fix if ($typeName === 'category') { $tempName = $this->categoryothername-> get($nameListCode . '.name', $nameListCode . ' categories'); // set lang $listLangName = $langView . '_' . FieldHelper::safe($tempName, true); // set field name $listFieldName = StringHelper::safe($tempName, 'W'); // add to lang array $this->language->set( $this->config->lang_target, $listLangName, $listFieldName ); } else { // if label was set use instead if (StringHelper::check($langLabel)) { $listLangName = $langLabel; // get field label from the lang label if ($this->language->exist($this->config->lang_target, $langLabel)) { $listFieldName = $this->language->get($this->config->lang_target, $langLabel); } else { // get it from the field xml string $listFieldName = (string) $this->placeholder->update_( GetHelper::between( $field['settings']->xml, 'label="', '"' ) ); } // make sure there is no html in the list field name $listFieldName = strip_tags($listFieldName); } else { // set lang (just in case) $listLangName = $langView . '_' . FieldHelper::safe($name, true); // set field name $listFieldName = StringHelper::safe($name, 'W'); // add to lang array $this->language->set( $this->config->lang_target, $listLangName, $listFieldName ); } } // extends value $extends_field = $custom['extends'] ?? ''; // build the list values if (($listSwitch || $listJoin) && $typeName != 'repeatable' && $typeName != 'subform') { // load to list builder if ($listSwitch) { // append values $this->lists->add($nameListCode, [ 'id' => (int) $field['field'], 'type' => $typeName, 'code' => $name, 'lang' => $listLangName, 'title' => (isset($field['title']) && $field['title']) ? true : false, 'alias' => (isset($field['alias']) && $field['alias']) ? true : false, 'link' => (isset($field['link']) && $field['link']) ? true : false, 'sort' => (isset($field['sort']) && $field['sort']) ? true : false, 'custom' => $custom, 'multiple' => $multiple, 'options' => $options, 'target' => (int) $field['list'] ], true); } // build custom builder list if ($listSwitch || $listJoin) { $this->customlist->set($nameSingleCode . '.' . $name, true); } } // load the list join builder if ($listJoin) { $this->listjoin->set($nameListCode . '.' . (int) $field['field'], [ 'type' => $typeName, 'code' => $name, 'lang' => $listLangName, 'title' => (isset($field['title']) && $field['title']) ? true : false, 'alias' => (isset($field['alias']) && $field['alias']) ? true : false, 'link' => (isset($field['link']) && $field['link']) ? true : false, 'sort' => (isset($field['sort']) && $field['sort']) ? true : false, 'custom' => $custom, 'multiple' => $multiple, 'options' => $options ]); } // update the field relations if (($field_relations = $this->fieldrelations->get($nameListCode . '.' . (int) $field['field'])) !== null) { $field_relations = (array) $field_relations; foreach ($field_relations as $area => &$field_values) { $field_values['type'] = $typeName; $field_values['code'] = $name; $field_values['custom'] = $custom; } $this->fieldrelations->set($nameListCode . '.' . (int) $field['field'], $field_relations); } // set the hidden field of this view if ($dbSwitch && $typeName === 'hidden') { $this->hiddenfields->add($nameSingleCode, ',"' . $name . '"', true); } // set all int fields of this view if ($dbSwitch && isset($field['settings']->datatype) && ($field['settings']->datatype === 'INT' || $field['settings']->datatype === 'TINYINT' || $field['settings']->datatype === 'BIGINT')) { $this->integerfields->add($nameSingleCode, ',"' . $name . '"', true); } // Get the default fields $default_fields = $this->config->default_fields; // set all dynamic field of this view if ($dbSwitch && $typeName != 'category' && $typeName != 'repeatable' && $typeName != 'subform' && !in_array($name, $default_fields)) { $this->dynamicfields->add($nameSingleCode, '"' . $name . '":"' . $name . '"', true); } // TODO we may need to add a switch instead (since now it uses the first editor field) // set the main(biggest) text field of this view if ($dbSwitch && $typeName === 'editor') { if (!$this->maintextfield->exists($nameSingleCode)) { $this->maintextfield->set($nameSingleCode, $name); } } // set the custom builder if (ArrayHelper::check($custom) && $typeName != 'category' && $typeName != 'repeatable' && $typeName != 'subform') { $this->customfield->add($nameListCode, [ 'type' => $typeName, 'code' => $name, 'lang' => $listLangName, 'custom' => $custom, 'method' => $field['settings']->store ], true); // only load this if table is set if (isset($custom['table']) && StringHelper::check( $custom['table'] )) { // set the custom fields needed in content type data $this->customfieldlinks->add( $nameSingleCode, ',{"sourceColumn": "' . $name . '","targetTable": "' . $custom['table'] . '","targetColumn": "' . $custom['id'] . '","displayColumn": "' . $custom['text'] . '"}', true ); } // build script switch for user if ($extends_field === 'user') { $this->scriptuserswitch->set($typeName, $typeName); } } if ($typeName === 'media') { $this->scriptmediaswitch->set($typeName, $typeName); } // setup category for this view if ($dbSwitch && $typeName === 'category') { $otherViews = $this->categoryothername-> get($nameListCode . '.views', $nameListCode); $otherView = $this->categoryothername-> get($nameListCode . '.view', $nameSingleCode); // get the xml extension name $_extension = $this->placeholder->update_( GetHelper::between( $field['settings']->xml, 'extension="', '"' ) ); // if they left out the extension for some reason if (!StringHelper::check($_extension)) { $_extension = 'com_' . $this->config->component_code_name . '.' . $otherView; } // check the context (does our target match) if (strpos((string) $_extension, '.') !== false) { $target_view = trim(explode('.', (string) $_extension)[1]); // from my understanding the target extension view and the otherView must align // so I will here check that it does, and if not raise an error message to fix this if ($target_view !== $otherView) { $target_extension = trim(explode('.', (string) $_extension)[0]); $correction = $target_extension . '.' . $otherView; $this->app->enqueueMessage( Text::sprintf( '
The
category field in (%s) admin view has a mismatching target view.
To correct the mismatch, the extension value %s
in the
field must be changed to %s
for
best category integration with Joomla.
Please watch
this tutorial before proceeding!!!,
code fix