first commit
This commit is contained in:
37
administrator/components/com_fields/fields.xml
Normal file
37
administrator/components/com_fields/fields.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="component" method="upgrade">
|
||||
<name>com_fields</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2016-03</creationDate>
|
||||
<copyright>(C) 2016 Open Source Matters, Inc.</copyright>
|
||||
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
|
||||
<authorEmail>admin@joomla.org</authorEmail>
|
||||
<authorUrl>www.joomla.org</authorUrl>
|
||||
<version>4.0.0</version>
|
||||
<description>COM_FIELDS_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Component\Fields</namespace>
|
||||
<files folder="site">
|
||||
<folder>forms</folder>
|
||||
<folder>layouts</folder>
|
||||
<folder>src</folder>
|
||||
</files>
|
||||
<media destination="com_fields" folder="media">
|
||||
<folder>js</folder>
|
||||
</media>
|
||||
<administration>
|
||||
<files folder="admin">
|
||||
<filename>fields.xml</filename>
|
||||
<folder>forms</folder>
|
||||
<folder>helpers</folder>
|
||||
<folder>services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages folder="admin">
|
||||
<language tag="en-GB">language/en-GB/com_fields.ini</language>
|
||||
<language tag="en-GB">language/en-GB/com_fields.sys.ini</language>
|
||||
</languages>
|
||||
</administration>
|
||||
</extension>
|
||||
|
||||
|
||||
356
administrator/components/com_fields/forms/field.xml
Normal file
356
administrator/components/com_fields/forms/field.xml
Normal file
@ -0,0 +1,356 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form addfieldprefix="Joomla\Component\Fields\Administrator\Field">
|
||||
<fieldset>
|
||||
<field
|
||||
name="id"
|
||||
type="text"
|
||||
label="JGLOBAL_FIELD_ID_LABEL"
|
||||
default="0"
|
||||
class="readonly"
|
||||
readonly="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="asset_id"
|
||||
type="hidden"
|
||||
filter="unset"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="context"
|
||||
type="hidden"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="group_id"
|
||||
type="fieldgroups"
|
||||
label="COM_FIELDS_FIELD_GROUP_LABEL"
|
||||
>
|
||||
<option value="0">JNONE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="assigned_cat_ids"
|
||||
type="categoryedit"
|
||||
label="JCATEGORY"
|
||||
extension="com_content"
|
||||
multiple="true"
|
||||
showon="only_use_in_subform:0"
|
||||
addfieldprefix="Joomla\Component\Categories\Administrator\Field"
|
||||
>
|
||||
<option value="0">JALL</option>
|
||||
<option value="-1">JNONE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="title"
|
||||
type="text"
|
||||
label="JGLOBAL_TITLE"
|
||||
required="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="name"
|
||||
type="text"
|
||||
label="JFIELD_NAME_LABEL"
|
||||
hint="JFIELD_NAME_PLACEHOLDER"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="type"
|
||||
type="type"
|
||||
label="COM_FIELDS_FIELD_TYPE_LABEL"
|
||||
default="text"
|
||||
required="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="required"
|
||||
type="radio"
|
||||
label="COM_FIELDS_FIELD_REQUIRED_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="only_use_in_subform"
|
||||
type="radio"
|
||||
label="COM_FIELDS_FIELD_ONLY_USE_IN_SUBFORM_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
showon="type!:subform"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
<field
|
||||
name="default_value"
|
||||
type="textarea"
|
||||
label="COM_FIELDS_FIELD_DEFAULT_VALUE_LABEL"
|
||||
filter="raw"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="state"
|
||||
type="list"
|
||||
label="JSTATUS"
|
||||
class="form-select-color-state"
|
||||
default="1"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JPUBLISHED</option>
|
||||
<option value="0">JUNPUBLISHED</option>
|
||||
<option value="2">JARCHIVED</option>
|
||||
<option value="-2">JTRASHED</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="checked_out"
|
||||
type="hidden"
|
||||
filter="unset"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="checked_out_time"
|
||||
type="hidden"
|
||||
filter="unset"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="created_user_id"
|
||||
type="user"
|
||||
label="JGLOBAL_FIELD_CREATED_BY_LABEL"
|
||||
validate="UserId"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="created_time"
|
||||
type="calendar"
|
||||
label="JGLOBAL_CREATED_DATE"
|
||||
translateformat="true"
|
||||
showtime="true"
|
||||
filter="user_utc"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="modified_by"
|
||||
type="user"
|
||||
label="JGLOBAL_FIELD_MODIFIED_BY_LABEL"
|
||||
class="readonly"
|
||||
readonly="true"
|
||||
filter="unset"
|
||||
validate="UserId"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="modified_time"
|
||||
type="calendar"
|
||||
label="JGLOBAL_FIELD_MODIFIED_LABEL"
|
||||
class="readonly"
|
||||
translateformat="true"
|
||||
showtime="true"
|
||||
readonly="true"
|
||||
filter="user_utc"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="language"
|
||||
type="contentlanguage"
|
||||
label="JFIELD_LANGUAGE_LABEL"
|
||||
>
|
||||
<option value="*">JALL</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="note"
|
||||
type="text"
|
||||
label="COM_FIELDS_FIELD_NOTE_LABEL"
|
||||
class="col-md-12"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="label"
|
||||
type="text"
|
||||
label="COM_FIELDS_FIELD_LABEL_LABEL"
|
||||
hint="JFIELD_ALIAS_PLACEHOLDER"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="description"
|
||||
type="textarea"
|
||||
label="JGLOBAL_DESCRIPTION"
|
||||
filter="HTML"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="access"
|
||||
type="accesslevel"
|
||||
label="JFIELD_ACCESS_LABEL"
|
||||
filter="UINT"
|
||||
validate="options"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="rules"
|
||||
type="rules"
|
||||
label="JFIELD_RULES_LABEL"
|
||||
translate_label="false"
|
||||
filter="rules"
|
||||
validate="rules"
|
||||
section="field"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="ordering"
|
||||
type="text"
|
||||
label="JFIELD_ORDERING_LABEL"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<fields name="params" label="COM_FIELDS_FIELD_BASIC_LABEL">
|
||||
<fieldset name="basic">
|
||||
<fieldset name="formoptions" label="COM_FIELDS_FIELD_FORMOPTIONS_HEADING">
|
||||
<field
|
||||
name="hint"
|
||||
type="text"
|
||||
label="COM_FIELDS_FIELD_PLACEHOLDER_LABEL"
|
||||
description="COM_FIELDS_FIELD_PLACEHOLDER_DESC"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="class"
|
||||
type="textarea"
|
||||
label="COM_FIELDS_FIELD_CLASS_LABEL"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="label_class"
|
||||
type="textarea"
|
||||
label="COM_FIELDS_FIELD_LABEL_FORM_CLASS_LABEL"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_on"
|
||||
type="list"
|
||||
label="COM_FIELDS_FIELD_EDITABLE_IN_LABEL"
|
||||
default=""
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">COM_FIELDS_FIELD_EDITABLE_IN_SITE</option>
|
||||
<option value="2">COM_FIELDS_FIELD_EDITABLE_IN_ADMIN</option>
|
||||
<option value="">COM_FIELDS_FIELD_EDITABLE_IN_BOTH</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="showon"
|
||||
type="text"
|
||||
label="COM_FIELDS_FIELD_SHOWON_LABEL"
|
||||
description="COM_FIELDS_FIELD_SHOWON_DESC"
|
||||
validate="ShowOn"
|
||||
/>
|
||||
|
||||
</fieldset>
|
||||
<fieldset name="renderoptions" label="COM_FIELDS_FIELD_RENDEROPTIONS_HEADING">
|
||||
|
||||
<field
|
||||
name="render_class"
|
||||
type="textarea"
|
||||
label="COM_FIELDS_FIELD_RENDER_CLASS_LABEL"
|
||||
description="COM_FIELDS_FIELD_RENDER_CLASS_DESC"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="value_render_class"
|
||||
type="textarea"
|
||||
label="COM_FIELDS_FIELD_VALUE_RENDER_CLASS_LABEL"
|
||||
description="COM_FIELDS_FIELD_VALUE_RENDER_CLASS_DESC"
|
||||
size="40"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="showlabel"
|
||||
type="radio"
|
||||
label="COM_FIELDS_FIELD_SHOWLABEL_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="1"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="label_render_class"
|
||||
type="textarea"
|
||||
label="COM_FIELDS_FIELD_LABEL_RENDER_CLASS_LABEL"
|
||||
showon="showlabel:1"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="display"
|
||||
type="list"
|
||||
label="COM_FIELDS_FIELD_DISPLAY_LABEL"
|
||||
default="2"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">COM_FIELDS_FIELD_DISPLAY_AFTER_TITLE</option>
|
||||
<option value="2">COM_FIELDS_FIELD_DISPLAY_BEFORE_DISPLAY</option>
|
||||
<option value="3">COM_FIELDS_FIELD_DISPLAY_AFTER_DISPLAY</option>
|
||||
<option value="0">COM_FIELDS_FIELD_DISPLAY_NO_DISPLAY</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="prefix"
|
||||
type="text"
|
||||
label="COM_FIELDS_FIELD_PREFIX_LABEL"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="suffix"
|
||||
type="text"
|
||||
label="COM_FIELDS_FIELD_SUFFIX_LABEL"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="layout"
|
||||
type="fieldLayout"
|
||||
label="COM_FIELDS_FIELD_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="display_readonly"
|
||||
type="list"
|
||||
label="JFIELD_DISPLAY_READONLY_LABEL"
|
||||
default="2"
|
||||
validate="options"
|
||||
>
|
||||
<option value="2">JGLOBAL_INHERIT</option>
|
||||
<option value="1">JYES</option>
|
||||
<option value="0">JNO</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
<fieldset name="smartsearchoptions" label="COM_FIELDS_FIELD_SMARTSEARCHOPTIONS_HEADING">
|
||||
<field
|
||||
name="searchindex"
|
||||
type="list"
|
||||
label="COM_FIELDS_FIELD_SEARCHINDEX_LABEL"
|
||||
default="0"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">COM_FIELDS_FIELD_SEARCHINDEX_DONT</option>
|
||||
<option value="1">COM_FIELDS_FIELD_SEARCHINDEX_SEARCHABLE</option>
|
||||
<option value="2">COM_FIELDS_FIELD_SEARCHINDEX_TAXONOMY</option>
|
||||
<option value="3">COM_FIELDS_FIELD_SEARCHINDEX_BOTH</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</form>
|
||||
119
administrator/components/com_fields/forms/filter_fields.xml
Normal file
119
administrator/components/com_fields/forms/filter_fields.xml
Normal file
@ -0,0 +1,119 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form addfieldprefix="Joomla\Component\Fields\Administrator\Field">
|
||||
<fieldset name="group">
|
||||
<field
|
||||
name="context"
|
||||
type="fieldcontexts"
|
||||
filtermode="selector"
|
||||
class="js-select-submit-on-change"
|
||||
/>
|
||||
</fieldset>
|
||||
<fields name="filter">
|
||||
<field
|
||||
name="search"
|
||||
type="text"
|
||||
inputmode="search"
|
||||
label="COM_FIELDS_FIELDS_FILTER_SEARCH_LABEL"
|
||||
description="COM_FIELDS_FIELDS_FILTER_SEARCH_DESC"
|
||||
hint="JSEARCH_FILTER"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="state"
|
||||
type="status"
|
||||
label="JSTATUS"
|
||||
class="js-select-submit-on-change"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_PUBLISHED</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="group_id"
|
||||
type="fieldgroups"
|
||||
label="COM_FIELDS_FIELD_GROUP_LABEL"
|
||||
state="0,1,2"
|
||||
class="js-select-submit-on-change"
|
||||
>
|
||||
<option value="">COM_FIELDS_VIEW_FIELDS_SELECT_GROUP</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="assigned_cat_ids"
|
||||
type="category"
|
||||
label="JCATEGORY"
|
||||
class="js-select-submit-on-change"
|
||||
addfieldprefix="Joomla\Component\Categories\Administrator\Field"
|
||||
>
|
||||
<option value="">COM_FIELDS_VIEW_FIELDS_SELECT_CATEGORY</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="access"
|
||||
type="accesslevel"
|
||||
label="JGRID_HEADING_ACCESS"
|
||||
class="js-select-submit-on-change"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_ACCESS</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="language"
|
||||
type="contentlanguage"
|
||||
label="JGRID_HEADING_LANGUAGE"
|
||||
class="js-select-submit-on-change"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_LANGUAGE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="only_use_in_subform"
|
||||
type="list"
|
||||
label="COM_FIELDS_FIELDS_FILTER_ONLY_USE_IN_SUBFORM_LABEL"
|
||||
class="js-select-submit-on-change"
|
||||
default=""
|
||||
validate="options"
|
||||
>
|
||||
<option value="">COM_FIELDS_ONLY_USE_IN_SUBFORM</option>
|
||||
<option value="0">COM_FIELDS_ONLY_USE_IN_SUBFORM_ANY</option>
|
||||
<option value="1">COM_FIELDS_ONLY_USE_IN_SUBFORM_SUBFORM</option>
|
||||
</field>
|
||||
</fields>
|
||||
|
||||
<fields name="list">
|
||||
<field
|
||||
name="fullordering"
|
||||
type="list"
|
||||
label="JGLOBAL_SORT_BY"
|
||||
statuses="*,0,1,2,-2"
|
||||
class="js-select-submit-on-change"
|
||||
default="a.ordering ASC"
|
||||
validate="options"
|
||||
>
|
||||
<option value="">JGLOBAL_SORT_BY</option>
|
||||
<option value="a.ordering ASC">JGRID_HEADING_ORDERING_ASC</option>
|
||||
<option value="a.ordering DESC">JGRID_HEADING_ORDERING_DESC</option>
|
||||
<option value="a.state ASC">JSTATUS_ASC</option>
|
||||
<option value="a.state DESC">JSTATUS_DESC</option>
|
||||
<option value="a.title ASC">JGLOBAL_TITLE_ASC</option>
|
||||
<option value="a.title DESC">JGLOBAL_TITLE_DESC</option>
|
||||
<option value="a.type ASC">COM_FIELDS_VIEW_FIELDS_SORT_TYPE_ASC</option>
|
||||
<option value="a.type DESC">COM_FIELDS_VIEW_FIELDS_SORT_TYPE_DESC</option>
|
||||
<option value="g.title ASC">COM_FIELDS_VIEW_FIELDS_SORT_GROUP_ASC</option>
|
||||
<option value="g.title DESC">COM_FIELDS_VIEW_FIELDS_SORT_GROUP_DESC</option>
|
||||
<option value="a.access ASC">JGRID_HEADING_ACCESS_ASC</option>
|
||||
<option value="a.access DESC">JGRID_HEADING_ACCESS_DESC</option>
|
||||
<option value="a.language ASC" requires="multilanguage">JGRID_HEADING_LANGUAGE_ASC</option>
|
||||
<option value="a.language DESC" requires="multilanguage">JGRID_HEADING_LANGUAGE_DESC</option>
|
||||
<option value="a.id ASC">JGRID_HEADING_ID_ASC</option>
|
||||
<option value="a.id DESC">JGRID_HEADING_ID_DESC</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="limit"
|
||||
type="limitbox"
|
||||
label="JGLOBAL_LIST_LIMIT"
|
||||
default="25"
|
||||
class="js-select-submit-on-change"
|
||||
/>
|
||||
</fields>
|
||||
</form>
|
||||
81
administrator/components/com_fields/forms/filter_groups.xml
Normal file
81
administrator/components/com_fields/forms/filter_groups.xml
Normal file
@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form addfieldprefix="Joomla\Component\Fields\Administrator\Field">
|
||||
<fieldset name="group">
|
||||
<field
|
||||
name="context"
|
||||
type="fieldcontexts"
|
||||
filtermode="selector"
|
||||
class="js-select-submit-on-change"
|
||||
/>
|
||||
</fieldset>
|
||||
<fields name="filter">
|
||||
<field
|
||||
name="search"
|
||||
type="text"
|
||||
inputmode="search"
|
||||
label="COM_FIELDS_GROUPS_FILTER_SEARCH_LABEL"
|
||||
description="COM_FIELDS_GROUPS_FILTER_SEARCH_DESC"
|
||||
hint="JSEARCH_FILTER"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="state"
|
||||
type="status"
|
||||
label="JSTATUS"
|
||||
class="js-select-submit-on-change"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_PUBLISHED</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="access"
|
||||
type="accesslevel"
|
||||
label="JGRID_HEADING_ACCESS"
|
||||
class="js-select-submit-on-change"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_ACCESS</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="language"
|
||||
type="contentlanguage"
|
||||
label="JGRID_HEADING_LANGUAGE"
|
||||
class="js-select-submit-on-change"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_LANGUAGE</option>
|
||||
</field>
|
||||
</fields>
|
||||
|
||||
<fields name="list">
|
||||
<field
|
||||
name="fullordering"
|
||||
type="list"
|
||||
label="JGLOBAL_SORT_BY"
|
||||
class="js-select-submit-on-change"
|
||||
default="a.ordering ASC"
|
||||
validate="options"
|
||||
>
|
||||
<option value="">JGLOBAL_SORT_BY</option>
|
||||
<option value="a.ordering ASC">JGRID_HEADING_ORDERING_ASC</option>
|
||||
<option value="a.ordering DESC">JGRID_HEADING_ORDERING_DESC</option>
|
||||
<option value="a.state ASC">JSTATUS_ASC</option>
|
||||
<option value="a.state DESC">JSTATUS_DESC</option>
|
||||
<option value="a.title ASC">JGLOBAL_TITLE_ASC</option>
|
||||
<option value="a.title DESC">JGLOBAL_TITLE_DESC</option>
|
||||
<option value="a.access ASC">JGRID_HEADING_ACCESS_ASC</option>
|
||||
<option value="a.access DESC">JGRID_HEADING_ACCESS_DESC</option>
|
||||
<option value="a.language ASC" requires="multilanguage">JGRID_HEADING_LANGUAGE_ASC</option>
|
||||
<option value="a.language DESC" requires="multilanguage">JGRID_HEADING_LANGUAGE_DESC</option>
|
||||
<option value="a.id ASC">JGRID_HEADING_ID_ASC</option>
|
||||
<option value="a.id DESC">JGRID_HEADING_ID_DESC</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="limit"
|
||||
type="limitbox"
|
||||
label="JGLOBAL_LIST_LIMIT"
|
||||
default="25"
|
||||
class="js-select-submit-on-change"
|
||||
/>
|
||||
</fields>
|
||||
</form>
|
||||
155
administrator/components/com_fields/forms/group.xml
Normal file
155
administrator/components/com_fields/forms/group.xml
Normal file
@ -0,0 +1,155 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form addfieldprefix="Joomla\Component\Fields\Administrator\Field">
|
||||
<fieldset>
|
||||
<field
|
||||
name="id"
|
||||
type="text"
|
||||
label="JGLOBAL_FIELD_ID_LABEL"
|
||||
default="0"
|
||||
class="readonly"
|
||||
readonly="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="asset_id"
|
||||
type="hidden"
|
||||
filter="unset"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="context"
|
||||
type="hidden"
|
||||
class="readonly"
|
||||
readonly="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="title"
|
||||
type="text"
|
||||
label="JGLOBAL_TITLE"
|
||||
required="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="state"
|
||||
type="list"
|
||||
label="JSTATUS"
|
||||
class="form-select-color-state"
|
||||
default="1"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JPUBLISHED</option>
|
||||
<option value="0">JUNPUBLISHED</option>
|
||||
<option value="2">JARCHIVED</option>
|
||||
<option value="-2">JTRASHED</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="checked_out"
|
||||
type="hidden"
|
||||
filter="unset"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="checked_out_time"
|
||||
type="hidden"
|
||||
filter="unset"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="created"
|
||||
type="calendar"
|
||||
label="JGLOBAL_CREATED_DATE"
|
||||
translateformat="true"
|
||||
showtime="true"
|
||||
filter="user_utc"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="created_by"
|
||||
type="user"
|
||||
label="JGLOBAL_FIELD_CREATED_BY_LABEL"
|
||||
validate="UserId"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="modified"
|
||||
type="text"
|
||||
label="JGLOBAL_FIELD_MODIFIED_LABEL"
|
||||
class="readonly"
|
||||
filter="unset"
|
||||
readonly="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="modified_by"
|
||||
type="user"
|
||||
label="JGLOBAL_FIELD_MODIFIED_BY_LABEL"
|
||||
class="readonly"
|
||||
readonly="true"
|
||||
filter="unset"
|
||||
validate="UserId"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="language"
|
||||
type="contentlanguage"
|
||||
label="JFIELD_LANGUAGE_LABEL"
|
||||
>
|
||||
<option value="*">JALL</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="note"
|
||||
type="text"
|
||||
label="COM_FIELDS_FIELD_NOTE_LABEL"
|
||||
class="col-md-12"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="description"
|
||||
type="textarea"
|
||||
label="JGLOBAL_DESCRIPTION"
|
||||
filter="HTML"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="access"
|
||||
type="accesslevel"
|
||||
label="JFIELD_ACCESS_LABEL"
|
||||
filter="UINT"
|
||||
validate="options"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="rules"
|
||||
type="rules"
|
||||
label="JFIELD_RULES_LABEL"
|
||||
translate_label="false"
|
||||
filter="rules"
|
||||
validate="rules"
|
||||
section="fieldgroup"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="ordering"
|
||||
type="text"
|
||||
label="JFIELD_ORDERING_LABEL"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<fields name="params" label="COM_FIELDS_FIELD_BASIC_LABEL">
|
||||
<fieldset name="basic">
|
||||
<field
|
||||
name="display_readonly"
|
||||
type="radio"
|
||||
label="JFIELD_DISPLAY_READONLY_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="1"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</form>
|
||||
27
administrator/components/com_fields/helpers/fields.php
Normal file
27
administrator/components/com_fields/helpers/fields.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
|
||||
*/
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* FieldsHelper
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @deprecated 4.3 will be removed in 6.0
|
||||
* Use \Joomla\Component\Fields\Administrator\Helper\FieldsHelper instead
|
||||
*/
|
||||
class FieldsHelper extends \Joomla\Component\Fields\Administrator\Helper\FieldsHelper
|
||||
{
|
||||
}
|
||||
57
administrator/components/com_fields/services/provider.php
Normal file
57
administrator/components/com_fields/services/provider.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Categories\CategoryFactoryInterface;
|
||||
use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface;
|
||||
use Joomla\CMS\Extension\ComponentInterface;
|
||||
use Joomla\CMS\Extension\Service\Provider\CategoryFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\ComponentDispatcherFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\MVCFactory;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\Component\Fields\Administrator\Extension\FieldsComponent;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The fields service provider.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->registerServiceProvider(new CategoryFactory('\\Joomla\\Component\\Fields'));
|
||||
$container->registerServiceProvider(new MVCFactory('\\Joomla\\Component\\Fields'));
|
||||
$container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\Fields'));
|
||||
|
||||
$container->set(
|
||||
ComponentInterface::class,
|
||||
function (Container $container) {
|
||||
$component = new FieldsComponent($container->get(ComponentDispatcherFactoryInterface::class));
|
||||
|
||||
$component->setMVCFactory($container->get(MVCFactoryInterface::class));
|
||||
$component->setCategoryFactory($container->get(CategoryFactoryInterface::class));
|
||||
|
||||
return $component;
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Fields Controller
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class DisplayController extends BaseController
|
||||
{
|
||||
/**
|
||||
* The default view.
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $default_view = 'fields';
|
||||
|
||||
/**
|
||||
* Typical view method for MVC based architecture
|
||||
*
|
||||
* This function is provide as a default implementation, in most cases
|
||||
* you will need to override it in your own controllers.
|
||||
*
|
||||
* @param boolean $cachable If true, the view output will be cached
|
||||
* @param array|bool $urlparams An array of safe URL parameters and their variable types.
|
||||
* @see \Joomla\CMS\Filter\InputFilter::clean() for valid values.
|
||||
*
|
||||
* @return BaseController|boolean A Controller object to support chaining.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function display($cachable = false, $urlparams = false)
|
||||
{
|
||||
// Set the default view name and format from the Request.
|
||||
$vName = $this->input->get('view', 'fields');
|
||||
$id = $this->input->getInt('id');
|
||||
|
||||
// Check for edit form.
|
||||
if ($vName == 'field' && !$this->checkEditId('com_fields.edit.field', $id)) {
|
||||
// Somehow the person just went to the form - we don't allow that.
|
||||
if (!\count($this->app->getMessageQueue())) {
|
||||
$this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error');
|
||||
}
|
||||
|
||||
$this->setRedirect(Route::_('index.php?option=com_fields&view=fields&context=' . $this->input->get('context'), false));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::display($cachable, $urlparams);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,196 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\Application\CMSApplication;
|
||||
use Joomla\CMS\MVC\Controller\FormController;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
|
||||
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* The Field controller
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class FieldController extends FormController
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $internalContext;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $component;
|
||||
|
||||
/**
|
||||
* The prefix to use with controller messages.
|
||||
*
|
||||
* @var string
|
||||
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $text_prefix = 'COM_FIELDS_FIELD';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config An optional associative array of configuration settings.
|
||||
* Recognized key values include 'name', 'default_task', 'model_path', and
|
||||
* 'view_path' (this list is not meant to be comprehensive).
|
||||
* @param MVCFactoryInterface $factory The factory.
|
||||
* @param CMSApplication $app The Application for the dispatcher
|
||||
* @param Input $input Input
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function __construct($config = [], MVCFactoryInterface $factory = null, $app = null, $input = null)
|
||||
{
|
||||
parent::__construct($config, $factory, $app, $input);
|
||||
|
||||
$this->internalContext = $this->app->getUserStateFromRequest('com_fields.fields.context', 'context', 'com_content.article', 'CMD');
|
||||
$parts = FieldsHelper::extract($this->internalContext);
|
||||
$this->component = $parts ? $parts[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method override to check if you can add a new record.
|
||||
*
|
||||
* @param array $data An array of input data.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function allowAdd($data = [])
|
||||
{
|
||||
return $this->app->getIdentity()->authorise('core.create', $this->component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method override to check if you can edit an existing record.
|
||||
*
|
||||
* @param array $data An array of input data.
|
||||
* @param string $key The name of the key for the primary key.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function allowEdit($data = [], $key = 'id')
|
||||
{
|
||||
$recordId = (int) isset($data[$key]) ? $data[$key] : 0;
|
||||
$user = $this->app->getIdentity();
|
||||
|
||||
// Zero record (id:0), return component edit permission by calling parent controller method
|
||||
if (!$recordId) {
|
||||
return parent::allowEdit($data, $key);
|
||||
}
|
||||
|
||||
// Check edit on the record asset (explicit or inherited)
|
||||
if ($user->authorise('core.edit', $this->component . '.field.' . $recordId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check edit own on the record asset (explicit or inherited)
|
||||
if ($user->authorise('core.edit.own', $this->component . '.field.' . $recordId)) {
|
||||
// Existing record already has an owner, get it
|
||||
$record = $this->getModel()->getItem($recordId);
|
||||
|
||||
if (empty($record)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Grant if current user is owner of the record
|
||||
return $user->id == $record->created_user_id;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to run batch operations.
|
||||
*
|
||||
* @param object $model The model.
|
||||
*
|
||||
* @return boolean True if successful, false otherwise and internal error is set.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function batch($model = null)
|
||||
{
|
||||
$this->checkToken();
|
||||
|
||||
// Set the model
|
||||
$model = $this->getModel('Field');
|
||||
|
||||
// Preset the redirect
|
||||
$this->setRedirect('index.php?option=com_fields&view=fields&context=' . $this->internalContext);
|
||||
|
||||
return parent::batch($model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URL arguments to append to an item redirect.
|
||||
*
|
||||
* @param integer $recordId The primary key id for the item.
|
||||
* @param string $urlVar The name of the URL variable for the id.
|
||||
*
|
||||
* @return string The arguments to append to the redirect URL.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id')
|
||||
{
|
||||
return parent::getRedirectToItemAppend($recordId) . '&context=' . $this->internalContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URL arguments to append to a list redirect.
|
||||
*
|
||||
* @return string The arguments to append to the redirect URL.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function getRedirectToListAppend()
|
||||
{
|
||||
return parent::getRedirectToListAppend() . '&context=' . $this->internalContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that allows child controller access to model data after the data has been saved.
|
||||
*
|
||||
* @param BaseDatabaseModel $model The data model object.
|
||||
* @param array $validData The validated data.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function postSaveHook(BaseDatabaseModel $model, $validData = [])
|
||||
{
|
||||
$item = $model->getItem();
|
||||
|
||||
if (isset($item->params) && \is_array($item->params)) {
|
||||
$registry = new Registry();
|
||||
$registry->loadArray($item->params);
|
||||
$item->params = (string) $registry;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\MVC\Controller\AdminController;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Fields list controller class.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class FieldsController extends AdminController
|
||||
{
|
||||
/**
|
||||
* The prefix to use with controller messages.
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $text_prefix = 'COM_FIELDS_FIELD';
|
||||
|
||||
/**
|
||||
* Proxy for getModel.
|
||||
*
|
||||
* @param string $name The name of the model.
|
||||
* @param string $prefix The prefix for the PHP class name.
|
||||
* @param array $config Array of configuration parameters.
|
||||
*
|
||||
* @return \Joomla\CMS\MVC\Model\BaseDatabaseModel
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function getModel($name = 'Field', $prefix = 'Administrator', $config = ['ignore_request' => true])
|
||||
{
|
||||
return parent::getModel($name, $prefix, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append context variable to list redirect so that parent menu item stays open after an
|
||||
* admin action like publish, un-publish... fields
|
||||
*
|
||||
* @return string The arguments to append to the redirect URL.
|
||||
*
|
||||
* @since 4.2.9
|
||||
*/
|
||||
protected function getRedirectToListAppend()
|
||||
{
|
||||
$append = parent::getRedirectToListAppend();
|
||||
|
||||
$context = $this->input->getString('context');
|
||||
|
||||
if ($context) {
|
||||
$append .= '&context=' . $context;
|
||||
}
|
||||
|
||||
return $append;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,202 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\Application\CMSApplication;
|
||||
use Joomla\CMS\MVC\Controller\FormController;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
|
||||
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* The Group controller
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class GroupController extends FormController
|
||||
{
|
||||
/**
|
||||
* The prefix to use with controller messages.
|
||||
*
|
||||
* @var string
|
||||
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $text_prefix = 'COM_FIELDS_GROUP';
|
||||
|
||||
/**
|
||||
* The component for which the group applies.
|
||||
*
|
||||
* @var string
|
||||
* @since 3.7.0
|
||||
*/
|
||||
private $component = '';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config An optional associative array of configuration settings.
|
||||
* Recognized key values include 'name', 'default_task', 'model_path', and
|
||||
* 'view_path' (this list is not meant to be comprehensive).
|
||||
* @param MVCFactoryInterface $factory The factory.
|
||||
* @param CMSApplication $app The Application for the dispatcher
|
||||
* @param Input $input Input
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function __construct($config = [], MVCFactoryInterface $factory = null, $app = null, $input = null)
|
||||
{
|
||||
parent::__construct($config, $factory, $app, $input);
|
||||
|
||||
$parts = FieldsHelper::extract($this->input->getCmd('context'));
|
||||
|
||||
if ($parts) {
|
||||
$this->component = $parts[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to run batch operations.
|
||||
*
|
||||
* @param object $model The model.
|
||||
*
|
||||
* @return boolean True if successful, false otherwise and internal error is set.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function batch($model = null)
|
||||
{
|
||||
$this->checkToken();
|
||||
|
||||
// Set the model
|
||||
$model = $this->getModel('Group');
|
||||
|
||||
// Preset the redirect
|
||||
$this->setRedirect('index.php?option=com_fields&view=groups');
|
||||
|
||||
return parent::batch($model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method override to check if you can add a new record.
|
||||
*
|
||||
* @param array $data An array of input data.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function allowAdd($data = [])
|
||||
{
|
||||
return $this->app->getIdentity()->authorise('core.create', $this->component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method override to check if you can edit an existing record.
|
||||
*
|
||||
* @param array $data An array of input data.
|
||||
* @param string $key The name of the key for the primary key.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function allowEdit($data = [], $key = 'parent_id')
|
||||
{
|
||||
$recordId = (int) isset($data[$key]) ? $data[$key] : 0;
|
||||
$user = $this->app->getIdentity();
|
||||
|
||||
// Zero record (parent_id:0), return component edit permission by calling parent controller method
|
||||
if (!$recordId) {
|
||||
return parent::allowEdit($data, $key);
|
||||
}
|
||||
|
||||
// Check edit on the record asset (explicit or inherited)
|
||||
if ($user->authorise('core.edit', $this->component . '.fieldgroup.' . $recordId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check edit own on the record asset (explicit or inherited)
|
||||
if ($user->authorise('core.edit.own', $this->component . '.fieldgroup.' . $recordId) || $user->authorise('core.edit.own', $this->component)) {
|
||||
// Existing record already has an owner, get it
|
||||
$record = $this->getModel()->getItem($recordId);
|
||||
|
||||
if (empty($record)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Grant if current user is owner of the record
|
||||
return $user->id == $record->created_by;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that allows child controller access to model data after the data has been saved.
|
||||
*
|
||||
* @param BaseDatabaseModel $model The data model object.
|
||||
* @param array $validData The validated data.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function postSaveHook(BaseDatabaseModel $model, $validData = [])
|
||||
{
|
||||
$item = $model->getItem();
|
||||
|
||||
if (isset($item->params) && \is_array($item->params)) {
|
||||
$registry = new Registry();
|
||||
$registry->loadArray($item->params);
|
||||
$item->params = (string) $registry;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URL arguments to append to an item redirect.
|
||||
*
|
||||
* @param integer $recordId The primary key id for the item.
|
||||
* @param string $urlVar The name of the URL variable for the id.
|
||||
*
|
||||
* @return string The arguments to append to the redirect URL.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id')
|
||||
{
|
||||
$append = parent::getRedirectToItemAppend($recordId);
|
||||
$append .= '&context=' . $this->input->get('context');
|
||||
|
||||
return $append;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URL arguments to append to a list redirect.
|
||||
*
|
||||
* @return string The arguments to append to the redirect URL.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected function getRedirectToListAppend()
|
||||
{
|
||||
$append = parent::getRedirectToListAppend();
|
||||
$append .= '&context=' . $this->input->get('context');
|
||||
|
||||
return $append;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\MVC\Controller\AdminController;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Groups list controller class.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class GroupsController extends AdminController
|
||||
{
|
||||
/**
|
||||
* The prefix to use with controller messages.
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $text_prefix = 'COM_FIELDS_GROUP';
|
||||
|
||||
/**
|
||||
* Proxy for getModel.
|
||||
*
|
||||
* @param string $name The name of the model.
|
||||
* @param string $prefix The prefix for the PHP class name.
|
||||
* @param array $config Array of configuration parameters.
|
||||
*
|
||||
* @return \Joomla\CMS\MVC\Model\BaseDatabaseModel
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function getModel($name = 'Group', $prefix = 'Administrator', $config = ['ignore_request' => true])
|
||||
{
|
||||
return parent::getModel($name, $prefix, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append context variable to list redirect so that parent menu item stays open after an
|
||||
* admin action like publish, un-publish... field groups
|
||||
*
|
||||
* @return string The arguments to append to the redirect URL.
|
||||
*
|
||||
* @since 4.2.9
|
||||
*/
|
||||
protected function getRedirectToListAppend()
|
||||
{
|
||||
$append = parent::getRedirectToListAppend();
|
||||
|
||||
$context = $this->input->getString('context');
|
||||
|
||||
if ($context) {
|
||||
$append .= '&context=' . $context;
|
||||
}
|
||||
|
||||
return $append;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Access\Exception\NotAllowed;
|
||||
use Joomla\CMS\Dispatcher\ComponentDispatcher;
|
||||
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* ComponentDispatcher class for com_fields
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class Dispatcher extends ComponentDispatcher
|
||||
{
|
||||
/**
|
||||
* Method to check component access permission
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function checkAccess()
|
||||
{
|
||||
$context = $this->app->getUserStateFromRequest(
|
||||
'com_fields.groups.context',
|
||||
'context',
|
||||
$this->app->getUserStateFromRequest('com_fields.fields.context', 'context', 'com_content.article', 'CMD'),
|
||||
'CMD'
|
||||
);
|
||||
|
||||
$parts = FieldsHelper::extract($context);
|
||||
|
||||
if (!$parts || !$this->app->getIdentity()->authorise('core.manage', $parts[0])) {
|
||||
throw new NotAllowed($this->app->getLanguage()->_('JERROR_ALERTNOAUTHOR'), 403);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Extension;
|
||||
|
||||
use Joomla\CMS\Categories\CategoryServiceInterface;
|
||||
use Joomla\CMS\Categories\CategoryServiceTrait;
|
||||
use Joomla\CMS\Extension\MVCComponent;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Component class for com_fields
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class FieldsComponent extends MVCComponent implements CategoryServiceInterface
|
||||
{
|
||||
use CategoryServiceTrait;
|
||||
|
||||
/**
|
||||
* Returns the table for the count items functions for the given section.
|
||||
*
|
||||
* @param string $section The section
|
||||
*
|
||||
* @return string|null
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected function getTableNameForSection(string $section = null)
|
||||
{
|
||||
return 'fields';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Field;
|
||||
|
||||
use Joomla\CMS\Access\Access;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Fields\FieldsServiceInterface;
|
||||
use Joomla\CMS\Form\Field\ListField;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Components Fieldgroup field.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class ComponentsFieldgroupField extends ListField
|
||||
{
|
||||
/**
|
||||
* The form field type.
|
||||
*
|
||||
* @var string
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $type = 'ComponentsFieldgroup';
|
||||
|
||||
/**
|
||||
* Method to get a list of options for a list input.
|
||||
*
|
||||
* @return array An array of JHtml options.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
// Initialise variable.
|
||||
$db = $this->getDatabase();
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select('DISTINCT a.name AS text, a.element AS value')
|
||||
->from('#__extensions as a')
|
||||
->where('a.enabled >= 1')
|
||||
->where('a.type =' . $db->quote('component'));
|
||||
|
||||
$items = $db->setQuery($query)->loadObjectList();
|
||||
|
||||
$options = [];
|
||||
|
||||
if (\count($items)) {
|
||||
$lang = Factory::getLanguage();
|
||||
|
||||
$components = [];
|
||||
|
||||
// Search for components supporting Fieldgroups - suppose that these components support fields as well
|
||||
foreach ($items as &$item) {
|
||||
$availableActions = Access::getActionsFromFile(
|
||||
JPATH_ADMINISTRATOR . '/components/' . $item->value . '/access.xml',
|
||||
"/access/section[@name='fieldgroup']/"
|
||||
);
|
||||
|
||||
if (!empty($availableActions)) {
|
||||
// Load language
|
||||
$source = JPATH_ADMINISTRATOR . '/components/' . $item->value;
|
||||
$lang->load($item->value . 'sys', JPATH_ADMINISTRATOR)
|
||||
|| $lang->load($item->value . 'sys', $source);
|
||||
|
||||
// Translate component name
|
||||
$item->text = Text::_($item->text);
|
||||
|
||||
$components[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($components)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ($components as $component) {
|
||||
// Search for different contexts
|
||||
$c = Factory::getApplication()->bootComponent($component->value);
|
||||
|
||||
if ($c instanceof FieldsServiceInterface) {
|
||||
$contexts = $c->getContexts();
|
||||
|
||||
foreach ($contexts as $context) {
|
||||
$newOption = new \stdClass();
|
||||
$newOption->value = strtolower($component->value . '.' . $context);
|
||||
$newOption->text = $component->text . ' - ' . Text::_($context);
|
||||
$options[] = $newOption;
|
||||
}
|
||||
} else {
|
||||
$options[] = $component;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by name
|
||||
$items = ArrayHelper::sortObjects($options, 'text', 1, true, true);
|
||||
}
|
||||
|
||||
// Merge any additional options in the XML definition.
|
||||
$options = array_merge(parent::getOptions(), $items);
|
||||
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Field;
|
||||
|
||||
use Joomla\CMS\Access\Access;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Fields\FieldsServiceInterface;
|
||||
use Joomla\CMS\Form\Field\ListField;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Components Fields field.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class ComponentsFieldsField extends ListField
|
||||
{
|
||||
/**
|
||||
* The form field type.
|
||||
*
|
||||
* @var string
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $type = 'ComponentsFields';
|
||||
|
||||
/**
|
||||
* Method to get a list of options for a list input.
|
||||
*
|
||||
* @return array An array of JHtml options.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
// Initialise variable.
|
||||
$db = $this->getDatabase();
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select('DISTINCT a.name AS text, a.element AS value')
|
||||
->from('#__extensions as a')
|
||||
->where('a.enabled >= 1')
|
||||
->where('a.type =' . $db->quote('component'));
|
||||
|
||||
$items = $db->setQuery($query)->loadObjectList();
|
||||
|
||||
$options = [];
|
||||
|
||||
if (\count($items)) {
|
||||
$lang = Factory::getLanguage();
|
||||
|
||||
$components = [];
|
||||
|
||||
// Search for components supporting Fieldgroups - suppose that these components support fields as well
|
||||
foreach ($items as &$item) {
|
||||
$availableActions = Access::getActionsFromFile(
|
||||
JPATH_ADMINISTRATOR . '/components/' . $item->value . '/access.xml',
|
||||
"/access/section[@name='fieldgroup']/"
|
||||
);
|
||||
|
||||
if (!empty($availableActions)) {
|
||||
// Load language
|
||||
$source = JPATH_ADMINISTRATOR . '/components/' . $item->value;
|
||||
$lang->load($item->value . 'sys', JPATH_ADMINISTRATOR)
|
||||
|| $lang->load($item->value . 'sys', $source);
|
||||
|
||||
// Translate component name
|
||||
$item->text = Text::_($item->text);
|
||||
|
||||
$components[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($components)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ($components as $component) {
|
||||
// Search for different contexts
|
||||
$c = Factory::getApplication()->bootComponent($component->value);
|
||||
|
||||
if ($c instanceof FieldsServiceInterface) {
|
||||
$contexts = $c->getContexts();
|
||||
|
||||
foreach ($contexts as $context) {
|
||||
$newOption = new \stdClass();
|
||||
$newOption->value = strtolower($component->value . '.' . $context);
|
||||
$newOption->text = $component->text . ' - ' . Text::_($context);
|
||||
$options[] = $newOption;
|
||||
}
|
||||
} else {
|
||||
$options[] = $component;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by name
|
||||
$items = ArrayHelper::sortObjects($options, 'text', 1, true, true);
|
||||
}
|
||||
|
||||
// Merge any additional options in the XML definition.
|
||||
$options = array_merge(parent::getOptions(), $items);
|
||||
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2005 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Field;
|
||||
|
||||
use Joomla\CMS\Filesystem\Folder;
|
||||
use Joomla\CMS\Form\FormField;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\Filesystem\Path;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Form Field to display a list of the layouts for a field from
|
||||
* the extension or template overrides.
|
||||
*
|
||||
* @since 3.9.0
|
||||
*/
|
||||
class FieldLayoutField extends FormField
|
||||
{
|
||||
/**
|
||||
* The form field type.
|
||||
*
|
||||
* @var string
|
||||
* @since 3.9.0
|
||||
*/
|
||||
protected $type = 'FieldLayout';
|
||||
|
||||
/**
|
||||
* Method to get the field input for a field layout field.
|
||||
*
|
||||
* @return string The field input.
|
||||
*
|
||||
* @since 3.9.0
|
||||
*/
|
||||
protected function getInput()
|
||||
{
|
||||
$extension = explode('.', $this->form->getValue('context'));
|
||||
$extension = $extension[0];
|
||||
|
||||
if ($extension) {
|
||||
// Get the database object and a new query object.
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
// Build the query.
|
||||
$query->select('element, name')
|
||||
->from('#__extensions')
|
||||
->where('client_id = 0')
|
||||
->where('type = ' . $db->quote('template'))
|
||||
->where('enabled = 1');
|
||||
|
||||
// Set the query and load the templates.
|
||||
$db->setQuery($query);
|
||||
$templates = $db->loadObjectList('element');
|
||||
|
||||
// Build the search paths for component layouts.
|
||||
$component_path = Path::clean(JPATH_SITE . '/components/' . $extension . '/layouts/field');
|
||||
|
||||
// Prepare array of component layouts
|
||||
$component_layouts = [];
|
||||
|
||||
// Prepare the grouped list
|
||||
$groups = [];
|
||||
|
||||
// Add "Use Default"
|
||||
$groups[]['items'][] = HTMLHelper::_('select.option', '', Text::_('JOPTION_USE_DEFAULT'));
|
||||
|
||||
// Add the layout options from the component path.
|
||||
if (is_dir($component_path) && ($component_layouts = Folder::files($component_path, '^[^_]*\.php$', false, true))) {
|
||||
// Create the group for the component
|
||||
$groups['_'] = [];
|
||||
$groups['_']['id'] = $this->id . '__';
|
||||
$groups['_']['text'] = Text::sprintf('JOPTION_FROM_COMPONENT');
|
||||
$groups['_']['items'] = [];
|
||||
|
||||
foreach ($component_layouts as $i => $file) {
|
||||
// Add an option to the component group
|
||||
$value = basename($file, '.php');
|
||||
$component_layouts[$i] = $value;
|
||||
|
||||
if ($value === 'render') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$groups['_']['items'][] = HTMLHelper::_('select.option', $value, $value);
|
||||
}
|
||||
}
|
||||
|
||||
// Loop on all templates
|
||||
if ($templates) {
|
||||
foreach ($templates as $template) {
|
||||
$files = [];
|
||||
$template_paths = [
|
||||
Path::clean(JPATH_SITE . '/templates/' . $template->element . '/html/layouts/' . $extension . '/field'),
|
||||
Path::clean(JPATH_SITE . '/templates/' . $template->element . '/html/layouts/com_fields/field'),
|
||||
Path::clean(JPATH_SITE . '/templates/' . $template->element . '/html/layouts/field'),
|
||||
];
|
||||
|
||||
// Add the layout options from the template paths.
|
||||
foreach ($template_paths as $template_path) {
|
||||
if (is_dir($template_path)) {
|
||||
$files = array_merge($files, Folder::files($template_path, '^[^_]*\.php$', false, true));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($files as $i => $file) {
|
||||
$value = basename($file, '.php');
|
||||
|
||||
// Remove the default "render.php" or layout files that exist in the component folder
|
||||
if ($value === 'render' || \in_array($value, $component_layouts)) {
|
||||
unset($files[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (\count($files)) {
|
||||
// Create the group for the template
|
||||
$groups[$template->name] = [];
|
||||
$groups[$template->name]['id'] = $this->id . '_' . $template->element;
|
||||
$groups[$template->name]['text'] = Text::sprintf('JOPTION_FROM_TEMPLATE', $template->name);
|
||||
$groups[$template->name]['items'] = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
// Add an option to the template group
|
||||
$value = basename($file, '.php');
|
||||
$groups[$template->name]['items'][] = HTMLHelper::_('select.option', $value, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compute attributes for the grouped list
|
||||
$attr = $this->element['size'] ? ' size="' . (int) $this->element['size'] . '"' : '';
|
||||
$attr .= $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
// Prepare HTML code
|
||||
$html = [];
|
||||
|
||||
// Compute the current selected values
|
||||
$selected = [$this->value];
|
||||
|
||||
// Add a grouped list
|
||||
$html[] = HTMLHelper::_(
|
||||
'select.groupedlist',
|
||||
$groups,
|
||||
$this->name,
|
||||
['id' => $this->id, 'group.id' => 'id', 'list.attr' => $attr, 'list.select' => $selected]
|
||||
);
|
||||
|
||||
return implode($html);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Field;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Fields\FieldsServiceInterface;
|
||||
use Joomla\CMS\Form\Field\ListField;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Fields Contexts
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class FieldcontextsField extends ListField
|
||||
{
|
||||
/**
|
||||
* Type of the field
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'Fieldcontexts';
|
||||
|
||||
/**
|
||||
* Method to get the field input markup for a generic list.
|
||||
* Use the multiple attribute to enable multiselect.
|
||||
*
|
||||
* @return string The field input markup.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function getInput()
|
||||
{
|
||||
return $this->getOptions() ? parent::getInput() : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the field options.
|
||||
*
|
||||
* @return array The field option objects.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
$parts = explode('.', $this->value);
|
||||
|
||||
$component = Factory::getApplication()->bootComponent($parts[0]);
|
||||
|
||||
if ($component instanceof FieldsServiceInterface) {
|
||||
return $component->getContexts();
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Field;
|
||||
|
||||
use Joomla\CMS\Form\Field\ListField;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Fields Groups
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class FieldgroupsField extends ListField
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'Fieldgroups';
|
||||
|
||||
/**
|
||||
* Method to get the field options.
|
||||
*
|
||||
* @return array The field option objects.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
$context = (string) $this->element['context'];
|
||||
$states = $this->element['state'] ?: '0,1';
|
||||
$states = ArrayHelper::toInteger(explode(',', $states));
|
||||
|
||||
$user = $this->getCurrentUser();
|
||||
$viewlevels = ArrayHelper::toInteger($user->getAuthorisedViewLevels());
|
||||
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true);
|
||||
$query->select(
|
||||
[
|
||||
$db->quoteName('title', 'text'),
|
||||
$db->quoteName('id', 'value'),
|
||||
$db->quoteName('state'),
|
||||
]
|
||||
);
|
||||
$query->from($db->quoteName('#__fields_groups'));
|
||||
$query->whereIn($db->quoteName('state'), $states);
|
||||
$query->where($db->quoteName('context') . ' = :context');
|
||||
$query->whereIn($db->quoteName('access'), $viewlevels);
|
||||
$query->order('ordering asc, id asc');
|
||||
$query->bind(':context', $context);
|
||||
|
||||
$db->setQuery($query);
|
||||
$options = $db->loadObjectList();
|
||||
|
||||
foreach ($options as $option) {
|
||||
if ($option->state == 0) {
|
||||
$option->text = '[' . $option->text . ']';
|
||||
}
|
||||
|
||||
if ($option->state == 2) {
|
||||
$option->text = '{' . $option->text . '}';
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge(parent::getOptions(), $options);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Field;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Form\Field\ListField;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Fields Section
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class SectionField extends ListField
|
||||
{
|
||||
/**
|
||||
* Type of the field
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'Section';
|
||||
|
||||
/**
|
||||
* Method to attach a JForm object to the field.
|
||||
*
|
||||
* @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object.
|
||||
* @param mixed $value The form field value to validate.
|
||||
* @param string $group The field name group control value. This acts as an array container for the field.
|
||||
* For example if the field has name="foo" and the group value is set to "bar" then the
|
||||
* full field name would end up being "bar[foo]".
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function setup(\SimpleXMLElement $element, $value, $group = null)
|
||||
{
|
||||
$return = parent::setup($element, $value, $group);
|
||||
|
||||
// Onchange must always be the change context function
|
||||
$this->onchange = 'Joomla.fieldsChangeContext(this.value);';
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the field input markup for a generic list.
|
||||
* Use the multiple attribute to enable multiselect.
|
||||
*
|
||||
* @return string The field input markup.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function getInput()
|
||||
{
|
||||
Factory::getApplication()->getDocument()->getWebAssetManager()
|
||||
->useScript('com_fields.admin-field-changecontext');
|
||||
|
||||
return parent::getInput();
|
||||
}
|
||||
}
|
||||
128
administrator/components/com_fields/src/Field/SubfieldsField.php
Normal file
128
administrator/components/com_fields/src/Field/SubfieldsField.php
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Field;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Form\Field\ListField;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Fields Subfields. Represents a list field with the options being all possible
|
||||
* custom field types, except the 'subform' custom field type.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class SubfieldsField extends ListField
|
||||
{
|
||||
/**
|
||||
* The name of this Field type.
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public $type = 'Subfields';
|
||||
|
||||
/**
|
||||
* Configuration option for this field type to could filter the displayed custom field instances
|
||||
* by a given context. Default value empty string. If given empty string, displays all custom fields.
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected $context = '';
|
||||
|
||||
/**
|
||||
* Array to do a fast in-memory caching of all custom field items. Used to not bother the
|
||||
* FieldsHelper with a call every time this field is being rendered.
|
||||
*
|
||||
* @var array
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected static $customFieldsCache = [];
|
||||
|
||||
/**
|
||||
* Method to get the field options.
|
||||
*
|
||||
* @return array The field option objects.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
$options = parent::getOptions();
|
||||
|
||||
// Check whether we have a result for this context yet
|
||||
if (!isset(static::$customFieldsCache[$this->context])) {
|
||||
static::$customFieldsCache[$this->context] = FieldsHelper::getFields($this->context, null, false, null, true);
|
||||
}
|
||||
|
||||
// Iterate over the custom fields for this context
|
||||
foreach (static::$customFieldsCache[$this->context] as $customField) {
|
||||
// Skip our own subform type. We won't have subform in subform.
|
||||
if ($customField->type == 'subform') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$options[] = HTMLHelper::_(
|
||||
'select.option',
|
||||
$customField->id,
|
||||
($customField->title . ' (' . $customField->type . ')')
|
||||
);
|
||||
}
|
||||
|
||||
// Sorting the fields based on the text which is displayed
|
||||
usort(
|
||||
$options,
|
||||
function ($a, $b) {
|
||||
return strcmp($a->text, $b->text);
|
||||
}
|
||||
);
|
||||
|
||||
if (\count($options) == 0) {
|
||||
Factory::getApplication()->enqueueMessage(Text::_('COM_FIELDS_NO_FIELDS_TO_CREATE_SUBFORM_FIELD_WARNING'), 'warning');
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to attach a JForm object to the field.
|
||||
*
|
||||
* @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object.
|
||||
* @param mixed $value The form field value to validate.
|
||||
* @param string $group The field name group control value. This acts as an array container for the field.
|
||||
* For example if the field has name="foo" and the group value is set to "bar" then the
|
||||
* full field name would end up being "bar[foo]".
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function setup(\SimpleXMLElement $element, $value, $group = null)
|
||||
{
|
||||
$return = parent::setup($element, $value, $group);
|
||||
|
||||
if ($return) {
|
||||
$this->context = (string) $this->element['context'];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
88
administrator/components/com_fields/src/Field/TypeField.php
Normal file
88
administrator/components/com_fields/src/Field/TypeField.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Field;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Form\Field\ListField;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Fields Type
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class TypeField extends ListField
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'Type';
|
||||
|
||||
/**
|
||||
* Method to attach a JForm object to the field.
|
||||
*
|
||||
* @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object.
|
||||
* @param mixed $value The form field value to validate.
|
||||
* @param string $group The field name group control value. This acts as an array container for the field.
|
||||
* For example if the field has name="foo" and the group value is set to "bar" then the
|
||||
* full field name would end up being "bar[foo]".
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function setup(\SimpleXMLElement $element, $value, $group = null)
|
||||
{
|
||||
$return = parent::setup($element, $value, $group);
|
||||
|
||||
$this->onchange = 'Joomla.typeHasChanged(this);';
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the field options.
|
||||
*
|
||||
* @return array The field option objects.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
$options = parent::getOptions();
|
||||
|
||||
$fieldTypes = FieldsHelper::getFieldTypes();
|
||||
|
||||
foreach ($fieldTypes as $fieldType) {
|
||||
$options[] = HTMLHelper::_('select.option', $fieldType['type'], $fieldType['label']);
|
||||
}
|
||||
|
||||
// Sorting the fields based on the text which is displayed
|
||||
usort(
|
||||
$options,
|
||||
function ($a, $b) {
|
||||
return strcmp($a->text, $b->text);
|
||||
}
|
||||
);
|
||||
|
||||
// Load scripts
|
||||
Factory::getApplication()->getDocument()->getWebAssetManager()
|
||||
->useScript('com_fields.admin-field-typehaschanged')
|
||||
->useScript('webcomponent.core-loader');
|
||||
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
721
administrator/components/com_fields/src/Helper/FieldsHelper.php
Normal file
721
administrator/components/com_fields/src/Helper/FieldsHelper.php
Normal file
@ -0,0 +1,721 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Helper;
|
||||
|
||||
use Joomla\CMS\Event\CustomFields\AfterPrepareFieldEvent;
|
||||
use Joomla\CMS\Event\CustomFields\BeforePrepareFieldEvent;
|
||||
use Joomla\CMS\Event\CustomFields\GetTypesEvent;
|
||||
use Joomla\CMS\Event\CustomFields\PrepareDomEvent;
|
||||
use Joomla\CMS\Event\CustomFields\PrepareFieldEvent;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Fields\FieldsServiceInterface;
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Form\FormHelper;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Object\CMSObject;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\Component\Fields\Administrator\Model\FieldModel;
|
||||
use Joomla\Component\Fields\Administrator\Model\FieldsModel;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* FieldsHelper
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class FieldsHelper
|
||||
{
|
||||
/**
|
||||
* @var FieldsModel
|
||||
*/
|
||||
private static $fieldsCache = null;
|
||||
|
||||
/**
|
||||
* @var FieldModel
|
||||
*/
|
||||
private static $fieldCache = null;
|
||||
|
||||
/**
|
||||
* Extracts the component and section from the context string which has to
|
||||
* be in the format component.context.
|
||||
*
|
||||
* @param string $contextString contextString
|
||||
* @param object $item optional item object
|
||||
*
|
||||
* @return array|null
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function extract($contextString, $item = null)
|
||||
{
|
||||
if ($contextString === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parts = explode('.', $contextString, 2);
|
||||
|
||||
if (\count($parts) < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$newSection = '';
|
||||
|
||||
$component = Factory::getApplication()->bootComponent($parts[0]);
|
||||
|
||||
if ($component instanceof FieldsServiceInterface) {
|
||||
$newSection = $component->validateSection($parts[1], $item);
|
||||
}
|
||||
|
||||
if ($newSection) {
|
||||
$parts[1] = $newSection;
|
||||
}
|
||||
|
||||
return $parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fields for the given context.
|
||||
* If the item is an object the returned fields do have an additional field
|
||||
* "value" which represents the value for the given item. If the item has an
|
||||
* assigned_cat_ids field, then additionally fields which belong to that
|
||||
* category will be returned.
|
||||
* Should the value being prepared to be shown in an HTML context then
|
||||
* prepareValue must be set to true. No further escaping needs to be done.
|
||||
* The values of the fields can be overridden by an associative array where the keys
|
||||
* have to be a name and its corresponding value.
|
||||
*
|
||||
* @param string $context The context of the content passed to the helper
|
||||
* @param null $item The item being edited in the form
|
||||
* @param int|bool $prepareValue (if int is display event): 1 - AfterTitle, 2 - BeforeDisplay, 3 - AfterDisplay, 0 - OFF
|
||||
* @param array|null $valuesToOverride The values to override
|
||||
* @param bool $includeSubformFields Should I include fields marked as Only Use In Subform?
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Exception
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function getFields(
|
||||
$context,
|
||||
$item = null,
|
||||
$prepareValue = false,
|
||||
array $valuesToOverride = null,
|
||||
bool $includeSubformFields = false
|
||||
) {
|
||||
if (self::$fieldsCache === null) {
|
||||
// Load the model
|
||||
self::$fieldsCache = Factory::getApplication()->bootComponent('com_fields')
|
||||
->getMVCFactory()->createModel('Fields', 'Administrator', ['ignore_request' => true]);
|
||||
|
||||
self::$fieldsCache->setState('filter.state', 1);
|
||||
self::$fieldsCache->setState('list.limit', 0);
|
||||
}
|
||||
|
||||
if ($includeSubformFields) {
|
||||
self::$fieldsCache->setState('filter.only_use_in_subform', '');
|
||||
} else {
|
||||
self::$fieldsCache->setState('filter.only_use_in_subform', 0);
|
||||
}
|
||||
|
||||
if (\is_array($item)) {
|
||||
$item = (object) $item;
|
||||
}
|
||||
|
||||
if (Multilanguage::isEnabled() && isset($item->language) && $item->language != '*') {
|
||||
self::$fieldsCache->setState('filter.language', ['*', $item->language]);
|
||||
}
|
||||
|
||||
self::$fieldsCache->setState('filter.context', $context);
|
||||
self::$fieldsCache->setState('filter.assigned_cat_ids', []);
|
||||
|
||||
/*
|
||||
* If item has assigned_cat_ids parameter display only fields which
|
||||
* belong to the category
|
||||
*/
|
||||
if ($item && (isset($item->catid) || isset($item->fieldscatid))) {
|
||||
$assignedCatIds = $item->catid ?? $item->fieldscatid;
|
||||
|
||||
if (!\is_array($assignedCatIds)) {
|
||||
$assignedCatIds = explode(',', $assignedCatIds);
|
||||
}
|
||||
|
||||
// Fields without any category assigned should show as well
|
||||
$assignedCatIds[] = 0;
|
||||
|
||||
self::$fieldsCache->setState('filter.assigned_cat_ids', $assignedCatIds);
|
||||
}
|
||||
|
||||
$fields = self::$fieldsCache->getItems();
|
||||
|
||||
if ($fields === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($item && isset($item->id)) {
|
||||
if (self::$fieldCache === null) {
|
||||
self::$fieldCache = Factory::getApplication()->bootComponent('com_fields')
|
||||
->getMVCFactory()->createModel('Field', 'Administrator', ['ignore_request' => true]);
|
||||
}
|
||||
|
||||
/** @var DispatcherInterface $dispatcher */
|
||||
$dispatcher = Factory::getContainer()->get(DispatcherInterface::class);
|
||||
PluginHelper::importPlugin('fields', null, true, $dispatcher);
|
||||
|
||||
$fieldIds = array_map(
|
||||
function ($f) {
|
||||
return $f->id;
|
||||
},
|
||||
$fields
|
||||
);
|
||||
|
||||
$fieldValues = self::$fieldCache->getFieldValues($fieldIds, $item->id);
|
||||
|
||||
$new = [];
|
||||
|
||||
foreach ($fields as $key => $original) {
|
||||
/*
|
||||
* Doing a clone, otherwise fields for different items will
|
||||
* always reference to the same object
|
||||
*/
|
||||
$field = clone $original;
|
||||
|
||||
if ($valuesToOverride && \array_key_exists($field->name, $valuesToOverride)) {
|
||||
$field->value = $valuesToOverride[$field->name];
|
||||
} elseif ($valuesToOverride && \array_key_exists($field->id, $valuesToOverride)) {
|
||||
$field->value = $valuesToOverride[$field->id];
|
||||
} elseif (\array_key_exists($field->id, $fieldValues)) {
|
||||
$field->value = $fieldValues[$field->id];
|
||||
}
|
||||
|
||||
if (!isset($field->value) || $field->value === '') {
|
||||
$field->value = $field->default_value;
|
||||
}
|
||||
|
||||
$field->rawvalue = $field->value;
|
||||
|
||||
// If boolean prepare, if int, it is the event type: 1 - After Title, 2 - Before Display Content, 3 - After Display Content, 0 - Do not prepare
|
||||
if ($prepareValue && (\is_bool($prepareValue) || $prepareValue === (int) $field->params->get('display', '2'))) {
|
||||
/*
|
||||
* On before field prepare
|
||||
* Event allow plugins to modify the output of the field before it is prepared
|
||||
*/
|
||||
$dispatcher->dispatch('onCustomFieldsBeforePrepareField', new BeforePrepareFieldEvent('onCustomFieldsBeforePrepareField', [
|
||||
'context' => $context,
|
||||
'item' => $item,
|
||||
'subject' => $field,
|
||||
]));
|
||||
|
||||
// Gathering the value for the field
|
||||
$value = $dispatcher->dispatch('onCustomFieldsPrepareField', new PrepareFieldEvent('onCustomFieldsPrepareField', [
|
||||
'context' => $context,
|
||||
'item' => $item,
|
||||
'subject' => $field,
|
||||
]))->getArgument('result', []);
|
||||
|
||||
if (\is_array($value)) {
|
||||
$value = implode(' ', $value);
|
||||
}
|
||||
|
||||
/*
|
||||
* On after field render
|
||||
* Event allows plugins to modify the output of the prepared field
|
||||
*/
|
||||
$eventAfter = new AfterPrepareFieldEvent('onCustomFieldsAfterPrepareField', [
|
||||
'context' => $context,
|
||||
'item' => $item,
|
||||
'subject' => $field,
|
||||
'value' => &$value, // @todo: Remove reference in Joomla 6, see AfterPrepareFieldEvent::__constructor()
|
||||
]);
|
||||
$dispatcher->dispatch('onCustomFieldsAfterPrepareField', $eventAfter);
|
||||
$value = $eventAfter->getValue();
|
||||
|
||||
// Assign the value
|
||||
$field->value = $value;
|
||||
}
|
||||
|
||||
$new[$key] = $field;
|
||||
}
|
||||
|
||||
$fields = $new;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the layout file and data on the context and does a fall back to
|
||||
* Fields afterwards.
|
||||
*
|
||||
* @param string $context The context of the content passed to the helper
|
||||
* @param string $layoutFile layoutFile
|
||||
* @param array $displayData displayData
|
||||
*
|
||||
* @return NULL|string
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function render($context, $layoutFile, $displayData)
|
||||
{
|
||||
$value = '';
|
||||
|
||||
/*
|
||||
* Because the layout refreshes the paths before the render function is
|
||||
* called, so there is no way to load the layout overrides in the order
|
||||
* template -> context -> fields.
|
||||
* If there is no override in the context then we need to call the
|
||||
* layout from Fields.
|
||||
*/
|
||||
if ($parts = self::extract($context)) {
|
||||
// Trying to render the layout on the component from the context
|
||||
$value = LayoutHelper::render($layoutFile, $displayData, null, ['component' => $parts[0], 'client' => 0]);
|
||||
}
|
||||
|
||||
if ($value == '') {
|
||||
// Trying to render the layout on Fields itself
|
||||
$value = LayoutHelper::render($layoutFile, $displayData, null, ['component' => 'com_fields','client' => 0]);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* PrepareForm
|
||||
*
|
||||
* @param string $context The context of the content passed to the helper
|
||||
* @param Form $form form
|
||||
* @param object $data data.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function prepareForm($context, Form $form, $data)
|
||||
{
|
||||
// Extracting the component and section
|
||||
$parts = self::extract($context);
|
||||
|
||||
if (! $parts) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$context = $parts[0] . '.' . $parts[1];
|
||||
|
||||
// When no fields available return here
|
||||
$fields = self::getFields($parts[0] . '.' . $parts[1], new CMSObject());
|
||||
|
||||
if (! $fields) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$component = $parts[0];
|
||||
$section = $parts[1];
|
||||
|
||||
$assignedCatids = $data->catid ?? $data->fieldscatid ?? $form->getValue('catid');
|
||||
|
||||
// Account for case that a submitted form has a multi-value category id field (e.g. a filtering form), just use the first category
|
||||
$assignedCatids = \is_array($assignedCatids)
|
||||
? (int) reset($assignedCatids)
|
||||
: (int) $assignedCatids;
|
||||
|
||||
if (!$assignedCatids && $formField = $form->getField('catid')) {
|
||||
$assignedCatids = $formField->getAttribute('default', null);
|
||||
|
||||
if (!$assignedCatids) {
|
||||
// Choose the first category available
|
||||
$catOptions = $formField->options;
|
||||
|
||||
if ($catOptions && !empty($catOptions[0]->value)) {
|
||||
$assignedCatids = (int) $catOptions[0]->value;
|
||||
}
|
||||
}
|
||||
|
||||
$data->fieldscatid = $assignedCatids;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is a catid field we need to reload the page when the catid
|
||||
* is changed
|
||||
*/
|
||||
if ($form->getField('catid') && $parts[0] != 'com_fields') {
|
||||
/*
|
||||
* Setting some parameters for the category field
|
||||
*/
|
||||
$form->setFieldAttribute('catid', 'refresh-enabled', true);
|
||||
$form->setFieldAttribute('catid', 'refresh-cat-id', $assignedCatids);
|
||||
$form->setFieldAttribute('catid', 'refresh-section', $section);
|
||||
}
|
||||
|
||||
// Getting the fields
|
||||
$fields = self::getFields($parts[0] . '.' . $parts[1], $data);
|
||||
|
||||
if (!$fields) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$fieldTypes = self::getFieldTypes();
|
||||
|
||||
// Creating the dom
|
||||
$xml = new \DOMDocument('1.0', 'UTF-8');
|
||||
$fieldsNode = $xml->appendChild(new \DOMElement('form'))->appendChild(new \DOMElement('fields'));
|
||||
$fieldsNode->setAttribute('name', 'com_fields');
|
||||
|
||||
// Organizing the fields according to their group
|
||||
$fieldsPerGroup = [0 => []];
|
||||
|
||||
foreach ($fields as $field) {
|
||||
if (!\array_key_exists($field->type, $fieldTypes)) {
|
||||
// Field type is not available
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!\array_key_exists($field->group_id, $fieldsPerGroup)) {
|
||||
$fieldsPerGroup[$field->group_id] = [];
|
||||
}
|
||||
|
||||
if ($path = $fieldTypes[$field->type]['path']) {
|
||||
// Add the lookup path for the field
|
||||
FormHelper::addFieldPath($path);
|
||||
}
|
||||
|
||||
if ($path = $fieldTypes[$field->type]['rules']) {
|
||||
// Add the lookup path for the rule
|
||||
FormHelper::addRulePath($path);
|
||||
}
|
||||
|
||||
$fieldsPerGroup[$field->group_id][] = $field;
|
||||
}
|
||||
|
||||
$model = Factory::getApplication()->bootComponent('com_fields')
|
||||
->getMVCFactory()->createModel('Groups', 'Administrator', ['ignore_request' => true]);
|
||||
$model->setState('filter.context', $context);
|
||||
/** @var DispatcherInterface $dispatcher */
|
||||
$dispatcher = Factory::getContainer()->get(DispatcherInterface::class);
|
||||
|
||||
/**
|
||||
* $model->getItems() would only return existing groups, but we also
|
||||
* have the 'default' group with id 0 which is not in the database,
|
||||
* so we create it virtually here.
|
||||
*/
|
||||
$defaultGroup = new \stdClass();
|
||||
$defaultGroup->id = 0;
|
||||
$defaultGroup->title = '';
|
||||
$defaultGroup->description = '';
|
||||
$iterateGroups = array_merge([$defaultGroup], $model->getItems());
|
||||
|
||||
// Looping through the groups
|
||||
foreach ($iterateGroups as $group) {
|
||||
if (empty($fieldsPerGroup[$group->id])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Defining the field set
|
||||
/** @var \DOMElement $fieldset */
|
||||
$fieldset = $fieldsNode->appendChild(new \DOMElement('fieldset'));
|
||||
$fieldset->setAttribute('name', 'fields-' . $group->id);
|
||||
$fieldset->setAttribute('addfieldpath', '/administrator/components/' . $component . '/models/fields');
|
||||
$fieldset->setAttribute('addrulepath', '/administrator/components/' . $component . '/models/rules');
|
||||
|
||||
$label = $group->title;
|
||||
$description = $group->description;
|
||||
|
||||
if (!$label) {
|
||||
$key = strtoupper($component . '_FIELDS_' . $section . '_LABEL');
|
||||
|
||||
if (!Factory::getLanguage()->hasKey($key)) {
|
||||
$key = 'JGLOBAL_FIELDS';
|
||||
}
|
||||
|
||||
$label = $key;
|
||||
}
|
||||
|
||||
if (!$description) {
|
||||
$key = strtoupper($component . '_FIELDS_' . $section . '_DESC');
|
||||
|
||||
if (Factory::getLanguage()->hasKey($key)) {
|
||||
$description = $key;
|
||||
}
|
||||
}
|
||||
|
||||
$fieldset->setAttribute('label', $label);
|
||||
$fieldset->setAttribute('description', strip_tags($description));
|
||||
|
||||
// Looping through the fields for that context
|
||||
foreach ($fieldsPerGroup[$group->id] as $field) {
|
||||
try {
|
||||
$dispatcher->dispatch('onCustomFieldsPrepareDom', new PrepareDomEvent('onCustomFieldsPrepareDom', [
|
||||
'subject' => $field,
|
||||
'fieldset' => $fieldset,
|
||||
'form' => $form,
|
||||
]));
|
||||
|
||||
/*
|
||||
* If the field belongs to an assigned_cat_id but the assigned_cat_ids in the data
|
||||
* is not known, set the required flag to false on any circumstance.
|
||||
*/
|
||||
if (!$assignedCatids && !empty($field->assigned_cat_ids) && $form->getField($field->name)) {
|
||||
$form->setFieldAttribute($field->name, 'required', 'false');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// When the field set is empty, then remove it
|
||||
if (!$fieldset->hasChildNodes()) {
|
||||
$fieldsNode->removeChild($fieldset);
|
||||
}
|
||||
}
|
||||
|
||||
// Loading the XML fields string into the form
|
||||
$form->load($xml->saveXML());
|
||||
|
||||
$model = Factory::getApplication()->bootComponent('com_fields')
|
||||
->getMVCFactory()->createModel('Field', 'Administrator', ['ignore_request' => true]);
|
||||
|
||||
if (
|
||||
(!isset($data->id) || !$data->id) && Factory::getApplication()->getInput()->getCmd('controller') == 'modules'
|
||||
&& Factory::getApplication()->isClient('site')
|
||||
) {
|
||||
// Modules on front end editing don't have data and an id set
|
||||
$data->id = Factory::getApplication()->getInput()->getInt('id');
|
||||
}
|
||||
|
||||
// Looping through the fields again to set the value
|
||||
if (!isset($data->id) || !$data->id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($fields as $field) {
|
||||
$value = $model->getFieldValue($field->id, $data->id);
|
||||
|
||||
if ($value === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!\is_array($value) && $value !== '') {
|
||||
// Function getField doesn't cache the fields, so we try to do it only when necessary
|
||||
$formField = $form->getField($field->name, 'com_fields');
|
||||
|
||||
if ($formField && $formField->forceMultiple) {
|
||||
$value = (array) $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Setting the value on the field
|
||||
$form->setValue($field->name, 'com_fields', $value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a boolean if the actual logged in user can edit the given field value.
|
||||
*
|
||||
* @param \stdClass $field The field
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function canEditFieldValue($field)
|
||||
{
|
||||
$parts = self::extract($field->context);
|
||||
|
||||
return Factory::getUser()->authorise('core.edit.value', $parts[0] . '.field.' . (int) $field->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a boolean based on field (and field group) display / show_on settings
|
||||
*
|
||||
* @param \stdClass $field The field
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.8.7
|
||||
*/
|
||||
public static function displayFieldOnForm($field)
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
|
||||
// Detect if the field should be shown at all
|
||||
if ($field->params->get('show_on') == 1 && $app->isClient('administrator')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($field->params->get('show_on') == 2 && $app->isClient('site')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!self::canEditFieldValue($field)) {
|
||||
$fieldDisplayReadOnly = $field->params->get('display_readonly', '2');
|
||||
|
||||
if ($fieldDisplayReadOnly == '2') {
|
||||
// Inherit from field group display read-only setting
|
||||
$groupModel = $app->bootComponent('com_fields')
|
||||
->getMVCFactory()->createModel('Group', 'Administrator', ['ignore_request' => true]);
|
||||
$groupDisplayReadOnly = $groupModel->getItem($field->group_id)->params->get('display_readonly', '1');
|
||||
$fieldDisplayReadOnly = $groupDisplayReadOnly;
|
||||
}
|
||||
|
||||
if ($fieldDisplayReadOnly == '0') {
|
||||
// Do not display field on form when field is read-only
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Display field on form
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets assigned categories ids for a field
|
||||
*
|
||||
* @param \stdClass[] $fieldId The field ID
|
||||
*
|
||||
* @return array Array with the assigned category ids
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public static function getAssignedCategoriesIds($fieldId)
|
||||
{
|
||||
$fieldId = (int) $fieldId;
|
||||
|
||||
if (!$fieldId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
$query->select($db->quoteName('a.category_id'))
|
||||
->from($db->quoteName('#__fields_categories', 'a'))
|
||||
->where('a.field_id = ' . $fieldId);
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
return $db->loadColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets assigned categories titles for a field
|
||||
*
|
||||
* @param \stdClass[] $fieldId The field ID
|
||||
*
|
||||
* @return array Array with the assigned categories
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function getAssignedCategoriesTitles($fieldId)
|
||||
{
|
||||
$fieldId = (int) $fieldId;
|
||||
|
||||
if (!$fieldId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
$query->select($db->quoteName('c.title'))
|
||||
->from($db->quoteName('#__fields_categories', 'a'))
|
||||
->join('INNER', $db->quoteName('#__categories', 'c') . ' ON a.category_id = c.id')
|
||||
->where($db->quoteName('field_id') . ' = :fieldid')
|
||||
->bind(':fieldid', $fieldId, ParameterType::INTEGER);
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
return $db->loadColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fields system plugin extension id.
|
||||
*
|
||||
* @return integer The fields system plugin extension id.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function getFieldsPluginId()
|
||||
{
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('extension_id'))
|
||||
->from($db->quoteName('#__extensions'))
|
||||
->where($db->quoteName('folder') . ' = ' . $db->quote('system'))
|
||||
->where($db->quoteName('element') . ' = ' . $db->quote('fields'));
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
$result = (int) $db->loadResult();
|
||||
} catch (\RuntimeException $e) {
|
||||
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
|
||||
$result = 0;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the fields plugins and returns an array of field types from the plugins.
|
||||
*
|
||||
* The returned array contains arrays with the following keys:
|
||||
* - label: The label of the field
|
||||
* - type: The type of the field
|
||||
* - path: The path of the folder where the field can be found
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function getFieldTypes()
|
||||
{
|
||||
/** @var DispatcherInterface $dispatcher */
|
||||
$dispatcher = Factory::getContainer()->get(DispatcherInterface::class);
|
||||
PluginHelper::importPlugin('fields', null, true, $dispatcher);
|
||||
$eventData = $dispatcher->dispatch('onCustomFieldsGetTypes', new GetTypesEvent('onCustomFieldsGetTypes'))->getArgument('result', []);
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach ($eventData as $fields) {
|
||||
foreach ($fields as $fieldDescription) {
|
||||
if (!\array_key_exists('path', $fieldDescription)) {
|
||||
$fieldDescription['path'] = null;
|
||||
}
|
||||
|
||||
if (!\array_key_exists('rules', $fieldDescription)) {
|
||||
$fieldDescription['rules'] = null;
|
||||
}
|
||||
|
||||
$data[$fieldDescription['type']] = $fieldDescription;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the internal cache for the custom fields.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.8.0
|
||||
*/
|
||||
public static function clearFieldsCache()
|
||||
{
|
||||
self::$fieldCache = null;
|
||||
self::$fieldsCache = null;
|
||||
}
|
||||
}
|
||||
1252
administrator/components/com_fields/src/Model/FieldModel.php
Normal file
1252
administrator/components/com_fields/src/Model/FieldModel.php
Normal file
File diff suppressed because it is too large
Load Diff
464
administrator/components/com_fields/src/Model/FieldsModel.php
Normal file
464
administrator/components/com_fields/src/Model/FieldsModel.php
Normal file
@ -0,0 +1,464 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Model;
|
||||
|
||||
use Joomla\CMS\Categories\CategoryServiceInterface;
|
||||
use Joomla\CMS\Categories\SectionNotFoundException;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\CMS\MVC\Model\ListModel;
|
||||
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Registry\Registry;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Fields Model
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class FieldsModel extends ListModel
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $config An array of configuration options (name, state, dbo, table_path, ignore_request).
|
||||
* @param MVCFactoryInterface $factory The factory.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct($config = [], MVCFactoryInterface $factory = null)
|
||||
{
|
||||
if (empty($config['filter_fields'])) {
|
||||
$config['filter_fields'] = [
|
||||
'id', 'a.id',
|
||||
'title', 'a.title',
|
||||
'type', 'a.type',
|
||||
'name', 'a.name',
|
||||
'state', 'a.state',
|
||||
'access', 'a.access',
|
||||
'access_level',
|
||||
'only_use_in_subform',
|
||||
'language', 'a.language',
|
||||
'ordering', 'a.ordering',
|
||||
'checked_out', 'a.checked_out',
|
||||
'checked_out_time', 'a.checked_out_time',
|
||||
'created_time', 'a.created_time',
|
||||
'created_user_id', 'a.created_user_id',
|
||||
'group_title', 'g.title',
|
||||
'category_id', 'a.category_id',
|
||||
'group_id', 'a.group_id',
|
||||
'assigned_cat_ids',
|
||||
];
|
||||
}
|
||||
|
||||
parent::__construct($config, $factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* This method should only be called once per instantiation and is designed
|
||||
* to be called on the first call to the getState() method unless the model
|
||||
* configuration flag to ignore the request is set.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @param string $ordering An optional ordering field.
|
||||
* @param string $direction An optional direction (asc|desc).
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function populateState($ordering = null, $direction = null)
|
||||
{
|
||||
// List state information.
|
||||
parent::populateState('a.ordering', 'asc');
|
||||
|
||||
$context = $this->getUserStateFromRequest($this->context . '.context', 'context', 'com_content.article', 'CMD');
|
||||
$this->setState('filter.context', $context);
|
||||
|
||||
// Split context into component and optional section
|
||||
$parts = FieldsHelper::extract($context);
|
||||
|
||||
if ($parts) {
|
||||
$this->setState('filter.component', $parts[0]);
|
||||
$this->setState('filter.section', $parts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a store id based on the model configuration state.
|
||||
*
|
||||
* This is necessary because the model is used by the component and
|
||||
* different modules that might need different sets of data or different
|
||||
* ordering requirements.
|
||||
*
|
||||
* @param string $id An identifier string to generate the store id.
|
||||
*
|
||||
* @return string A store id.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function getStoreId($id = '')
|
||||
{
|
||||
// Compile the store id.
|
||||
$id .= ':' . $this->getState('filter.search');
|
||||
$id .= ':' . $this->getState('filter.context');
|
||||
$id .= ':' . serialize($this->getState('filter.assigned_cat_ids'));
|
||||
$id .= ':' . $this->getState('filter.state');
|
||||
$id .= ':' . $this->getState('filter.group_id');
|
||||
$id .= ':' . serialize($this->getState('filter.language'));
|
||||
$id .= ':' . $this->getState('filter.only_use_in_subform');
|
||||
|
||||
return parent::getStoreId($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a DatabaseQuery object for retrieving the data set from a database.
|
||||
*
|
||||
* @return \Joomla\Database\DatabaseQuery A DatabaseQuery object to retrieve the data set.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function getListQuery()
|
||||
{
|
||||
// Create a new query object.
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true);
|
||||
$user = $this->getCurrentUser();
|
||||
$app = Factory::getApplication();
|
||||
|
||||
// Select the required fields from the table.
|
||||
$query->select(
|
||||
$this->getState(
|
||||
'list.select',
|
||||
'DISTINCT a.id, a.title, a.name, a.checked_out, a.checked_out_time, a.note' .
|
||||
', a.state, a.access, a.created_time, a.created_user_id, a.ordering, a.language' .
|
||||
', a.fieldparams, a.params, a.type, a.default_value, a.context, a.group_id' .
|
||||
', a.label, a.description, a.required, a.only_use_in_subform'
|
||||
)
|
||||
);
|
||||
$query->from('#__fields AS a');
|
||||
|
||||
// Join over the language
|
||||
$query->select('l.title AS language_title, l.image AS language_image')
|
||||
->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language');
|
||||
|
||||
// Join over the users for the checked out user.
|
||||
$query->select('uc.name AS editor')->join('LEFT', '#__users AS uc ON uc.id=a.checked_out');
|
||||
|
||||
// Join over the asset groups.
|
||||
$query->select('ag.title AS access_level')->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access');
|
||||
|
||||
// Join over the users for the author.
|
||||
$query->select('ua.name AS author_name')->join('LEFT', '#__users AS ua ON ua.id = a.created_user_id');
|
||||
|
||||
// Join over the field groups.
|
||||
$query->select('g.title AS group_title, g.access as group_access, g.state AS group_state, g.note as group_note');
|
||||
$query->join('LEFT', '#__fields_groups AS g ON g.id = a.group_id');
|
||||
|
||||
// Filter by context
|
||||
if ($context = $this->getState('filter.context')) {
|
||||
$query->where($db->quoteName('a.context') . ' = :context')
|
||||
->bind(':context', $context);
|
||||
}
|
||||
|
||||
// Filter by access level.
|
||||
if ($access = $this->getState('filter.access')) {
|
||||
if (\is_array($access)) {
|
||||
$access = ArrayHelper::toInteger($access);
|
||||
$query->whereIn($db->quoteName('a.access'), $access);
|
||||
} else {
|
||||
$access = (int) $access;
|
||||
$query->where($db->quoteName('a.access') . ' = :access')
|
||||
->bind(':access', $access, ParameterType::INTEGER);
|
||||
}
|
||||
}
|
||||
|
||||
if (($categories = $this->getState('filter.assigned_cat_ids')) && $context) {
|
||||
$categories = (array) $categories;
|
||||
$categories = ArrayHelper::toInteger($categories);
|
||||
$parts = FieldsHelper::extract($context);
|
||||
|
||||
if ($parts) {
|
||||
// Get the categories for this component (and optionally this section, if available)
|
||||
$cat = (
|
||||
function () use ($parts) {
|
||||
// Get the CategoryService for this component
|
||||
$componentObject = $this->bootComponent($parts[0]);
|
||||
|
||||
if (!$componentObject instanceof CategoryServiceInterface) {
|
||||
// No CategoryService -> no categories
|
||||
return null;
|
||||
}
|
||||
|
||||
$cat = null;
|
||||
|
||||
// Try to get the categories for this component and section
|
||||
try {
|
||||
$cat = $componentObject->getCategory([], $parts[1] ?: '');
|
||||
} catch (SectionNotFoundException $e) {
|
||||
// Not found for component and section -> Now try once more without the section, so only component
|
||||
try {
|
||||
$cat = $componentObject->getCategory();
|
||||
} catch (SectionNotFoundException $e) {
|
||||
// If we haven't found it now, return (no categories available for this component)
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// So we found categories for at least the component, return them
|
||||
return $cat;
|
||||
}
|
||||
)();
|
||||
|
||||
if ($cat) {
|
||||
foreach ($categories as $assignedCatIds) {
|
||||
// Check if we have the actual category
|
||||
$parent = $cat->get($assignedCatIds);
|
||||
|
||||
if ($parent) {
|
||||
$categories[] = (int) $parent->id;
|
||||
|
||||
// Traverse the tree up to get all the fields which are attached to a parent
|
||||
while ($parent->getParent() && $parent->getParent()->id != 'root') {
|
||||
$parent = $parent->getParent();
|
||||
$categories[] = (int) $parent->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$categories = array_unique($categories);
|
||||
|
||||
// Join over the assigned categories
|
||||
$query->join('LEFT', $db->quoteName('#__fields_categories') . ' AS fc ON fc.field_id = a.id');
|
||||
|
||||
if (\in_array('0', $categories)) {
|
||||
$query->where(
|
||||
'(' .
|
||||
$db->quoteName('fc.category_id') . ' IS NULL OR ' .
|
||||
$db->quoteName('fc.category_id') . ' IN (' . implode(',', $query->bindArray(array_values($categories), ParameterType::INTEGER)) . ')' .
|
||||
')'
|
||||
);
|
||||
} else {
|
||||
$query->whereIn($db->quoteName('fc.category_id'), $categories);
|
||||
}
|
||||
}
|
||||
|
||||
// Implement View Level Access
|
||||
if (!$app->isClient('administrator') || !$user->authorise('core.admin')) {
|
||||
$groups = $user->getAuthorisedViewLevels();
|
||||
$query->whereIn($db->quoteName('a.access'), $groups);
|
||||
$query->extendWhere(
|
||||
'AND',
|
||||
[
|
||||
$db->quoteName('a.group_id') . ' = 0',
|
||||
$db->quoteName('g.access') . ' IN (' . implode(',', $query->bindArray($groups, ParameterType::INTEGER)) . ')',
|
||||
],
|
||||
'OR'
|
||||
);
|
||||
}
|
||||
|
||||
// Filter by state
|
||||
$state = $this->getState('filter.state');
|
||||
|
||||
// Include group state only when not on on back end list
|
||||
$includeGroupState = !$app->isClient('administrator') ||
|
||||
$app->getInput()->get('option') != 'com_fields' ||
|
||||
$app->getInput()->get('view') != 'fields';
|
||||
|
||||
if (is_numeric($state)) {
|
||||
$state = (int) $state;
|
||||
$query->where($db->quoteName('a.state') . ' = :state')
|
||||
->bind(':state', $state, ParameterType::INTEGER);
|
||||
|
||||
if ($includeGroupState) {
|
||||
$query->extendWhere(
|
||||
'AND',
|
||||
[
|
||||
$db->quoteName('a.group_id') . ' = 0',
|
||||
$db->quoteName('g.state') . ' = :gstate',
|
||||
],
|
||||
'OR'
|
||||
)
|
||||
->bind(':gstate', $state, ParameterType::INTEGER);
|
||||
}
|
||||
} elseif (!$state) {
|
||||
$query->whereIn($db->quoteName('a.state'), [0, 1]);
|
||||
|
||||
if ($includeGroupState) {
|
||||
$query->extendWhere(
|
||||
'AND',
|
||||
[
|
||||
$db->quoteName('a.group_id') . ' = 0',
|
||||
$db->quoteName('g.state') . ' IN (' . implode(',', $query->bindArray([0, 1], ParameterType::INTEGER)) . ')',
|
||||
],
|
||||
'OR'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$groupId = $this->getState('filter.group_id');
|
||||
|
||||
if (is_numeric($groupId)) {
|
||||
$groupId = (int) $groupId;
|
||||
$query->where($db->quoteName('a.group_id') . ' = :groupid')
|
||||
->bind(':groupid', $groupId, ParameterType::INTEGER);
|
||||
}
|
||||
|
||||
$onlyUseInSubForm = $this->getState('filter.only_use_in_subform');
|
||||
|
||||
if (is_numeric($onlyUseInSubForm)) {
|
||||
$onlyUseInSubForm = (int) $onlyUseInSubForm;
|
||||
$query->where($db->quoteName('a.only_use_in_subform') . ' = :only_use_in_subform')
|
||||
->bind(':only_use_in_subform', $onlyUseInSubForm, ParameterType::INTEGER);
|
||||
}
|
||||
|
||||
// Filter by search in title
|
||||
$search = $this->getState('filter.search');
|
||||
|
||||
if (!empty($search)) {
|
||||
if (stripos($search, 'id:') === 0) {
|
||||
$search = (int) substr($search, 3);
|
||||
$query->where($db->quoteName('a.id') . ' = :id')
|
||||
->bind(':id', $search, ParameterType::INTEGER);
|
||||
} elseif (stripos($search, 'author:') === 0) {
|
||||
$search = '%' . substr($search, 7) . '%';
|
||||
$query->where(
|
||||
'(' .
|
||||
$db->quoteName('ua.name') . ' LIKE :name OR ' .
|
||||
$db->quoteName('ua.username') . ' LIKE :username' .
|
||||
')'
|
||||
)
|
||||
->bind(':name', $search)
|
||||
->bind(':username', $search);
|
||||
} else {
|
||||
$search = '%' . str_replace(' ', '%', trim($search)) . '%';
|
||||
$query->where(
|
||||
'(' .
|
||||
$db->quoteName('a.title') . ' LIKE :title OR ' .
|
||||
$db->quoteName('a.name') . ' LIKE :sname OR ' .
|
||||
$db->quoteName('a.note') . ' LIKE :note' .
|
||||
')'
|
||||
)
|
||||
->bind(':title', $search)
|
||||
->bind(':sname', $search)
|
||||
->bind(':note', $search);
|
||||
}
|
||||
}
|
||||
|
||||
// Filter on the language.
|
||||
if ($language = $this->getState('filter.language')) {
|
||||
$language = (array) $language;
|
||||
|
||||
$query->whereIn($db->quoteName('a.language'), $language, ParameterType::STRING);
|
||||
}
|
||||
|
||||
// Add the list ordering clause
|
||||
$listOrdering = $this->state->get('list.ordering', 'a.ordering');
|
||||
$orderDirn = $this->state->get('list.direction', 'ASC');
|
||||
|
||||
$query->order($db->escape($listOrdering) . ' ' . $db->escape($orderDirn));
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of objects from the results of database query.
|
||||
*
|
||||
* @param string $query The query.
|
||||
* @param integer $limitstart Offset.
|
||||
* @param integer $limit The number of records.
|
||||
*
|
||||
* @return array An array of results.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function _getList($query, $limitstart = 0, $limit = 0)
|
||||
{
|
||||
$result = parent::_getList($query, $limitstart, $limit);
|
||||
|
||||
if (\is_array($result)) {
|
||||
foreach ($result as $field) {
|
||||
$field->fieldparams = new Registry($field->fieldparams);
|
||||
$field->params = new Registry($field->params);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filter form
|
||||
*
|
||||
* @param array $data data
|
||||
* @param boolean $loadData load current data
|
||||
*
|
||||
* @return \Joomla\CMS\Form\Form|bool the Form object or false
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function getFilterForm($data = [], $loadData = true)
|
||||
{
|
||||
$form = parent::getFilterForm($data, $loadData);
|
||||
|
||||
if ($form) {
|
||||
$form->setValue('context', null, $this->getState('filter.context'));
|
||||
$form->setFieldAttribute('group_id', 'context', $this->getState('filter.context'), 'filter');
|
||||
$form->setFieldAttribute('assigned_cat_ids', 'extension', $this->state->get('filter.component'), 'filter');
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the groups for the batch method
|
||||
*
|
||||
* @return array An array of groups
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function getGroups()
|
||||
{
|
||||
$user = $this->getCurrentUser();
|
||||
$viewlevels = ArrayHelper::toInteger($user->getAuthorisedViewLevels());
|
||||
$context = $this->state->get('filter.context');
|
||||
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true);
|
||||
$query->select(
|
||||
[
|
||||
$db->quoteName('title', 'text'),
|
||||
$db->quoteName('id', 'value'),
|
||||
$db->quoteName('state'),
|
||||
]
|
||||
);
|
||||
$query->from($db->quoteName('#__fields_groups'));
|
||||
$query->whereIn($db->quoteName('state'), [0, 1]);
|
||||
$query->where($db->quoteName('context') . ' = :context');
|
||||
$query->whereIn($db->quoteName('access'), $viewlevels);
|
||||
$query->bind(':context', $context);
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
return $db->loadObjectList();
|
||||
}
|
||||
}
|
||||
380
administrator/components/com_fields/src/Model/GroupModel.php
Normal file
380
administrator/components/com_fields/src/Model/GroupModel.php
Normal file
@ -0,0 +1,380 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Model;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Model\AdminModel;
|
||||
use Joomla\CMS\Table\Table;
|
||||
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
|
||||
use Joomla\Filesystem\Path;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Group Model
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class GroupModel extends AdminModel
|
||||
{
|
||||
/**
|
||||
* @var null|string
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public $typeAlias = null;
|
||||
|
||||
/**
|
||||
* Allowed batch commands
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $batch_commands = [
|
||||
'assetgroup_id' => 'batchAccess',
|
||||
'language_id' => 'batchLanguage',
|
||||
];
|
||||
|
||||
/**
|
||||
* Method to save the form data.
|
||||
*
|
||||
* @param array $data The form data.
|
||||
*
|
||||
* @return boolean True on success, False on error.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function save($data)
|
||||
{
|
||||
// Alter the title for save as copy
|
||||
$input = Factory::getApplication()->getInput();
|
||||
|
||||
// Save new group as unpublished
|
||||
if ($input->get('task') == 'save2copy') {
|
||||
$data['state'] = 0;
|
||||
}
|
||||
|
||||
return parent::save($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a table object, load it if necessary.
|
||||
*
|
||||
* @param string $name The table name. Optional.
|
||||
* @param string $prefix The class prefix. Optional.
|
||||
* @param array $options Configuration array for model. Optional.
|
||||
*
|
||||
* @return Table A Table object
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getTable($name = 'Group', $prefix = 'Administrator', $options = [])
|
||||
{
|
||||
return parent::getTable($name, $prefix, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method for getting the form from the model.
|
||||
*
|
||||
* @param array $data Data for the form.
|
||||
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
|
||||
*
|
||||
* @return mixed A Form object on success, false on failure
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function getForm($data = [], $loadData = true)
|
||||
{
|
||||
$context = $this->getState('filter.context');
|
||||
$jinput = Factory::getApplication()->getInput();
|
||||
|
||||
if (empty($context) && isset($data['context'])) {
|
||||
$context = $data['context'];
|
||||
$this->setState('filter.context', $context);
|
||||
}
|
||||
|
||||
// Get the form.
|
||||
$form = $this->loadForm(
|
||||
'com_fields.group.' . $context,
|
||||
'group',
|
||||
[
|
||||
'control' => 'jform',
|
||||
'load_data' => $loadData,
|
||||
]
|
||||
);
|
||||
|
||||
if (empty($form)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Modify the form based on Edit State access controls.
|
||||
if (empty($data['context'])) {
|
||||
$data['context'] = $context;
|
||||
}
|
||||
|
||||
$user = $this->getCurrentUser();
|
||||
|
||||
if (!$user->authorise('core.edit.state', $context . '.fieldgroup.' . $jinput->get('id'))) {
|
||||
// Disable fields for display.
|
||||
$form->setFieldAttribute('ordering', 'disabled', 'true');
|
||||
$form->setFieldAttribute('state', 'disabled', 'true');
|
||||
|
||||
// Disable fields while saving. The controller has already verified this is a record you can edit.
|
||||
$form->setFieldAttribute('ordering', 'filter', 'unset');
|
||||
$form->setFieldAttribute('state', 'filter', 'unset');
|
||||
}
|
||||
|
||||
// Don't allow to change the created_by user if not allowed to access com_users.
|
||||
if (!$user->authorise('core.manage', 'com_users')) {
|
||||
$form->setFieldAttribute('created_by', 'filter', 'unset');
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to test whether a record can be deleted.
|
||||
*
|
||||
* @param object $record A record object.
|
||||
*
|
||||
* @return boolean True if allowed to delete the record. Defaults to the permission for the component.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function canDelete($record)
|
||||
{
|
||||
if (empty($record->id) || $record->state != -2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->getCurrentUser()->authorise('core.delete', $record->context . '.fieldgroup.' . (int) $record->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to test whether a record can have its state changed.
|
||||
*
|
||||
* @param object $record A record object.
|
||||
*
|
||||
* @return boolean True if allowed to change the state of the record. Defaults to the permission for the
|
||||
* component.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function canEditState($record)
|
||||
{
|
||||
$user = $this->getCurrentUser();
|
||||
|
||||
// Check for existing fieldgroup.
|
||||
if (!empty($record->id)) {
|
||||
return $user->authorise('core.edit.state', $record->context . '.fieldgroup.' . (int) $record->id);
|
||||
}
|
||||
|
||||
// Default to component settings.
|
||||
return $user->authorise('core.edit.state', $record->context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function populateState()
|
||||
{
|
||||
parent::populateState();
|
||||
|
||||
$context = Factory::getApplication()->getUserStateFromRequest('com_fields.groups.context', 'context', 'com_fields', 'CMD');
|
||||
$this->setState('filter.context', $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* A protected method to get a set of ordering conditions.
|
||||
*
|
||||
* @param Table $table A Table object.
|
||||
*
|
||||
* @return array An array of conditions to add to ordering queries.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function getReorderConditions($table)
|
||||
{
|
||||
$db = $this->getDatabase();
|
||||
|
||||
return [
|
||||
$db->quoteName('context') . ' = ' . $db->quote($table->context),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to preprocess the form.
|
||||
*
|
||||
* @param Form $form A Form object.
|
||||
* @param mixed $data The data expected for the form.
|
||||
* @param string $group The name of the plugin group to import (defaults to "content").
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @see \Joomla\CMS\Form\FormField
|
||||
* @since 3.7.0
|
||||
* @throws \Exception if there is an error in the form event.
|
||||
*/
|
||||
protected function preprocessForm(Form $form, $data, $group = 'content')
|
||||
{
|
||||
parent::preprocessForm($form, $data, $group);
|
||||
|
||||
$parts = FieldsHelper::extract($this->state->get('filter.context'));
|
||||
|
||||
// If we don't have a valid context then return early
|
||||
if (!$parts) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract the component name
|
||||
$component = $parts[0];
|
||||
|
||||
// Extract the section name
|
||||
$section = $parts[1];
|
||||
|
||||
// Set the access control rules field component value.
|
||||
$form->setFieldAttribute('rules', 'component', $component);
|
||||
|
||||
// Looking first in the component models/forms folder
|
||||
$path = Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/fieldgroup/' . $section . '.xml');
|
||||
|
||||
if (file_exists($path)) {
|
||||
$lang = Factory::getLanguage();
|
||||
$lang->load($component, JPATH_BASE);
|
||||
$lang->load($component, JPATH_BASE . '/components/' . $component);
|
||||
|
||||
if (!$form->loadFile($path, false)) {
|
||||
throw new \Exception(Text::_('JERROR_LOADFILE_FAILED'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to validate the form data.
|
||||
*
|
||||
* @param Form $form The form to validate against.
|
||||
* @param array $data The data to validate.
|
||||
* @param string $group The name of the field group to validate.
|
||||
*
|
||||
* @return array|boolean Array of filtered data if valid, false otherwise.
|
||||
*
|
||||
* @see \Joomla\CMS\Form\FormRule
|
||||
* @see \Joomla\CMS\Filter\InputFilter
|
||||
* @since 3.9.23
|
||||
*/
|
||||
public function validate($form, $data, $group = null)
|
||||
{
|
||||
if (!$this->getCurrentUser()->authorise('core.admin', 'com_fields')) {
|
||||
if (isset($data['rules'])) {
|
||||
unset($data['rules']);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::validate($form, $data, $group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the data that should be injected in the form.
|
||||
*
|
||||
* @return array The default data is an empty array.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function loadFormData()
|
||||
{
|
||||
// Check the session for previously entered form data.
|
||||
$app = Factory::getApplication();
|
||||
$input = $app->getInput();
|
||||
$data = $app->getUserState('com_fields.edit.group.data', []);
|
||||
|
||||
if (empty($data)) {
|
||||
$data = $this->getItem();
|
||||
|
||||
// Pre-select some filters (Status, Language, Access) in edit form if those have been selected in Field Group Manager
|
||||
if (!$data->id) {
|
||||
// Check for which context the Field Group Manager is used and get selected fields
|
||||
$context = substr($app->getUserState('com_fields.groups.filter.context', ''), 4);
|
||||
$filters = (array) $app->getUserState('com_fields.groups.' . $context . '.filter');
|
||||
|
||||
$data->set(
|
||||
'state',
|
||||
$input->getInt('state', (!empty($filters['state']) ? $filters['state'] : null))
|
||||
);
|
||||
$data->set(
|
||||
'language',
|
||||
$input->getString('language', (!empty($filters['language']) ? $filters['language'] : null))
|
||||
);
|
||||
$data->set(
|
||||
'access',
|
||||
$input->getInt('access', (!empty($filters['access']) ? $filters['access'] : $app->get('access')))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->preprocessData('com_fields.group', $data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a single record.
|
||||
*
|
||||
* @param integer $pk The id of the primary key.
|
||||
*
|
||||
* @return mixed Object on success, false on failure.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function getItem($pk = null)
|
||||
{
|
||||
if ($item = parent::getItem($pk)) {
|
||||
// Prime required properties.
|
||||
if (empty($item->id)) {
|
||||
$item->context = $this->getState('filter.context');
|
||||
}
|
||||
|
||||
if (property_exists($item, 'params')) {
|
||||
$item->params = new Registry($item->params);
|
||||
}
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the cache
|
||||
*
|
||||
* @param string $group The cache group
|
||||
* @param integer $clientId No longer used, will be removed without replacement
|
||||
* @deprecated 4.3 will be removed in 6.0
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function cleanCache($group = null, $clientId = 0)
|
||||
{
|
||||
$context = Factory::getApplication()->getInput()->get('context');
|
||||
|
||||
parent::cleanCache($context);
|
||||
}
|
||||
}
|
||||
240
administrator/components/com_fields/src/Model/GroupsModel.php
Normal file
240
administrator/components/com_fields/src/Model/GroupsModel.php
Normal file
@ -0,0 +1,240 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Model;
|
||||
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\CMS\MVC\Model\ListModel;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Registry\Registry;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Groups Model
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class GroupsModel extends ListModel
|
||||
{
|
||||
/**
|
||||
* Context string for the model type. This is used to handle uniqueness
|
||||
* when dealing with the getStoreId() method and caching data structures.
|
||||
*
|
||||
* @var string
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $context = 'com_fields.groups';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $config An array of configuration options (name, state, dbo, table_path, ignore_request).
|
||||
* @param MVCFactoryInterface $factory The factory.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct($config = [], MVCFactoryInterface $factory = null)
|
||||
{
|
||||
if (empty($config['filter_fields'])) {
|
||||
$config['filter_fields'] = [
|
||||
'id', 'a.id',
|
||||
'title', 'a.title',
|
||||
'type', 'a.type',
|
||||
'state', 'a.state',
|
||||
'access', 'a.access',
|
||||
'access_level',
|
||||
'language', 'a.language',
|
||||
'ordering', 'a.ordering',
|
||||
'checked_out', 'a.checked_out',
|
||||
'checked_out_time', 'a.checked_out_time',
|
||||
'created', 'a.created',
|
||||
'created_by', 'a.created_by',
|
||||
];
|
||||
}
|
||||
|
||||
parent::__construct($config, $factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* This method should only be called once per instantiation and is designed
|
||||
* to be called on the first call to the getState() method unless the model
|
||||
* configuration flag to ignore the request is set.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @param string $ordering An optional ordering field.
|
||||
* @param string $direction An optional direction (asc|desc).
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function populateState($ordering = null, $direction = null)
|
||||
{
|
||||
// List state information.
|
||||
parent::populateState('a.ordering', 'asc');
|
||||
|
||||
$context = $this->getUserStateFromRequest($this->context . '.context', 'context', 'com_content', 'CMD');
|
||||
$this->setState('filter.context', $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a store id based on the model configuration state.
|
||||
*
|
||||
* This is necessary because the model is used by the component and
|
||||
* different modules that might need different sets of data or different
|
||||
* ordering requirements.
|
||||
*
|
||||
* @param string $id An identifier string to generate the store id.
|
||||
*
|
||||
* @return string A store id.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function getStoreId($id = '')
|
||||
{
|
||||
// Compile the store id.
|
||||
$id .= ':' . $this->getState('filter.search');
|
||||
$id .= ':' . $this->getState('filter.context');
|
||||
$id .= ':' . $this->getState('filter.state');
|
||||
$id .= ':' . print_r($this->getState('filter.language'), true);
|
||||
|
||||
return parent::getStoreId($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a DatabaseQuery object for retrieving the data set from a database.
|
||||
*
|
||||
* @return \Joomla\Database\DatabaseQuery A DatabaseQuery object to retrieve the data set.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function getListQuery()
|
||||
{
|
||||
// Create a new query object.
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true);
|
||||
$user = $this->getCurrentUser();
|
||||
|
||||
// Select the required fields from the table.
|
||||
$query->select($this->getState('list.select', 'a.*'));
|
||||
$query->from('#__fields_groups AS a');
|
||||
|
||||
// Join over the language
|
||||
$query->select('l.title AS language_title, l.image AS language_image')
|
||||
->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language');
|
||||
|
||||
// Join over the users for the checked out user.
|
||||
$query->select('uc.name AS editor')->join('LEFT', '#__users AS uc ON uc.id=a.checked_out');
|
||||
|
||||
// Join over the asset groups.
|
||||
$query->select('ag.title AS access_level')->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access');
|
||||
|
||||
// Join over the users for the author.
|
||||
$query->select('ua.name AS author_name')->join('LEFT', '#__users AS ua ON ua.id = a.created_by');
|
||||
|
||||
// Filter by context
|
||||
if ($context = $this->getState('filter.context', 'com_fields')) {
|
||||
$query->where($db->quoteName('a.context') . ' = :context')
|
||||
->bind(':context', $context);
|
||||
}
|
||||
|
||||
// Filter by access level.
|
||||
if ($access = $this->getState('filter.access')) {
|
||||
if (\is_array($access)) {
|
||||
$access = ArrayHelper::toInteger($access);
|
||||
$query->whereIn($db->quoteName('a.access'), $access);
|
||||
} else {
|
||||
$access = (int) $access;
|
||||
$query->where($db->quoteName('a.access') . ' = :access')
|
||||
->bind(':access', $access, ParameterType::INTEGER);
|
||||
}
|
||||
}
|
||||
|
||||
// Implement View Level Access
|
||||
if (!$user->authorise('core.admin')) {
|
||||
$groups = $user->getAuthorisedViewLevels();
|
||||
$query->whereIn($db->quoteName('a.access'), $groups);
|
||||
}
|
||||
|
||||
// Filter by published state
|
||||
$state = $this->getState('filter.state');
|
||||
|
||||
if (is_numeric($state)) {
|
||||
$state = (int) $state;
|
||||
$query->where($db->quoteName('a.state') . ' = :state')
|
||||
->bind(':state', $state, ParameterType::INTEGER);
|
||||
} elseif (!$state) {
|
||||
$query->whereIn($db->quoteName('a.state'), [0, 1]);
|
||||
}
|
||||
|
||||
// Filter by search in title
|
||||
$search = $this->getState('filter.search');
|
||||
|
||||
if (!empty($search)) {
|
||||
if (stripos($search, 'id:') === 0) {
|
||||
$search = (int) substr($search, 3);
|
||||
$query->where($db->quoteName('a.id') . ' = :search')
|
||||
->bind(':id', $search, ParameterType::INTEGER);
|
||||
} else {
|
||||
$search = '%' . str_replace(' ', '%', trim($search)) . '%';
|
||||
$query->where($db->quoteName('a.title') . ' LIKE :search')
|
||||
->bind(':search', $search);
|
||||
}
|
||||
}
|
||||
|
||||
// Filter on the language.
|
||||
if ($language = $this->getState('filter.language')) {
|
||||
$language = (array) $language;
|
||||
|
||||
$query->whereIn($db->quoteName('a.language'), $language, ParameterType::STRING);
|
||||
}
|
||||
|
||||
// Add the list ordering clause
|
||||
$listOrdering = $this->getState('list.ordering', 'a.ordering');
|
||||
$listDirn = $db->escape($this->getState('list.direction', 'ASC'));
|
||||
|
||||
$query->order($db->escape($listOrdering) . ' ' . $listDirn);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of objects from the results of database query.
|
||||
*
|
||||
* @param string $query The query.
|
||||
* @param integer $limitstart Offset.
|
||||
* @param integer $limit The number of records.
|
||||
*
|
||||
* @return array An array of results.
|
||||
*
|
||||
* @since 3.8.7
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function _getList($query, $limitstart = 0, $limit = 0)
|
||||
{
|
||||
$result = parent::_getList($query, $limitstart, $limit);
|
||||
|
||||
if (\is_array($result)) {
|
||||
foreach ($result as $group) {
|
||||
$group->params = new Registry($group->params);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Plugin;
|
||||
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Base plugin for all list based plugins
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class FieldsListPlugin extends FieldsPlugin
|
||||
{
|
||||
/**
|
||||
* Transforms the field into a DOM XML element and appends it as a child on the given parent.
|
||||
*
|
||||
* @param \stdClass $field The field.
|
||||
* @param \DOMElement $parent The field node parent.
|
||||
* @param Form $form The form.
|
||||
*
|
||||
* @return \DOMElement
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function onCustomFieldsPrepareDom($field, \DOMElement $parent, Form $form)
|
||||
{
|
||||
$fieldNode = parent::onCustomFieldsPrepareDom($field, $parent, $form);
|
||||
|
||||
if (!$fieldNode) {
|
||||
return $fieldNode;
|
||||
}
|
||||
|
||||
$fieldNode->setAttribute('validate', 'options');
|
||||
|
||||
foreach ($this->getOptionsFromField($field) as $value => $name) {
|
||||
$option = new \DOMElement('option', htmlspecialchars($value, ENT_COMPAT, 'UTF-8'));
|
||||
$option->textContent = htmlspecialchars(Text::_($name), ENT_COMPAT, 'UTF-8');
|
||||
|
||||
$element = $fieldNode->appendChild($option);
|
||||
$element->setAttribute('value', $value);
|
||||
}
|
||||
|
||||
return $fieldNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of key values to put in a list from the given field.
|
||||
*
|
||||
* @param \stdClass $field The field.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function getOptionsFromField($field)
|
||||
{
|
||||
$data = [];
|
||||
|
||||
// Fetch the options from the plugin
|
||||
$params = clone $this->params;
|
||||
$params->merge($field->fieldparams);
|
||||
|
||||
foreach ($params->get('options', []) as $option) {
|
||||
$op = (object) $option;
|
||||
$data[$op->value] = $op->name;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
392
administrator/components/com_fields/src/Plugin/FieldsPlugin.php
Normal file
392
administrator/components/com_fields/src/Plugin/FieldsPlugin.php
Normal file
@ -0,0 +1,392 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Plugin;
|
||||
|
||||
use Joomla\CMS\Event\CustomFields\GetTypesEvent;
|
||||
use Joomla\CMS\Event\CustomFields\PrepareDomEvent;
|
||||
use Joomla\CMS\Event\CustomFields\PrepareFieldEvent;
|
||||
use Joomla\CMS\Event\Model\PrepareFormEvent;
|
||||
use Joomla\CMS\Filesystem\Folder;
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Plugin\CMSPlugin;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Abstract Fields Plugin
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
abstract class FieldsPlugin extends CMSPlugin
|
||||
{
|
||||
/**
|
||||
* Affects constructor behavior. If true, language files will be loaded automatically.
|
||||
*
|
||||
* @var boolean
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $autoloadLanguage = true;
|
||||
|
||||
/**
|
||||
* Application object.
|
||||
*
|
||||
* @var \Joomla\CMS\Application\CMSApplication
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* Returns an array of events this subscriber will listen to.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
'onCustomFieldsGetTypes' => 'getFieldTypes',
|
||||
'onCustomFieldsPrepareField' => 'prepareField',
|
||||
'onCustomFieldsPrepareDom' => 'prepareDom',
|
||||
'onContentPrepareForm' => 'prepareForm',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the custom fields types.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function getFieldTypes(GetTypesEvent $event)
|
||||
{
|
||||
$result = $this->onCustomFieldsGetTypes();
|
||||
|
||||
if ($result) {
|
||||
$event->addResult($result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the field value.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function prepareField(PrepareFieldEvent $event)
|
||||
{
|
||||
$result = $this->onCustomFieldsPrepareField($event->getContext(), $event->getItem(), $event->getField());
|
||||
|
||||
if ($result) {
|
||||
$event->addResult($result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the field into a DOM XML element and appends it as a child on the given parent.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function prepareDom(PrepareDomEvent $event)
|
||||
{
|
||||
$this->onCustomFieldsPrepareDom($event->getField(), $event->getFieldset(), $event->getForm());
|
||||
}
|
||||
|
||||
/**
|
||||
* The form event. Load additional parameters when available into the field form.
|
||||
* Only when the type of the form is of interest.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function prepareForm(PrepareFormEvent $event)
|
||||
{
|
||||
$this->onContentPrepareForm($event->getForm(), $event->getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the custom fields types.
|
||||
*
|
||||
* @return string[][]
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function onCustomFieldsGetTypes()
|
||||
{
|
||||
// Cache filesystem access / checks
|
||||
static $types_cache = [];
|
||||
|
||||
if (isset($types_cache[$this->_type . $this->_name])) {
|
||||
return $types_cache[$this->_type . $this->_name];
|
||||
}
|
||||
|
||||
$types = [];
|
||||
|
||||
// The root of the plugin
|
||||
$root = JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name;
|
||||
|
||||
foreach (Folder::files($root . '/tmpl', '.php') as $layout) {
|
||||
// Strip the extension
|
||||
$layout = str_replace('.php', '', $layout);
|
||||
|
||||
// The data array
|
||||
$data = [];
|
||||
|
||||
// The language key
|
||||
$key = strtoupper($layout);
|
||||
|
||||
if ($key != strtoupper($this->_name)) {
|
||||
$key = strtoupper($this->_name) . '_' . $layout;
|
||||
}
|
||||
|
||||
// Needed attributes
|
||||
$data['type'] = $layout;
|
||||
|
||||
if ($this->app->getLanguage()->hasKey('PLG_FIELDS_' . $key . '_LABEL')) {
|
||||
$data['label'] = Text::sprintf('PLG_FIELDS_' . $key . '_LABEL', strtolower($key));
|
||||
|
||||
// Fix wrongly set parentheses in RTL languages
|
||||
if ($this->app->getLanguage()->isRtl()) {
|
||||
$data['label'] .= '‎';
|
||||
}
|
||||
} else {
|
||||
$data['label'] = $key;
|
||||
}
|
||||
|
||||
$path = $root . '/fields';
|
||||
|
||||
// Add the path when it exists
|
||||
if (file_exists($path)) {
|
||||
$data['path'] = $path;
|
||||
}
|
||||
|
||||
$path = $root . '/rules';
|
||||
|
||||
// Add the path when it exists
|
||||
if (file_exists($path)) {
|
||||
$data['rules'] = $path;
|
||||
}
|
||||
|
||||
$types[] = $data;
|
||||
}
|
||||
|
||||
// Add to cache and return the data
|
||||
$types_cache[$this->_type . $this->_name] = $types;
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the field value.
|
||||
*
|
||||
* @param string $context The context.
|
||||
* @param \stdclass $item The item.
|
||||
* @param \stdclass $field The field.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function onCustomFieldsPrepareField($context, $item, $field)
|
||||
{
|
||||
// Check if the field should be processed by us
|
||||
if (!$this->isTypeSupported($field->type)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Merge the params from the plugin and field which has precedence
|
||||
$fieldParams = clone $this->params;
|
||||
$fieldParams->merge($field->fieldparams);
|
||||
|
||||
// Get the path for the layout file
|
||||
$path = PluginHelper::getLayoutPath('fields', $this->_name, $field->type);
|
||||
|
||||
// Render the layout
|
||||
ob_start();
|
||||
include $path;
|
||||
$output = ob_get_clean();
|
||||
|
||||
// Return the output
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the field into a DOM XML element and appends it as a child on the given parent.
|
||||
*
|
||||
* @param \stdClass $field The field.
|
||||
* @param \DOMElement $parent The field node parent.
|
||||
* @param Form $form The form.
|
||||
*
|
||||
* @return \DOMElement
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function onCustomFieldsPrepareDom($field, \DOMElement $parent, Form $form)
|
||||
{
|
||||
// Check if the field should be processed by us
|
||||
if (!$this->isTypeSupported($field->type)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Detect if the field is configured to be displayed on the form
|
||||
if (!FieldsHelper::displayFieldOnForm($field)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create the node
|
||||
$node = $parent->appendChild(new \DOMElement('field'));
|
||||
|
||||
// Set the attributes
|
||||
$node->setAttribute('name', $field->name);
|
||||
$node->setAttribute('type', $field->type);
|
||||
$node->setAttribute('label', $field->label);
|
||||
$node->setAttribute('labelclass', $field->params->get('label_class', ''));
|
||||
$node->setAttribute('description', $field->description);
|
||||
$node->setAttribute('class', $field->params->get('class', ''));
|
||||
$node->setAttribute('hint', $field->params->get('hint', ''));
|
||||
$node->setAttribute('required', $field->required ? 'true' : 'false');
|
||||
|
||||
$showon_attribute = $field->params->get('showon', '');
|
||||
if ($showon_attribute) {
|
||||
$node->setAttribute('showon', $showon_attribute);
|
||||
}
|
||||
|
||||
if ($layout = $field->params->get('form_layout')) {
|
||||
$node->setAttribute('layout', $layout);
|
||||
}
|
||||
|
||||
if ($field->default_value !== '') {
|
||||
$defaultNode = $node->appendChild(new \DOMElement('default'));
|
||||
$defaultNode->appendChild(new \DOMCdataSection($field->default_value));
|
||||
}
|
||||
|
||||
// Combine the two params
|
||||
$params = clone $this->params;
|
||||
$params->merge($field->fieldparams);
|
||||
|
||||
// Set the specific field parameters
|
||||
foreach ($params->toArray() as $key => $param) {
|
||||
if (\is_array($param)) {
|
||||
// Multidimensional arrays (eg. list options) can't be transformed properly
|
||||
$param = \count($param) == \count($param, COUNT_RECURSIVE) ? implode(',', $param) : '';
|
||||
}
|
||||
|
||||
if ($param === '' || (!\is_string($param) && !is_numeric($param))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$node->setAttribute($key, $param);
|
||||
}
|
||||
|
||||
// Check if it is allowed to edit the field
|
||||
if (!FieldsHelper::canEditFieldValue($field)) {
|
||||
$node->setAttribute('disabled', 'true');
|
||||
}
|
||||
|
||||
// Return the node
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* The form event. Load additional parameters when available into the field form.
|
||||
* Only when the type of the form is of interest.
|
||||
*
|
||||
* @param Form $form The form
|
||||
* @param \stdClass $data The data
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function onContentPrepareForm(Form $form, $data)
|
||||
{
|
||||
$path = $this->getFormPath($form, $data);
|
||||
|
||||
if ($path === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the specific plugin parameters
|
||||
$form->load(file_get_contents($path), true, '/form/*');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path of the XML definition file for the field parameters
|
||||
*
|
||||
* @param Form $form The form
|
||||
* @param \stdClass $data The data
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected function getFormPath(Form $form, $data)
|
||||
{
|
||||
// Check if the field form is calling us
|
||||
if (strpos($form->getName(), 'com_fields.field') !== 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Ensure it is an object
|
||||
$formData = (object) $data;
|
||||
|
||||
// Gather the type
|
||||
$type = $form->getValue('type');
|
||||
|
||||
if (!empty($formData->type)) {
|
||||
$type = $formData->type;
|
||||
}
|
||||
|
||||
// Not us
|
||||
if (!$this->isTypeSupported($type)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$path = JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name . '/params/' . $type . '.xml';
|
||||
|
||||
// Check if params file exists
|
||||
if (!file_exists($path)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given type is supported by the plugin.
|
||||
*
|
||||
* @param string $type The type
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function isTypeSupported($type)
|
||||
{
|
||||
foreach ($this->onCustomFieldsGetTypes() as $typeSpecification) {
|
||||
if ($type == $typeSpecification['type']) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
323
administrator/components/com_fields/src/Table/FieldTable.php
Normal file
323
administrator/components/com_fields/src/Table/FieldTable.php
Normal file
@ -0,0 +1,323 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Table;
|
||||
|
||||
use Joomla\CMS\Access\Rules;
|
||||
use Joomla\CMS\Application\ApplicationHelper;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Table\Table;
|
||||
use Joomla\CMS\User\CurrentUserInterface;
|
||||
use Joomla\CMS\User\CurrentUserTrait;
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
use Joomla\Registry\Registry;
|
||||
use Joomla\String\StringHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Fields Table
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class FieldTable extends Table implements CurrentUserInterface
|
||||
{
|
||||
use CurrentUserTrait;
|
||||
|
||||
/**
|
||||
* Indicates that columns fully support the NULL value in the database
|
||||
*
|
||||
* @var boolean
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected $_supportNullValue = true;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param DatabaseDriver $db Database connector object
|
||||
* @param ?DispatcherInterface $dispatcher Event dispatcher for this table
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db, DispatcherInterface $dispatcher = null)
|
||||
{
|
||||
parent::__construct('#__fields', 'id', $db, $dispatcher);
|
||||
|
||||
$this->setColumnAlias('published', 'state');
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to bind an associative array or object to the \Joomla\CMS\Table\Table instance.This
|
||||
* method only binds properties that are publicly accessible and optionally
|
||||
* takes an array of properties to ignore when binding.
|
||||
*
|
||||
* @param mixed $src An associative array or object to bind to the \Joomla\CMS\Table\Table instance.
|
||||
* @param mixed $ignore An optional array or space separated list of properties to ignore while binding.
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function bind($src, $ignore = '')
|
||||
{
|
||||
if (isset($src['params']) && \is_array($src['params'])) {
|
||||
$registry = new Registry();
|
||||
$registry->loadArray($src['params']);
|
||||
$src['params'] = (string) $registry;
|
||||
}
|
||||
|
||||
if (isset($src['fieldparams']) && \is_array($src['fieldparams'])) {
|
||||
// Make sure $registry->options contains no duplicates when the field type is subform
|
||||
if (isset($src['type']) && $src['type'] == 'subform' && isset($src['fieldparams']['options'])) {
|
||||
// Fast lookup map to check which custom field ids we have already seen
|
||||
$seen_customfields = [];
|
||||
|
||||
// Container for the new $src['fieldparams']['options']
|
||||
$options = [];
|
||||
|
||||
// Iterate through the old options
|
||||
$i = 0;
|
||||
|
||||
foreach ($src['fieldparams']['options'] as $option) {
|
||||
// Check whether we have not yet seen this custom field id
|
||||
if (!isset($seen_customfields[$option['customfield']])) {
|
||||
// We haven't, so add it to the final options
|
||||
$seen_customfields[$option['customfield']] = true;
|
||||
$options['option' . $i] = $option;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
// And replace the options with the deduplicated ones.
|
||||
$src['fieldparams']['options'] = $options;
|
||||
}
|
||||
|
||||
$registry = new Registry();
|
||||
$registry->loadArray($src['fieldparams']);
|
||||
$src['fieldparams'] = (string) $registry;
|
||||
}
|
||||
|
||||
// Bind the rules.
|
||||
if (isset($src['rules']) && \is_array($src['rules'])) {
|
||||
$rules = new Rules($src['rules']);
|
||||
$this->setRules($rules);
|
||||
}
|
||||
|
||||
return parent::bind($src, $ignore);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to perform sanity checks on the \Joomla\CMS\Table\Table instance properties to ensure
|
||||
* they are safe to store in the database. Child classes should override this
|
||||
* method to make sure the data they are storing in the database is safe and
|
||||
* as expected before storage.
|
||||
*
|
||||
* @return boolean True if the instance is sane and able to be stored in the database.
|
||||
*
|
||||
* @link https://docs.joomla.org/Special:MyLanguage/JTable/check
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
// Check for valid name
|
||||
if (trim($this->title) == '') {
|
||||
$this->setError(Text::_('COM_FIELDS_MUSTCONTAIN_A_TITLE_FIELD'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (empty($this->name)) {
|
||||
$this->name = $this->title;
|
||||
}
|
||||
|
||||
$this->name = ApplicationHelper::stringURLSafe($this->name, $this->language);
|
||||
|
||||
if (trim(str_replace('-', '', $this->name)) == '') {
|
||||
$this->name = StringHelper::increment($this->name, 'dash');
|
||||
}
|
||||
|
||||
$this->name = str_replace(',', '-', $this->name);
|
||||
|
||||
// Verify that the name is unique
|
||||
$table = new self($this->_db, $this->getDispatcher());
|
||||
|
||||
if ($table->load(['name' => $this->name]) && ($table->id != $this->id || $this->id == 0)) {
|
||||
$this->setError(Text::_('COM_FIELDS_ERROR_UNIQUE_NAME'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->name = str_replace(',', '-', $this->name);
|
||||
|
||||
if (empty($this->type)) {
|
||||
$this->type = 'text';
|
||||
}
|
||||
|
||||
if (empty($this->fieldparams)) {
|
||||
$this->fieldparams = '{}';
|
||||
}
|
||||
|
||||
$date = Factory::getDate()->toSql();
|
||||
$user = $this->getCurrentUser();
|
||||
|
||||
// Set created date if not set.
|
||||
if (!(int) $this->created_time) {
|
||||
$this->created_time = $date;
|
||||
}
|
||||
|
||||
if ($this->id) {
|
||||
// Existing item
|
||||
$this->modified_time = $date;
|
||||
$this->modified_by = $user->get('id');
|
||||
} else {
|
||||
if (!(int) $this->modified_time) {
|
||||
$this->modified_time = $this->created_time;
|
||||
}
|
||||
|
||||
if (empty($this->created_user_id)) {
|
||||
$this->created_user_id = $user->get('id');
|
||||
}
|
||||
|
||||
if (empty($this->modified_by)) {
|
||||
$this->modified_by = $this->created_user_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->group_id)) {
|
||||
$this->group_id = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded store function
|
||||
*
|
||||
* @param boolean $updateNulls True to update fields even if they are null.
|
||||
*
|
||||
* @return mixed False on failure, positive integer on success.
|
||||
*
|
||||
* @see Table::store()
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function store($updateNulls = true)
|
||||
{
|
||||
return parent::store($updateNulls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to compute the default name of the asset.
|
||||
* The default name is in the form table_name.id
|
||||
* where id is the value of the primary key of the table.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function _getAssetName()
|
||||
{
|
||||
$contextArray = explode('.', $this->context);
|
||||
|
||||
return $contextArray[0] . '.field.' . (int) $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to return the title to use for the asset table. In
|
||||
* tracking the assets a title is kept for each asset so that there is some
|
||||
* context available in a unified access manager. Usually this would just
|
||||
* return $this->title or $this->name or whatever is being used for the
|
||||
* primary name of the row. If this method is not overridden, the asset name is used.
|
||||
*
|
||||
* @return string The string to use as the title in the asset table.
|
||||
*
|
||||
* @link https://docs.joomla.org/Special:MyLanguage/JTable/getAssetTitle
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function _getAssetTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the parent asset under which to register this one.
|
||||
* By default, all assets are registered to the ROOT node with ID,
|
||||
* which will default to 1 if none exists.
|
||||
* The extended class can define a table and id to lookup. If the
|
||||
* asset does not exist it will be created.
|
||||
*
|
||||
* @param Table $table A Table object for the asset parent.
|
||||
* @param integer $id Id to look up
|
||||
*
|
||||
* @return integer
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function _getAssetParentId(Table $table = null, $id = null)
|
||||
{
|
||||
$contextArray = explode('.', $this->context);
|
||||
$component = $contextArray[0];
|
||||
|
||||
if ($this->group_id) {
|
||||
$assetId = $this->getAssetId($component . '.fieldgroup.' . (int) $this->group_id);
|
||||
|
||||
if ($assetId) {
|
||||
return $assetId;
|
||||
}
|
||||
} else {
|
||||
$assetId = $this->getAssetId($component);
|
||||
|
||||
if ($assetId) {
|
||||
return $assetId;
|
||||
}
|
||||
}
|
||||
|
||||
return parent::_getAssetParentId($table, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an asset id for the given name or false.
|
||||
*
|
||||
* @param string $name The asset name
|
||||
*
|
||||
* @return number|boolean
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
private function getAssetId($name)
|
||||
{
|
||||
$db = $this->getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('id'))
|
||||
->from($db->quoteName('#__assets'))
|
||||
->where($db->quoteName('name') . ' = :name')
|
||||
->bind(':name', $name);
|
||||
|
||||
// Get the asset id from the database.
|
||||
$db->setQuery($query);
|
||||
|
||||
$assetId = null;
|
||||
|
||||
if ($result = $db->loadResult()) {
|
||||
$assetId = (int) $result;
|
||||
|
||||
if ($assetId) {
|
||||
return $assetId;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
220
administrator/components/com_fields/src/Table/GroupTable.php
Normal file
220
administrator/components/com_fields/src/Table/GroupTable.php
Normal file
@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Table;
|
||||
|
||||
use Joomla\CMS\Access\Rules;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Table\Table;
|
||||
use Joomla\CMS\User\CurrentUserInterface;
|
||||
use Joomla\CMS\User\CurrentUserTrait;
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Groups Table
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class GroupTable extends Table implements CurrentUserInterface
|
||||
{
|
||||
use CurrentUserTrait;
|
||||
|
||||
/**
|
||||
* Indicates that columns fully support the NULL value in the database
|
||||
*
|
||||
* @var boolean
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected $_supportNullValue = true;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param DatabaseDriver $db Database connector object
|
||||
* @param ?DispatcherInterface $dispatcher Event dispatcher for this table
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db, DispatcherInterface $dispatcher = null)
|
||||
{
|
||||
parent::__construct('#__fields_groups', 'id', $db, $dispatcher);
|
||||
|
||||
$this->setColumnAlias('published', 'state');
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to bind an associative array or object to the \Joomla\CMS\Table\Table instance.This
|
||||
* method only binds properties that are publicly accessible and optionally
|
||||
* takes an array of properties to ignore when binding.
|
||||
*
|
||||
* @param mixed $src An associative array or object to bind to the \Joomla\CMS\Table\Table instance.
|
||||
* @param mixed $ignore An optional array or space separated list of properties to ignore while binding.
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function bind($src, $ignore = '')
|
||||
{
|
||||
if (isset($src['params']) && \is_array($src['params'])) {
|
||||
$registry = new Registry();
|
||||
$registry->loadArray($src['params']);
|
||||
$src['params'] = (string) $registry;
|
||||
}
|
||||
|
||||
// Bind the rules.
|
||||
if (isset($src['rules']) && \is_array($src['rules'])) {
|
||||
$rules = new Rules($src['rules']);
|
||||
$this->setRules($rules);
|
||||
}
|
||||
|
||||
return parent::bind($src, $ignore);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to perform sanity checks on the \Joomla\CMS\Table\Table instance properties to ensure
|
||||
* they are safe to store in the database. Child classes should override this
|
||||
* method to make sure the data they are storing in the database is safe and
|
||||
* as expected before storage.
|
||||
*
|
||||
* @return boolean True if the instance is sane and able to be stored in the database.
|
||||
*
|
||||
* @link https://docs.joomla.org/Special:MyLanguage/JTable/check
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
// Check for a title.
|
||||
if (trim($this->title) == '') {
|
||||
$this->setError(Text::_('COM_FIELDS_MUSTCONTAIN_A_TITLE_GROUP'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$date = Factory::getDate()->toSql();
|
||||
$user = $this->getCurrentUser();
|
||||
|
||||
// Set created date if not set.
|
||||
if (!(int) $this->created) {
|
||||
$this->created = $date;
|
||||
}
|
||||
|
||||
if ($this->id) {
|
||||
$this->modified = $date;
|
||||
$this->modified_by = $user->get('id');
|
||||
} else {
|
||||
if (!(int) $this->modified) {
|
||||
$this->modified = $this->created;
|
||||
}
|
||||
|
||||
if (empty($this->created_by)) {
|
||||
$this->created_by = $user->get('id');
|
||||
}
|
||||
|
||||
if (empty($this->modified_by)) {
|
||||
$this->modified_by = $this->created_by;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->params === null) {
|
||||
$this->params = '{}';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded store function
|
||||
*
|
||||
* @param boolean $updateNulls True to update fields even if they are null.
|
||||
*
|
||||
* @return mixed False on failure, positive integer on success.
|
||||
*
|
||||
* @see Table::store()
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function store($updateNulls = true)
|
||||
{
|
||||
return parent::store($updateNulls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to compute the default name of the asset.
|
||||
* The default name is in the form table_name.id
|
||||
* where id is the value of the primary key of the table.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function _getAssetName()
|
||||
{
|
||||
$component = explode('.', $this->context);
|
||||
|
||||
return $component[0] . '.fieldgroup.' . (int) $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to return the title to use for the asset table. In
|
||||
* tracking the assets a title is kept for each asset so that there is some
|
||||
* context available in a unified access manager. Usually this would just
|
||||
* return $this->title or $this->name or whatever is being used for the
|
||||
* primary name of the row. If this method is not overridden, the asset name is used.
|
||||
*
|
||||
* @return string The string to use as the title in the asset table.
|
||||
*
|
||||
* @link https://docs.joomla.org/Special:MyLanguage/JTable/getAssetTitle
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function _getAssetTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the parent asset under which to register this one.
|
||||
* By default, all assets are registered to the ROOT node with ID,
|
||||
* which will default to 1 if none exists.
|
||||
* The extended class can define a table and id to lookup. If the
|
||||
* asset does not exist it will be created.
|
||||
*
|
||||
* @param Table $table A Table object for the asset parent.
|
||||
* @param integer $id Id to look up
|
||||
*
|
||||
* @return integer
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function _getAssetParentId(Table $table = null, $id = null)
|
||||
{
|
||||
$component = explode('.', $this->context);
|
||||
$db = $this->getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('id'))
|
||||
->from($db->quoteName('#__assets'))
|
||||
->where($db->quoteName('name') . ' = :name')
|
||||
->bind(':name', $component[0]);
|
||||
$db->setQuery($query);
|
||||
|
||||
if ($assetId = (int) $db->loadResult()) {
|
||||
return $assetId;
|
||||
}
|
||||
|
||||
return parent::_getAssetParentId($table, $id);
|
||||
}
|
||||
}
|
||||
167
administrator/components/com_fields/src/View/Field/HtmlView.php
Normal file
167
administrator/components/com_fields/src/View/Field/HtmlView.php
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\View\Field;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Helper\ContentHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Object\CMSObject;
|
||||
use Joomla\CMS\Toolbar\Toolbar;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
use Joomla\Filesystem\Path;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Field View
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* @var CMSObject
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $item;
|
||||
|
||||
/**
|
||||
* @var \Joomla\Registry\Registry
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @see HtmlView::loadTemplate()
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->form = $this->get('Form');
|
||||
$this->item = $this->get('Item');
|
||||
$this->state = $this->get('State');
|
||||
|
||||
$this->canDo = ContentHelper::getActions($this->state->get('field.component'), 'field', $this->item->id);
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
Factory::getApplication()->getInput()->set('hidemainmenu', true);
|
||||
|
||||
$this->addToolbar();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the toolbar.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function addToolbar()
|
||||
{
|
||||
$component = $this->state->get('field.component');
|
||||
$section = $this->state->get('field.section');
|
||||
$userId = $this->getCurrentUser()->get('id');
|
||||
$canDo = $this->canDo;
|
||||
$toolbar = Toolbar::getInstance();
|
||||
|
||||
$isNew = ($this->item->id == 0);
|
||||
$checkedOut = !(\is_null($this->item->checked_out) || $this->item->checked_out == $userId);
|
||||
|
||||
// Avoid nonsense situation.
|
||||
if ($component == 'com_fields') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load component language file
|
||||
$lang = $this->getLanguage();
|
||||
$lang->load($component, JPATH_ADMINISTRATOR)
|
||||
|| $lang->load($component, Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component));
|
||||
|
||||
$title = Text::sprintf('COM_FIELDS_VIEW_FIELD_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE', Text::_(strtoupper($component)));
|
||||
|
||||
// Prepare the toolbar.
|
||||
ToolbarHelper::title(
|
||||
$title,
|
||||
'puzzle field-' . ($isNew ? 'add' : 'edit') . ' ' . substr($component, 4) . ($section ? "-$section" : '') . '-field-' .
|
||||
($isNew ? 'add' : 'edit')
|
||||
);
|
||||
|
||||
// For new records, check the create permission.
|
||||
if ($isNew) {
|
||||
$toolbar->apply('field.apply');
|
||||
$saveGroup = $toolbar->dropdownButton('save-group');
|
||||
$saveGroup->configure(
|
||||
function (Toolbar $childBar) {
|
||||
$childBar->save('field.save');
|
||||
$childBar->save2new('field.save2new');
|
||||
}
|
||||
);
|
||||
$toolbar->cancel('field.cancel', 'JTOOLBAR_CANCEL');
|
||||
} else {
|
||||
// Since it's an existing record, check the edit permission, or fall back to edit own if the owner.
|
||||
$itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId);
|
||||
|
||||
// Can't save the record if it's checked out and editable
|
||||
if (!$checkedOut && $itemEditable) {
|
||||
$toolbar->apply('field.apply');
|
||||
}
|
||||
|
||||
$saveGroup = $toolbar->dropdownButton('save-group');
|
||||
$saveGroup->configure(
|
||||
function (Toolbar $childBar) use ($checkedOut, $itemEditable, $canDo) {
|
||||
if (!$checkedOut && $itemEditable) {
|
||||
$childBar->save('field.save');
|
||||
|
||||
// We can save this record, but check the create permission to see if we can return to make a new one.
|
||||
if ($canDo->get('core.create')) {
|
||||
$childBar->save2new('field.save2new');
|
||||
}
|
||||
}
|
||||
|
||||
// If an existing item, can save to a copy.
|
||||
if ($canDo->get('core.create')) {
|
||||
$childBar->save2copy('field.save2copy');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$toolbar->cancel('field.cancel');
|
||||
}
|
||||
|
||||
$toolbar->help('Fields:_Edit');
|
||||
}
|
||||
}
|
||||
195
administrator/components/com_fields/src/View/Fields/HtmlView.php
Normal file
195
administrator/components/com_fields/src/View/Fields/HtmlView.php
Normal file
@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\View\Fields;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Helper\ContentHelper;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Toolbar\Button\DropdownButton;
|
||||
use Joomla\CMS\Toolbar\Toolbar;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
|
||||
use Joomla\Filesystem\Path;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Fields View
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public $filterForm;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public $activeFilters;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $items;
|
||||
|
||||
/**
|
||||
* @var \Joomla\CMS\Pagination\Pagination
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $pagination;
|
||||
|
||||
/**
|
||||
* @var \Joomla\Registry\Registry
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @see \Joomla\CMS\MVC\View\HtmlView::loadTemplate()
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->state = $this->get('State');
|
||||
$this->items = $this->get('Items');
|
||||
$this->pagination = $this->get('Pagination');
|
||||
$this->filterForm = $this->get('FilterForm');
|
||||
$this->activeFilters = $this->get('ActiveFilters');
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
// Display a warning if the fields system plugin is disabled
|
||||
if (!PluginHelper::isEnabled('system', 'fields')) {
|
||||
$link = Route::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . FieldsHelper::getFieldsPluginId());
|
||||
Factory::getApplication()->enqueueMessage(Text::sprintf('COM_FIELDS_SYSTEM_PLUGIN_NOT_ENABLED', $link), 'warning');
|
||||
}
|
||||
|
||||
// Only add toolbar when not in modal window.
|
||||
if ($this->getLayout() !== 'modal') {
|
||||
$this->addToolbar();
|
||||
|
||||
// We do not need to filter by language when multilingual is disabled
|
||||
if (!Multilanguage::isEnabled()) {
|
||||
unset($this->activeFilters['language']);
|
||||
$this->filterForm->removeField('language', 'filter');
|
||||
}
|
||||
}
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the toolbar.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function addToolbar()
|
||||
{
|
||||
$fieldId = $this->state->get('filter.field_id');
|
||||
$component = $this->state->get('filter.component');
|
||||
$section = $this->state->get('filter.section');
|
||||
$canDo = ContentHelper::getActions($component, 'field', $fieldId);
|
||||
$toolbar = Toolbar::getInstance();
|
||||
|
||||
// Avoid nonsense situation.
|
||||
if ($component == 'com_fields') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load extension language file
|
||||
$lang = $this->getLanguage();
|
||||
$lang->load($component, JPATH_ADMINISTRATOR)
|
||||
|| $lang->load($component, Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component));
|
||||
|
||||
$title = Text::sprintf('COM_FIELDS_VIEW_FIELDS_TITLE', Text::_(strtoupper($component)));
|
||||
|
||||
// Prepare the toolbar.
|
||||
ToolbarHelper::title($title, 'puzzle-piece fields ' . substr($component, 4) . ($section ? "-$section" : '') . '-fields');
|
||||
|
||||
if ($canDo->get('core.create')) {
|
||||
$toolbar->addNew('field.add');
|
||||
}
|
||||
|
||||
if ($canDo->get('core.edit.state') || $this->getCurrentUser()->authorise('core.admin')) {
|
||||
/** @var DropdownButton $dropdown */
|
||||
$dropdown = $toolbar->dropdownButton('status-group', 'JTOOLBAR_CHANGE_STATUS')
|
||||
->toggleSplit(false)
|
||||
->icon('icon-ellipsis-h')
|
||||
->buttonClass('btn btn-action')
|
||||
->listCheck(true);
|
||||
|
||||
$childBar = $dropdown->getChildToolbar();
|
||||
|
||||
if ($canDo->get('core.edit.state')) {
|
||||
$childBar->publish('fields.publish')->listCheck(true);
|
||||
$childBar->unpublish('fields.unpublish')->listCheck(true);
|
||||
$childBar->archive('fields.archive')->listCheck(true);
|
||||
}
|
||||
|
||||
if ($this->getCurrentUser()->authorise('core.admin')) {
|
||||
$childBar->checkin('fields.checkin')->listCheck(true);
|
||||
}
|
||||
|
||||
if ($canDo->get('core.edit.state') && !$this->state->get('filter.state') == -2) {
|
||||
$childBar->trash('fields.trash')->listCheck(true);
|
||||
}
|
||||
|
||||
// Add a batch button
|
||||
if ($canDo->get('core.create') && $canDo->get('core.edit') && $canDo->get('core.edit.state')) {
|
||||
$childBar->popupButton('batch', 'JTOOLBAR_BATCH')
|
||||
->selector('collapseModal')
|
||||
->listCheck(true);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete', $component)) {
|
||||
$toolbar->delete('fields.delete', 'JTOOLBAR_EMPTY_TRASH')
|
||||
->message('JGLOBAL_CONFIRM_DELETE')
|
||||
->listCheck(true);
|
||||
}
|
||||
|
||||
if ($canDo->get('core.admin') || $canDo->get('core.options')) {
|
||||
$toolbar->preferences($component);
|
||||
}
|
||||
|
||||
$toolbar->help('Fields');
|
||||
}
|
||||
}
|
||||
189
administrator/components/com_fields/src/View/Group/HtmlView.php
Normal file
189
administrator/components/com_fields/src/View/Group/HtmlView.php
Normal file
@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\View\Group;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Helper\ContentHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Object\CMSObject;
|
||||
use Joomla\CMS\Toolbar\Toolbar;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
|
||||
use Joomla\Filesystem\Path;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Group View
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* @var CMSObject
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $item;
|
||||
|
||||
/**
|
||||
* @var \Joomla\Registry\Registry
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* The actions the user is authorised to perform
|
||||
*
|
||||
* @var \Joomla\Registry\Registry
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $canDo;
|
||||
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->form = $this->get('Form');
|
||||
$this->item = $this->get('Item');
|
||||
$this->state = $this->get('State');
|
||||
|
||||
$component = '';
|
||||
$parts = FieldsHelper::extract($this->state->get('filter.context'));
|
||||
|
||||
if ($parts) {
|
||||
$component = $parts[0];
|
||||
}
|
||||
|
||||
$this->canDo = ContentHelper::getActions($component, 'fieldgroup', $this->item->id);
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
$this->addToolbar();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the toolbar.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function addToolbar()
|
||||
{
|
||||
Factory::getApplication()->getInput()->set('hidemainmenu', true);
|
||||
|
||||
$component = '';
|
||||
$parts = FieldsHelper::extract($this->state->get('filter.context'));
|
||||
$toolbar = Toolbar::getInstance();
|
||||
|
||||
if ($parts) {
|
||||
$component = $parts[0];
|
||||
}
|
||||
|
||||
$userId = $this->getCurrentUser()->get('id');
|
||||
$canDo = $this->canDo;
|
||||
|
||||
$isNew = ($this->item->id == 0);
|
||||
$checkedOut = !(\is_null($this->item->checked_out) || $this->item->checked_out == $userId);
|
||||
|
||||
// Avoid nonsense situation.
|
||||
if ($component == 'com_fields') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load component language file
|
||||
$lang = $this->getLanguage();
|
||||
$lang->load($component, JPATH_ADMINISTRATOR)
|
||||
|| $lang->load($component, Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component));
|
||||
|
||||
$title = Text::sprintf('COM_FIELDS_VIEW_GROUP_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE', Text::_(strtoupper($component)));
|
||||
|
||||
// Prepare the toolbar.
|
||||
ToolbarHelper::title(
|
||||
$title,
|
||||
'puzzle-piece field-' . ($isNew ? 'add' : 'edit') . ' ' . substr($component, 4) . '-group-' .
|
||||
($isNew ? 'add' : 'edit')
|
||||
);
|
||||
|
||||
// For new records, check the create permission.
|
||||
if ($isNew) {
|
||||
$toolbar->apply('group.apply');
|
||||
$saveGroup = $toolbar->dropdownButton('save-group');
|
||||
|
||||
$saveGroup->configure(
|
||||
function (Toolbar $childBar) {
|
||||
$childBar->save('group.save');
|
||||
$childBar->save2new('group.save2new');
|
||||
}
|
||||
);
|
||||
|
||||
$toolbar->cancel('group.cancel', 'JTOOLBAR_CANCEL');
|
||||
} else {
|
||||
// Since it's an existing record, check the edit permission, or fall back to edit own if the owner.
|
||||
$itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId);
|
||||
|
||||
// Can't save the record if it's checked out and editable
|
||||
if (!$checkedOut && $itemEditable) {
|
||||
$toolbar->apply('group.apply');
|
||||
}
|
||||
|
||||
$saveGroup = $toolbar->dropdownButton('save-group');
|
||||
$saveGroup->configure(
|
||||
function (Toolbar $childBar) use ($checkedOut, $itemEditable, $canDo) {
|
||||
if (!$checkedOut && $itemEditable) {
|
||||
$childBar->save('group.save');
|
||||
|
||||
// We can save this record, but check the create permission to see if we can return to make a new one.
|
||||
if ($canDo->get('core.create')) {
|
||||
$childBar->save2new('group.save2new');
|
||||
}
|
||||
}
|
||||
|
||||
// If an existing item, can save to a copy.
|
||||
if ($canDo->get('core.create')) {
|
||||
$childBar->save2copy('group.save2copy');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$toolbar->cancel('group.cancel');
|
||||
}
|
||||
|
||||
$toolbar->help('Field_Groups:_Edit');
|
||||
}
|
||||
}
|
||||
197
administrator/components/com_fields/src/View/Groups/HtmlView.php
Normal file
197
administrator/components/com_fields/src/View/Groups/HtmlView.php
Normal file
@ -0,0 +1,197 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\View\Groups;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Helper\ContentHelper;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Toolbar\Button\DropdownButton;
|
||||
use Joomla\CMS\Toolbar\Toolbar;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
|
||||
use Joomla\Filesystem\Path;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Groups View
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public $filterForm;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public $activeFilters;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $items;
|
||||
|
||||
/**
|
||||
* @var \Joomla\CMS\Pagination\Pagination
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $pagination;
|
||||
|
||||
/**
|
||||
* @var \Joomla\Registry\Registry
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @see HtmlView::loadTemplate()
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->state = $this->get('State');
|
||||
$this->items = $this->get('Items');
|
||||
$this->pagination = $this->get('Pagination');
|
||||
$this->filterForm = $this->get('FilterForm');
|
||||
$this->activeFilters = $this->get('ActiveFilters');
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
// Display a warning if the fields system plugin is disabled
|
||||
if (!PluginHelper::isEnabled('system', 'fields')) {
|
||||
$link = Route::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . FieldsHelper::getFieldsPluginId());
|
||||
Factory::getApplication()->enqueueMessage(Text::sprintf('COM_FIELDS_SYSTEM_PLUGIN_NOT_ENABLED', $link), 'warning');
|
||||
}
|
||||
|
||||
$this->addToolbar();
|
||||
|
||||
// We do not need to filter by language when multilingual is disabled
|
||||
if (!Multilanguage::isEnabled()) {
|
||||
unset($this->activeFilters['language']);
|
||||
$this->filterForm->removeField('language', 'filter');
|
||||
}
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the toolbar.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected function addToolbar()
|
||||
{
|
||||
$toolbar = Toolbar::getInstance();
|
||||
$groupId = $this->state->get('filter.group_id');
|
||||
$component = '';
|
||||
$parts = FieldsHelper::extract($this->state->get('filter.context'));
|
||||
|
||||
if ($parts) {
|
||||
$component = $parts[0];
|
||||
}
|
||||
|
||||
$canDo = ContentHelper::getActions($component, 'fieldgroup', $groupId);
|
||||
|
||||
// Avoid nonsense situation.
|
||||
if ($component == 'com_fields') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load component language file
|
||||
$lang = $this->getLanguage();
|
||||
$lang->load($component, JPATH_ADMINISTRATOR)
|
||||
|| $lang->load($component, Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component));
|
||||
|
||||
$title = Text::sprintf('COM_FIELDS_VIEW_GROUPS_TITLE', Text::_(strtoupper($component)));
|
||||
|
||||
// Prepare the toolbar.
|
||||
ToolbarHelper::title($title, 'puzzle-piece fields ' . substr($component, 4) . '-groups');
|
||||
|
||||
if ($canDo->get('core.create')) {
|
||||
$toolbar->addNew('group.add');
|
||||
}
|
||||
|
||||
if ($canDo->get('core.edit.state') || $this->getCurrentUser()->authorise('core.admin')) {
|
||||
/** @var DropdownButton $dropdown */
|
||||
$dropdown = $toolbar->dropdownButton('status-group', 'JTOOLBAR_CHANGE_STATUS')
|
||||
->toggleSplit(false)
|
||||
->icon('icon-ellipsis-h')
|
||||
->buttonClass('btn btn-action')
|
||||
->listCheck(true);
|
||||
|
||||
$childBar = $dropdown->getChildToolbar();
|
||||
|
||||
if ($canDo->get('core.edit.state')) {
|
||||
$childBar->publish('groups.publish')->listCheck(true);
|
||||
$childBar->unpublish('groups.unpublish')->listCheck(true);
|
||||
$childBar->archive('groups.archive')->listCheck(true);
|
||||
}
|
||||
|
||||
if ($this->getCurrentUser()->authorise('core.admin')) {
|
||||
$childBar->checkin('groups.checkin')->listCheck(true);
|
||||
}
|
||||
|
||||
if ($canDo->get('core.edit.state') && !$this->state->get('filter.state') == -2) {
|
||||
$childBar->trash('groups.trash')->listCheck(true);
|
||||
}
|
||||
|
||||
// Add a batch button
|
||||
if ($canDo->get('core.create') && $canDo->get('core.edit') && $canDo->get('core.edit.state')) {
|
||||
$childBar->popupButton('batch', 'JTOOLBAR_BATCH')
|
||||
->selector('collapseModal')
|
||||
->listCheck(true);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete', $component)) {
|
||||
$toolbar->delete('groups.delete', 'JTOOLBAR_EMPTY_TRASH')
|
||||
->message('JGLOBAL_CONFIRM_DELETE')
|
||||
->listCheck(true);
|
||||
}
|
||||
|
||||
if ($canDo->get('core.admin') || $canDo->get('core.options')) {
|
||||
$toolbar->preferences($component);
|
||||
}
|
||||
|
||||
$toolbar->help('Field_Groups');
|
||||
}
|
||||
}
|
||||
102
administrator/components/com_fields/tmpl/field/edit.php
Normal file
102
administrator/components/com_fields/tmpl/field/edit.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
$app = Factory::getApplication();
|
||||
$input = $app->getInput();
|
||||
|
||||
$this->useCoreUI = true;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('keepalive')
|
||||
->useScript('form.validate')
|
||||
->useScript('com_fields.admin-field-edit');
|
||||
|
||||
?>
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_fields&context=' . $input->getCmd('context', 'com_content') . '&layout=edit&id=' . (int) $this->item->id); ?>" method="post" name="adminForm" id="item-form" aria-label="<?php echo Text::_('COM_FIELDS_FIELD_FORM_' . ((int) $this->item->id === 0 ? 'NEW' : 'EDIT'), true); ?>" class="form-validate">
|
||||
|
||||
<?php echo LayoutHelper::render('joomla.edit.title_alias', $this); ?>
|
||||
|
||||
<div class="main-card">
|
||||
<?php echo HTMLHelper::_('uitab.startTabSet', 'myTab', ['active' => 'general', 'recall' => true, 'breakpoint' => 768]); ?>
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'general', Text::_('COM_FIELDS_VIEW_FIELD_FIELDSET_GENERAL', true)); ?>
|
||||
<div class="row">
|
||||
<div class="col-lg-9">
|
||||
<?php echo $this->form->renderField('type'); ?>
|
||||
<?php echo $this->form->renderField('name'); ?>
|
||||
<?php echo $this->form->renderField('label'); ?>
|
||||
<?php echo $this->form->renderField('description'); ?>
|
||||
<?php echo $this->form->renderField('required'); ?>
|
||||
<?php echo $this->form->renderField('only_use_in_subform'); ?>
|
||||
<?php echo $this->form->renderField('default_value'); ?>
|
||||
|
||||
<?php foreach ($this->form->getFieldsets('fieldparams') as $name => $fieldSet) : ?>
|
||||
<?php foreach ($this->form->getFieldset($name) as $field) : ?>
|
||||
<?php echo $field->renderField(); ?>
|
||||
<?php endforeach; ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<?php $this->set(
|
||||
'fields',
|
||||
[
|
||||
[
|
||||
'published',
|
||||
'state',
|
||||
'enabled',
|
||||
],
|
||||
'group_id',
|
||||
'assigned_cat_ids',
|
||||
'access',
|
||||
'language',
|
||||
'note',
|
||||
]
|
||||
); ?>
|
||||
<?php echo LayoutHelper::render('joomla.edit.global', $this); ?>
|
||||
<?php $this->set('fields', null); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
<?php $this->set('ignore_fieldsets', ['fieldparams']); ?>
|
||||
<?php echo LayoutHelper::render('joomla.edit.params', $this); ?>
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'publishing', Text::_('JGLOBAL_FIELDSET_PUBLISHING', true)); ?>
|
||||
<fieldset id="fieldset-publishingdata" class="options-form">
|
||||
<legend><?php echo Text::_('JGLOBAL_FIELDSET_PUBLISHING'); ?></legend>
|
||||
<div>
|
||||
<?php echo LayoutHelper::render('joomla.edit.publishingdata', $this); ?>
|
||||
<?php echo $this->form->renderField('searchindexing'); ?>
|
||||
</div>
|
||||
</fieldset>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
<?php if ($this->canDo->get('core.admin')) : ?>
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'rules', Text::_('JGLOBAL_ACTION_PERMISSIONS_LABEL', true)); ?>
|
||||
<fieldset id="fieldset-rules" class="options-form">
|
||||
<legend><?php echo Text::_('JGLOBAL_ACTION_PERMISSIONS_LABEL'); ?></legend>
|
||||
<div>
|
||||
<?php echo $this->form->getInput('rules'); ?>
|
||||
</div>
|
||||
</fieldset>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo HTMLHelper::_('uitab.endTabSet'); ?>
|
||||
<?php echo $this->form->getInput('context'); ?>
|
||||
<input type="hidden" name="task" value="">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
</form>
|
||||
225
administrator/components/com_fields/tmpl/fields/default.php
Normal file
225
administrator/components/com_fields/tmpl/fields/default.php
Normal file
@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Categories\Categories;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Session\Session;
|
||||
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
|
||||
|
||||
/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('table.columns')
|
||||
->useScript('multiselect');
|
||||
|
||||
$app = Factory::getApplication();
|
||||
$user = $this->getCurrentUser();
|
||||
$userId = $user->get('id');
|
||||
$context = $this->escape($this->state->get('filter.context'));
|
||||
$component = $this->state->get('filter.component');
|
||||
$section = $this->state->get('filter.section');
|
||||
$listOrder = $this->escape($this->state->get('list.ordering'));
|
||||
$listDirn = $this->escape($this->state->get('list.direction'));
|
||||
$ordering = ($listOrder == 'a.ordering');
|
||||
$saveOrder = ($listOrder == 'a.ordering' && strtolower($listDirn) == 'asc');
|
||||
|
||||
// The category object of the component
|
||||
$category = Categories::getInstance(str_replace('com_', '', $component) . '.' . $section);
|
||||
|
||||
// If there is no category for the component and section, then check the component only
|
||||
if (!$category) {
|
||||
$category = Categories::getInstance(str_replace('com_', '', $component));
|
||||
}
|
||||
|
||||
if ($saveOrder && !empty($this->items)) {
|
||||
$saveOrderingUrl = 'index.php?option=com_fields&task=fields.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1';
|
||||
HTMLHelper::_('draggablelist.draggable');
|
||||
}
|
||||
|
||||
$searchToolsOptions = [];
|
||||
|
||||
// Only show field contexts filter if there are more than one option
|
||||
if (count($this->filterForm->getField('context')->options) > 1) {
|
||||
$searchToolsOptions['selectorFieldName'] = 'context';
|
||||
}
|
||||
?>
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_fields&view=fields&context=' . $this->state->get('filter.context')); ?>" method="post" name="adminForm" id="adminForm">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div id="j-main-container" class="j-main-container">
|
||||
<?php echo LayoutHelper::render('joomla.searchtools.default', ['view' => $this, 'options' => $searchToolsOptions]); ?>
|
||||
<?php if (empty($this->items)) : ?>
|
||||
<div class="alert alert-info">
|
||||
<span class="icon-info-circle" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('INFO'); ?></span>
|
||||
<?php echo Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<table class="table" id="fieldList">
|
||||
<caption class="visually-hidden">
|
||||
<?php echo Text::_('COM_FIELDS_FIELDS_TABLE_CAPTION'); ?>,
|
||||
<span id="orderedBy"><?php echo Text::_('JGLOBAL_SORTED_BY'); ?> </span>,
|
||||
<span id="filteredBy"><?php echo Text::_('JGLOBAL_FILTERED_BY'); ?></span>
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="w-1 text-center">
|
||||
<?php echo HTMLHelper::_('grid.checkall'); ?>
|
||||
</td>
|
||||
<th scope="col" class="w-1 text-center d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', '', 'a.ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING', 'icon-sort'); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-1 text-center">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JSTATUS', 'a.state', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGLOBAL_TITLE', 'a.title', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'COM_FIELDS_FIELD_TYPE_LABEL', 'a.type', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'COM_FIELDS_FIELD_GROUP_LABEL', 'g.title', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-10 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_ACCESS', 'a.access', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<?php if (Multilanguage::isEnabled()) : ?>
|
||||
<th scope="col" class="w-10 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_LANGUAGE', 'a.language', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<?php endif; ?>
|
||||
<th scope="col" class="w-5 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody <?php if ($saveOrder) :
|
||||
?> class="js-draggable" data-url="<?php echo $saveOrderingUrl; ?>" data-direction="<?php echo strtolower($listDirn); ?>" data-nested="true"<?php
|
||||
endif; ?>>
|
||||
<?php foreach ($this->items as $i => $item) : ?>
|
||||
<?php $ordering = ($listOrder == 'a.ordering'); ?>
|
||||
<?php $canEdit = $user->authorise('core.edit', $component . '.field.' . $item->id); ?>
|
||||
<?php $canCheckin = $user->authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || is_null($item->checked_out); ?>
|
||||
<?php $canEditOwn = $user->authorise('core.edit.own', $component . '.field.' . $item->id) && $item->created_user_id == $userId; ?>
|
||||
<?php $canChange = $user->authorise('core.edit.state', $component . '.field.' . $item->id) && $canCheckin; ?>
|
||||
<tr class="row<?php echo $i % 2; ?>" data-draggable-group="<?php echo $item->group_id; ?>" item-id="<?php echo $item->id; ?>">
|
||||
<td class="text-center">
|
||||
<?php echo HTMLHelper::_('grid.id', $i, $item->id, false, 'cid', 'cb', $item->title); ?>
|
||||
</td>
|
||||
<td class="text-center d-none d-md-table-cell">
|
||||
<?php $iconClass = ''; ?>
|
||||
<?php if (!$canChange) : ?>
|
||||
<?php $iconClass = ' inactive'; ?>
|
||||
<?php elseif (!$saveOrder) : ?>
|
||||
<?php $iconClass = ' inactive" title="' . Text::_('JORDERINGDISABLED'); ?>
|
||||
<?php endif; ?>
|
||||
<span class="sortable-handler<?php echo $iconClass; ?>">
|
||||
<span class="icon-ellipsis-v" aria-hidden="true"></span>
|
||||
</span>
|
||||
<?php if ($canChange && $saveOrder) : ?>
|
||||
<input type="text" class="hidden" name="order[]" size="5" value="<?php echo $item->ordering; ?>">
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<?php echo HTMLHelper::_('jgrid.published', $item->state, $i, 'fields.', $canChange, 'cb'); ?>
|
||||
</td>
|
||||
<th scope="row">
|
||||
<div class="break-word">
|
||||
<?php if ($item->checked_out) : ?>
|
||||
<?php echo HTMLHelper::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'fields.', $canCheckin); ?>
|
||||
<?php endif; ?>
|
||||
<?php if ($canEdit || $canEditOwn) : ?>
|
||||
<a href="<?php echo Route::_('index.php?option=com_fields&task=field.edit&id=' . $item->id . '&context=' . $context); ?>" title="<?php echo Text::_('JACTION_EDIT'); ?> <?php echo $this->escape($item->title); ?>">
|
||||
<?php echo $this->escape($item->title); ?></a>
|
||||
<?php else : ?>
|
||||
<?php echo $this->escape($item->title); ?>
|
||||
<?php endif; ?>
|
||||
<div class="small break-word">
|
||||
<?php if (empty($item->note)) : ?>
|
||||
<?php echo Text::sprintf('JGLOBAL_LIST_NAME', $this->escape($item->name)); ?>
|
||||
<?php else : ?>
|
||||
<?php echo Text::sprintf('JGLOBAL_LIST_NAME_NOTE', $this->escape($item->name), $this->escape($item->note)); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ($item->only_use_in_subform) : ?>
|
||||
<div class="small badge bg-secondary">
|
||||
<?php echo Text::_('COM_FIELDS_FIELD_ONLY_USE_IN_SUBFORM_BADGE'); ?>
|
||||
</div>
|
||||
<?php elseif ($category) : ?>
|
||||
<div class="small">
|
||||
<?php echo Text::_('JCATEGORY') . ': '; ?>
|
||||
<?php $categories = FieldsHelper::getAssignedCategoriesTitles($item->id); ?>
|
||||
<?php if ($categories) : ?>
|
||||
<?php echo implode(', ', $categories); ?>
|
||||
<?php else : ?>
|
||||
<?php $category_ids = FieldsHelper::getAssignedCategoriesIds($item->id); ?>
|
||||
<?php echo (in_array('-1', $category_ids)) ? Text::_('JNONE') : Text::_('JALL'); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</th>
|
||||
<td class="small">
|
||||
<?php echo $this->escape($item->type); ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo $this->escape($item->group_title); ?>
|
||||
</td>
|
||||
<td class="small d-none d-md-table-cell">
|
||||
<?php echo $this->escape($item->access_level); ?>
|
||||
</td>
|
||||
<?php if (Multilanguage::isEnabled()) : ?>
|
||||
<td class="small d-none d-md-table-cell">
|
||||
<?php echo LayoutHelper::render('joomla.content.language', $item); ?>
|
||||
</td>
|
||||
<?php endif; ?>
|
||||
<td class="d-none d-md-table-cell">
|
||||
<span><?php echo (int) $item->id; ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php // load the pagination. ?>
|
||||
<?php echo $this->pagination->getListFooter(); ?>
|
||||
|
||||
<?php // Load the batch processing form. ?>
|
||||
<?php
|
||||
if (
|
||||
$user->authorise('core.create', $component)
|
||||
&& $user->authorise('core.edit', $component)
|
||||
&& $user->authorise('core.edit.state', $component)
|
||||
) : ?>
|
||||
<?php echo HTMLHelper::_(
|
||||
'bootstrap.renderModal',
|
||||
'collapseModal',
|
||||
[
|
||||
'title' => Text::_('COM_FIELDS_VIEW_FIELDS_BATCH_OPTIONS'),
|
||||
'footer' => $this->loadTemplate('batch_footer')
|
||||
],
|
||||
$this->loadTemplate('batch_body')
|
||||
); ?>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<input type="hidden" name="task" value="">
|
||||
<input type="hidden" name="boxchecked" value="0">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
21
administrator/components/com_fields/tmpl/fields/default.xml
Normal file
21
administrator/components/com_fields/tmpl/fields/default.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<layout title="COM_FIELDS_FIELDS_VIEW_DEFAULT_TITLE">
|
||||
<message>
|
||||
<![CDATA[COM_FIELDS_FIELDS_VIEW_DEFAULT_DESC]]>
|
||||
</message>
|
||||
</layout>
|
||||
<fieldset name="request">
|
||||
<fields name="request">
|
||||
<field
|
||||
name="extension"
|
||||
type="ComponentsFields"
|
||||
label="COM_FIELDS_CHOOSE_CONTEXT_LABEL"
|
||||
required="true"
|
||||
addfieldprefix="Joomla\Component\Fields\Administrator\Field"
|
||||
>
|
||||
<option value="">COM_MENUS_OPTION_SELECT_CONTEXT</option>
|
||||
</field>
|
||||
</fields>
|
||||
</fieldset>
|
||||
</metadata>
|
||||
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('com_fields.admin-fields-batch');
|
||||
$wa->useScript('joomla.batch-copymove');
|
||||
|
||||
$context = $this->escape($this->state->get('filter.context'));
|
||||
?>
|
||||
|
||||
<div class="p-3">
|
||||
<div class="row">
|
||||
<?php if (Multilanguage::isEnabled()) : ?>
|
||||
<div class="form-group col-md-6">
|
||||
<div class="controls">
|
||||
<?php echo LayoutHelper::render('joomla.html.batch.language', []); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="form-group col-md-6">
|
||||
<div class="controls">
|
||||
<?php echo LayoutHelper::render('joomla.html.batch.access', []); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<div class="controls">
|
||||
<?php $options = [
|
||||
HTMLHelper::_('select.option', 'c', Text::_('JLIB_HTML_BATCH_COPY')),
|
||||
HTMLHelper::_('select.option', 'm', Text::_('JLIB_HTML_BATCH_MOVE'))
|
||||
];
|
||||
?>
|
||||
<label id="batch-choose-action-lbl" for="batch-group-id">
|
||||
<?php echo Text::_('COM_FIELDS_BATCH_GROUP_LABEL'); ?>
|
||||
</label>
|
||||
<div id="batch-choose-action" class="control-group">
|
||||
<select name="batch[group_id]" class="form-select" id="batch-group-id">
|
||||
<option value=""><?php echo Text::_('JLIB_HTML_BATCH_NO_CATEGORY'); ?></option>
|
||||
<option value="nogroup"><?php echo Text::_('COM_FIELDS_BATCH_GROUP_OPTION_NONE'); ?></option>
|
||||
<?php echo HTMLHelper::_('select.options', $this->get('Groups'), 'value', 'text'); ?>
|
||||
</select>
|
||||
</div>
|
||||
<div id="batch-copy-move">
|
||||
<?php echo Text::_('JLIB_HTML_BATCH_MOVE_QUESTION'); ?>
|
||||
<?php echo HTMLHelper::_('select.radiolist', $options, 'batch[move_copy]', '', 'value', 'text', 'm'); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
?>
|
||||
<button type="button" class="btn btn-secondary" onclick="document.getElementById('batch-field-id').value='';document.getElementById('batch-access').value='';document.getElementById('batch-language-id').value=''" data-bs-dismiss="modal">
|
||||
<?php echo Text::_('JCANCEL'); ?>
|
||||
</button>
|
||||
<button type="submit" class="btn btn-success" onclick="Joomla.submitbutton('field.batch');return false;">
|
||||
<?php echo Text::_('JGLOBAL_BATCH_PROCESS'); ?>
|
||||
</button>
|
||||
141
administrator/components/com_fields/tmpl/fields/modal.php
Normal file
141
administrator/components/com_fields/tmpl/fields/modal.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Session\Session;
|
||||
|
||||
if (Factory::getApplication()->isClient('site')) {
|
||||
Session::checkToken('get') or die(Text::_('JINVALID_TOKEN'));
|
||||
}
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('com_fields.admin-fields-modal')->useScript('modal-content-select');
|
||||
|
||||
$listOrder = $this->escape($this->state->get('list.ordering'));
|
||||
$listDirn = $this->escape($this->state->get('list.direction'));
|
||||
$editor = Factory::getApplication()->getInput()->get('editor', '', 'cmd');
|
||||
?>
|
||||
<div class="container-popup">
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_fields&view=fields&layout=modal&tmpl=component&editor=' . $editor . '&' . Session::getFormToken() . '=1'); ?>" method="post" name="adminForm" id="adminForm">
|
||||
|
||||
<?php echo LayoutHelper::render('joomla.searchtools.default', ['view' => $this]); ?>
|
||||
<?php if (empty($this->items)) : ?>
|
||||
<div class="alert alert-info">
|
||||
<span class="icon-info-circle" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('INFO'); ?></span>
|
||||
<?php echo Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<table class="table" id="fieldList">
|
||||
<caption class="visually-hidden">
|
||||
<?php echo Text::_('COM_FIELDS_FIELDS_TABLE_CAPTION'); ?>,
|
||||
<span id="orderedBy"><?php echo Text::_('JGLOBAL_SORTED_BY'); ?> </span>,
|
||||
<span id="filteredBy"><?php echo Text::_('JGLOBAL_FILTERED_BY'); ?></span>
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="w-1 text-center">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JSTATUS', 'a.state', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col" class="title">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGLOBAL_TITLE', 'a.title', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-15 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'COM_FIELDS_FIELD_GROUP_LABEL', 'g.title', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-10 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'COM_FIELDS_FIELD_TYPE_LABEL', 'a.type', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-10 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_ACCESS', 'a.access', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-10 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_LANGUAGE', 'a.language', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-1 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$iconStates = [
|
||||
-2 => 'icon-trash',
|
||||
0 => 'icon-times',
|
||||
1 => 'icon-check',
|
||||
2 => 'icon-folder',
|
||||
];
|
||||
foreach ($this->items as $i => $item) :
|
||||
$attrs = 'data-content-select data-content-type="com_fields.field"'
|
||||
. ' data-id="' . ((int) $item->id) . '"'
|
||||
. ' data-title="' . $this->escape($item->title) . '"'
|
||||
. ' data-name="' . $this->escape($item->name) . '"'
|
||||
. ' data-group="' . ((int) $item->group_id) . '"';
|
||||
|
||||
$attrs1 = $attrs;
|
||||
$attrs1 .= ' data-html="{field ' . ((int) $item->id) . '}"';
|
||||
$attrs2 = $attrs;
|
||||
$attrs2 .= ' data-html="{fieldgroup ' . ((int) $item->group_id) . '}"';
|
||||
|
||||
// @TODO: Remove onclick="" after full transition to postMessage()
|
||||
?>
|
||||
<tr class="row<?php echo $i % 2; ?>">
|
||||
<td class="text-center">
|
||||
<span class="tbody-icon">
|
||||
<span class="<?php echo $iconStates[$this->escape($item->state)]; ?>" aria-hidden="true"></span>
|
||||
</span>
|
||||
</td>
|
||||
<th scope="row" class="has-context">
|
||||
<button type="button" class="btn btn-sm btn-success w-100" <?php echo $attrs1; ?>
|
||||
onclick="Joomla.fieldIns('<?php echo $this->escape($item->id); ?>', '<?php echo $this->escape($editor); ?>');">
|
||||
<?php echo $this->escape($item->title); ?>
|
||||
</button>
|
||||
</th>
|
||||
<td class="small d-none d-md-table-cell">
|
||||
<button type="button" class="btn btn-sm btn-warning w-100" <?php echo $item->group_id ? $attrs2 : ''; ?>
|
||||
onclick="Joomla.fieldgroupIns('<?php echo $this->escape($item->group_id); ?>', '<?php echo $this->escape($editor); ?>');">
|
||||
<?php echo $item->group_id ? $this->escape($item->group_title) : Text::_('JNONE'); ?>
|
||||
</button>
|
||||
</td>
|
||||
<td class="small d-none d-md-table-cell">
|
||||
<?php echo $item->type; ?>
|
||||
</td>
|
||||
<td class="small d-none d-md-table-cell">
|
||||
<?php echo $this->escape($item->access_level); ?>
|
||||
</td>
|
||||
<td class="small d-none d-md-table-cell">
|
||||
<?php echo LayoutHelper::render('joomla.content.language', $item); ?>
|
||||
</td>
|
||||
<td class="d-none d-md-table-cell">
|
||||
<?php echo (int) $item->id; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php // load the pagination. ?>
|
||||
<?php echo $this->pagination->getListFooter(); ?>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<input type="hidden" name="task" value="">
|
||||
<input type="hidden" name="boxchecked" value="0">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
85
administrator/components/com_fields/tmpl/group/edit.php
Normal file
85
administrator/components/com_fields/tmpl/group/edit.php
Normal file
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('keepalive')
|
||||
->useScript('form.validate');
|
||||
|
||||
$app = Factory::getApplication();
|
||||
$input = $app->getInput();
|
||||
|
||||
$this->useCoreUI = true;
|
||||
|
||||
?>
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_fields&context=' . $this->state->get('filter.context') . '&layout=edit&id=' . (int) $this->item->id); ?>" method="post" name="adminForm" id="item-form" aria-label="<?php echo Text::_('COM_FIELDS_GROUP_FORM_' . ((int) $this->item->id === 0 ? 'NEW' : 'EDIT'), true); ?>" class="form-validate">
|
||||
<?php echo LayoutHelper::render('joomla.edit.title_alias', $this); ?>
|
||||
<div class="main-card form-horizontal">
|
||||
<?php echo HTMLHelper::_('uitab.startTabSet', 'myTab', ['active' => 'general', 'recall' => true, 'breakpoint' => 768]); ?>
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'general', Text::_('COM_FIELDS_VIEW_FIELD_FIELDSET_GENERAL', true)); ?>
|
||||
<div class="row">
|
||||
<div class="col-lg-9">
|
||||
<?php echo $this->form->renderField('label'); ?>
|
||||
<?php echo $this->form->renderField('description'); ?>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<?php $this->set(
|
||||
'fields',
|
||||
[
|
||||
[
|
||||
'published',
|
||||
'state',
|
||||
'enabled',
|
||||
],
|
||||
'access',
|
||||
'language',
|
||||
'note',
|
||||
]
|
||||
); ?>
|
||||
<?php echo LayoutHelper::render('joomla.edit.global', $this); ?>
|
||||
<?php $this->set('fields', null); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
<?php $this->set('ignore_fieldsets', ['fieldparams']); ?>
|
||||
<?php echo LayoutHelper::render('joomla.edit.params', $this); ?>
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'publishing', Text::_('JGLOBAL_FIELDSET_PUBLISHING', true)); ?>
|
||||
<fieldset id="fieldset-rules" class="options-form">
|
||||
<legend><?php echo Text::_('JGLOBAL_FIELDSET_PUBLISHING'); ?></legend>
|
||||
<div>
|
||||
<?php echo LayoutHelper::render('joomla.edit.publishingdata', $this); ?>
|
||||
</div>
|
||||
</fieldset>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
<?php if ($this->canDo->get('core.admin')) : ?>
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'rules', Text::_('JGLOBAL_ACTION_PERMISSIONS_LABEL', true)); ?>
|
||||
<fieldset id="fieldset-rules" class="options-form">
|
||||
<legend><?php echo Text::_('JGLOBAL_ACTION_PERMISSIONS_LABEL'); ?></legend>
|
||||
<div>
|
||||
<?php echo $this->form->getInput('rules'); ?>
|
||||
</div>
|
||||
</fieldset>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo HTMLHelper::_('uitab.endTabSet'); ?>
|
||||
<?php echo $this->form->getInput('context'); ?>
|
||||
<input type="hidden" name="task" value="">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
</form>
|
||||
193
administrator/components/com_fields/tmpl/groups/default.php
Normal file
193
administrator/components/com_fields/tmpl/groups/default.php
Normal file
@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Session\Session;
|
||||
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
|
||||
|
||||
/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('table.columns')
|
||||
->useScript('multiselect');
|
||||
|
||||
$app = Factory::getApplication();
|
||||
$user = $this->getCurrentUser();
|
||||
$userId = $user->get('id');
|
||||
|
||||
$component = '';
|
||||
$parts = FieldsHelper::extract($this->state->get('filter.context'));
|
||||
|
||||
if ($parts) {
|
||||
$component = $this->escape($parts[0]);
|
||||
}
|
||||
|
||||
$listOrder = $this->escape($this->state->get('list.ordering'));
|
||||
$listDirn = $this->escape($this->state->get('list.direction'));
|
||||
$ordering = ($listOrder == 'a.ordering');
|
||||
$saveOrder = ($listOrder == 'a.ordering' && strtolower($listDirn) == 'asc');
|
||||
|
||||
if ($saveOrder && !empty($this->items)) {
|
||||
$saveOrderingUrl = 'index.php?option=com_fields&task=groups.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1';
|
||||
HTMLHelper::_('draggablelist.draggable');
|
||||
}
|
||||
|
||||
$context = $this->escape($this->state->get('filter.context'));
|
||||
|
||||
$searchToolsOptions = [];
|
||||
|
||||
// Only show field contexts filter if there are more than one option
|
||||
if (count($this->filterForm->getField('context')->options) > 1) {
|
||||
$searchToolsOptions['selectorFieldName'] = 'context';
|
||||
}
|
||||
?>
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_fields&view=groups&context=' . $context); ?>" method="post" name="adminForm" id="adminForm">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div id="j-main-container" class="j-main-container">
|
||||
<?php echo LayoutHelper::render('joomla.searchtools.default', ['view' => $this, 'options' => $searchToolsOptions]); ?>
|
||||
<?php if (empty($this->items)) : ?>
|
||||
<div class="alert alert-info">
|
||||
<span class="icon-info-circle" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('INFO'); ?></span>
|
||||
<?php echo Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<table class="table" id="fieldgroupList">
|
||||
<caption class="visually-hidden">
|
||||
<?php echo Text::_('COM_FIELDS_GROUPS_TABLE_CAPTION'); ?>,
|
||||
<span id="orderedBy"><?php echo Text::_('JGLOBAL_SORTED_BY'); ?> </span>,
|
||||
<span id="filteredBy"><?php echo Text::_('JGLOBAL_FILTERED_BY'); ?></span>
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="w-1 text-center">
|
||||
<?php echo HTMLHelper::_('grid.checkall'); ?>
|
||||
</td>
|
||||
<th scope="col" class="w-1 text-center d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', '', 'a.ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING', 'icon-sort'); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-1 text-center">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JSTATUS', 'a.state', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGLOBAL_TITLE', 'a.title', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-10 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_ACCESS', 'a.access', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<?php if (Multilanguage::isEnabled()) : ?>
|
||||
<th scope="col" class="w-5 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_LANGUAGE', 'a.language', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<?php endif; ?>
|
||||
<th scope="col" class="w-1 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody <?php if ($saveOrder) :
|
||||
?> class="js-draggable" data-url="<?php echo $saveOrderingUrl; ?>" data-direction="<?php echo strtolower($listDirn); ?>" data-nested="true"<?php
|
||||
endif; ?>>
|
||||
<?php foreach ($this->items as $i => $item) : ?>
|
||||
<?php $ordering = ($listOrder == 'a.ordering'); ?>
|
||||
<?php $canEdit = $user->authorise('core.edit', $component . '.fieldgroup.' . $item->id); ?>
|
||||
<?php $canCheckin = $user->authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || is_null($item->checked_out); ?>
|
||||
<?php $canEditOwn = $user->authorise('core.edit.own', $component . '.fieldgroup.' . $item->id) && $item->created_by == $userId; ?>
|
||||
<?php $canChange = $user->authorise('core.edit.state', $component . '.fieldgroup.' . $item->id) && $canCheckin; ?>
|
||||
<tr class="row<?php echo $i % 2; ?>" data-draggable-group="0" item-id="<?php echo $item->id; ?>">
|
||||
<td class="text-center">
|
||||
<?php echo HTMLHelper::_('grid.id', $i, $item->id, false, 'cid', 'cb', $item->title); ?>
|
||||
</td>
|
||||
<td class="text-center d-none d-md-table-cell">
|
||||
<?php $iconClass = ''; ?>
|
||||
<?php if (!$canChange) : ?>
|
||||
<?php $iconClass = ' inactive'; ?>
|
||||
<?php elseif (!$saveOrder) : ?>
|
||||
<?php $iconClass = ' inactive" title="' . Text::_('JORDERINGDISABLED'); ?>
|
||||
<?php endif; ?>
|
||||
<span class="sortable-handler<?php echo $iconClass; ?>">
|
||||
<span class="icon-ellipsis-v" aria-hidden="true"></span>
|
||||
</span>
|
||||
<?php if ($canChange && $saveOrder) : ?>
|
||||
<input type="text" class="hidden" name="order[]" size="5" value="<?php echo $item->ordering; ?>">
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<?php echo HTMLHelper::_('jgrid.published', $item->state, $i, 'groups.', $canChange, 'cb'); ?>
|
||||
</td>
|
||||
<th scope="row">
|
||||
<div class="break-word">
|
||||
<?php if ($item->checked_out) : ?>
|
||||
<?php echo HTMLHelper::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'groups.', $canCheckin); ?>
|
||||
<?php endif; ?>
|
||||
<?php if ($canEdit || $canEditOwn) : ?>
|
||||
<a href="<?php echo Route::_('index.php?option=com_fields&task=group.edit&id=' . $item->id . '&context=' . $context); ?>" title="<?php echo Text::_('JACTION_EDIT'); ?> <?php echo $this->escape($item->title); ?>">
|
||||
<?php echo $this->escape($item->title); ?></a>
|
||||
<?php else : ?>
|
||||
<?php echo $this->escape($item->title); ?>
|
||||
<?php endif; ?>
|
||||
<div class="small break-word">
|
||||
<?php if ($item->note) : ?>
|
||||
<?php echo Text::sprintf('JGLOBAL_LIST_NOTE', $this->escape($item->note)); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
<td class="small d-none d-md-table-cell">
|
||||
<?php echo $this->escape($item->access_level); ?>
|
||||
</td>
|
||||
<?php if (Multilanguage::isEnabled()) : ?>
|
||||
<td class="small d-none d-md-table-cell">
|
||||
<?php echo LayoutHelper::render('joomla.content.language', $item); ?>
|
||||
</td>
|
||||
<?php endif; ?>
|
||||
<td class="d-none d-md-table-cell">
|
||||
<span><?php echo (int) $item->id; ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php // load the pagination. ?>
|
||||
<?php echo $this->pagination->getListFooter(); ?>
|
||||
|
||||
<?php // Load the batch processing form. ?>
|
||||
<?php
|
||||
if (
|
||||
$user->authorise('core.create', $component)
|
||||
&& $user->authorise('core.edit', $component)
|
||||
&& $user->authorise('core.edit.state', $component)
|
||||
) : ?>
|
||||
<?php echo HTMLHelper::_(
|
||||
'bootstrap.renderModal',
|
||||
'collapseModal',
|
||||
[
|
||||
'title' => Text::_('COM_FIELDS_VIEW_GROUPS_BATCH_OPTIONS'),
|
||||
'footer' => $this->loadTemplate('batch_footer')
|
||||
],
|
||||
$this->loadTemplate('batch_body')
|
||||
); ?>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<input type="hidden" name="task" value="">
|
||||
<input type="hidden" name="boxchecked" value="0">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
21
administrator/components/com_fields/tmpl/groups/default.xml
Normal file
21
administrator/components/com_fields/tmpl/groups/default.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<layout title="COM_FIELDS_GROUPS_VIEW_DEFAULT_TITLE">
|
||||
<message>
|
||||
<![CDATA[COM_FIELDS_GROUPS_VIEW_DEFAULT_DESC]]>
|
||||
</message>
|
||||
</layout>
|
||||
<fieldset name="request">
|
||||
<fields name="request">
|
||||
<field
|
||||
name="extension"
|
||||
type="ComponentsFieldgroup"
|
||||
label="COM_FIELDS_CHOOSE_CONTEXT_LABEL"
|
||||
required="true"
|
||||
addfieldprefix="Joomla\Component\Fields\Administrator\Field"
|
||||
>
|
||||
<option value="">COM_MENUS_OPTION_SELECT_CONTEXT</option>
|
||||
</field>
|
||||
</fields>
|
||||
</fieldset>
|
||||
</metadata>
|
||||
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
?>
|
||||
|
||||
<div class="p-3">
|
||||
<div class="row">
|
||||
<?php if (Multilanguage::isEnabled()) : ?>
|
||||
<div class="form-group col-md-6">
|
||||
<div class="controls">
|
||||
<?php echo LayoutHelper::render('joomla.html.batch.language', []); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="form-group col-md-6">
|
||||
<div class="controls">
|
||||
<?php echo LayoutHelper::render('joomla.html.batch.access', []); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
?>
|
||||
<button type="button" class="btn btn-secondary" onclick="document.getElementById('batch-field-id').value='';document.getElementById('batch-access').value='';document.getElementById('batch-language-id').value=''" data-bs-dismiss="modal">
|
||||
<?php echo Text::_('JCANCEL'); ?>
|
||||
</button>
|
||||
<button type="submit" class="btn btn-success" onclick="Joomla.submitbutton('group.batch');return false;">
|
||||
<?php echo Text::_('JGLOBAL_BATCH_PROCESS'); ?>
|
||||
</button>
|
||||
Reference in New Issue
Block a user