jcb-compiler/src/79739667-72c6-4576-9830-7b1.../code.php

679 lines
20 KiB
PHP

<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Creator;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Language\Fieldset as Language;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event;
use VDM\Joomla\Componentbuilder\Compiler\Adminview\Permission;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldDynamic;
use VDM\Joomla\Componentbuilder\Compiler\Builder\FieldNames;
use VDM\Joomla\Componentbuilder\Compiler\Builder\AccessSwitch;
use VDM\Joomla\Componentbuilder\Compiler\Builder\MetaData;
use VDM\Joomla\Componentbuilder\Compiler\Creator\Layout;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Xml;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Creator\Fieldsetinterface;
/**
* Fieldset XML Creator Class
*
* @since 3.2.0
*/
final class FieldsetXML implements Fieldsetinterface
{
/**
* The Config Class.
*
* @var Config
* @since 3.2.0
*/
protected Config $config;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 3.2.0
*/
protected Placeholder $placeholder;
/**
* The Fieldset Class.
*
* @var Language
* @since 3.2.0
*/
protected Language $language;
/**
* The EventInterface Class.
*
* @var Event
* @since 3.2.0
*/
protected Event $event;
/**
* The Permission Class.
*
* @var Permission
* @since 3.2.0
*/
protected Permission $permission;
/**
* The FieldDynamic Class.
*
* @var FieldDynamic
* @since 3.2.0
*/
protected FieldDynamic $fielddynamic;
/**
* The FieldNames Class.
*
* @var FieldNames
* @since 3.2.0
*/
protected FieldNames $fieldnames;
/**
* The AccessSwitch Class.
*
* @var AccessSwitch
* @since 3.2.0
*/
protected AccessSwitch $accessswitch;
/**
* The MetaData Class.
*
* @var MetaData
* @since 3.2.0
*/
protected MetaData $metadata;
/**
* The Layout Class.
*
* @var Layout
* @since 3.2.0
*/
protected Layout $layout;
/**
* The Counter Class.
*
* @var Counter
* @since 3.2.0
*/
protected Counter $counter;
/**
* The Xml Class.
*
* @var Xml
* @since 3.2.0
*/
protected Xml $xml;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param Language $language The Fieldset Class.
* @param Event $event The EventInterface Class.
* @param Permission $permission The Permission Class.
* @param FieldDynamic $fielddynamic The FieldDynamic Class.
* @param FieldNames $fieldnames The FieldNames Class.
* @param AccessSwitch $accessswitch The AccessSwitch Class.
* @param MetaData $metadata The MetaData Class.
* @param Layout $layout The Layout Class.
* @param Counter $counter The Counter Class.
* @param Xml $xml The Xml Class.
*
* @since 3.2.0
*/
public function __construct(Config $config, Placeholder $placeholder,
Language $language, Event $event, Permission $permission,
FieldDynamic $fielddynamic, FieldNames $fieldnames,
AccessSwitch $accessswitch, MetaData $metadata,
Layout $layout, Counter $counter, Xml $xml)
{
$this->config = $config;
$this->placeholder = $placeholder;
$this->language = $language;
$this->event = $event;
$this->permission = $permission;
$this->fielddynamic = $fielddynamic;
$this->fieldnames = $fieldnames;
$this->accessswitch = $accessswitch;
$this->metadata = $metadata;
$this->layout = $layout;
$this->counter = $counter;
$this->xml = $xml;
}
/**
* Get a fieldset
*
* @param array $view The view data
* @param string $component The component name
* @param string $nameSingleCode The single view name
* @param string $nameListCode The list view name
*
* @return string The fields set as a string or empty string if no field found.
* @since 3.2.0
*/
public function get(array $view, string $component, string $nameSingleCode,
string $nameListCode): string
{
// setup the fieldset language values of this view
if (!isset($view['settings']->fields)
|| !ArrayHelper::check($view['settings']->fields))
{
return '';
}
// add metadata to the view
$metadata = false;
if (isset($view['metadata']) && $view['metadata'])
{
$metadata = true;
}
// add access to the view
$access = false;
if (isset($view['access']) && $view['access'])
{
$access = true;
}
// main lang prefix
$lang_view = $this->config->lang_prefix . '_'
. $this->placeholder->get('VIEW');
$lang_views = $this->config->lang_prefix . '_'
. $this->placeholder->get('VIEWS');
$name_single = $view['settings']->name_single ?? 'Error';
$name_list = $view['settings']->name_list ?? 'Error';
$lang_target = $this->config->lang_target ?? 'both';
// load the language values
$this->language->set(
$access,
$metadata,
$lang_target,
$lang_view,
$lang_views,
$name_single,
$name_list,
$nameSingleCode,
$nameListCode
);
// set the read only
$read_only_xml = [];
if ($view['settings']->type == 2)
{
$read_only_xml['readonly'] = true;
$read_only_xml['disabled'] = true;
}
// start adding dynamc fields
$dynamic_fields_xml = [];
// set the custom table key
$dbkey = 'g';
// Trigger Event: jcb_ce_onBeforeBuildFields
$this->event->trigger(
'jcb_ce_onBeforeBuildFields',
[&$dynamic_fields_xml, &$read_only_xml,
&$dbkey, &$view, &$component, &$nameSingleCode,
&$nameListCode, &$lang_view,
&$lang_views]
);
// TODO we should add the global and local view switch if field for front end
foreach ($view['settings']->fields as $field)
{
$dynamic_fields_xml[] = $this->fielddynamic->get(
$field, $view, $view['settings']->type, $lang_view,
$nameSingleCode, $nameListCode, $this->placeholder->active, $dbkey,
true
);
}
// Trigger Event: jcb_ce_onAfterBuildFields
$this->event->trigger(
'jcb_ce_onAfterBuildFields',
[&$dynamic_fields_xml, &$read_only_xml,
&$dbkey, &$view, &$component, &$nameSingleCode,
&$nameListCode, &$lang_view,
&$lang_views]
);
// set the default fields
$main_xml = new \simpleXMLElement('<a/>');
$field_set_xml = $main_xml->addChild('fieldset');
$field_set_xml->addAttribute('name', 'details');
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__) . " Default Fields."
);
$this->xml->comment(
$field_set_xml,
Line::_(__Line__, __Class__) . " Id Field. Type: Text (joomla)"
);
// if id is not set
if (!$this->fieldnames->isString($nameSingleCode . '.id'))
{
$attributes = [
'name' => 'id',
'type' => 'text',
'class' => 'readonly',
'readonly' => "true",
'label' => 'JGLOBAL_FIELD_ID_LABEL',
'description' => 'JGLOBAL_FIELD_ID_DESC',
'size' => 10,
'default' => 0
];
$field_xml = $field_set_xml->addChild('field');
$this->xml->attributes($field_xml, $attributes);
// count the static field created
$this->counter->field++;
}
// if created is not set
if (!$this->fieldnames->isString($nameSingleCode . '.created'))
{
$attributes = [
'name' => 'created',
'type' => 'calendar',
'label' => $lang_view . '_CREATED_DATE_LABEL',
'description' => $lang_view . '_CREATED_DATE_DESC',
'size' => 22,
'format' => '%Y-%m-%d %H:%M:%S',
'filter' => 'user_utc'
];
$attributes = array_merge($attributes, $read_only_xml);
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__)
. " Date Created Field. Type: Calendar (joomla)"
);
$field_xml = $field_set_xml->addChild('field');
$this->xml->attributes($field_xml, $attributes);
// count the static field created
$this->counter->field++;
}
// if created_by is not set
if (!$this->fieldnames->isString($nameSingleCode . '.created_by'))
{
$attributes = [
'name' => 'created_by',
'type' => 'user',
'label' => $lang_view . '_CREATED_BY_LABEL',
'description' => $lang_view . '_CREATED_BY_DESC',
];
$attributes = array_merge($attributes, $read_only_xml);
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__)
. " User Created Field. Type: User (joomla)"
);
$field_xml = $field_set_xml->addChild('field');
$this->xml->attributes($field_xml, $attributes);
// count the static field created
$this->counter->field++;
}
// if published is not set
if (!$this->fieldnames->isString($nameSingleCode . '.published'))
{
$attributes = [
'name' => 'published',
'type' => 'list',
'label' => 'JSTATUS'
];
$attributes = array_merge($attributes, $read_only_xml);
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__)
. " Published Field. Type: List (joomla)"
);
$field_xml = $field_set_xml->addChild('field');
$this->xml->attributes($field_xml, $attributes);
// count the static field created
$this->counter->field++;
foreach (['JPUBLISHED' => 1, 'JUNPUBLISHED' => 0,
'JARCHIVED' => 2, 'JTRASHED' => -2] as $text => $value
)
{
$optionXML = $field_xml->addChild('option');
$optionXML->addAttribute('value', $value);
$optionXML[] = $text;
}
}
// if modified is not set
if (!$this->fieldnames->isString($nameSingleCode . '.modified'))
{
$attributes = [
'name' => 'modified',
'type' => 'calendar',
'class' => 'readonly',
'label' => $lang_view . '_MODIFIED_DATE_LABEL',
'description' => $lang_view . '_MODIFIED_DATE_DESC',
'size' => 22,
'readonly' => "true",
'format' => '%Y-%m-%d %H:%M:%S',
'filter' => 'user_utc'
];
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__)
. " Date Modified Field. Type: Calendar (joomla)"
);
$field_xml = $field_set_xml->addChild('field');
$this->xml->attributes($field_xml, $attributes);
// count the static field created
$this->counter->field++;
}
// if modified_by is not set
if (!$this->fieldnames->isString($nameSingleCode . '.modified_by'))
{
$attributes = [
'name' => 'modified_by',
'type' => 'user',
'label' => $lang_view . '_MODIFIED_BY_LABEL',
'description' => $lang_view . '_MODIFIED_BY_DESC',
'class' => 'readonly',
'readonly' => 'true',
'filter' => 'unset'
];
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__)
. " User Modified Field. Type: User (joomla)"
);
$field_xml = $field_set_xml->addChild('field');
$this->xml->attributes($field_xml, $attributes);
// count the static field created
$this->counter->field++;
}
// check if view has access
if ($this->accessswitch->exists($nameSingleCode)
&& !$this->fieldnames->isString($nameSingleCode . '.access'))
{
$attributes = [
'name' => 'access',
'type' => 'accesslevel',
'label' => 'JFIELD_ACCESS_LABEL',
'description' => 'JFIELD_ACCESS_DESC',
'default' => 1,
'required' => "false"
];
$attributes = array_merge($attributes, $read_only_xml);
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__)
. " Access Field. Type: Accesslevel (joomla)"
);
$field_xml = $field_set_xml->addChild('field');
$this->xml->attributes($field_xml, $attributes);
// count the static field created
$this->counter->field++;
}
// if ordering is not set
if (!$this->fieldnames->isString($nameSingleCode . '.ordering'))
{
$attributes = [
'name' => 'ordering',
'type' => 'number',
'class' => 'inputbox validate-ordering',
'label' => $lang_view . '_ORDERING_LABEL',
'description' => '',
'default' => 0,
'size' => 6,
'required' => "false"
];
$attributes = array_merge($attributes, $read_only_xml);
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__)
. " Ordering Field. Type: Numbers (joomla)"
);
$field_xml = $field_set_xml->addChild('field');
$this->xml->attributes($field_xml, $attributes);
// count the static field created
$this->counter->field++;
}
// if version is not set
if (!$this->fieldnames->isString($nameSingleCode . '.version'))
{
$attributes = [
'name' => 'version',
'type' => 'text',
'class' => 'readonly',
'label' => $lang_view . '_VERSION_LABEL',
'description' => $lang_view . '_VERSION_DESC',
'size' => 6,
'default' => 1,
'readonly' => "true",
'filter' => 'unset'
];
$this->xml->comment(
$field_set_xml,
Line::_(__Line__, __Class__) . " Version Field. Type: Text (joomla)"
);
$field_xml = $field_set_xml->addChild('field');
$this->xml->attributes($field_xml, $attributes);
// count the static field created
$this->counter->field++;
}
// check if metadata is added to this view
if ($this->metadata->isString($nameSingleCode))
{
// metakey
if (!$this->fieldnames->isString($nameSingleCode . '.metakey'))
{
$attributes = [
'name' => 'metakey',
'type' => 'textarea',
'label' => 'JFIELD_META_KEYWORDS_LABEL',
'description' => 'JFIELD_META_KEYWORDS_DESC',
'rows' => 3,
'cols' => 30
];
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__)
. " Metakey Field. Type: Textarea (joomla)"
);
$field_xml = $field_set_xml->addChild('field');
$this->xml->attributes(
$field_xml, $attributes
);
// count the static field created
$this->counter->field++;
}
// metadesc
if (!$this->fieldnames->isString($nameSingleCode . '.metadesc'))
{
$attributes['name'] = 'metadesc';
$attributes['label'] = 'JFIELD_META_DESCRIPTION_LABEL';
$attributes['description'] = 'JFIELD_META_DESCRIPTION_DESC';
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__)
. " Metadesc Field. Type: Textarea (joomla)"
);
$field_xml = $field_set_xml->addChild('field');
$this->xml->attributes(
$field_xml, $attributes
);
// count the static field created
$this->counter->field++;
}
}
// fix the permissions field "title" issue gh-629
// check if the title is not already set
if (!$this->fieldnames->isString($nameSingleCode . '.title')
&& $this->permission->check($view, $nameSingleCode))
{
// set the field/tab name
$field_name = "title";
$tab_name = "publishing";
$attributes = [
'name' => $field_name,
'type' => 'hidden',
'default' => $component . ' ' . $nameSingleCode
];
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__)
. " Was added due to Permissions JS needing a Title field"
);
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__)
. " Let us know at gh-629 should this change"
);
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__)
. " https://github.com/vdm-io/Joomla-Component-Builder/issues/629#issuecomment-750117235"
);
$field_xml = $field_set_xml->addChild('field');
$this->xml->attributes($field_xml, $attributes);
// count the static field created
$this->counter->field++;
// setup needed field values for layout
$field_array = [];
$field_array['order_edit'] = 0;
$field_array['tab'] = 15;
$field_array['alignment'] = 1;
// make sure it gets added to view
$this->layout->set(
$nameSingleCode, $tab_name, $field_name, $field_array
);
}
// load the dynamic fields now
if (count((array) $dynamic_fields_xml))
{
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__) . " Dynamic Fields."
);
foreach ($dynamic_fields_xml as $dynamicfield)
{
$this->xml->append($field_set_xml, $dynamicfield);
}
}
// check if metadata is added to this view
if ($this->metadata->isString($nameSingleCode))
{
if (!$this->fieldnames->isString($nameSingleCode . '.robots')
|| !$this->fieldnames->isString($nameSingleCode . '.author')
|| !$this->fieldnames->isString($nameSingleCode . '.rights'))
{
$this->xml->comment(
$field_set_xml, Line::_(__Line__, __Class__) . " Metadata Fields"
);
$fields_xml = $field_set_xml->addChild('fields');
$fields_xml->addAttribute('name', 'metadata');
$fields_xml->addAttribute(
'label', 'JGLOBAL_FIELDSET_METADATA_OPTIONS'
);
$fields_field_set_xml = $fields_xml->addChild('fieldset');
$fields_field_set_xml->addAttribute('name', 'vdmmetadata');
$fields_field_set_xml->addAttribute(
'label', 'JGLOBAL_FIELDSET_METADATA_OPTIONS'
);
// robots
if (!$this->fieldnames->isString($nameSingleCode . '.robots'))
{
$this->xml->comment(
$fields_field_set_xml, Line::_(__Line__, __Class__)
. " Robots Field. Type: List (joomla)"
);
$robots = $fields_field_set_xml->addChild('field');
$attributes = [
'name' => 'robots',
'type' => 'list',
'label' => 'JFIELD_METADATA_ROBOTS_LABEL',
'description' => 'JFIELD_METADATA_ROBOTS_DESC'
];
$this->xml->attributes(
$robots, $attributes
);
// count the static field created
$this->counter->field++;
$options = [
'JGLOBAL_USE_GLOBAL' => '',
'JGLOBAL_INDEX_FOLLOW' => 'index, follow',
'JGLOBAL_NOINDEX_FOLLOW' => 'noindex, follow',
'JGLOBAL_INDEX_NOFOLLOW' => 'index, nofollow',
'JGLOBAL_NOINDEX_NOFOLLOW' => 'noindex, nofollow',
];
foreach ($options as $text => $value)
{
$option = $robots->addChild('option');
$option->addAttribute('value', $value);
$option[] = $text;
}
}
// author
if (!$this->fieldnames->isString($nameSingleCode . '.author'))
{
$this->xml->comment(
$fields_field_set_xml, Line::_(__Line__, __Class__)
. " Author Field. Type: Text (joomla)"
);
$author = $fields_field_set_xml->addChild('field');
$attributes = [
'name' => 'author',
'type' => 'text',
'label' => 'JAUTHOR',
'description' => 'JFIELD_METADATA_AUTHOR_DESC',
'size' => 20
];
$this->xml->attributes(
$author, $attributes
);
// count the static field created
$this->counter->field++;
}
// rights
if (!$this->fieldnames->isString($nameSingleCode . '.rights'))
{
$this->xml->comment(
$fields_field_set_xml, Line::_(__Line__, __Class__)
. " Rights Field. Type: Textarea (joomla)"
);
$rights = $fields_field_set_xml->addChild('field');
$attributes = [
'name' => 'rights',
'type' => 'textarea',
'label' => 'JFIELD_META_RIGHTS_LABEL',
'description' => 'JFIELD_META_RIGHTS_DESC',
'required' => 'false',
'filter' => 'string',
'cols' => 30,
'rows' => 2
];
$this->xml->attributes(
$rights, $attributes
);
// count the static field created
$this->counter->field++;
}
}
}
// return the set
return $this->xml->pretty($main_xml, 'fieldset');
}
}