init
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><title></title>
|
||||
@@ -0,0 +1,782 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_articles</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2024-07</creationDate>
|
||||
<copyright>(C) 2024 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>5.2.0</version>
|
||||
<description>MOD_ARTICLES_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\Articles</namespace>
|
||||
<files>
|
||||
<folder module="mod_articles">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_articles.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_articles.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Articles" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic"
|
||||
addfieldprefix="Joomla\Component\Content\Administrator\Field" >
|
||||
<field
|
||||
name="mode"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_MODE_LABEL"
|
||||
description="MOD_ARTICLES_FIELD_MODE_DESC"
|
||||
default="normal"
|
||||
validate="options"
|
||||
>
|
||||
<option value="normal">MOD_ARTICLES_OPTION_NORMAL_VALUE</option>
|
||||
<option value="dynamic">MOD_ARTICLES_OPTION_DYNAMIC_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_on_article_page"
|
||||
type="radio"
|
||||
label="MOD_ARTICLES_FIELD_SHOWONARTICLEPAGE_LABEL"
|
||||
description="MOD_ARTICLES_FIELD_SHOWONARTICLEPAGE_DESC"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="1"
|
||||
filter="integer"
|
||||
showon="mode:dynamic"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="count"
|
||||
type="number"
|
||||
label="MOD_ARTICLES_FIELD_COUNT_LABEL"
|
||||
description="MOD_ARTICLES_FIELD_COUNT_DESC"
|
||||
default="5"
|
||||
filter="integer"
|
||||
min="0"
|
||||
validate="number"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="category_filtering_type"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_CATFILTERINGTYPE_LABEL"
|
||||
description="MOD_ARTICLES_FIELD_CATFILTERINGTYPE_DESC"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">MOD_ARTICLES_OPTION_EXCLUSIVE_VALUE</option>
|
||||
<option value="1">MOD_ARTICLES_OPTION_INCLUSIVE_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="catid"
|
||||
type="category"
|
||||
label="JCATEGORY"
|
||||
extension="com_content"
|
||||
multiple="true"
|
||||
layout="joomla.form.field.list-fancy-select"
|
||||
filter="intarray"
|
||||
class="multipleCategories"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_child_category_articles"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_SHOWCHILDCATEGORYARTICLES_LABEL"
|
||||
description="MOD_ARTICLES_FIELD_SHOWCHILDCATEGORYARTICLES_DESC"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">MOD_ARTICLES_OPTION_EXCLUDE_VALUE</option>
|
||||
<option value="1">MOD_ARTICLES_OPTION_INCLUDE_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="levels"
|
||||
type="number"
|
||||
label="MOD_ARTICLES_FIELD_CATDEPTH_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
showon="show_child_category_articles:1"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="exclude_current"
|
||||
type="radio"
|
||||
label="MOD_ARTICLES_FIELD_EXCLUDE_CURRENT_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="ex_or_include_articles"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_EX_OR_INCLUDE_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">MOD_ARTICLES_OPTION_EXCLUDE_VALUE</option>
|
||||
<option value="1">MOD_ARTICLES_OPTION_INCLUDE_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="excluded_articles"
|
||||
type="subform"
|
||||
label="MOD_ARTICLES_FIELD_EXCLUDEDARTICLES_LABEL"
|
||||
multiple="true"
|
||||
buttons="add,remove"
|
||||
showon="ex_or_include_articles:0"
|
||||
>
|
||||
<form>
|
||||
<field
|
||||
name="id"
|
||||
type="modal_article"
|
||||
label="MOD_ARTICLES_FIELD_SELECT_ARTICLE_LABEL"
|
||||
select="true"
|
||||
new="false"
|
||||
edit="false"
|
||||
clear="true"
|
||||
/>
|
||||
</form>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="included_articles"
|
||||
type="subform"
|
||||
label="MOD_ARTICLES_FIELD_INCLUDEDARTICLES_LABEL"
|
||||
multiple="true"
|
||||
buttons="add,remove"
|
||||
showon="ex_or_include_articles:1"
|
||||
>
|
||||
<form>
|
||||
<field
|
||||
name="id"
|
||||
type="modal_article"
|
||||
label="MOD_ARTICLES_FIELD_SELECT_ARTICLE_LABEL"
|
||||
select="true"
|
||||
new="false"
|
||||
edit="false"
|
||||
clear="true"
|
||||
/>
|
||||
</form>
|
||||
</field>
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="display"
|
||||
label="MOD_ARTICLES_FIELD_GROUP_DISPLAY_LABEL"
|
||||
>
|
||||
<field
|
||||
name="title_only"
|
||||
type="radio"
|
||||
label="MOD_ARTICLES_FIELD_TITLEONLY_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="articles_layout"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_LAYOUT_LABEL"
|
||||
description="MOD_ARTICLES_FIELD_LAYOUT_DESC"
|
||||
default="0"
|
||||
filter="integer"
|
||||
showon="title_only:0"
|
||||
>
|
||||
<option value="0">MOD_ARTICLES_FIELD_LAYOUT_VERT</option>
|
||||
<option value="1">MOD_ARTICLES_FIELD_LAYOUT_HOR</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="layout_columns"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_LAYOUT_COL_LABEL"
|
||||
default="3"
|
||||
filter="integer"
|
||||
showon="title_only:0[AND]articles_layout:1"
|
||||
validate="options"
|
||||
>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="4">4</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="item_title"
|
||||
type="radio"
|
||||
label="MOD_ARTICLES_FIELD_TITLE_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="1"
|
||||
filter="integer"
|
||||
showon="title_only:0"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="item_heading"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_TITLE_HEADING"
|
||||
default="h4"
|
||||
showon="title_only:0[AND]item_title:1"
|
||||
validate="options"
|
||||
>
|
||||
<option value="h1">JH1</option>
|
||||
<option value="h2">JH2</option>
|
||||
<option value="h3">JH3</option>
|
||||
<option value="h4">JH4</option>
|
||||
<option value="h5">JH5</option>
|
||||
<option value="h6">JH6</option>
|
||||
<option value="div">MOD_ARTICLES_FIELD_TITLE_HEADING_NONE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="link_titles"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_FIELD_LINKTITLES_LABEL"
|
||||
default="1"
|
||||
showon="title_only:0[AND]item_title:1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_author"
|
||||
type="radio"
|
||||
label="JAUTHOR"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
filter="integer"
|
||||
showon="title_only:0"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_category"
|
||||
type="radio"
|
||||
label="JCATEGORY"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
filter="integer"
|
||||
showon="title_only:0"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_category_link"
|
||||
type="radio"
|
||||
label="MOD_ARTICLES_FIELD_SHOWCATEGORYLINK_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
filter="integer"
|
||||
showon="title_only:0[AND]show_category:1"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_date"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="JDATE"
|
||||
default="0"
|
||||
filter="integer"
|
||||
showon="title_only:0"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_date_field"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_DATEFIELD_LABEL"
|
||||
default="created"
|
||||
showon="title_only:0[AND]show_date:1"
|
||||
validate="options"
|
||||
>
|
||||
<option value="created">MOD_ARTICLES_OPTION_CREATED_VALUE</option>
|
||||
<option value="modified">MOD_ARTICLES_OPTION_MODIFIED_VALUE</option>
|
||||
<option value="publish_up">MOD_ARTICLES_OPTION_STARTPUBLISHING_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_date_format"
|
||||
type="text"
|
||||
label="MOD_ARTICLES_FIELD_DATEFIELDFORMAT_LABEL"
|
||||
description="MOD_ARTICLES_FIELD_DATEFIELDFORMAT_DESC"
|
||||
default="Y-m-d H:i:s"
|
||||
showon="title_only:0[AND]show_date:1"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_hits"
|
||||
type="radio"
|
||||
label="MOD_ARTICLES_FIELD_SHOWHITS_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
filter="integer"
|
||||
showon="title_only:0"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="info_layout"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_INFOLAYOUT_LABEL"
|
||||
description="MOD_ARTICLES_FIELD_INFOLAYOUT_DESC"
|
||||
default="0"
|
||||
filter="integer"
|
||||
showon="show_date:1[OR]show_category:1[OR]show_hits:1[OR]show_author:1[AND]title_only:0"
|
||||
>
|
||||
<option value="0">MOD_ARTICLES_FIELD_LAYOUT_MULTILINE</option>
|
||||
<option value="1">MOD_ARTICLES_FIELD_LAYOUT_SINGLELINE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_tags"
|
||||
type="radio"
|
||||
label="JTAG"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
filter="integer"
|
||||
showon="title_only:0"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="trigger_events"
|
||||
type="radio"
|
||||
label="MOD_ARTICLES_FIELD_TRIGGER_EVENTS_LABEL"
|
||||
description="MOD_ARTICLES_FIELD_TRIGGER_EVENTS_DESC"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
filter="integer"
|
||||
showon="title_only:0"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_introtext"
|
||||
type="radio"
|
||||
label="MOD_ARTICLES_FIELD_SHOWINTROTEXT_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
filter="integer"
|
||||
showon="title_only:0"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="introtext_limit"
|
||||
type="number"
|
||||
label="MOD_ARTICLES_FIELD_INTROTEXTLIMIT_LABEL"
|
||||
description="MOD_ARTICLES_FIELD_INTROTEXTLIMIT_DESC"
|
||||
default="100"
|
||||
filter="integer"
|
||||
showon="title_only:0[AND]show_introtext:1"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="image"
|
||||
type="radio"
|
||||
label="MOD_ARTICLES_FIELD_IMAGES_LABEL"
|
||||
description="MOD_ARTICLES_FIELD_IMAGES_DESC"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
filter="integer"
|
||||
showon="title_only:0[AND]show_introtext:1"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="img_intro_full"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_IMAGES_ARTICLE_LABEL"
|
||||
default="none"
|
||||
validate="options"
|
||||
showon="title_only:0"
|
||||
>
|
||||
<option value="intro">MOD_ARTICLES_OPTION_INTROIMAGE</option>
|
||||
<option value="full">MOD_ARTICLES_OPTION_FULLIMAGE</option>
|
||||
<option value="none">JNO</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_readmore"
|
||||
type="radio"
|
||||
label="JGLOBAL_SHOW_READMORE_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
filter="integer"
|
||||
showon="title_only:0"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_readmore_title"
|
||||
type="radio"
|
||||
label="JGLOBAL_SHOW_READMORE_TITLE_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="1"
|
||||
filter="integer"
|
||||
showon="title_only:0[AND]show_readmore:1"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="readmore_limit"
|
||||
type="number"
|
||||
label="JGLOBAL_SHOW_READMORE_LIMIT_LABEL"
|
||||
default="15"
|
||||
filter="integer"
|
||||
showon="title_only:0[AND]show_readmore:1[AND]show_readmore_title:1"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="filtering"
|
||||
label="MOD_ARTICLES_FIELD_GROUP_FILTERING_LABEL"
|
||||
>
|
||||
<field
|
||||
name="show_featured"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_SHOWFEATURED_LABEL"
|
||||
default="show"
|
||||
validate="options"
|
||||
>
|
||||
<option value="show">JSHOW</option>
|
||||
<option value="hide">JHIDE</option>
|
||||
<option value="only">MOD_ARTICLES_OPTION_ONLYFEATURED_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="filteringspacer1"
|
||||
type="spacer"
|
||||
hr="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_archived"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_ONLYARCHIVED_LABEL"
|
||||
default="hide"
|
||||
validate="options"
|
||||
>
|
||||
<option value="show">MOD_ARTICLES_OPTION_ONLYARCHIVEDSHOW_VALUE</option>
|
||||
<option value="hide">MOD_ARTICLES_OPTION_ONLYARCHIVEDHIDE_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_unpublished"
|
||||
type="radio"
|
||||
label="MOD_ARTICLES_FIELD_UNPUBLISHED_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
filter="integer"
|
||||
showon="show_archived!:show"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="filteringspacer2"
|
||||
type="spacer"
|
||||
hr="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="filter_tag"
|
||||
type="tag"
|
||||
label="JTAG"
|
||||
mode="nested"
|
||||
multiple="true"
|
||||
filter="intarray"
|
||||
class="multipleTags"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="filteringspacer3"
|
||||
type="spacer"
|
||||
hr="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="author_filtering_type"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_AUTHORFILTERING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">MOD_ARTICLES_OPTION_EXCLUSIVE_VALUE</option>
|
||||
<option value="1">MOD_ARTICLES_OPTION_INCLUSIVE_VALUE</option>
|
||||
<option value="2">MOD_ARTICLES_OPTION_ONLYCURRENTUSER_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="created_by"
|
||||
type="author"
|
||||
label="MOD_ARTICLES_FIELD_AUTHOR_LABEL"
|
||||
multiple="true"
|
||||
layout="joomla.form.field.list-fancy-select"
|
||||
filter="intarray"
|
||||
class="multipleAuthors"
|
||||
showon="author_filtering_type!:2"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="filteringspacer4"
|
||||
type="spacer"
|
||||
hr="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="author_alias_filtering_type"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_AUTHORALIASFILTERING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">MOD_ARTICLES_OPTION_EXCLUSIVE_VALUE</option>
|
||||
<option value="1">MOD_ARTICLES_OPTION_INCLUSIVE_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="created_by_alias"
|
||||
type="sql"
|
||||
label="MOD_ARTICLES_FIELD_AUTHORALIAS_LABEL"
|
||||
multiple="true"
|
||||
layout="joomla.form.field.list-fancy-select"
|
||||
query="select distinct(created_by_alias) from #__content where created_by_alias != '' order by created_by_alias ASC"
|
||||
key_field="created_by_alias"
|
||||
value_field="created_by_alias"
|
||||
class="multipleAuthorAliases"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="filteringspacer5"
|
||||
type="spacer"
|
||||
hr="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="date_filtering"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_DATEFILTERING_LABEL"
|
||||
default="off"
|
||||
validate="options"
|
||||
>
|
||||
<option value="off">MOD_ARTICLES_OPTION_OFF_VALUE</option>
|
||||
<option value="range">MOD_ARTICLES_OPTION_DATERANGE_VALUE</option>
|
||||
<option value="relative">MOD_ARTICLES_OPTION_RELATIVEDAY_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="date_field"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_DATERANGEFIELD_LABEL"
|
||||
default="a.created"
|
||||
showon="date_filtering!:off"
|
||||
validate="options"
|
||||
>
|
||||
<option value="a.created">MOD_ARTICLES_OPTION_CREATED_VALUE</option>
|
||||
<option value="a.modified">MOD_ARTICLES_OPTION_MODIFIED_VALUE</option>
|
||||
<option value="a.publish_up">MOD_ARTICLES_OPTION_STARTPUBLISHING_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="start_date_range"
|
||||
type="calendar"
|
||||
label="MOD_ARTICLES_FIELD_STARTDATE_LABEL"
|
||||
translateformat="true"
|
||||
showtime="true"
|
||||
filter="user_utc"
|
||||
showon="date_filtering:range"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="end_date_range"
|
||||
type="calendar"
|
||||
label="MOD_ARTICLES_FIELD_ENDDATE_LABEL"
|
||||
translateformat="true"
|
||||
showtime="true"
|
||||
filter="user_utc"
|
||||
showon="date_filtering:range"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="relative_date"
|
||||
type="number"
|
||||
label="MOD_ARTICLES_FIELD_RELATIVEDATE_LABEL"
|
||||
default="30"
|
||||
filter="integer"
|
||||
showon="date_filtering:relative"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="ordering"
|
||||
label="MOD_ARTICLES_FIELD_GROUP_ORDERING_LABEL"
|
||||
>
|
||||
<field
|
||||
name="article_ordering"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_ARTICLEORDERING_LABEL"
|
||||
default="a.title"
|
||||
validate="options"
|
||||
>
|
||||
<option value="a.ordering">MOD_ARTICLES_OPTION_ORDERING_VALUE</option>
|
||||
<option value="fp.ordering">MOD_ARTICLES_OPTION_ORDERINGFEATURED_VALUE</option>
|
||||
<option value="a.title">JGLOBAL_TITLE</option>
|
||||
<option value="a.id">MOD_ARTICLES_OPTION_ID_VALUE</option>
|
||||
<option value="a.alias">JFIELD_ALIAS_LABEL</option>
|
||||
<option value="a.created">MOD_ARTICLES_OPTION_CREATED_VALUE</option>
|
||||
<option value="modified">MOD_ARTICLES_OPTION_MODIFIED_VALUE</option>
|
||||
<option value="publish_up">MOD_ARTICLES_OPTION_STARTPUBLISHING_VALUE</option>
|
||||
<option value="a.publish_down">MOD_ARTICLES_OPTION_FINISHPUBLISHING_VALUE</option>
|
||||
<option value="random">MOD_ARTICLES_OPTION_RANDOM_VALUE</option>
|
||||
<option value="a.hits" requires="hits">MOD_ARTICLES_OPTION_HITS_VALUE</option>
|
||||
<option value="rating_count" requires="vote">MOD_ARTICLES_OPTION_VOTE_VALUE</option>
|
||||
<option value="rating" requires="vote">MOD_ARTICLES_OPTION_RATING_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="article_ordering_direction"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_ARTICLEORDERINGDIR_LABEL"
|
||||
default="ASC"
|
||||
validate="options"
|
||||
>
|
||||
<option value="DESC">MOD_ARTICLES_OPTION_DESCENDING_VALUE</option>
|
||||
<option value="ASC">MOD_ARTICLES_OPTION_ASCENDING_VALUE</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="grouping"
|
||||
label="MOD_ARTICLES_FIELD_GROUP_GROUPING_LABEL"
|
||||
>
|
||||
<field
|
||||
name="article_grouping"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_ARTICLEGROUPING_LABEL"
|
||||
default="none"
|
||||
validate="options"
|
||||
>
|
||||
<option value="none">JNONE</option>
|
||||
<option value="year">MOD_ARTICLES_OPTION_YEAR_VALUE</option>
|
||||
<option value="month_year">MOD_ARTICLES_OPTION_MONTHYEAR_VALUE</option>
|
||||
<option value="author">JAUTHOR</option>
|
||||
<option value="category_title">JCATEGORY</option>
|
||||
<option value="tags">JTAG</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="date_grouping_field"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_DATEGROUPINGFIELD_LABEL"
|
||||
description="MOD_ARTICLES_FIELD_DATEGROUPINGFIELD_DESC"
|
||||
default="created"
|
||||
showon="article_grouping:year,month_year"
|
||||
validate="options"
|
||||
>
|
||||
<option value="created">MOD_ARTICLES_OPTION_CREATED_VALUE</option>
|
||||
<option value="modified">MOD_ARTICLES_OPTION_MODIFIED_VALUE</option>
|
||||
<option value="publish_up">MOD_ARTICLES_OPTION_STARTPUBLISHING_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="month_year_format"
|
||||
type="text"
|
||||
label="MOD_ARTICLES_FIELD_MONTHYEARFORMAT_LABEL"
|
||||
description="MOD_ARTICLES_FIELD_MONTHYEARFORMAT_DESC"
|
||||
default="F Y"
|
||||
showon="article_grouping:year,month_year"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="article_grouping_direction"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_FIELD_ARTICLEGROUPINGDIR_LABEL"
|
||||
default="ksort"
|
||||
showon="article_grouping!:none"
|
||||
validate="options"
|
||||
>
|
||||
<option value="krsort">MOD_ARTICLES_OPTION_DESCENDING_VALUE</option>
|
||||
<option value="ksort">MOD_ARTICLES_OPTION_ASCENDING_VALUE</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="owncache"
|
||||
type="list"
|
||||
label="COM_MODULES_FIELD_CACHING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="cache_time"
|
||||
type="number"
|
||||
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
|
||||
default="900"
|
||||
filter="integer"
|
||||
/>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles
|
||||
*
|
||||
* @copyright (C) 2024 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The articles module service provider.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Articles'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\Articles\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles
|
||||
*
|
||||
* @copyright (C) 2024 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Articles\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
use Joomla\CMS\Helper\ModuleHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_articles
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
protected function getLayoutData(): array
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
$params = $data['params'];
|
||||
|
||||
// Prep for Normal or Dynamic Modes
|
||||
$mode = $params->get('mode', 'normal');
|
||||
$idBase = null;
|
||||
|
||||
switch ($mode) {
|
||||
case 'dynamic':
|
||||
$option = $data['input']->get('option');
|
||||
$view = $data['input']->get('view');
|
||||
|
||||
if ($option === 'com_content') {
|
||||
switch ($view) {
|
||||
case 'category':
|
||||
case 'categories':
|
||||
$idBase = $data['input']->getInt('id');
|
||||
break;
|
||||
case 'article':
|
||||
if ($params->get('show_on_article_page', 1)) {
|
||||
$idBase = $data['input']->getInt('catid');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$idBase = $params->get('catid');
|
||||
break;
|
||||
}
|
||||
|
||||
$cacheParams = new \stdClass();
|
||||
$cacheParams->cachemode = 'id';
|
||||
$cacheParams->class = $this->getHelperFactory()->getHelper('ArticlesHelper');
|
||||
$cacheParams->method = 'getArticles';
|
||||
$cacheParams->methodparams = [$params, $data['app']];
|
||||
$cacheParams->modeparams = md5(serialize([$idBase, $this->module->module, $this->module->id]));
|
||||
|
||||
$data['list'] = ModuleHelper::moduleCache($this->module, $params, $cacheParams);
|
||||
|
||||
$data['grouped'] = $params->get('article_grouping', 'none') !== 'none';
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,601 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles
|
||||
*
|
||||
* @copyright (C) 2024 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Articles\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Access\Access;
|
||||
use Joomla\CMS\Application\SiteApplication;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Date\Date;
|
||||
use Joomla\CMS\Event\Content;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\Content\Administrator\Extension\ContentComponent;
|
||||
use Joomla\Component\Content\Site\Helper\RouteHelper;
|
||||
use Joomla\Database\DatabaseAwareInterface;
|
||||
use Joomla\Database\DatabaseAwareTrait;
|
||||
use Joomla\Registry\Registry;
|
||||
use Joomla\String\StringHelper;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Helper for mod_articles
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
class ArticlesHelper implements DatabaseAwareInterface
|
||||
{
|
||||
use DatabaseAwareTrait;
|
||||
|
||||
/**
|
||||
* Retrieve a list of articles
|
||||
*
|
||||
* @param Registry $params The module parameters.
|
||||
* @param SiteApplication $app The current application.
|
||||
*
|
||||
* @return object[]
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
public function getArticles(Registry $params, SiteApplication $app)
|
||||
{
|
||||
$factory = $app->bootComponent('com_content')->getMVCFactory();
|
||||
|
||||
// Get an instance of the generic articles model
|
||||
$articles = $factory->createModel('Articles', 'Site', ['ignore_request' => true]);
|
||||
|
||||
// Set application parameters in model
|
||||
$input = $app->getInput();
|
||||
$appParams = $app->getParams();
|
||||
$articles->setState('params', $appParams);
|
||||
|
||||
$articles->setState('list.start', 0);
|
||||
$articles->setState('filter.published', ContentComponent::CONDITION_PUBLISHED);
|
||||
|
||||
// Set the filters based on the module params
|
||||
$articles->setState('list.limit', (int) $params->get('count', 0));
|
||||
$articles->setState('load_tags', $params->get('show_tags', 0) || $params->get('article_grouping', 'none') === 'tags');
|
||||
|
||||
// Get the user object
|
||||
$user = $app->getIdentity();
|
||||
|
||||
// Access filter
|
||||
$access = !ComponentHelper::getParams('com_content')->get('show_noauth');
|
||||
$authorised = Access::getAuthorisedViewLevels($user->id);
|
||||
$articles->setState('filter.access', $access);
|
||||
|
||||
// Prep for Normal or Dynamic Modes
|
||||
$mode = $params->get('mode', 'normal');
|
||||
|
||||
switch ($mode) {
|
||||
case 'dynamic':
|
||||
$option = $input->get('option');
|
||||
$view = $input->get('view');
|
||||
|
||||
if ($option === 'com_content') {
|
||||
switch ($view) {
|
||||
case 'category':
|
||||
case 'categories':
|
||||
$catids = [$input->getInt('id')];
|
||||
break;
|
||||
case 'article':
|
||||
if ($params->get('show_on_article_page', 1)) {
|
||||
$article_id = $input->getInt('id');
|
||||
$catid = $input->getInt('catid');
|
||||
|
||||
if (!$catid) {
|
||||
// Get an instance of the generic article model
|
||||
$article = $factory->createModel('Article', 'Site', ['ignore_request' => true]);
|
||||
|
||||
$article->setState('params', $appParams);
|
||||
$article->setState('filter.published', 1);
|
||||
$article->setState('article.id', (int) $article_id);
|
||||
$item = $article->getItem();
|
||||
$catids = [$item->catid];
|
||||
} else {
|
||||
$catids = [$catid];
|
||||
}
|
||||
} else {
|
||||
// Return right away if show_on_article_page option is off
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Return right away if not on the category or article views
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Return right away if not on a com_content page
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$catids = $params->get('catid');
|
||||
$articles->setState('filter.category_id.include', (bool) $params->get('category_filtering_type', 1));
|
||||
break;
|
||||
}
|
||||
|
||||
// Category filter
|
||||
if ($catids) {
|
||||
if ($params->get('show_child_category_articles', 0) && (int) $params->get('levels', 0) > 0) {
|
||||
// Get an instance of the generic categories model
|
||||
$categories = $factory->createModel('Categories', 'Site', ['ignore_request' => true]);
|
||||
$categories->setState('params', $appParams);
|
||||
$levels = $params->get('levels', 1) ?: 9999;
|
||||
$categories->setState('filter.get_children', $levels);
|
||||
$categories->setState('filter.published', 1);
|
||||
$categories->setState('filter.access', $access);
|
||||
$additional_catids = [];
|
||||
|
||||
foreach ($catids as $catid) {
|
||||
$categories->setState('filter.parentId', $catid);
|
||||
$recursive = true;
|
||||
$items = $categories->getItems($recursive);
|
||||
|
||||
if ($items) {
|
||||
foreach ($items as $category) {
|
||||
$condition = (($category->level - $categories->getParent()->level) <= $levels);
|
||||
|
||||
if ($condition) {
|
||||
$additional_catids[] = $category->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$catids = array_unique(array_merge($catids, $additional_catids));
|
||||
}
|
||||
|
||||
$articles->setState('filter.category_id', $catids);
|
||||
}
|
||||
|
||||
// Ordering
|
||||
$ordering = $params->get('article_ordering', 'a.ordering');
|
||||
|
||||
switch ($ordering) {
|
||||
case 'random':
|
||||
$articles->setState('list.ordering', $this->getDatabase()->createQuery()->rand());
|
||||
break;
|
||||
|
||||
case 'rating_count':
|
||||
case 'rating':
|
||||
$articles->setState('list.ordering', $ordering);
|
||||
$articles->setState('list.direction', $params->get('article_ordering_direction', 'ASC'));
|
||||
|
||||
if (!PluginHelper::isEnabled('content', 'vote')) {
|
||||
$articles->setState('list.ordering', 'a.ordering');
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$articles->setState('list.ordering', $ordering);
|
||||
$articles->setState('list.direction', $params->get('article_ordering_direction', 'ASC'));
|
||||
break;
|
||||
}
|
||||
|
||||
// Filter by multiple tags
|
||||
$articles->setState('filter.tag', $params->get('filter_tag', []));
|
||||
|
||||
// Filter by featured
|
||||
$articles->setState('filter.featured', $params->get('show_featured', 'show'));
|
||||
|
||||
// Filter by author
|
||||
if ($params->get('author_filtering_type', 1) === 2) {
|
||||
$articles->setState('filter.author_id', [$user->id]);
|
||||
} else {
|
||||
$articles->setState('filter.author_id', $params->get('created_by', []));
|
||||
$articles->setState('filter.author_id.include', $params->get('author_filtering_type', 1));
|
||||
}
|
||||
|
||||
$articles->setState('filter.author_alias', $params->get('created_by_alias', []));
|
||||
$articles->setState('filter.author_alias.include', $params->get('author_alias_filtering_type', 1));
|
||||
|
||||
// Filter archived articles
|
||||
if ($params->get('show_archived', 'hide') === 'show') {
|
||||
$articles->setState('filter.published', ContentComponent::CONDITION_ARCHIVED);
|
||||
}
|
||||
|
||||
// Filter unpublished articles
|
||||
if ($params->get('show_unpublished', 0) === 1 && (($user->authorise('core.edit.state', 'com_content') && $user->authorise('core.edit', 'com_content')) || ($user->authorise('core.edit.state', 'com_content') && $user->authorise('core.edit.own', 'com_content')))) {
|
||||
$articles->setState('filter.published', [ContentComponent::CONDITION_UNPUBLISHED, ContentComponent::CONDITION_PUBLISHED]);
|
||||
}
|
||||
|
||||
// Check if we include or exclude articles and process data
|
||||
$ex_or_include_articles = $params->get('ex_or_include_articles', 0);
|
||||
$filterInclude = true;
|
||||
$articlesList = [];
|
||||
$currentArticleId = $input->get('id', 0, 'UINT');
|
||||
|
||||
$isArticleAndShouldExcluded = $params->get('exclude_current', 1) === 1
|
||||
&& $input->get('option') === 'com_content'
|
||||
&& $input->get('view') === 'article';
|
||||
|
||||
$articlesListToProcess = $params->get('included_articles', '');
|
||||
|
||||
if ($ex_or_include_articles === 0) {
|
||||
$filterInclude = false;
|
||||
|
||||
if ($isArticleAndShouldExcluded) {
|
||||
$articlesList[] = $currentArticleId;
|
||||
}
|
||||
|
||||
$articlesListToProcess = $params->get('excluded_articles', '');
|
||||
}
|
||||
|
||||
foreach (ArrayHelper::fromObject($articlesListToProcess) as $article) {
|
||||
if (
|
||||
$ex_or_include_articles === 1
|
||||
&& $isArticleAndShouldExcluded
|
||||
&& (int) $article['id'] === $currentArticleId
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$articlesList[] = (int) $article['id'];
|
||||
}
|
||||
|
||||
// Edge case when the user select include mode but didn't add an article,
|
||||
// we might have to exclude the current article
|
||||
if (
|
||||
$ex_or_include_articles === 1
|
||||
&& $isArticleAndShouldExcluded
|
||||
&& empty($articlesList)
|
||||
) {
|
||||
$filterInclude = false;
|
||||
$articlesList[] = $currentArticleId;
|
||||
}
|
||||
|
||||
if (!empty($articlesList)) {
|
||||
$articles->setState('filter.article_id', $articlesList);
|
||||
$articles->setState('filter.article_id.include', $filterInclude);
|
||||
}
|
||||
|
||||
$date_filtering = $params->get('date_filtering', 'off');
|
||||
|
||||
if ($date_filtering !== 'off') {
|
||||
$articles->setState('filter.date_filtering', $date_filtering);
|
||||
$articles->setState('filter.date_field', $params->get('date_field', 'a.created'));
|
||||
$articles->setState('filter.start_date_range', $params->get('start_date_range', '1000-01-01 00:00:00'));
|
||||
$articles->setState('filter.end_date_range', $params->get('end_date_range', '9999-12-31 23:59:59'));
|
||||
$articles->setState('filter.relative_date', $params->get('relative_date', 30));
|
||||
}
|
||||
|
||||
// Filter by language
|
||||
$articles->setState('filter.language', $app->getLanguageFilter());
|
||||
|
||||
$items = $articles->getItems();
|
||||
|
||||
// Display options
|
||||
$show_date = $params->get('show_date', 0);
|
||||
$show_date_field = $params->get('show_date_field', 'created');
|
||||
$show_date_format = $params->get('show_date_format', 'Y-m-d H:i:s');
|
||||
$show_category = $params->get('show_category', 0);
|
||||
$show_category_link = $params->get('show_category_link', 0);
|
||||
$show_hits = $params->get('show_hits', 0);
|
||||
$show_author = $params->get('show_author', 0);
|
||||
$show_introtext = $params->get('show_introtext', 0);
|
||||
$introtext_limit = $params->get('introtext_limit', 100);
|
||||
|
||||
// Find current Article ID if on an article page
|
||||
$option = $input->get('option');
|
||||
$view = $input->get('view');
|
||||
|
||||
if ($option === 'com_content' && $view === 'article') {
|
||||
$active_article_id = $input->getInt('id');
|
||||
} else {
|
||||
$active_article_id = 0;
|
||||
}
|
||||
|
||||
// Prepare data for display using display options
|
||||
foreach ($items as &$item) {
|
||||
$item->slug = $item->id . ':' . $item->alias;
|
||||
|
||||
$articleLink = Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language));
|
||||
|
||||
if ($access || \in_array($item->access, $authorised)) {
|
||||
// We know that user has the privilege to view the article
|
||||
$item->link = $articleLink;
|
||||
} else {
|
||||
$menu = $app->getMenu();
|
||||
$menuitems = $menu->getItems('link', 'index.php?option=com_users&view=login');
|
||||
|
||||
if (isset($menuitems[0])) {
|
||||
$Itemid = $menuitems[0]->id;
|
||||
} elseif ($input->getInt('Itemid') > 0) {
|
||||
// Use Itemid from requesting page only if there is no existing menu
|
||||
$Itemid = $input->getInt('Itemid');
|
||||
}
|
||||
|
||||
$return = base64_encode($articleLink);
|
||||
|
||||
$item->link = Route::_('index.php?option=com_users&view=login&Itemid=' . $Itemid . '&return=' . $return);
|
||||
}
|
||||
|
||||
$item->event = new \stdClass();
|
||||
|
||||
// Check if we should trigger additional plugin events
|
||||
if ($params->get('trigger_events', 0)) {
|
||||
$dispatcher = Factory::getApplication()->getDispatcher();
|
||||
|
||||
// Process the content plugins.
|
||||
PluginHelper::importPlugin('content', null, true, $dispatcher);
|
||||
|
||||
$contentEventArguments = [
|
||||
'context' => 'com_content.article',
|
||||
'subject' => $item,
|
||||
'params' => $item->params,
|
||||
'page' => 0,
|
||||
];
|
||||
|
||||
// onContentPrepare plugins work on $item->text
|
||||
if (!isset($item->text)) {
|
||||
$item->text = $item->introtext . ' ' . $item->fulltext;
|
||||
}
|
||||
|
||||
$contentEvents = [
|
||||
'onContentPrepare' => new Content\ContentPrepareEvent('onContentPrepare', $contentEventArguments),
|
||||
'afterDisplayTitle' => new Content\AfterTitleEvent('onContentAfterTitle', $contentEventArguments),
|
||||
'beforeDisplayContent' => new Content\BeforeDisplayEvent('onContentBeforeDisplay', $contentEventArguments),
|
||||
'afterDisplayContent' => new Content\AfterDisplayEvent('onContentAfterDisplay', $contentEventArguments),
|
||||
];
|
||||
|
||||
foreach ($contentEvents as $resultKey => $event) {
|
||||
$results = $dispatcher->dispatch($event->getName(), $event)->getArgument('result', []);
|
||||
|
||||
$item->event->{$resultKey} = $results ? trim(implode("\n", $results)) : '';
|
||||
}
|
||||
} else {
|
||||
$item->event->onContentPrepare = '';
|
||||
$item->event->afterDisplayTitle = '';
|
||||
$item->event->beforeDisplayContent = '';
|
||||
$item->event->afterDisplayContent = '';
|
||||
}
|
||||
|
||||
// Used for styling the active article
|
||||
$item->active = $item->id == $active_article_id ? 'active' : '';
|
||||
|
||||
if ($show_date) {
|
||||
$item->displayDate = HTMLHelper::_('date', $item->$show_date_field, $show_date_format);
|
||||
}
|
||||
|
||||
if ($show_category) {
|
||||
$item->displayCategoryTitle = $item->category_title;
|
||||
}
|
||||
|
||||
if ($show_category_link) {
|
||||
$item->displayCategoryLink = Route::_(RouteHelper::getCategoryRoute($item->catid, $item->category_language));
|
||||
}
|
||||
|
||||
$item->displayAuthorName = $show_author ? $item->author : '';
|
||||
$item->displayCategoryTitle = $show_category ? $item->category_title : '';
|
||||
$item->displayCategoryLink = $show_category_link ? $item->displayCategoryLink : '';
|
||||
$item->displayDate = $show_date ? $item->displayDate : '';
|
||||
$item->displayHits = $show_hits ? $item->hits : '';
|
||||
|
||||
if ($show_introtext) {
|
||||
$item->displayIntrotext = HTMLHelper::_('content.prepare', $item->introtext, '', 'mod_articles.content');
|
||||
|
||||
// Remove any images belongs to the text
|
||||
if (!$params->get('image')) {
|
||||
// Remove any images and empty links from the intro text
|
||||
$item->displayIntrotext = preg_replace(['/\\<img[^>]*>/', '/<a[^>]*><\\/a>/'], '', $item->displayIntrotext);
|
||||
}
|
||||
|
||||
if ($introtext_limit != 0) {
|
||||
$item->displayIntrotext = HTMLHelper::_('string.truncateComplex', $item->displayIntrotext, $introtext_limit);
|
||||
}
|
||||
}
|
||||
|
||||
// Show the Intro/Full image field of the article
|
||||
if ($params->get('img_intro_full') !== 'none') {
|
||||
$images = (new Registry($item->images))->toObject();
|
||||
$item->imageSrc = '';
|
||||
|
||||
if ($params->get('img_intro_full') === 'intro' && !empty($images->image_intro)) {
|
||||
$item->imageSrc = htmlspecialchars($images->image_intro, ENT_COMPAT, 'UTF-8');
|
||||
$images->float_intro .= ' mod-articles-image';
|
||||
} elseif ($params->get('img_intro_full') === 'full' && !empty($images->image_fulltext)) {
|
||||
$item->imageSrc = htmlspecialchars($images->image_fulltext, ENT_COMPAT, 'UTF-8');
|
||||
$images->float_fulltext .= ' mod-articles-image';
|
||||
}
|
||||
|
||||
$item->images = json_encode($images);
|
||||
}
|
||||
|
||||
$item->displayReadmore = $item->alternative_readmore;
|
||||
}
|
||||
|
||||
// Check if items need be grouped
|
||||
$article_grouping = $params->get('article_grouping', 'none');
|
||||
$article_grouping_direction = $params->get('article_grouping_direction', 'ksort');
|
||||
$grouped = $article_grouping !== 'none';
|
||||
|
||||
if ($items && $grouped) {
|
||||
switch ($article_grouping) {
|
||||
case 'year':
|
||||
case 'month_year':
|
||||
$items = ArticlesHelper::groupByDate(
|
||||
$items,
|
||||
$article_grouping_direction,
|
||||
$article_grouping,
|
||||
$params->get('month_year_format', 'F Y'),
|
||||
$params->get('date_grouping_field', 'created')
|
||||
);
|
||||
break;
|
||||
case 'author':
|
||||
case 'category_title':
|
||||
$items = ArticlesHelper::groupBy($items, $article_grouping, $article_grouping_direction);
|
||||
break;
|
||||
case 'tags':
|
||||
$items = ArticlesHelper::groupByTags($items, $article_grouping_direction);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups items by field
|
||||
*
|
||||
* @param array $list list of items
|
||||
* @param string $fieldName name of field that is used for grouping
|
||||
* @param string $direction ordering direction
|
||||
* @param null $fieldNameToKeep field name to keep
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
public static function groupBy($list, $fieldName, $direction, $fieldNameToKeep = null)
|
||||
{
|
||||
$grouped = [];
|
||||
|
||||
if (!\is_array($list)) {
|
||||
if ($list === '') {
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
$list = [$list];
|
||||
}
|
||||
|
||||
foreach ($list as $key => $item) {
|
||||
if (!isset($grouped[$item->$fieldName])) {
|
||||
$grouped[$item->$fieldName] = [];
|
||||
}
|
||||
|
||||
if ($fieldNameToKeep === null) {
|
||||
$grouped[$item->$fieldName][$key] = $item;
|
||||
} else {
|
||||
$grouped[$item->$fieldName][$key] = $item->$fieldNameToKeep;
|
||||
}
|
||||
|
||||
unset($list[$key]);
|
||||
}
|
||||
|
||||
$direction($grouped);
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups items by date
|
||||
*
|
||||
* @param array $list list of items
|
||||
* @param string $direction ordering direction
|
||||
* @param string $type type of grouping
|
||||
* @param string $monthYearFormat date format to use
|
||||
* @param string $field date field to group by
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
public static function groupByDate($list, $direction = 'ksort', $type = 'year', $monthYearFormat = 'F Y', $field = 'created')
|
||||
{
|
||||
$grouped = [];
|
||||
|
||||
if (!\is_array($list)) {
|
||||
if ($list === '') {
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
$list = [$list];
|
||||
}
|
||||
|
||||
foreach ($list as $key => $item) {
|
||||
switch ($type) {
|
||||
case 'month_year':
|
||||
$month_year = StringHelper::substr($item->$field, 0, 7);
|
||||
|
||||
if (!isset($grouped[$month_year])) {
|
||||
$grouped[$month_year] = [];
|
||||
}
|
||||
|
||||
$grouped[$month_year][$key] = $item;
|
||||
break;
|
||||
|
||||
default:
|
||||
$year = StringHelper::substr($item->$field, 0, 4);
|
||||
|
||||
if (!isset($grouped[$year])) {
|
||||
$grouped[$year] = [];
|
||||
}
|
||||
|
||||
$grouped[$year][$key] = $item;
|
||||
break;
|
||||
}
|
||||
|
||||
unset($list[$key]);
|
||||
}
|
||||
|
||||
$direction($grouped);
|
||||
|
||||
if ($type === 'month_year') {
|
||||
foreach ($grouped as $group => $items) {
|
||||
$date = new Date($group);
|
||||
$formatted_group = $date->format($monthYearFormat);
|
||||
$grouped[$formatted_group] = $items;
|
||||
|
||||
unset($grouped[$group]);
|
||||
}
|
||||
}
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups items by tags
|
||||
*
|
||||
* @param array $list list of items
|
||||
* @param string $direction ordering direction
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
public static function groupByTags($list, $direction = 'ksort')
|
||||
{
|
||||
$grouped = [];
|
||||
$untagged = [];
|
||||
|
||||
if (!$list) {
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
foreach ($list as $item) {
|
||||
if ($item->tags->itemTags) {
|
||||
foreach ($item->tags->itemTags as $tag) {
|
||||
$grouped[$tag->title][] = $item;
|
||||
}
|
||||
} else {
|
||||
$untagged[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
$direction($grouped);
|
||||
|
||||
if ($untagged) {
|
||||
$grouped['MOD_ARTICLES_UNTAGGED'] = $untagged;
|
||||
}
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles
|
||||
*
|
||||
* @copyright (C) 2024 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\Helper\ModuleHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $app->getDocument()->getWebAssetManager();
|
||||
$wa->registerAndUseStyle('mod_articles', 'mod_articles/mod-articles.css');
|
||||
|
||||
if (!$list) {
|
||||
return;
|
||||
}
|
||||
|
||||
$groupHeading = 'h4';
|
||||
|
||||
if ((bool) $module->showtitle) {
|
||||
$modTitle = $params->get('header_tag');
|
||||
|
||||
if ($modTitle == 'h1') {
|
||||
$groupHeading = 'h2';
|
||||
} elseif ($modTitle == 'h2') {
|
||||
$groupHeading = 'h3';
|
||||
}
|
||||
}
|
||||
|
||||
$layoutSuffix = $params->get('title_only', 0) ? '_titles' : '_items';
|
||||
|
||||
?>
|
||||
<?php if ($grouped) : ?>
|
||||
<?php foreach ($list as $groupName => $items) : ?>
|
||||
<div class="mod-articles-group">
|
||||
<<?php echo $groupHeading; ?>><?php echo Text::_($groupName); ?></<?php echo $groupHeading; ?>>
|
||||
<?php require ModuleHelper::getLayoutPath('mod_articles', $params->get('layout', 'default') . $layoutSuffix); ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php else : ?>
|
||||
<?php $items = $list; ?>
|
||||
<?php require ModuleHelper::getLayoutPath('mod_articles', $params->get('layout', 'default') . $layoutSuffix); ?>
|
||||
<?php endif;
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles
|
||||
*
|
||||
* @copyright (C) 2024 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;
|
||||
|
||||
if ($params->get('articles_layout') == 1) {
|
||||
$gridCols = 'grid-cols-' . $params->get('layout_columns');
|
||||
}
|
||||
|
||||
$currentDate = Factory::getDate()->format('Y-m-d H:i:s');
|
||||
|
||||
?>
|
||||
<ul class="mod-articles-items<?php echo ($params->get('articles_layout') == 1 ? ' mod-articles-grid ' . $gridCols : ''); ?> mod-list">
|
||||
<?php foreach ($items as $item) : ?>
|
||||
<?php
|
||||
$displayInfo = $item->displayHits || $item->displayAuthorName || $item->displayCategoryTitle || $item->displayDate;
|
||||
$canEdit = $item->params->get('access-edit');
|
||||
?>
|
||||
<?php if ($params->get('item_title') || $displayInfo || $params->get('show_tags') || $params->get('show_introtext') || $params->get('img_intro_full') && !empty($item->imageSrc) || $params->get('show_readmore')) : ?>
|
||||
<li>
|
||||
<article class="mod-articles-item" itemscope itemtype="https://schema.org/Article">
|
||||
<div class="mod-articles-item-content">
|
||||
|
||||
<?php if ($params->get('item_title')) : ?>
|
||||
<?php $item_heading = $params->get('item_heading', 'h4'); ?>
|
||||
<<?php echo $item_heading; ?> class="mod-articles-title" itemprop="name">
|
||||
<?php if ($params->get('link_titles') == 1) : ?>
|
||||
<?php $attributes = ['class' => 'mod-articles-link ' . $item->active, 'itemprop' => 'url']; ?>
|
||||
<?php $link = htmlspecialchars($item->link, ENT_COMPAT, 'UTF-8', false); ?>
|
||||
<?php $title = htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8', false); ?>
|
||||
<?php echo HTMLHelper::_('link', $link, $title, $attributes); ?>
|
||||
<?php else : ?>
|
||||
<?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>
|
||||
<?php endif; ?>
|
||||
</<?php echo $item_heading; ?>>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($item->state === 0) : ?>
|
||||
<span class="badge bg-warning"><?php echo Text::_('JUNPUBLISHED'); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($item->publish_up > $currentDate) : ?>
|
||||
<span class="badge bg-warning"><?php echo Text::_('JNOTPUBLISHEDYET'); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($item->publish_down !== null && $item->publish_down < $currentDate) : ?>
|
||||
<span class="badge bg-warning"><?php echo Text::_('JEXPIRED'); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php echo $item->event->afterDisplayTitle; ?>
|
||||
|
||||
<?php if ($displayInfo) : ?>
|
||||
<?php $listClass = ($params->get('info_layout') == 1) ? 'list-inline' : 'list-unstyled'; ?>
|
||||
<dl class="<?php echo $listClass; ?>">
|
||||
<dt class="article-info-term">
|
||||
<span class="visually-hidden">
|
||||
<?php echo Text::_('MOD_ARTICLES_INFO'); ?>
|
||||
</span>
|
||||
</dt>
|
||||
|
||||
<?php if ($item->displayAuthorName) : ?>
|
||||
<dd class="mod-articles-writtenby <?php echo ($params->get('info_layout') == 1 ? 'list-inline-item' : ''); ?>">
|
||||
<?php echo LayoutHelper::render('joomla.icon.iconclass', ['icon' => 'icon-user icon-fw']); ?>
|
||||
<?php echo htmlspecialchars($item->displayAuthorName, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</dd>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($item->displayCategoryTitle) : ?>
|
||||
<dd class="mod-articles-category <?php echo ($params->get('info_layout') == 1 ? 'list-inline-item' : ''); ?>">
|
||||
<?php echo LayoutHelper::render('joomla.icon.iconclass', ['icon' => 'icon-folder-open icon-fw']); ?>
|
||||
<?php if ($item->displayCategoryLink) : ?>
|
||||
<a href="<?php echo $item->displayCategoryLink; ?>">
|
||||
<?php echo htmlspecialchars($item->displayCategoryTitle, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<?php echo htmlspecialchars($item->displayCategoryTitle, ENT_QUOTES, 'UTF-8'); ?>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($item->displayDate) : ?>
|
||||
<dd class="mod-articles-date <?php echo ($params->get('info_layout') == 1 ? 'list-inline-item' : ''); ?>">
|
||||
<?php echo LayoutHelper::render('joomla.icon.iconclass', ['icon' => 'icon-calendar icon-fw']); ?>
|
||||
<?php echo htmlspecialchars($item->displayDate, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</dd>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($item->displayHits) : ?>
|
||||
<dd class="mod-articles-hits <?php echo ($params->get('info_layout') == 1 ? 'list-inline-item' : ''); ?>">
|
||||
<?php echo LayoutHelper::render('joomla.icon.iconclass', ['icon' => 'icon-eye icon-fw']); ?>
|
||||
<?php echo $item->displayHits; ?>
|
||||
</dd>
|
||||
<?php endif; ?>
|
||||
</dl>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (in_array($params->get('img_intro_full'), ['intro', 'full']) && !empty($item->imageSrc)) : ?>
|
||||
<?php echo LayoutHelper::render('joomla.content.' . $params->get('img_intro_full') . '_image', $item); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($params->get('show_tags', 0) && $item->tags->itemTags) : ?>
|
||||
<div class="mod-articles-tags">
|
||||
<?php echo LayoutHelper::render('joomla.content.tags', $item->tags->itemTags); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php echo $item->event->beforeDisplayContent; ?>
|
||||
|
||||
<?php if ($params->get('show_introtext', 1)) : ?>
|
||||
<?php echo $item->displayIntrotext; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php echo $item->event->afterDisplayContent; ?>
|
||||
|
||||
<?php if ($params->get('show_readmore') && !empty($item->fulltext)) : ?>
|
||||
<?php if ($params->get('show_readmore_title', '') !== '') : ?>
|
||||
<?php $item->params->set('show_readmore_title', $params->get('show_readmore_title')); ?>
|
||||
<?php $item->params->set('readmore_limit', $params->get('readmore_limit')); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo LayoutHelper::render('joomla.content.readmore', ['item' => $item, 'params' => $item->params, 'link' => $item->link]); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</article>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles
|
||||
*
|
||||
* @copyright (C) 2024 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\Language\Text;
|
||||
|
||||
$currentDate = Factory::getDate()->format('Y-m-d H:i:s');
|
||||
|
||||
?>
|
||||
<ul class="mod-articles mod-list">
|
||||
<?php foreach ($items as $item) : ?>
|
||||
<li itemscope itemtype="https://schema.org/Article">
|
||||
<a <?php echo $item->active ? 'class="' . $item->active . '" ' : ''; ?>href="<?php echo $item->link; ?>" itemprop="url">
|
||||
<span itemprop="name">
|
||||
<?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<?php if ($item->state == 0) : ?>
|
||||
<span class="badge bg-warning"><?php echo Text::_('JUNPUBLISHED'); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($item->publish_up > $currentDate) : ?>
|
||||
<span class="badge bg-warning"><?php echo Text::_('JNOTPUBLISHEDYET'); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($item->publish_down !== null && $item->publish_down < $currentDate) : ?>
|
||||
<span class="badge bg-warning"><?php echo Text::_('JEXPIRED'); ?></span>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_articles_archive</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2006-07</creationDate>
|
||||
<copyright>(C) 2006 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>3.0.0</version>
|
||||
<description>MOD_ARTICLES_ARCHIVE_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\ArticlesArchive</namespace>
|
||||
<files>
|
||||
<folder module="mod_articles_archive">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_articles_archive.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_articles_archive.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Articles_-_Archived" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic">
|
||||
<field
|
||||
name="count"
|
||||
type="number"
|
||||
label="MOD_ARTICLES_ARCHIVE_FIELD_COUNT_LABEL"
|
||||
default="10"
|
||||
filter="integer"
|
||||
min="1"
|
||||
validate="number"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cache"
|
||||
type="list"
|
||||
label="COM_MODULES_FIELD_CACHING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="cache_time"
|
||||
type="number"
|
||||
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
|
||||
default="900"
|
||||
filter="integer"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cachemode"
|
||||
type="hidden"
|
||||
default="static"
|
||||
>
|
||||
<option value="static"></option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_archive
|
||||
*
|
||||
* @copyright (C) 2023 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The articles archive module service provider.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\ArticlesArchive'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\ArticlesArchive\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_archive
|
||||
*
|
||||
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\ArticlesArchive\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_articles_archive
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
protected function getLayoutData(): array
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
|
||||
$data['list'] = $this->getHelperFactory()->getHelper('ArticlesArchiveHelper')->getArticlesByMonths($data['params'], $data['app']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_archive
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\ArticlesArchive\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Application\SiteApplication;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\Content\Administrator\Extension\ContentComponent;
|
||||
use Joomla\Database\DatabaseAwareInterface;
|
||||
use Joomla\Database\DatabaseAwareTrait;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Helper for mod_articles_archive
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class ArticlesArchiveHelper implements DatabaseAwareInterface
|
||||
{
|
||||
use DatabaseAwareTrait;
|
||||
|
||||
/**
|
||||
* Retrieve a list of months with archived articles
|
||||
*
|
||||
* @param Registry $moduleParams The module parameters.
|
||||
* @param SiteApplication $app The current application.
|
||||
*
|
||||
* @return \stdClass[]
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
public function getArticlesByMonths(Registry $moduleParams, SiteApplication $app): array
|
||||
{
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->createQuery();
|
||||
|
||||
$query->select($query->month($db->quoteName('created')) . ' AS created_month')
|
||||
->select('MIN(' . $db->quoteName('created') . ') AS created')
|
||||
->select($query->year($db->quoteName('created')) . ' AS created_year')
|
||||
->from($db->quoteName('#__content', 'c'))
|
||||
->where($db->quoteName('c.state') . ' = ' . ContentComponent::CONDITION_ARCHIVED)
|
||||
->group($query->year($db->quoteName('c.created')) . ', ' . $query->month($db->quoteName('c.created')))
|
||||
->order($query->year($db->quoteName('c.created')) . ' DESC, ' . $query->month($db->quoteName('c.created')) . ' DESC');
|
||||
|
||||
// Filter by language
|
||||
if ($app->getLanguageFilter()) {
|
||||
$query->whereIn($db->quoteName('language'), [$app->getLanguage()->getTag(), '*'], ParameterType::STRING);
|
||||
}
|
||||
|
||||
$query->setLimit((int) $moduleParams->get('count'));
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
$rows = (array) $db->loadObjectList();
|
||||
} catch (\RuntimeException) {
|
||||
$app->enqueueMessage(Text::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error');
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
$menu = $app->getMenu();
|
||||
$item = $menu->getItems('link', 'index.php?option=com_content&view=archive', true);
|
||||
$itemid = (isset($item) && !empty($item->id)) ? '&Itemid=' . $item->id : '';
|
||||
|
||||
$i = 0;
|
||||
$lists = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$date = Factory::getDate($row->created);
|
||||
|
||||
$createdMonth = $date->format('n');
|
||||
$createdYear = $date->format('Y');
|
||||
|
||||
$createdYearCal = HTMLHelper::_('date', $row->created, 'Y');
|
||||
$monthNameCal = HTMLHelper::_('date', $row->created, 'F');
|
||||
|
||||
$lists[$i] = new \stdClass();
|
||||
|
||||
$lists[$i]->link = Route::_('index.php?option=com_content&view=archive&year=' . $createdYear . '&month=' . $createdMonth . $itemid);
|
||||
$lists[$i]->text = Text::sprintf('MOD_ARTICLES_ARCHIVE_DATE', $monthNameCal, $createdYearCal);
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
return $lists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve list of archived articles
|
||||
*
|
||||
* @param Registry &$params module parameters
|
||||
*
|
||||
* @return \stdClass[]
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @deprecated 4.4.0 will be removed in 7.0
|
||||
* Use the non-static method getArticlesByMonths
|
||||
* Example: Factory::getApplication()->bootModule('mod_articles_archive', 'site')
|
||||
* ->getHelper('ArticlesArchiveHelper')
|
||||
* ->getArticlesByMonths($params, Factory::getApplication())
|
||||
*/
|
||||
public static function getList(&$params)
|
||||
{
|
||||
/** @var SiteApplication $app */
|
||||
$app = Factory::getApplication();
|
||||
|
||||
return (new self())->getArticlesByMonths($params, $app);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_archive
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
if (!$list) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<ul class="mod-articlesarchive archive-module mod-list">
|
||||
<?php foreach ($list as $item) : ?>
|
||||
<li>
|
||||
<a href="<?php echo $item->link; ?>">
|
||||
<?php echo $item->text; ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
@@ -0,0 +1,173 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_articles_categories</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2010-02</creationDate>
|
||||
<copyright>(C) 2010 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>3.0.0</version>
|
||||
<description>MOD_ARTICLES_CATEGORIES_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\ArticlesCategories</namespace>
|
||||
<files>
|
||||
<folder module="mod_articles_categories">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_articles_categories.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_articles_categories.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Articles_-_Categories" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic" addfieldprefix="Joomla\Component\Categories\Administrator\Field">
|
||||
<field
|
||||
name="parent"
|
||||
type="modal_category"
|
||||
label="MOD_ARTICLES_CATEGORIES_FIELD_PARENT_LABEL"
|
||||
extension="com_content"
|
||||
filter="integer"
|
||||
published=""
|
||||
select="true"
|
||||
new="true"
|
||||
edit="true"
|
||||
clear="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_description"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_CATEGORIES_FIELD_SHOW_DESCRIPTION_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="numitems"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_CATEGORIES_FIELD_NUMITEMS_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_children"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_CATEGORIES_FIELD_SHOW_CHILDREN_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="count"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_CATEGORIES_FIELD_COUNT_LABEL"
|
||||
description="MOD_ARTICLES_CATEGORIES_FIELD_COUNT_DESC"
|
||||
default="0"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">JALL</option>
|
||||
<option value="1">J1</option>
|
||||
<option value="2">J2</option>
|
||||
<option value="3">J3</option>
|
||||
<option value="4">J4</option>
|
||||
<option value="5">J5</option>
|
||||
<option value="6">J6</option>
|
||||
<option value="7">J7</option>
|
||||
<option value="8">J8</option>
|
||||
<option value="9">J9</option>
|
||||
<option value="10">J10</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="maxlevel"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_CATEGORIES_FIELD_MAXLEVEL_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">JALL</option>
|
||||
<option value="1">J1</option>
|
||||
<option value="2">J2</option>
|
||||
<option value="3">J3</option>
|
||||
<option value="4">J4</option>
|
||||
<option value="5">J5</option>
|
||||
<option value="6">J6</option>
|
||||
<option value="7">J7</option>
|
||||
<option value="8">J8</option>
|
||||
<option value="9">J9</option>
|
||||
<option value="10">J10</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="item_heading"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_CATEGORIES_TITLE_HEADING_LABEL"
|
||||
default="4"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JH1</option>
|
||||
<option value="2">JH2</option>
|
||||
<option value="3">JH3</option>
|
||||
<option value="4">JH4</option>
|
||||
<option value="5">JH5</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="owncache"
|
||||
type="list"
|
||||
label="COM_MODULES_FIELD_CACHING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="cache_time"
|
||||
type="number"
|
||||
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
|
||||
default="900"
|
||||
filter="integer"
|
||||
/>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_categories
|
||||
*
|
||||
* @copyright (C) 2022 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The articles categories module service provider.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\ArticlesCategories'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\ArticlesCategories\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_categories
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\ArticlesCategories\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
use Joomla\CMS\Helper\ModuleHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_articles_categories
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
protected function getLayoutData(): array
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
$params = $data['params'];
|
||||
|
||||
$cacheParams = new \stdClass();
|
||||
$cacheParams->cachemode = 'id';
|
||||
$cacheParams->class = $this->getHelperFactory()->getHelper('ArticlesCategoriesHelper');
|
||||
$cacheParams->method = 'getChildrenCategories';
|
||||
$cacheParams->methodparams = [$params, $data['app']];
|
||||
$cacheParams->modeparams = md5(serialize($this->module->id));
|
||||
|
||||
$data['list'] = ModuleHelper::moduleCache($this->module, $params, $cacheParams);
|
||||
|
||||
$data['startLevel'] = $data['list'] ? reset($data['list'])->getParent()->level : null;
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_categories
|
||||
*
|
||||
* @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\ArticlesCategories\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Application\SiteApplication;
|
||||
use Joomla\CMS\Categories\CategoryInterface;
|
||||
use Joomla\CMS\Categories\CategoryNode;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\Database\DatabaseAwareInterface;
|
||||
use Joomla\Database\DatabaseAwareTrait;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Helper for mod_articles_categories
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class ArticlesCategoriesHelper implements DatabaseAwareInterface
|
||||
{
|
||||
use DatabaseAwareTrait;
|
||||
|
||||
/**
|
||||
* Given a parent category, return a list of children categories
|
||||
*
|
||||
* @param Registry $moduleParams The module parameters.
|
||||
* @param SiteApplication $app The current application.
|
||||
*
|
||||
* @return CategoryNode[]
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
public function getChildrenCategories(Registry $moduleParams, SiteApplication $app): array
|
||||
{
|
||||
// Joomla\CMS\Categories\Categories options to set
|
||||
$options = [];
|
||||
|
||||
// Get the number of items in this category or descendants of this category at the expense of performance.
|
||||
$options['countItems'] = $moduleParams->get('numitems', 0);
|
||||
|
||||
/** @var CategoryInterface $categoryFactory */
|
||||
$categoryFactory = $app->bootComponent('com_content')->getCategory($options);
|
||||
|
||||
/** @var CategoryNode $parentCategory */
|
||||
$parentCategory = $categoryFactory->get($moduleParams->get('parent', 'root'));
|
||||
|
||||
if ($parentCategory === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Get all the children categories of this node
|
||||
$childrenCategories = $parentCategory->getChildren();
|
||||
|
||||
$count = $moduleParams->get('count', 0);
|
||||
|
||||
if ($count > 0 && \count($childrenCategories) > $count) {
|
||||
$childrenCategories = \array_slice($childrenCategories, 0, $count);
|
||||
}
|
||||
|
||||
return $childrenCategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of categories
|
||||
*
|
||||
* @param Registry $params module parameters
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @deprecated 4.4.0 will be removed in 7.0
|
||||
* Use the non-static method getChildrenCategories
|
||||
* Example: Factory::getApplication()->bootModule('mod_articles_categories', 'site')
|
||||
* ->getHelper('ArticlesCategoriesHelper')
|
||||
* ->getChildrenCategories($params, Factory::getApplication())
|
||||
*/
|
||||
public static function getList($params)
|
||||
{
|
||||
/** @var SiteApplication $app */
|
||||
$app = Factory::getApplication();
|
||||
|
||||
return (new self())->getChildrenCategories($params, $app);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_categories
|
||||
*
|
||||
* @copyright (C) 2010 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\Helper\ModuleHelper;
|
||||
|
||||
if (!$list) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<ul class="mod-articlescategories categories-module mod-list">
|
||||
<?php require ModuleHelper::getLayoutPath('mod_articles_categories', $params->get('layout', 'default') . '_items'); ?>
|
||||
</ul>
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_categories
|
||||
*
|
||||
* @copyright (C) 2010 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\Helper\ModuleHelper;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\Content\Site\Helper\RouteHelper;
|
||||
|
||||
$input = $app->getInput();
|
||||
$option = $input->getCmd('option');
|
||||
$view = $input->getCmd('view');
|
||||
$id = $input->getInt('id');
|
||||
|
||||
foreach ($list as $item) : ?>
|
||||
<li<?php if ($id == $item->id && in_array($view, ['category', 'categories']) && $option == 'com_content') {
|
||||
echo ' class="active"';
|
||||
} ?>>
|
||||
<a href="<?php echo Route::_(RouteHelper::getCategoryRoute($item->id, $item->language)); ?>">
|
||||
<?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>
|
||||
<?php if ($params->get('numitems')) : ?>
|
||||
(<?php echo $item->numitems; ?>)
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
|
||||
<?php if ($params->get('show_description', 0)) : ?>
|
||||
<?php echo HTMLHelper::_('content.prepare', $item->description, $item->getParams(), 'mod_articles_categories.content'); ?>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
if (
|
||||
$params->get('show_children', 0) && (($params->get('maxlevel', 0) == 0)
|
||||
|| ($params->get('maxlevel') >= ($item->level - $startLevel)))
|
||||
&& count($item->getChildren())
|
||||
) : ?>
|
||||
<?php echo '<ul>'; ?>
|
||||
<?php $temp = $list; ?>
|
||||
<?php $list = $item->getChildren(); ?>
|
||||
<?php require ModuleHelper::getLayoutPath('mod_articles_categories', $params->get('layout', 'default') . '_items'); ?>
|
||||
<?php $list = $temp; ?>
|
||||
<?php echo '</ul>'; ?>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
@@ -0,0 +1,571 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_articles_category</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2010-02</creationDate>
|
||||
<copyright>(C) 2010 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>3.0.0</version>
|
||||
<description>MOD_ARTICLES_CATEGORY_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\ArticlesCategory</namespace>
|
||||
<files>
|
||||
<folder module="mod_articles_category">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_articles_category.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_articles_category.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Articles_-_Category" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic">
|
||||
<field
|
||||
name="mode"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_MODE_LABEL"
|
||||
description="MOD_ARTICLES_CATEGORY_FIELD_MODE_DESC"
|
||||
default="normal"
|
||||
validate="options"
|
||||
>
|
||||
<option value="normal">MOD_ARTICLES_CATEGORY_OPTION_NORMAL_VALUE</option>
|
||||
<option value="dynamic">MOD_ARTICLES_CATEGORY_OPTION_DYNAMIC_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_on_article_page"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_SHOWONARTICLEPAGE_LABEL"
|
||||
description="MOD_ARTICLES_CATEGORY_FIELD_SHOWONARTICLEPAGE_DESC"
|
||||
default="1"
|
||||
filter="integer"
|
||||
showon="mode:dynamic"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
|
||||
<fieldset
|
||||
name="filtering"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_GROUP_FILTERING_LABEL"
|
||||
>
|
||||
|
||||
<field
|
||||
name="count"
|
||||
type="number"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_COUNT_LABEL"
|
||||
description="MOD_ARTICLES_CATEGORY_FIELD_COUNT_DESC"
|
||||
default="0"
|
||||
filter="integer"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_front"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_SHOWFEATURED_LABEL"
|
||||
default="show"
|
||||
validate="options"
|
||||
>
|
||||
<option value="show">JSHOW</option>
|
||||
<option value="hide">JHIDE</option>
|
||||
<option value="only">MOD_ARTICLES_CATEGORY_OPTION_ONLYFEATURED_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="filteringspacer0"
|
||||
type="spacer"
|
||||
hr="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="category_filtering_type"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_CATFILTERINGTYPE_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">MOD_ARTICLES_CATEGORY_OPTION_EXCLUSIVE_VALUE</option>
|
||||
<option value="1">MOD_ARTICLES_CATEGORY_OPTION_INCLUSIVE_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="catid"
|
||||
type="category"
|
||||
label="JCATEGORY"
|
||||
extension="com_content"
|
||||
multiple="true"
|
||||
layout="joomla.form.field.list-fancy-select"
|
||||
filter="intarray"
|
||||
class="multipleCategories"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_child_category_articles"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_SHOWCHILDCATEGORYARTICLES_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">MOD_ARTICLES_CATEGORY_OPTION_EXCLUDE_VALUE</option>
|
||||
<option value="1">MOD_ARTICLES_CATEGORY_OPTION_INCLUDE_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="levels"
|
||||
type="number"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_CATDEPTH_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
showon="show_child_category_articles:1"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="filteringspacer1"
|
||||
type="spacer"
|
||||
hr="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="filter_tag"
|
||||
type="tag"
|
||||
label="JTAG"
|
||||
mode="nested"
|
||||
multiple="true"
|
||||
filter="intarray"
|
||||
class="multipleTags"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="filteringspacer2"
|
||||
type="spacer"
|
||||
hr="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="author_filtering_type"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_AUTHORFILTERING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">MOD_ARTICLES_CATEGORY_OPTION_EXCLUSIVE_VALUE</option>
|
||||
<option value="1">MOD_ARTICLES_CATEGORY_OPTION_INCLUSIVE_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="created_by"
|
||||
type="author"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_AUTHOR_LABEL"
|
||||
multiple="true"
|
||||
layout="joomla.form.field.list-fancy-select"
|
||||
filter="intarray"
|
||||
class="multipleAuthors"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="filteringspacer3"
|
||||
type="spacer"
|
||||
hr="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="author_alias_filtering_type"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_AUTHORALIASFILTERING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">MOD_ARTICLES_CATEGORY_OPTION_EXCLUSIVE_VALUE</option>
|
||||
<option value="1">MOD_ARTICLES_CATEGORY_OPTION_INCLUSIVE_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="created_by_alias"
|
||||
type="sql"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_AUTHORALIAS_LABEL"
|
||||
multiple="true"
|
||||
layout="joomla.form.field.list-fancy-select"
|
||||
query="select distinct(created_by_alias) from #__content where created_by_alias != '' order by created_by_alias ASC"
|
||||
key_field="created_by_alias"
|
||||
value_field="created_by_alias"
|
||||
class="multipleAuthorAliases"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="filteringspacer4"
|
||||
type="spacer"
|
||||
hr="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="excluded_articles"
|
||||
type="textarea"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_EXCLUDEDARTICLES_LABEL"
|
||||
cols="10"
|
||||
rows="3"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="filteringspacer5"
|
||||
type="spacer"
|
||||
hr="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="date_filtering"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_DATEFILTERING_LABEL"
|
||||
default="off"
|
||||
validate="options"
|
||||
>
|
||||
<option value="off">MOD_ARTICLES_CATEGORY_OPTION_OFF_VALUE</option>
|
||||
<option value="range">MOD_ARTICLES_CATEGORY_OPTION_DATERANGE_VALUE</option>
|
||||
<option value="relative">MOD_ARTICLES_CATEGORY_OPTION_RELATIVEDAY_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="date_field"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_DATERANGEFIELD_LABEL"
|
||||
default="a.created"
|
||||
showon="date_filtering!:off"
|
||||
validate="options"
|
||||
>
|
||||
<option value="a.created">MOD_ARTICLES_CATEGORY_OPTION_CREATED_VALUE</option>
|
||||
<option value="a.modified">MOD_ARTICLES_CATEGORY_OPTION_MODIFIED_VALUE</option>
|
||||
<option value="a.publish_up">MOD_ARTICLES_CATEGORY_OPTION_STARTPUBLISHING_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="start_date_range"
|
||||
type="calendar"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_STARTDATE_LABEL"
|
||||
translateformat="true"
|
||||
showtime="true"
|
||||
filter="user_utc"
|
||||
showon="date_filtering:range"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="end_date_range"
|
||||
type="calendar"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_ENDDATE_LABEL"
|
||||
translateformat="true"
|
||||
showtime="true"
|
||||
filter="user_utc"
|
||||
showon="date_filtering:range"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="relative_date"
|
||||
type="number"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_RELATIVEDATE_LABEL"
|
||||
default="30"
|
||||
filter="integer"
|
||||
showon="date_filtering:relative"
|
||||
/>
|
||||
|
||||
</fieldset>
|
||||
|
||||
<fieldset
|
||||
name="ordering"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_GROUP_ORDERING_LABEL"
|
||||
>
|
||||
|
||||
<field
|
||||
name="article_ordering"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_ARTICLEORDERING_LABEL"
|
||||
default="a.title"
|
||||
validate="options"
|
||||
>
|
||||
<option value="a.ordering">MOD_ARTICLES_CATEGORY_OPTION_ORDERING_VALUE</option>
|
||||
<option value="fp.ordering">MOD_ARTICLES_CATEGORY_OPTION_ORDERINGFEATURED_VALUE</option>
|
||||
<option value="a.hits" requires="hits">MOD_ARTICLES_CATEGORY_OPTION_HITS_VALUE</option>
|
||||
<option value="a.title">JGLOBAL_TITLE</option>
|
||||
<option value="a.id">MOD_ARTICLES_CATEGORY_OPTION_ID_VALUE</option>
|
||||
<option value="a.alias">JFIELD_ALIAS_LABEL</option>
|
||||
<option value="a.created">MOD_ARTICLES_CATEGORY_OPTION_CREATED_VALUE</option>
|
||||
<option value="modified">MOD_ARTICLES_CATEGORY_OPTION_MODIFIED_VALUE</option>
|
||||
<option value="publish_up">MOD_ARTICLES_CATEGORY_OPTION_STARTPUBLISHING_VALUE</option>
|
||||
<option value="a.publish_down">MOD_ARTICLES_CATEGORY_OPTION_FINISHPUBLISHING_VALUE</option>
|
||||
<option value="random">MOD_ARTICLES_CATEGORY_OPTION_RANDOM_VALUE</option>
|
||||
<option value="rating_count" requires="vote">MOD_ARTICLES_CATEGORY_OPTION_VOTE_VALUE</option>
|
||||
<option value="rating" requires="vote">MOD_ARTICLES_CATEGORY_OPTION_RATING_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="article_ordering_direction"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_ARTICLEORDERINGDIR_LABEL"
|
||||
default="ASC"
|
||||
validate="options"
|
||||
>
|
||||
<option value="DESC">MOD_ARTICLES_CATEGORY_OPTION_DESCENDING_VALUE</option>
|
||||
<option value="ASC">MOD_ARTICLES_CATEGORY_OPTION_ASCENDING_VALUE</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
|
||||
<fieldset
|
||||
name="grouping"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_GROUP_GROUPING_LABEL"
|
||||
>
|
||||
|
||||
<field
|
||||
name="article_grouping"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_ARTICLEGROUPING_LABEL"
|
||||
default="none"
|
||||
validate="options"
|
||||
>
|
||||
<option value="none">JNONE</option>
|
||||
<option value="year">MOD_ARTICLES_CATEGORY_OPTION_YEAR_VALUE</option>
|
||||
<option value="month_year">MOD_ARTICLES_CATEGORY_OPTION_MONTHYEAR_VALUE</option>
|
||||
<option value="author">JAUTHOR</option>
|
||||
<option value="category_title">JCATEGORY</option>
|
||||
<option value="tags">JTAG</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="date_grouping_field"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_DATEGROUPINGFIELD_LABEL"
|
||||
description="MOD_ARTICLES_CATEGORY_FIELD_DATEGROUPINGFIELD_DESC"
|
||||
default="created"
|
||||
showon="article_grouping:year,month_year"
|
||||
validate="options"
|
||||
>
|
||||
<option value="created">MOD_ARTICLES_CATEGORY_OPTION_CREATED_VALUE</option>
|
||||
<option value="modified">MOD_ARTICLES_CATEGORY_OPTION_MODIFIED_VALUE</option>
|
||||
<option value="publish_up">MOD_ARTICLES_CATEGORY_OPTION_STARTPUBLISHING_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="month_year_format"
|
||||
type="text"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_MONTHYEARFORMAT_LABEL"
|
||||
description="MOD_ARTICLES_CATEGORY_FIELD_MONTHYEARFORMAT_DESC"
|
||||
default="F Y"
|
||||
showon="article_grouping:year,month_year"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="article_grouping_direction"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_ARTICLEGROUPINGDIR_LABEL"
|
||||
default="ksort"
|
||||
showon="article_grouping!:none"
|
||||
validate="options"
|
||||
>
|
||||
<option value="krsort">MOD_ARTICLES_CATEGORY_OPTION_DESCENDING_VALUE</option>
|
||||
<option value="ksort">MOD_ARTICLES_CATEGORY_OPTION_ASCENDING_VALUE</option>
|
||||
</field>
|
||||
|
||||
</fieldset>
|
||||
|
||||
<fieldset
|
||||
name="display"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_GROUP_DISPLAY_LABEL"
|
||||
>
|
||||
|
||||
<field
|
||||
name="link_titles"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_LINKTITLES_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_date"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="JDATE"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_date_field"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_DATEFIELD_LABEL"
|
||||
default="created"
|
||||
showon="show_date:1"
|
||||
validate="options"
|
||||
>
|
||||
<option value="created">MOD_ARTICLES_CATEGORY_OPTION_CREATED_VALUE</option>
|
||||
<option value="modified">MOD_ARTICLES_CATEGORY_OPTION_MODIFIED_VALUE</option>
|
||||
<option value="publish_up">MOD_ARTICLES_CATEGORY_OPTION_STARTPUBLISHING_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_date_format"
|
||||
type="text"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_DATEFIELDFORMAT_LABEL"
|
||||
description="MOD_ARTICLES_CATEGORY_FIELD_DATEFIELDFORMAT_DESC"
|
||||
default="Y-m-d H:i:s"
|
||||
showon="show_date:1"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_category"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="JCATEGORY"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_hits"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_SHOWHITS_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_author"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="JAUTHOR"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_tags"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="JTAG"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_introtext"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_SHOWINTROTEXT_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="introtext_limit"
|
||||
type="number"
|
||||
label="MOD_ARTICLES_CATEGORY_FIELD_INTROTEXTLIMIT_LABEL"
|
||||
default="100"
|
||||
filter="integer"
|
||||
showon="show_introtext:1"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_readmore"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="JGLOBAL_SHOW_READMORE_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_readmore_title"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="JGLOBAL_SHOW_READMORE_TITLE_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
showon="show_readmore:1"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="readmore_limit"
|
||||
type="number"
|
||||
label="JGLOBAL_SHOW_READMORE_LIMIT_LABEL"
|
||||
default="15"
|
||||
filter="integer"
|
||||
showon="show_readmore:1[AND]show_readmore_title:1"
|
||||
/>
|
||||
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="advanced">
|
||||
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="owncache"
|
||||
type="list"
|
||||
label="COM_MODULES_FIELD_CACHING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="cache_time"
|
||||
type="number"
|
||||
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
|
||||
default="900"
|
||||
filter="integer"
|
||||
/>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_category
|
||||
*
|
||||
* @copyright (C) 2022 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The articles category module service provider.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\ArticlesCategory'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\ArticlesCategory\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_category
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\ArticlesCategory\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
use Joomla\CMS\Helper\ModuleHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_articles_category
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
protected function getLayoutData(): array
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
$params = $data['params'];
|
||||
|
||||
// Prep for Normal or Dynamic Modes
|
||||
$mode = $params->get('mode', 'normal');
|
||||
$idBase = null;
|
||||
|
||||
switch ($mode) {
|
||||
case 'dynamic':
|
||||
$option = $data['input']->get('option');
|
||||
$view = $data['input']->get('view');
|
||||
|
||||
if ($option === 'com_content') {
|
||||
switch ($view) {
|
||||
case 'category':
|
||||
case 'categories':
|
||||
$idBase = $data['input']->getInt('id');
|
||||
break;
|
||||
case 'article':
|
||||
if ($params->get('show_on_article_page', 1)) {
|
||||
$idBase = $data['input']->getInt('catid');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$idBase = $params->get('catid');
|
||||
break;
|
||||
}
|
||||
|
||||
$cacheParams = new \stdClass();
|
||||
$cacheParams->cachemode = 'id';
|
||||
$cacheParams->class = $this->getHelperFactory()->getHelper('ArticlesCategoryHelper');
|
||||
$cacheParams->method = 'getArticles';
|
||||
$cacheParams->methodparams = [$params, $data['app']];
|
||||
$cacheParams->modeparams = md5(serialize([$idBase, $this->module->module, $this->module->id]));
|
||||
|
||||
$data['list'] = ModuleHelper::moduleCache($this->module, $params, $cacheParams);
|
||||
|
||||
$data['grouped'] = $params->get('article_grouping', 'none') !== 'none';
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,553 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_category
|
||||
*
|
||||
* @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\ArticlesCategory\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Access\Access;
|
||||
use Joomla\CMS\Application\SiteApplication;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Date\Date;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\Content\Administrator\Extension\ContentComponent;
|
||||
use Joomla\Component\Content\Site\Helper\RouteHelper;
|
||||
use Joomla\Database\DatabaseAwareInterface;
|
||||
use Joomla\Database\DatabaseAwareTrait;
|
||||
use Joomla\Registry\Registry;
|
||||
use Joomla\String\StringHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Helper for mod_articles_category
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class ArticlesCategoryHelper implements DatabaseAwareInterface
|
||||
{
|
||||
use DatabaseAwareTrait;
|
||||
|
||||
/**
|
||||
* Retrieve a list of article
|
||||
*
|
||||
* @param Registry $params The module parameters.
|
||||
* @param SiteApplication $app The current application.
|
||||
*
|
||||
* @return object[]
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
public function getArticles(Registry $params, SiteApplication $app)
|
||||
{
|
||||
$factory = $app->bootComponent('com_content')->getMVCFactory();
|
||||
|
||||
// Get an instance of the generic articles model
|
||||
$articles = $factory->createModel('Articles', 'Site', ['ignore_request' => true]);
|
||||
|
||||
// Set application parameters in model
|
||||
$input = $app->getInput();
|
||||
$appParams = $app->getParams();
|
||||
$articles->setState('params', $appParams);
|
||||
|
||||
$articles->setState('list.start', 0);
|
||||
$articles->setState('filter.published', ContentComponent::CONDITION_PUBLISHED);
|
||||
|
||||
// Set the filters based on the module params
|
||||
$articles->setState('list.limit', (int) $params->get('count', 0));
|
||||
$articles->setState('load_tags', $params->get('show_tags', 0) || $params->get('article_grouping', 'none') === 'tags');
|
||||
|
||||
// Access filter
|
||||
$access = !ComponentHelper::getParams('com_content')->get('show_noauth');
|
||||
$authorised = Access::getAuthorisedViewLevels($app->getIdentity()->id);
|
||||
$articles->setState('filter.access', $access);
|
||||
|
||||
// Prep for Normal or Dynamic Modes
|
||||
$mode = $params->get('mode', 'normal');
|
||||
|
||||
switch ($mode) {
|
||||
case 'dynamic':
|
||||
$option = $input->get('option');
|
||||
$view = $input->get('view');
|
||||
|
||||
if ($option === 'com_content') {
|
||||
switch ($view) {
|
||||
case 'category':
|
||||
case 'categories':
|
||||
$catids = [$input->getInt('id')];
|
||||
break;
|
||||
case 'article':
|
||||
if ($params->get('show_on_article_page', 1)) {
|
||||
$article_id = $input->getInt('id');
|
||||
$catid = $input->getInt('catid');
|
||||
|
||||
if (!$catid) {
|
||||
// Get an instance of the generic article model
|
||||
$article = $factory->createModel('Article', 'Site', ['ignore_request' => true]);
|
||||
|
||||
$article->setState('params', $appParams);
|
||||
$article->setState('filter.published', 1);
|
||||
$article->setState('article.id', (int) $article_id);
|
||||
$item = $article->getItem();
|
||||
$catids = [$item->catid];
|
||||
} else {
|
||||
$catids = [$catid];
|
||||
}
|
||||
} else {
|
||||
// Return right away if show_on_article_page option is off
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Return right away if not on the category or article views
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Return right away if not on a com_content page
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$catids = $params->get('catid');
|
||||
$articles->setState('filter.category_id.include', (bool) $params->get('category_filtering_type', 1));
|
||||
break;
|
||||
}
|
||||
|
||||
// Category filter
|
||||
if ($catids) {
|
||||
if ($params->get('show_child_category_articles', 0) && (int) $params->get('levels', 0) > 0) {
|
||||
// Get an instance of the generic categories model
|
||||
$categories = $factory->createModel('Categories', 'Site', ['ignore_request' => true]);
|
||||
$categories->setState('params', $appParams);
|
||||
$levels = $params->get('levels', 1) ?: 9999;
|
||||
$categories->setState('filter.get_children', $levels);
|
||||
$categories->setState('filter.published', 1);
|
||||
$categories->setState('filter.access', $access);
|
||||
$additional_catids = [];
|
||||
|
||||
foreach ($catids as $catid) {
|
||||
$categories->setState('filter.parentId', $catid);
|
||||
$recursive = true;
|
||||
$items = $categories->getItems($recursive);
|
||||
|
||||
if ($items) {
|
||||
foreach ($items as $category) {
|
||||
$condition = (($category->level - $categories->getParent()->level) <= $levels);
|
||||
|
||||
if ($condition) {
|
||||
$additional_catids[] = $category->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$catids = array_unique(array_merge($catids, $additional_catids));
|
||||
}
|
||||
|
||||
$articles->setState('filter.category_id', $catids);
|
||||
}
|
||||
|
||||
// Ordering
|
||||
$ordering = $params->get('article_ordering', 'a.ordering');
|
||||
|
||||
switch ($ordering) {
|
||||
case 'random':
|
||||
$articles->setState('list.ordering', $this->getDatabase()->createQuery()->rand());
|
||||
break;
|
||||
|
||||
case 'rating_count':
|
||||
case 'rating':
|
||||
$articles->setState('list.ordering', $ordering);
|
||||
$articles->setState('list.direction', $params->get('article_ordering_direction', 'ASC'));
|
||||
|
||||
if (!PluginHelper::isEnabled('content', 'vote')) {
|
||||
$articles->setState('list.ordering', 'a.ordering');
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$articles->setState('list.ordering', $ordering);
|
||||
$articles->setState('list.direction', $params->get('article_ordering_direction', 'ASC'));
|
||||
break;
|
||||
}
|
||||
|
||||
// Filter by multiple tags
|
||||
$articles->setState('filter.tag', $params->get('filter_tag', []));
|
||||
|
||||
$articles->setState('filter.featured', $params->get('show_front', 'show'));
|
||||
$articles->setState('filter.author_id', $params->get('created_by', []));
|
||||
$articles->setState('filter.author_id.include', $params->get('author_filtering_type', 1));
|
||||
$articles->setState('filter.author_alias', $params->get('created_by_alias', []));
|
||||
$articles->setState('filter.author_alias.include', $params->get('author_alias_filtering_type', 1));
|
||||
$excluded_articles = $params->get('excluded_articles', '');
|
||||
|
||||
if ($excluded_articles) {
|
||||
$excluded_articles = explode("\r\n", $excluded_articles);
|
||||
$articles->setState('filter.article_id', $excluded_articles);
|
||||
|
||||
// Exclude
|
||||
$articles->setState('filter.article_id.include', false);
|
||||
}
|
||||
|
||||
$date_filtering = $params->get('date_filtering', 'off');
|
||||
|
||||
if ($date_filtering !== 'off') {
|
||||
$articles->setState('filter.date_filtering', $date_filtering);
|
||||
$articles->setState('filter.date_field', $params->get('date_field', 'a.created'));
|
||||
$articles->setState('filter.start_date_range', $params->get('start_date_range', '1000-01-01 00:00:00'));
|
||||
$articles->setState('filter.end_date_range', $params->get('end_date_range', '9999-12-31 23:59:59'));
|
||||
$articles->setState('filter.relative_date', $params->get('relative_date', 30));
|
||||
}
|
||||
|
||||
// Filter by language
|
||||
$articles->setState('filter.language', $app->getLanguageFilter());
|
||||
|
||||
$items = $articles->getItems();
|
||||
|
||||
// Display options
|
||||
$show_date = $params->get('show_date', 0);
|
||||
$show_date_field = $params->get('show_date_field', 'created');
|
||||
$show_date_format = $params->get('show_date_format', 'Y-m-d H:i:s');
|
||||
$show_category = $params->get('show_category', 0);
|
||||
$show_hits = $params->get('show_hits', 0);
|
||||
$show_author = $params->get('show_author', 0);
|
||||
$show_introtext = $params->get('show_introtext', 0);
|
||||
$introtext_limit = $params->get('introtext_limit', 100);
|
||||
|
||||
// Find current Article ID if on an article page
|
||||
$option = $input->get('option');
|
||||
$view = $input->get('view');
|
||||
|
||||
if ($option === 'com_content' && $view === 'article') {
|
||||
$active_article_id = $input->getInt('id');
|
||||
} else {
|
||||
$active_article_id = 0;
|
||||
}
|
||||
|
||||
// Prepare data for display using display options
|
||||
foreach ($items as &$item) {
|
||||
$item->slug = $item->id . ':' . $item->alias;
|
||||
|
||||
if ($access || \in_array($item->access, $authorised)) {
|
||||
// We know that user has the privilege to view the article
|
||||
$item->link = Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language));
|
||||
} else {
|
||||
$menu = $app->getMenu();
|
||||
$menuitems = $menu->getItems('link', 'index.php?option=com_users&view=login');
|
||||
|
||||
if (isset($menuitems[0])) {
|
||||
$Itemid = $menuitems[0]->id;
|
||||
} elseif ($input->getInt('Itemid') > 0) {
|
||||
// Use Itemid from requesting page only if there is no existing menu
|
||||
$Itemid = $input->getInt('Itemid');
|
||||
}
|
||||
|
||||
$item->link = Route::_('index.php?option=com_users&view=login&Itemid=' . $Itemid);
|
||||
}
|
||||
|
||||
// Used for styling the active article
|
||||
$item->active = $item->id == $active_article_id ? 'active' : '';
|
||||
$item->displayDate = '';
|
||||
|
||||
if ($show_date) {
|
||||
$item->displayDate = HTMLHelper::_('date', $item->$show_date_field, $show_date_format);
|
||||
}
|
||||
|
||||
if ($item->catid) {
|
||||
$item->displayCategoryLink = Route::_(RouteHelper::getCategoryRoute($item->catid, $item->category_language));
|
||||
$item->displayCategoryTitle = $show_category ? '<a href="' . $item->displayCategoryLink . '">' . $item->category_title . '</a>' : '';
|
||||
} else {
|
||||
$item->displayCategoryTitle = $show_category ? $item->category_title : '';
|
||||
}
|
||||
|
||||
$item->displayHits = $show_hits ? $item->hits : '';
|
||||
$item->displayAuthorName = $show_author ? $item->author : '';
|
||||
|
||||
if ($show_introtext) {
|
||||
$item->introtext = HTMLHelper::_('content.prepare', $item->introtext, '', 'mod_articles_category.content');
|
||||
$item->introtext = self::_cleanIntrotext($item->introtext);
|
||||
}
|
||||
|
||||
$item->displayIntrotext = $show_introtext ? self::truncate($item->introtext, $introtext_limit) : '';
|
||||
$item->displayReadmore = $item->alternative_readmore;
|
||||
}
|
||||
|
||||
// Check if items need be grouped
|
||||
$article_grouping = $params->get('article_grouping', 'none');
|
||||
$article_grouping_direction = $params->get('article_grouping_direction', 'ksort');
|
||||
$grouped = $article_grouping !== 'none';
|
||||
|
||||
if ($items && $grouped) {
|
||||
switch ($article_grouping) {
|
||||
case 'year':
|
||||
case 'month_year':
|
||||
$items = ArticlesCategoryHelper::groupByDate(
|
||||
$items,
|
||||
$article_grouping_direction,
|
||||
$article_grouping,
|
||||
$params->get('month_year_format', 'F Y'),
|
||||
$params->get('date_grouping_field', 'created')
|
||||
);
|
||||
break;
|
||||
case 'author':
|
||||
case 'category_title':
|
||||
$items = ArticlesCategoryHelper::groupBy($items, $article_grouping, $article_grouping_direction);
|
||||
break;
|
||||
case 'tags':
|
||||
$items = ArticlesCategoryHelper::groupByTags($items, $article_grouping_direction);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of articles from a specific category
|
||||
*
|
||||
* @param Registry &$params object holding the models parameters
|
||||
*
|
||||
* @return array The array of users
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @deprecated 4.4.0 will be removed in 7.0
|
||||
* Use the non-static method getArticles
|
||||
* Example: Factory::getApplication()->bootModule('mod_articles_category', 'site')
|
||||
* ->getHelper('ArticlesCategoryHelper')
|
||||
* ->getArticles($params, Factory::getApplication())
|
||||
*/
|
||||
public static function getList(&$params)
|
||||
{
|
||||
/* @var SiteApplication $app */
|
||||
$app = Factory::getApplication();
|
||||
|
||||
return (new self())->getArticles($params, $app);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips unnecessary tags from the introtext
|
||||
*
|
||||
* @param string $introtext introtext to sanitize
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public static function _cleanIntrotext($introtext)
|
||||
{
|
||||
$introtext = str_replace(['<p>', '</p>'], ' ', $introtext);
|
||||
$introtext = strip_tags($introtext, '<a><em><strong><joomla-hidden-mail>');
|
||||
// Remove empty links
|
||||
$introtext = preg_replace('/<a[^>]*><\\/a>/', '', $introtext);
|
||||
|
||||
return trim($introtext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to truncate introtext
|
||||
*
|
||||
* The goal is to get the proper length plain text string with as much of
|
||||
* the html intact as possible with all tags properly closed.
|
||||
*
|
||||
* @param string $html The content of the introtext to be truncated
|
||||
* @param int $maxLength The maximum number of characters to render
|
||||
*
|
||||
* @return string The truncated string
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public static function truncate($html, $maxLength = 0)
|
||||
{
|
||||
$baseLength = \strlen($html);
|
||||
|
||||
// First get the plain text string. This is the rendered text we want to end up with.
|
||||
$ptString = HTMLHelper::_('string.truncate', $html, $maxLength, true, false);
|
||||
|
||||
for ($maxLength; $maxLength < $baseLength;) {
|
||||
// Now get the string if we allow html.
|
||||
$htmlString = HTMLHelper::_('string.truncate', $html, $maxLength, true, true);
|
||||
|
||||
// Now get the plain text from the html string.
|
||||
$htmlStringToPtString = HTMLHelper::_('string.truncate', $htmlString, $maxLength, true, false);
|
||||
|
||||
// If the new plain text string matches the original plain text string we are done.
|
||||
if ($ptString === $htmlStringToPtString) {
|
||||
return $htmlString;
|
||||
}
|
||||
|
||||
// Get the number of html tag characters in the first $maxlength characters
|
||||
$diffLength = \strlen($ptString) - \strlen($htmlStringToPtString);
|
||||
|
||||
// Set new $maxlength that adjusts for the html tags
|
||||
$maxLength += $diffLength;
|
||||
|
||||
if ($baseLength <= $maxLength || $diffLength <= 0) {
|
||||
return $htmlString;
|
||||
}
|
||||
}
|
||||
|
||||
return $ptString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups items by field
|
||||
*
|
||||
* @param array $list list of items
|
||||
* @param string $fieldName name of field that is used for grouping
|
||||
* @param string $direction ordering direction
|
||||
* @param null $fieldNameToKeep field name to keep
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public static function groupBy($list, $fieldName, $direction, $fieldNameToKeep = null)
|
||||
{
|
||||
$grouped = [];
|
||||
|
||||
if (!\is_array($list)) {
|
||||
if ($list === '') {
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
$list = [$list];
|
||||
}
|
||||
|
||||
foreach ($list as $key => $item) {
|
||||
if (!isset($grouped[$item->$fieldName])) {
|
||||
$grouped[$item->$fieldName] = [];
|
||||
}
|
||||
|
||||
if ($fieldNameToKeep === null) {
|
||||
$grouped[$item->$fieldName][$key] = $item;
|
||||
} else {
|
||||
$grouped[$item->$fieldName][$key] = $item->$fieldNameToKeep;
|
||||
}
|
||||
|
||||
unset($list[$key]);
|
||||
}
|
||||
|
||||
$direction($grouped);
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups items by date
|
||||
*
|
||||
* @param array $list list of items
|
||||
* @param string $direction ordering direction
|
||||
* @param string $type type of grouping
|
||||
* @param string $monthYearFormat date format to use
|
||||
* @param string $field date field to group by
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public static function groupByDate($list, $direction = 'ksort', $type = 'year', $monthYearFormat = 'F Y', $field = 'created')
|
||||
{
|
||||
$grouped = [];
|
||||
|
||||
if (!\is_array($list)) {
|
||||
if ($list === '') {
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
$list = [$list];
|
||||
}
|
||||
|
||||
foreach ($list as $key => $item) {
|
||||
switch ($type) {
|
||||
case 'month_year':
|
||||
$month_year = StringHelper::substr($item->$field, 0, 7);
|
||||
|
||||
if (!isset($grouped[$month_year])) {
|
||||
$grouped[$month_year] = [];
|
||||
}
|
||||
|
||||
$grouped[$month_year][$key] = $item;
|
||||
break;
|
||||
|
||||
default:
|
||||
$year = StringHelper::substr($item->$field, 0, 4);
|
||||
|
||||
if (!isset($grouped[$year])) {
|
||||
$grouped[$year] = [];
|
||||
}
|
||||
|
||||
$grouped[$year][$key] = $item;
|
||||
break;
|
||||
}
|
||||
|
||||
unset($list[$key]);
|
||||
}
|
||||
|
||||
$direction($grouped);
|
||||
|
||||
if ($type === 'month_year') {
|
||||
foreach ($grouped as $group => $items) {
|
||||
$date = new Date($group);
|
||||
$formatted_group = $date->format($monthYearFormat);
|
||||
$grouped[$formatted_group] = $items;
|
||||
|
||||
unset($grouped[$group]);
|
||||
}
|
||||
}
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups items by tags
|
||||
*
|
||||
* @param array $list list of items
|
||||
* @param string $direction ordering direction
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 3.9.0
|
||||
*/
|
||||
public static function groupByTags($list, $direction = 'ksort')
|
||||
{
|
||||
$grouped = [];
|
||||
$untagged = [];
|
||||
|
||||
if (!$list) {
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
foreach ($list as $item) {
|
||||
if ($item->tags->itemTags) {
|
||||
foreach ($item->tags->itemTags as $tag) {
|
||||
$grouped[$tag->title][] = $item;
|
||||
}
|
||||
} else {
|
||||
$untagged[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
$direction($grouped);
|
||||
|
||||
if ($untagged) {
|
||||
$grouped['MOD_ARTICLES_CATEGORY_UNTAGGED'] = $untagged;
|
||||
}
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_category
|
||||
*
|
||||
* @copyright (C) 2010 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\Helper\ModuleHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
if (!$list) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<ul class="mod-articlescategory category-module mod-list">
|
||||
<?php if ($grouped) : ?>
|
||||
<?php foreach ($list as $groupName => $items) : ?>
|
||||
<li>
|
||||
<div class="mod-articles-category-group"><?php echo Text::_($groupName); ?></div>
|
||||
<ul>
|
||||
<?php require ModuleHelper::getLayoutPath('mod_articles_category', $params->get('layout', 'default') . '_items'); ?>
|
||||
</ul>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
<?php else : ?>
|
||||
<?php $items = $list; ?>
|
||||
<?php require ModuleHelper::getLayoutPath('mod_articles_category', $params->get('layout', 'default') . '_items'); ?>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_category
|
||||
*
|
||||
* @copyright (C) 2020 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\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
|
||||
?>
|
||||
<?php foreach ($items as $item) : ?>
|
||||
<li>
|
||||
<?php if ($params->get('link_titles') == 1) : ?>
|
||||
<?php $attributes = ['class' => 'mod-articles-category-title ' . $item->active]; ?>
|
||||
<?php $link = htmlspecialchars($item->link, ENT_COMPAT, 'UTF-8', false); ?>
|
||||
<?php $title = htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8', false); ?>
|
||||
<?php echo HTMLHelper::_('link', $link, $title, $attributes); ?>
|
||||
<?php else : ?>
|
||||
<?php echo htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8'); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($item->displayHits) : ?>
|
||||
<span class="mod-articles-category-hits">
|
||||
(<?php echo $item->displayHits; ?>)
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($params->get('show_author')) : ?>
|
||||
<span class="mod-articles-category-writtenby">
|
||||
<?php echo htmlspecialchars($item->displayAuthorName, ENT_COMPAT, 'UTF-8'); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($item->displayCategoryTitle) : ?>
|
||||
<span class="mod-articles-category-category">
|
||||
(<?php echo htmlspecialchars($item->displayCategoryTitle, ENT_COMPAT, 'UTF-8'); ?>)
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($item->displayDate) : ?>
|
||||
<span class="mod-articles-category-date"><?php echo htmlspecialchars($item->displayDate, ENT_COMPAT, 'UTF-8'); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($params->get('show_tags', 0) && $item->tags->itemTags) : ?>
|
||||
<div class="mod-articles-category-tags">
|
||||
<?php echo LayoutHelper::render('joomla.content.tags', $item->tags->itemTags); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($params->get('show_introtext')) : ?>
|
||||
<p class="mod-articles-category-introtext">
|
||||
<?php echo $item->displayIntrotext; ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($params->get('show_readmore')) : ?>
|
||||
<p class="mod-articles-category-readmore">
|
||||
<a class="mod-articles-category-title <?php echo $item->active; ?>" href="<?php echo $item->link; ?>">
|
||||
<?php if (!$item->params->get('access-view')) : ?>
|
||||
<?php echo Text::_('MOD_ARTICLES_CATEGORY_REGISTER_TO_READ_MORE'); ?>
|
||||
<?php elseif ($item->alternative_readmore) : ?>
|
||||
<?php echo $item->alternative_readmore; ?>
|
||||
<?php echo HTMLHelper::_('string.truncate', $item->title, $params->get('readmore_limit'), true, false); ?>
|
||||
<?php if ($params->get('show_readmore_title', 0)) : ?>
|
||||
<?php echo HTMLHelper::_('string.truncate', $item->title, $params->get('readmore_limit'), true, false); ?>
|
||||
<?php endif; ?>
|
||||
<?php elseif ($params->get('show_readmore_title', 0)) : ?>
|
||||
<?php echo Text::_('MOD_ARTICLES_CATEGORY_READ_MORE'); ?>
|
||||
<?php echo HTMLHelper::_('string.truncate', $item->title, $params->get('readmore_limit'), true, false); ?>
|
||||
<?php else : ?>
|
||||
<?php echo Text::_('MOD_ARTICLES_CATEGORY_READ_MORE_TITLE'); ?>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
@@ -0,0 +1,143 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_articles_latest</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2004-07</creationDate>
|
||||
<copyright>(C) 2005 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>3.0.0</version>
|
||||
<description>MOD_LATEST_NEWS_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\ArticlesLatest</namespace>
|
||||
<files>
|
||||
<folder module="mod_articles_latest">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_articles_latest.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_articles_latest.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Articles_-_Latest" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic">
|
||||
<field
|
||||
name="catid"
|
||||
type="category"
|
||||
label="JCATEGORY"
|
||||
extension="com_content"
|
||||
multiple="true"
|
||||
layout="joomla.form.field.list-fancy-select"
|
||||
filter="intarray"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="count"
|
||||
type="number"
|
||||
label="MOD_LATEST_NEWS_FIELD_COUNT_LABEL"
|
||||
default="5"
|
||||
filter="integer"
|
||||
min="1"
|
||||
validate="number"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_featured"
|
||||
type="list"
|
||||
label="MOD_LATEST_NEWS_FIELD_FEATURED_LABEL"
|
||||
default=""
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="">JSHOW</option>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">MOD_LATEST_NEWS_VALUE_ONLY_SHOW_FEATURED</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="ordering"
|
||||
type="list"
|
||||
label="MOD_LATEST_NEWS_FIELD_ORDERING_LABEL"
|
||||
default="p_dsc"
|
||||
validate="options"
|
||||
>
|
||||
<option value="c_dsc">MOD_LATEST_NEWS_VALUE_RECENT_ADDED</option>
|
||||
<option value="m_dsc">MOD_LATEST_NEWS_VALUE_RECENT_MODIFIED</option>
|
||||
<option value="p_dsc">MOD_LATEST_NEWS_VALUE_RECENT_PUBLISHED</option>
|
||||
<option value="mc_dsc">MOD_LATEST_NEWS_VALUE_RECENT_TOUCHED</option>
|
||||
<option value="random">MOD_LATEST_NEWS_VALUE_RECENT_RAND</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="user_id"
|
||||
type="list"
|
||||
label="MOD_LATEST_NEWS_FIELD_USER_LABEL"
|
||||
default="0"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">MOD_LATEST_NEWS_VALUE_ANYONE</option>
|
||||
<option value="by_me">MOD_LATEST_NEWS_VALUE_ADDED_BY_ME</option>
|
||||
<option value="not_me">MOD_LATEST_NEWS_VALUE_NOTADDED_BY_ME</option>
|
||||
<option value="created_by">MOD_LATEST_NEWS_VALUE_CREATED_BY</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="author"
|
||||
type="author"
|
||||
label="MOD_LATEST_NEWS_FIELD_AUTHOR_LABEL"
|
||||
multiple="true"
|
||||
layout="joomla.form.field.list-fancy-select"
|
||||
showon="user_id:created_by"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cache"
|
||||
type="list"
|
||||
label="COM_MODULES_FIELD_CACHING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="cache_time"
|
||||
type="number"
|
||||
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
|
||||
default="900"
|
||||
filter="integer"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cachemode"
|
||||
type="hidden"
|
||||
default="static"
|
||||
>
|
||||
<option value="static"></option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_latest
|
||||
*
|
||||
* @copyright (C) 2022 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The article latest module service provider.
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\ArticlesLatest'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\ArticlesLatest\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_latest
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\ArticlesLatest\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_articles_latest
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
protected function getLayoutData()
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
|
||||
$data['list'] = $this->getHelperFactory()->getHelper('ArticlesLatestHelper')->getArticles($data['params'], $this->getApplication());
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_latest
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\ArticlesLatest\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Access\Access;
|
||||
use Joomla\CMS\Application\SiteApplication;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\Content\Site\Helper\RouteHelper;
|
||||
use Joomla\Component\Content\Site\Model\ArticlesModel;
|
||||
use Joomla\Database\DatabaseAwareInterface;
|
||||
use Joomla\Database\DatabaseAwareTrait;
|
||||
use Joomla\Registry\Registry;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Helper for mod_articles_latest
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class ArticlesLatestHelper implements DatabaseAwareInterface
|
||||
{
|
||||
use DatabaseAwareTrait;
|
||||
|
||||
/**
|
||||
* Retrieve a list of article
|
||||
*
|
||||
* @param Registry $params The module parameters.
|
||||
* @param ArticlesModel $model The model.
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public function getArticles(Registry $params, SiteApplication $app)
|
||||
{
|
||||
// Get the Dbo and User object
|
||||
$db = $this->getDatabase();
|
||||
$user = $app->getIdentity();
|
||||
|
||||
/** @var ArticlesModel $model */
|
||||
$model = $app->bootComponent('com_content')->getMVCFactory()->createModel('Articles', 'Site', ['ignore_request' => true]);
|
||||
|
||||
// Set application parameters in model
|
||||
$model->setState('params', $app->getParams());
|
||||
|
||||
$model->setState('list.start', 0);
|
||||
$model->setState('filter.published', 1);
|
||||
|
||||
// Set the filters based on the module params
|
||||
$model->setState('list.limit', (int) $params->get('count', 5));
|
||||
|
||||
// This module does not use tags data
|
||||
$model->setState('load_tags', false);
|
||||
|
||||
// Access filter
|
||||
$access = !ComponentHelper::getParams('com_content')->get('show_noauth');
|
||||
$authorised = Access::getAuthorisedViewLevels($user->id);
|
||||
$model->setState('filter.access', $access);
|
||||
|
||||
// Category filter
|
||||
$model->setState('filter.category_id', $params->get('catid', []));
|
||||
|
||||
// State filter
|
||||
$model->setState('filter.condition', 1);
|
||||
|
||||
// User filter
|
||||
$userId = $user->id;
|
||||
|
||||
switch ($params->get('user_id')) {
|
||||
case 'by_me':
|
||||
$model->setState('filter.author_id', (int) $userId);
|
||||
break;
|
||||
case 'not_me':
|
||||
$model->setState('filter.author_id', $userId);
|
||||
$model->setState('filter.author_id.include', false);
|
||||
break;
|
||||
|
||||
case 'created_by':
|
||||
$model->setState('filter.author_id', $params->get('author', []));
|
||||
break;
|
||||
|
||||
case '0':
|
||||
break;
|
||||
|
||||
default:
|
||||
$model->setState('filter.author_id', (int) $params->get('user_id'));
|
||||
break;
|
||||
}
|
||||
|
||||
// Filter by language
|
||||
$model->setState('filter.language', $app->getLanguageFilter());
|
||||
|
||||
// Featured switch
|
||||
$featured = $params->get('show_featured', '');
|
||||
|
||||
if ($featured === '') {
|
||||
$model->setState('filter.featured', 'show');
|
||||
} elseif ($featured) {
|
||||
$model->setState('filter.featured', 'only');
|
||||
} else {
|
||||
$model->setState('filter.featured', 'hide');
|
||||
}
|
||||
|
||||
// Set ordering
|
||||
$order_map = [
|
||||
'm_dsc' => 'a.modified DESC, a.created',
|
||||
'mc_dsc' => 'a.modified',
|
||||
'c_dsc' => 'a.created',
|
||||
'p_dsc' => 'a.publish_up',
|
||||
'random' => $db->createQuery()->rand(),
|
||||
];
|
||||
|
||||
$ordering = ArrayHelper::getValue($order_map, $params->get('ordering', 'p_dsc'), 'a.publish_up');
|
||||
$dir = 'DESC';
|
||||
|
||||
$model->setState('list.ordering', $ordering);
|
||||
$model->setState('list.direction', $dir);
|
||||
|
||||
$items = $model->getItems();
|
||||
|
||||
foreach ($items as &$item) {
|
||||
$item->slug = $item->id . ':' . $item->alias;
|
||||
|
||||
if ($access || \in_array($item->access, $authorised)) {
|
||||
// We know that user has the privilege to view the article
|
||||
$item->link = Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language));
|
||||
} else {
|
||||
$item->link = Route::_('index.php?option=com_users&view=login');
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of articles
|
||||
*
|
||||
* @param Registry $params The module parameters.
|
||||
* @param ArticlesModel $model The model.
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @deprecated 4.3 will be removed in 7.0
|
||||
* Use the non-static method getArticles
|
||||
* Example: Factory::getApplication()->bootModule('mod_articles_latest', 'site')
|
||||
* ->getHelper('ArticlesLatestHelper')
|
||||
* ->getArticles($params, Factory::getApplication())
|
||||
*/
|
||||
public static function getList(Registry $params, ArticlesModel $model)
|
||||
{
|
||||
return (new self())->getArticles($params, Factory::getApplication());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_latest
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
if (!$list) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<ul class="mod-articleslatest latestnews mod-list">
|
||||
<?php foreach ($list as $item) : ?>
|
||||
<li itemscope itemtype="https://schema.org/Article">
|
||||
<a href="<?php echo $item->link; ?>" itemprop="url">
|
||||
<span itemprop="name">
|
||||
<?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
@@ -0,0 +1,287 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_articles_news</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2006-07</creationDate>
|
||||
<copyright>(C) 2006 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>3.0.0</version>
|
||||
<description>MOD_ARTICLES_NEWS_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\ArticlesNews</namespace>
|
||||
<files>
|
||||
<folder module="mod_articles_news">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_articles_news.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_articles_news.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Articles_-_Newsflash"/>
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic">
|
||||
<field
|
||||
name="catid"
|
||||
type="category"
|
||||
label="JCATEGORY"
|
||||
extension="com_content"
|
||||
multiple="true"
|
||||
filter="intarray"
|
||||
class="multipleCategories"
|
||||
layout="joomla.form.field.list-fancy-select"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="tag"
|
||||
type="tag"
|
||||
label="JTAG"
|
||||
mode="nested"
|
||||
multiple="true"
|
||||
filter="intarray"
|
||||
class="multipleTags"
|
||||
custom="deny"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="image"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_NEWS_FIELD_IMAGES_LABEL"
|
||||
description="MOD_ARTICLES_NEWS_FIELD_IMAGES_DESC"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="img_intro_full"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_NEWS_FIELD_IMAGES_ARTICLE_LABEL"
|
||||
default="none"
|
||||
validate="options"
|
||||
>
|
||||
<option value="intro">MOD_ARTICLES_NEWS_OPTION_INTROIMAGE</option>
|
||||
<option value="full">MOD_ARTICLES_NEWS_OPTION_FULLIMAGE</option>
|
||||
<option value="none">JNO</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="item_title"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_NEWS_FIELD_TITLE_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="link_titles"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_NEWS_FIELD_LINKTITLE_LABEL"
|
||||
default=""
|
||||
filter="integer"
|
||||
class="form-select-color"
|
||||
showon="item_title:1"
|
||||
validate="options"
|
||||
>
|
||||
<option value="">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="item_heading"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_NEWS_TITLE_HEADING"
|
||||
default="h4"
|
||||
showon="item_title:1"
|
||||
validate="options"
|
||||
>
|
||||
<option value="h1">JH1</option>
|
||||
<option value="h2">JH2</option>
|
||||
<option value="h3">JH3</option>
|
||||
<option value="h4">JH4</option>
|
||||
<option value="h5">JH5</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="triggerevents"
|
||||
type="radio"
|
||||
label="MOD_ARTICLES_NEWS_FIELD_TRIGGEREVENTS_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="showLastSeparator"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_NEWS_FIELD_SEPARATOR_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_introtext"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_NEWS_FIELD_SHOWINTROTEXT_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="readmore"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_ARTICLES_NEWS_FIELD_READMORE_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="readmore_title"
|
||||
type="list"
|
||||
label="JGLOBAL_SHOW_READMORE_TITLE_LABEL"
|
||||
default=""
|
||||
showon="readmore:1"
|
||||
validate="options"
|
||||
>
|
||||
<option value="">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="count"
|
||||
type="number"
|
||||
label="MOD_ARTICLES_NEWS_FIELD_ITEMS_LABEL"
|
||||
default="5"
|
||||
filter="integer"
|
||||
min="1"
|
||||
validate="number"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_featured"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_NEWS_FIELD_FEATURED_LABEL"
|
||||
default=""
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="">JSHOW</option>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">MOD_ARTICLES_NEWS_VALUE_ONLY_SHOW_FEATURED</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="exclude_current"
|
||||
type="radio"
|
||||
label="MOD_ARTICLES_NEWS_FIELD_EXCLUDE_CURRENT_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="ordering"
|
||||
type="list"
|
||||
label="MOD_ARTICLES_NEWS_FIELD_ORDERING_LABEL"
|
||||
default="a.publish_up"
|
||||
validate="options"
|
||||
>
|
||||
<option value="a.publish_up">MOD_ARTICLES_NEWS_FIELD_ORDERING_PUBLISHED_DATE</option>
|
||||
<option value="a.created">MOD_ARTICLES_NEWS_FIELD_ORDERING_CREATED_DATE</option>
|
||||
<option value="a.modified">MOD_ARTICLES_NEWS_FIELD_ORDERING_MODIFIED_DATE</option>
|
||||
<option value="a.ordering">MOD_ARTICLES_NEWS_FIELD_ORDERING_ORDERING</option>
|
||||
<option value="a.hits">JGLOBAL_HITS</option>
|
||||
<option value="rand()">MOD_ARTICLES_NEWS_FIELD_ORDERING_RANDOM</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="direction"
|
||||
type="list"
|
||||
label="JGLOBAL_ORDER_DIRECTION_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
showon="ordering:a.publish_up,a.created,a.modified,a.ordering,a.hits"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">JGLOBAL_ORDER_ASCENDING</option>
|
||||
<option value="1">JGLOBAL_ORDER_DESCENDING</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cache"
|
||||
type="list"
|
||||
label="COM_MODULES_FIELD_CACHING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="cache_time"
|
||||
type="number"
|
||||
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
|
||||
default="900"
|
||||
filter="integer"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cachemode"
|
||||
type="hidden"
|
||||
default="itemid"
|
||||
>
|
||||
<option value="itemid"></option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_news
|
||||
*
|
||||
* @copyright (C) 2022 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The article news module service provider.
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\ArticlesNews'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\ArticlesNews\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_news
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\ArticlesNews\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_articles_news
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
protected function getLayoutData()
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
|
||||
$data['list'] = $this->getHelperFactory()->getHelper('ArticlesNewsHelper')->getArticles($data['params'], $this->getApplication());
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_news
|
||||
*
|
||||
* @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\ArticlesNews\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Access\Access;
|
||||
use Joomla\CMS\Application\SiteApplication;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
use Joomla\Component\Content\Site\Helper\RouteHelper;
|
||||
use Joomla\Database\DatabaseAwareInterface;
|
||||
use Joomla\Database\DatabaseAwareTrait;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Helper for mod_articles_news
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class ArticlesNewsHelper implements DatabaseAwareInterface
|
||||
{
|
||||
use DatabaseAwareTrait;
|
||||
|
||||
/**
|
||||
* Get a list of the latest articles from the article model.
|
||||
*
|
||||
* @param Registry $params Object holding the models parameters
|
||||
* @param SiteApplication $app The app
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public function getArticles(Registry $params, SiteApplication $app)
|
||||
{
|
||||
/** @var \Joomla\Component\Content\Site\Model\ArticlesModel $model */
|
||||
$model = $app->bootComponent('com_content')->getMVCFactory()->createModel('Articles', 'Site', ['ignore_request' => true]);
|
||||
|
||||
// Set application parameters in model
|
||||
$appParams = $app->getParams();
|
||||
$model->setState('params', $appParams);
|
||||
|
||||
$model->setState('list.start', 0);
|
||||
$model->setState('filter.published', 1);
|
||||
|
||||
// Set the filters based on the module params
|
||||
$model->setState('list.limit', (int) $params->get('count', 5));
|
||||
|
||||
// This module does not use tags data
|
||||
$model->setState('load_tags', false);
|
||||
|
||||
// Access filter
|
||||
$access = !ComponentHelper::getParams('com_content')->get('show_noauth');
|
||||
$authorised = Access::getAuthorisedViewLevels($app->getIdentity() ? $app->getIdentity()->id : 0);
|
||||
$model->setState('filter.access', $access);
|
||||
|
||||
// Category filter
|
||||
$model->setState('filter.category_id', $params->get('catid', []));
|
||||
|
||||
// Filter by language
|
||||
$model->setState('filter.language', $app->getLanguageFilter());
|
||||
|
||||
// Filter by tag
|
||||
$model->setState('filter.tag', $params->get('tag', []));
|
||||
|
||||
// Featured switch
|
||||
$featured = $params->get('show_featured', '');
|
||||
|
||||
if ($featured === '') {
|
||||
$model->setState('filter.featured', 'show');
|
||||
} elseif ($featured) {
|
||||
$model->setState('filter.featured', 'only');
|
||||
} else {
|
||||
$model->setState('filter.featured', 'hide');
|
||||
}
|
||||
|
||||
$input = $app->getInput();
|
||||
|
||||
// Filter by id in case it should be excluded
|
||||
if (
|
||||
$params->get('exclude_current', true)
|
||||
&& $input->get('option') === 'com_content'
|
||||
&& $input->get('view') === 'article'
|
||||
) {
|
||||
// Exclude the current article from displaying in this module
|
||||
$model->setState('filter.article_id', $input->get('id', 0, 'UINT'));
|
||||
$model->setState('filter.article_id.include', false);
|
||||
}
|
||||
|
||||
// Set ordering
|
||||
$ordering = $params->get('ordering', 'a.publish_up');
|
||||
$model->setState('list.ordering', $ordering);
|
||||
|
||||
if (trim($ordering) === 'rand()') {
|
||||
$model->setState('list.ordering', $this->getDatabase()->createQuery()->rand());
|
||||
} else {
|
||||
$direction = $params->get('direction', 1) ? 'DESC' : 'ASC';
|
||||
$model->setState('list.direction', $direction);
|
||||
$model->setState('list.ordering', $ordering);
|
||||
}
|
||||
|
||||
// Check if we should trigger additional plugin events
|
||||
$triggerEvents = $params->get('triggerevents', 1);
|
||||
|
||||
// Retrieve Content
|
||||
$items = $model->getItems();
|
||||
|
||||
foreach ($items as &$item) {
|
||||
$item->readmore = \strlen(trim($item->fulltext));
|
||||
$item->slug = $item->id . ':' . $item->alias;
|
||||
|
||||
if ($access || \in_array($item->access, $authorised)) {
|
||||
// We know that user has the privilege to view the article
|
||||
$item->link = Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language));
|
||||
$item->linkText = Text::_('MOD_ARTICLES_NEWS_READMORE');
|
||||
} else {
|
||||
$item->link = new Uri(Route::_('index.php?option=com_users&view=login', false));
|
||||
$item->link->setVar('return', base64_encode(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language)));
|
||||
$item->linkText = Text::_('MOD_ARTICLES_NEWS_READMORE_REGISTER');
|
||||
}
|
||||
|
||||
$item->introtext = HTMLHelper::_('content.prepare', $item->introtext, '', 'mod_articles_news.content');
|
||||
|
||||
// Remove any images belongs to the text
|
||||
if (!$params->get('image')) {
|
||||
// Remove any images and empty links from the intro text
|
||||
$item->introtext = preg_replace(['/\\<img[^>]*>/', '/<a[^>]*><\\/a>/'], '', $item->introtext);
|
||||
}
|
||||
|
||||
// Show the Intro/Full image field of the article
|
||||
if ($params->get('img_intro_full') !== 'none') {
|
||||
$images = json_decode($item->images);
|
||||
$item->imageSrc = '';
|
||||
$item->imageAlt = '';
|
||||
$item->imageCaption = '';
|
||||
|
||||
if ($params->get('img_intro_full') === 'intro' && !empty($images->image_intro)) {
|
||||
$item->imageSrc = htmlspecialchars($images->image_intro, ENT_COMPAT, 'UTF-8');
|
||||
$item->imageAlt = htmlspecialchars($images->image_intro_alt, ENT_COMPAT, 'UTF-8');
|
||||
|
||||
if ($images->image_intro_caption) {
|
||||
$item->imageCaption = htmlspecialchars($images->image_intro_caption, ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
} elseif ($params->get('img_intro_full') === 'full' && !empty($images->image_fulltext)) {
|
||||
$item->imageSrc = htmlspecialchars($images->image_fulltext, ENT_COMPAT, 'UTF-8');
|
||||
$item->imageAlt = htmlspecialchars($images->image_fulltext_alt, ENT_COMPAT, 'UTF-8');
|
||||
|
||||
if ($images->image_intro_caption) {
|
||||
$item->imageCaption = htmlspecialchars($images->image_fulltext_caption, ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($triggerEvents) {
|
||||
$item->text = '';
|
||||
$app->triggerEvent('onContentPrepare', ['com_content.article', &$item, &$params, 0]);
|
||||
|
||||
$results = $app->triggerEvent('onContentAfterTitle', ['com_content.article', &$item, &$params, 0]);
|
||||
$item->afterDisplayTitle = trim(implode("\n", $results));
|
||||
|
||||
$results = $app->triggerEvent('onContentBeforeDisplay', ['com_content.article', &$item, &$params, 0]);
|
||||
$item->beforeDisplayContent = trim(implode("\n", $results));
|
||||
|
||||
$results = $app->triggerEvent('onContentAfterDisplay', ['com_content.article', &$item, &$params, 0]);
|
||||
$item->afterDisplayContent = trim(implode("\n", $results));
|
||||
} else {
|
||||
$item->afterDisplayTitle = '';
|
||||
$item->beforeDisplayContent = '';
|
||||
$item->afterDisplayContent = '';
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of the latest articles from the article model
|
||||
*
|
||||
* @param \Joomla\Registry\Registry &$params object holding the models parameters
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @deprecated 4.3 will be removed in 7.0
|
||||
* Use the non-static method getArticles
|
||||
* Example: Factory::getApplication()->bootModule('mod_articles_news', 'site')
|
||||
* ->getHelper('ArticlesNewsHelper')
|
||||
* ->getArticles($params, Factory::getApplication())
|
||||
*/
|
||||
public static function getList(&$params)
|
||||
{
|
||||
return (new self())->getArticles($params, Factory::getApplication());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_news
|
||||
*
|
||||
* @copyright (C) 2010 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\Layout\LayoutHelper;
|
||||
?>
|
||||
<?php if ($params->get('item_title')) : ?>
|
||||
<?php $item_heading = $params->get('item_heading', 'h4'); ?>
|
||||
<<?php echo $item_heading; ?> class="newsflash-title">
|
||||
<?php if ($item->link !== '' && $params->get('link_titles')) : ?>
|
||||
<a href="<?php echo $item->link; ?>">
|
||||
<?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>
|
||||
<?php endif; ?>
|
||||
</<?php echo $item_heading; ?>>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($params->get('img_intro_full') !== 'none' && !empty($item->imageSrc)) : ?>
|
||||
<figure class="newsflash-image">
|
||||
<?php echo LayoutHelper::render(
|
||||
'joomla.html.image',
|
||||
[
|
||||
'src' => $item->imageSrc,
|
||||
'alt' => $item->imageAlt,
|
||||
]
|
||||
); ?>
|
||||
<?php if (!empty($item->imageCaption)) : ?>
|
||||
<figcaption>
|
||||
<?php echo htmlspecialchars($item->imageCaption, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</figcaption>
|
||||
<?php endif; ?>
|
||||
</figure>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!$params->get('intro_only')) : ?>
|
||||
<?php echo $item->afterDisplayTitle; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php echo $item->beforeDisplayContent; ?>
|
||||
|
||||
<?php if ($params->get('show_introtext', 1)) : ?>
|
||||
<?php echo $item->introtext; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php echo $item->afterDisplayContent; ?>
|
||||
|
||||
<?php if (isset($item->link) && $item->readmore != 0 && $params->get('readmore')) : ?>
|
||||
<?php // Overwrite global article setting if needed ?>
|
||||
<?php if ($params->get('readmore_title', '') !== '') : ?>
|
||||
<?php $item->params->set('show_readmore_title', $params->get('readmore_title')); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo LayoutHelper::render('joomla.content.readmore', ['item' => $item, 'params' => $item->params, 'link' => $item->link]); ?>
|
||||
<?php endif; ?>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_news
|
||||
*
|
||||
* @copyright (C) 2006 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\Helper\ModuleHelper;
|
||||
|
||||
if (!$list) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="mod-articlesnews newsflash">
|
||||
<?php foreach ($list as $item) : ?>
|
||||
<div class="mod-articlesnews__item" itemscope itemtype="https://schema.org/Article">
|
||||
<?php require ModuleHelper::getLayoutPath('mod_articles_news', '_item'); ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_news
|
||||
*
|
||||
* @copyright (C) 2006 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\Helper\ModuleHelper;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $app->getDocument()->getWebAssetManager();
|
||||
$wa->registerAndUseStyle('mod_articles_news_horizontal', 'mod_articles_news/template.css');
|
||||
|
||||
if (empty($list)) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<ul class="mod-articlesnews-horizontal newsflash-horiz mod-list">
|
||||
<?php foreach ($list as $item) : ?>
|
||||
<li itemscope itemtype="https://schema.org/Article">
|
||||
<?php require ModuleHelper::getLayoutPath('mod_articles_news', '_item'); ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_news
|
||||
*
|
||||
* @copyright (C) 2006 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\Helper\ModuleHelper;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $app->getDocument()->getWebAssetManager();
|
||||
$wa->registerAndUseStyle('mod_articles_news_vertical', 'mod_articles_news/template-vert.css');
|
||||
|
||||
if (!$list) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<ul class="mod-articlesnews-vertical newsflash-vert mod-list">
|
||||
<?php for ($i = 0, $n = count($list); $i < $n; $i++) : ?>
|
||||
<?php $item = $list[$i]; ?>
|
||||
<li class="newsflash-item" itemscope itemtype="https://schema.org/Article">
|
||||
<?php require ModuleHelper::getLayoutPath('mod_articles_news', '_item'); ?>
|
||||
|
||||
<?php if ($n > 1 && (($i < $n - 1) || $params->get('showLastSeparator'))) : ?>
|
||||
<span class="article-separator"> </span>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endfor; ?>
|
||||
</ul>
|
||||
@@ -0,0 +1,165 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_articles_popular</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2006-07</creationDate>
|
||||
<copyright>(C) 2006 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>3.0.0</version>
|
||||
<description>MOD_POPULAR_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\ArticlesPopular</namespace>
|
||||
<files>
|
||||
<folder module="mod_articles_popular">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_articles_popular.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_articles_popular.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Articles_-_Most_Read" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic">
|
||||
<field
|
||||
name="catid"
|
||||
type="category"
|
||||
label="JCATEGORY"
|
||||
extension="com_content"
|
||||
multiple="true"
|
||||
filter="intarray"
|
||||
layout="joomla.form.field.list-fancy-select"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="count"
|
||||
type="number"
|
||||
label="MOD_POPULAR_FIELD_COUNT_LABEL"
|
||||
default="5"
|
||||
filter="integer"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_front"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_POPULAR_FIELD_FEATURED_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="basicspacer1"
|
||||
type="spacer"
|
||||
hr="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="date_filtering"
|
||||
type="list"
|
||||
label="MOD_POPULAR_FIELD_DATEFILTERING_LABEL"
|
||||
default="off"
|
||||
validate="options"
|
||||
>
|
||||
<option value="off">MOD_POPULAR_OPTION_OFF_VALUE</option>
|
||||
<option value="range">MOD_POPULAR_OPTION_DATERANGE_VALUE</option>
|
||||
<option value="relative">MOD_POPULAR_OPTION_RELATIVEDAY_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="date_field"
|
||||
type="list"
|
||||
label="MOD_POPULAR_FIELD_DATEFIELD_LABEL"
|
||||
default="a.created"
|
||||
showon="date_filtering:range,relative"
|
||||
validate="options"
|
||||
>
|
||||
<option value="a.created">MOD_POPULAR_OPTION_CREATED_VALUE</option>
|
||||
<option value="a.modified">MOD_POPULAR_OPTION_MODIFIED_VALUE</option>
|
||||
<option value="a.publish_up">MOD_POPULAR_OPTION_STARTPUBLISHING_VALUE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="start_date_range"
|
||||
type="calendar"
|
||||
label="MOD_POPULAR_FIELD_STARTDATE_LABEL"
|
||||
translateformat="true"
|
||||
showtime="true"
|
||||
filter="user_utc"
|
||||
showon="date_filtering:range"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="end_date_range"
|
||||
type="calendar"
|
||||
label="MOD_POPULAR_FIELD_ENDDATE_LABEL"
|
||||
translateformat="true"
|
||||
showtime="true"
|
||||
filter="user_utc"
|
||||
showon="date_filtering:range"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="relative_date"
|
||||
type="number"
|
||||
label="MOD_POPULAR_FIELD_RELATIVEDATE_LABEL"
|
||||
default="30"
|
||||
filter="integer"
|
||||
showon="date_filtering:relative"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cache"
|
||||
type="list"
|
||||
label="COM_MODULES_FIELD_CACHING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="cache_time"
|
||||
type="number"
|
||||
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
|
||||
default="900"
|
||||
filter="integer"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cachemode"
|
||||
type="hidden"
|
||||
default="static"
|
||||
>
|
||||
<option value="static"></option>
|
||||
</field>
|
||||
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_popular
|
||||
*
|
||||
* @copyright (C) 2022 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The popular articles module service provider.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\ArticlesPopular'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\ArticlesPopular\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_popular
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\ArticlesPopular\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_articles_popular
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function getLayoutData()
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
|
||||
if (!ComponentHelper::getParams('com_content')->get('record_hits', 1)) {
|
||||
$data['hitsDisabledMessage'] = Text::_('JGLOBAL_RECORD_HITS_DISABLED');
|
||||
} else {
|
||||
$data['list'] = $this->getHelperFactory()->getHelper('ArticlesPopularHelper', $data)->getArticles($data['params'], $data['app']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_popular
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\ArticlesPopular\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Access\Access;
|
||||
use Joomla\CMS\Application\SiteApplication;
|
||||
use Joomla\CMS\Cache\CacheControllerFactoryInterface;
|
||||
use Joomla\CMS\Cache\Controller\OutputController;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\Content\Administrator\Extension\ContentComponent;
|
||||
use Joomla\Component\Content\Site\Helper\RouteHelper;
|
||||
use Joomla\Component\Content\Site\Model\ArticlesModel;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Helper for mod_articles_popular
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class ArticlesPopularHelper
|
||||
{
|
||||
/**
|
||||
* The module instance
|
||||
*
|
||||
* @var \stdClass
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected $module;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config An optional associative array of configuration settings.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function __construct($config = [])
|
||||
{
|
||||
$this->module = $config['module'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of months with archived articles
|
||||
*
|
||||
* @param Registry $params The module parameters.
|
||||
* @param SiteApplication $app The current application.
|
||||
*
|
||||
* @return object[]
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function getArticles(Registry $moduleParams, SiteApplication $app)
|
||||
{
|
||||
$cacheKey = md5(serialize([$moduleParams->toString(), $this->module->module, $this->module->id]));
|
||||
|
||||
/** @var OutputController $cache */
|
||||
$cache = Factory::getContainer()->get(CacheControllerFactoryInterface::class)
|
||||
->createCacheController('output', ['defaultgroup' => 'mod_articles_popular']);
|
||||
|
||||
if (!$cache->contains($cacheKey)) {
|
||||
$mvcContentFactory = $app->bootComponent('com_content')->getMVCFactory();
|
||||
|
||||
/** @var ArticlesModel $articlesModel */
|
||||
$articlesModel = $mvcContentFactory->createModel('Articles', 'Site', ['ignore_request' => true]);
|
||||
|
||||
// Set application parameters in model
|
||||
$appParams = $app->getParams();
|
||||
$articlesModel->setState('params', $appParams);
|
||||
|
||||
$articlesModel->setState('list.start', 0);
|
||||
$articlesModel->setState('filter.published', ContentComponent::CONDITION_PUBLISHED);
|
||||
|
||||
// Set the filters based on the module params
|
||||
$articlesModel->setState('list.limit', (int) $moduleParams->get('count', 5));
|
||||
$articlesModel->setState('filter.featured', $moduleParams->get('show_front', 1) == 1 ? 'show' : 'hide');
|
||||
|
||||
// This module does not use tags data
|
||||
$articlesModel->setState('load_tags', false);
|
||||
|
||||
// Access filter
|
||||
$access = !ComponentHelper::getParams('com_content')->get('show_noauth');
|
||||
$articlesModel->setState('filter.access', $access);
|
||||
|
||||
// Category filter
|
||||
$articlesModel->setState('filter.category_id', $moduleParams->get('catid', []));
|
||||
|
||||
// Date filter
|
||||
$date_filtering = $moduleParams->get('date_filtering', 'off');
|
||||
|
||||
if ($date_filtering !== 'off') {
|
||||
$articlesModel->setState('filter.date_filtering', $date_filtering);
|
||||
$articlesModel->setState('filter.date_field', $moduleParams->get('date_field', 'a.created'));
|
||||
$articlesModel->setState('filter.start_date_range', $moduleParams->get('start_date_range', '1000-01-01 00:00:00'));
|
||||
$articlesModel->setState('filter.end_date_range', $moduleParams->get('end_date_range', '9999-12-31 23:59:59'));
|
||||
$articlesModel->setState('filter.relative_date', $moduleParams->get('relative_date', 30));
|
||||
}
|
||||
|
||||
// Filter by language
|
||||
$articlesModel->setState('filter.language', $app->getLanguageFilter());
|
||||
|
||||
// Ordering
|
||||
$articlesModel->setState('list.ordering', 'a.hits');
|
||||
$articlesModel->setState('list.direction', 'DESC');
|
||||
|
||||
// Prepare the module output
|
||||
$items = [];
|
||||
$itemParams = new \stdClass();
|
||||
|
||||
$itemParams->authorised = Access::getAuthorisedViewLevels($app->getIdentity()->id);
|
||||
$itemParams->access = $access;
|
||||
|
||||
foreach ($articlesModel->getItems() as $item) {
|
||||
$items[] = $this->prepareItem($item, $itemParams);
|
||||
}
|
||||
|
||||
// Cache the output and return
|
||||
$cache->store($items, $cacheKey);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
// Return the cached output
|
||||
return $cache->get($cacheKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the article before render.
|
||||
*
|
||||
* @param object $item The article to prepare
|
||||
* @param \stdClass $params The model item
|
||||
*
|
||||
* @return object
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
private function prepareItem($item, $params): object
|
||||
{
|
||||
$item->slug = $item->id . ':' . $item->alias;
|
||||
|
||||
if ($params->access || \in_array($item->access, $params->authorised)) {
|
||||
// We know that user has the privilege to view the article
|
||||
$item->link = Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language));
|
||||
} else {
|
||||
$item->link = Route::_('index.php?option=com_users&view=login');
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of popular articles from the articles model
|
||||
*
|
||||
* @param \Joomla\Registry\Registry &$params object holding the models parameters
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @deprecated 4.3 will be removed in 7.0
|
||||
* Use the non-static method getArticles
|
||||
* Example: Factory::getApplication()->bootModule('mod_articles_popular', 'site')
|
||||
* ->getHelper('ArticlesPopularHelper')
|
||||
* ->getArticles($params, Factory::getApplication())
|
||||
*/
|
||||
public static function getList(&$params)
|
||||
{
|
||||
return (new self())->getArticles($params, Factory::getApplication());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_articles_popular
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
if (!isset($list)) {
|
||||
if (isset($hitsDisabledMessage)) {
|
||||
echo $hitsDisabledMessage;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<ul class="mostread mod-list">
|
||||
<?php foreach ($list as $item) : ?>
|
||||
<li itemscope itemtype="https://schema.org/Article">
|
||||
<a href="<?php echo $item->link; ?>" itemprop="url">
|
||||
<span itemprop="name">
|
||||
<?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
@@ -0,0 +1,154 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_banners</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2006-07</creationDate>
|
||||
<copyright>(C) 2006 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>3.0.0</version>
|
||||
<description>MOD_BANNERS_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\Banners</namespace>
|
||||
<files>
|
||||
<folder module="mod_banners">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_banners.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_banners.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Banners" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset
|
||||
name="basic"
|
||||
addfieldprefix="Joomla\Component\Banners\Administrator\Field"
|
||||
>
|
||||
|
||||
<field
|
||||
name="target"
|
||||
type="list"
|
||||
label="MOD_BANNERS_FIELD_TARGET_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">JBROWSERTARGET_PARENT</option>
|
||||
<option value="1">JBROWSERTARGET_NEW</option>
|
||||
<option value="2">JBROWSERTARGET_POPUP</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="count"
|
||||
type="number"
|
||||
label="MOD_BANNERS_FIELD_COUNT_LABEL"
|
||||
description="MOD_BANNERS_FIELD_COUNT_DESC"
|
||||
default="5"
|
||||
filter="integer"
|
||||
class="validate-numeric"
|
||||
min="1"
|
||||
validate="number"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cid"
|
||||
type="bannerclient"
|
||||
label="MOD_BANNERS_FIELD_BANNERCLIENT_LABEL"
|
||||
description="MOD_BANNERS_FIELD_BANNERCLIENT_DESC"
|
||||
filter="integer"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="catid"
|
||||
type="category"
|
||||
label="JCATEGORY"
|
||||
extension="com_banners"
|
||||
multiple="true"
|
||||
filter="intarray"
|
||||
class="multipleCategories"
|
||||
layout="joomla.form.field.list-fancy-select"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="tag_search"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_BANNERS_FIELD_TAG_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="ordering"
|
||||
type="list"
|
||||
label="MOD_BANNERS_FIELD_RANDOMISE_LABEL"
|
||||
default="0"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">MOD_BANNERS_VALUE_STICKYORDERING</option>
|
||||
<option value="random">MOD_BANNERS_VALUE_STICKYRANDOMISE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="header_text"
|
||||
type="textarea"
|
||||
label="MOD_BANNERS_FIELD_HEADER_LABEL"
|
||||
filter="safehtml"
|
||||
rows="3"
|
||||
cols="40"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="footer_text"
|
||||
type="textarea"
|
||||
label="MOD_BANNERS_FIELD_FOOTER_LABEL"
|
||||
filter="safehtml"
|
||||
rows="3"
|
||||
cols="40"
|
||||
/>
|
||||
</fieldset>
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cache"
|
||||
type="list"
|
||||
label="COM_MODULES_FIELD_CACHING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="cache_time"
|
||||
type="number"
|
||||
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
|
||||
default="900"
|
||||
filter="integer"
|
||||
/>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_banners
|
||||
*
|
||||
* @copyright (C) 2023 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The banners module service provider.
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Banners'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\Banners\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_banners
|
||||
*
|
||||
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Banners\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
use Joomla\Component\Banners\Administrator\Helper\BannersHelper as BannersComponentHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_banners
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
protected function getLayoutData(): array
|
||||
{
|
||||
BannersComponentHelper::updateReset();
|
||||
|
||||
$data = parent::getLayoutData();
|
||||
|
||||
$data['headerText'] = trim($data['params']->get('header_text', ''));
|
||||
$data['footerText'] = trim($data['params']->get('footer_text', ''));
|
||||
$data['list'] = $this->getHelperFactory()->getHelper('BannersHelper')->getBanners($data['params'], $this->getApplication());
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_banners
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Banners\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Application\CMSApplication;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Environment\Browser;
|
||||
use Joomla\Component\Banners\Site\Model\BannersModel;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Helper for mod_banners
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class BannersHelper
|
||||
{
|
||||
/**
|
||||
* Retrieve list of banners
|
||||
*
|
||||
* @param Registry $params The module parameters
|
||||
* @param CMSApplication $app The application
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
public function getBanners(Registry $params, CMSApplication $app)
|
||||
{
|
||||
/** @var BannersModel $model */
|
||||
$model = $app->bootComponent('com_banners')->getMVCFactory()->createModel('Banners', 'Site', ['ignore_request' => true]);
|
||||
|
||||
$keywords = explode(',', $app->getDocument()->getMetaData('keywords'));
|
||||
$config = ComponentHelper::getParams('com_banners');
|
||||
|
||||
$model->setState('filter.client_id', (int) $params->get('cid'));
|
||||
$model->setState('filter.category_id', $params->get('catid', []));
|
||||
$model->setState('list.limit', (int) $params->get('count', 1));
|
||||
$model->setState('list.start', 0);
|
||||
$model->setState('filter.ordering', $params->get('ordering'));
|
||||
$model->setState('filter.tag_search', $params->get('tag_search'));
|
||||
$model->setState('filter.keywords', $keywords);
|
||||
$model->setState('filter.language', $app->getLanguageFilter());
|
||||
|
||||
$banners = $model->getItems();
|
||||
|
||||
if ($banners) {
|
||||
if ($config->get('track_robots_impressions', 1) == 1 || !Browser::getInstance()->isRobot()) {
|
||||
$model->impress();
|
||||
}
|
||||
}
|
||||
|
||||
return $banners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve list of banners
|
||||
*
|
||||
* @param Registry $params The module parameters
|
||||
* @param BannersModel $model The model
|
||||
* @param CMSApplication $app The application
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @deprecated 5.1.0 will be removed in 7.0
|
||||
* Use the non-static method getBanners
|
||||
* Example: Factory::getApplication()->bootModule('mod_banners', 'site')
|
||||
* ->getHelper('BannersHelper')
|
||||
* ->getBanners($params, Factory::getApplication())
|
||||
*/
|
||||
public static function getList(Registry $params, BannersModel $model, CMSApplication $app)
|
||||
{
|
||||
return (new self())->getBanners($params, $app);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_banners
|
||||
*
|
||||
* @copyright (C) 2006 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\Helper\MediaHelper;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
?>
|
||||
<div class="mod-banners bannergroup">
|
||||
<?php if ($headerText) : ?>
|
||||
<div class="bannerheader">
|
||||
<?php echo $headerText; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php foreach ($list as $item) : ?>
|
||||
<div class="mod-banners__item banneritem">
|
||||
<?php $link = Route::_('index.php?option=com_banners&task=click&id=' . $item->id); ?>
|
||||
<?php if ($item->type == 1) : ?>
|
||||
<?php // Text based banners ?>
|
||||
<?php echo str_replace(['{CLICKURL}', '{NAME}'], [$link, $item->name], $item->custombannercode); ?>
|
||||
<?php else : ?>
|
||||
<?php $imageobject = HTMLHelper::cleanImageURL($item->params->get('imageurl')); ?>
|
||||
<?php $imageurl = $imageobject->url; ?>
|
||||
<?php if (!empty($imageurl) && (MediaHelper::isImage($imageurl) || MediaHelper::getMimeType($imageurl) === 'image/svg+xml')) : ?>
|
||||
<?php // Image based banner ?>
|
||||
<?php $baseurl = strpos($imageurl, 'http') === 0 ? '' : Uri::base(); ?>
|
||||
<?php $alt = $item->params->get('alt'); ?>
|
||||
<?php $alt = $alt ?: $item->name; ?>
|
||||
<?php $alt = $alt ?: Text::_('MOD_BANNERS_BANNER'); ?>
|
||||
<?php $width = $item->params->get('width'); ?>
|
||||
<?php $height = $item->params->get('height'); ?>
|
||||
<?php $imageAttribs = [
|
||||
'src' => $baseurl . $imageurl,
|
||||
'alt' => $alt
|
||||
];?>
|
||||
<?php if (!empty($width)) : ?>
|
||||
<?php $imageAttribs['width'] = $width; ?>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($height)) : ?>
|
||||
<?php $imageAttribs['height'] = $height; ?>
|
||||
<?php endif; ?>
|
||||
<?php $image = LayoutHelper::render('joomla.html.image', $imageAttribs); ?>
|
||||
<?php if ($item->clickurl) : ?>
|
||||
<?php // Wrap the banner in a link ?>
|
||||
<?php $target = $params->get('target', 1); ?>
|
||||
<?php if ($target == 1) : ?>
|
||||
<?php // Open in a new window ?>
|
||||
<a
|
||||
href="<?php echo $link; ?>" target="_blank" rel="noopener noreferrer"
|
||||
title="<?php echo htmlspecialchars($item->name, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<?php echo $image; ?>
|
||||
</a>
|
||||
<?php elseif ($target == 2) : ?>
|
||||
<?php // Open in a popup window ?>
|
||||
<a
|
||||
href="<?php echo $link; ?>" onclick="window.open(this.href, '',
|
||||
'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=780,height=550');
|
||||
return false"
|
||||
title="<?php echo htmlspecialchars($item->name, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<?php echo $image; ?>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<?php // Open in parent window ?>
|
||||
<a
|
||||
href="<?php echo $link; ?>"
|
||||
title="<?php echo htmlspecialchars($item->name, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<?php echo $image; ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<?php // Just display the image if no link specified ?>
|
||||
<?php echo $image; ?>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<?php if ($footerText) : ?>
|
||||
<div class="mod-banners__footer bannerfooter">
|
||||
<?php echo $footerText; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_breadcrumbs</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2006-07</creationDate>
|
||||
<copyright>(C) 2006 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>3.0.0</version>
|
||||
<description>MOD_BREADCRUMBS_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\Breadcrumbs</namespace>
|
||||
<files>
|
||||
<folder module="mod_breadcrumbs">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_breadcrumbs.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_breadcrumbs.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Breadcrumbs" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic">
|
||||
<field
|
||||
name="showHere"
|
||||
type="radio"
|
||||
label="MOD_BREADCRUMBS_FIELD_SHOWHERE_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="showHome"
|
||||
type="radio"
|
||||
label="MOD_BREADCRUMBS_FIELD_SHOWHOME_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="homeText"
|
||||
type="text"
|
||||
label="MOD_BREADCRUMBS_FIELD_HOMETEXT_LABEL"
|
||||
description="MOD_BREADCRUMBS_FIELD_HOMETEXT_DESC"
|
||||
showon="showHome:1"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="showLast"
|
||||
type="radio"
|
||||
label="MOD_BREADCRUMBS_FIELD_SHOWLAST_LABEL"
|
||||
default="1"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cache"
|
||||
type="list"
|
||||
label="COM_MODULES_FIELD_CACHING_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="cache_time"
|
||||
type="number"
|
||||
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cachemode"
|
||||
type="hidden"
|
||||
default="itemid"
|
||||
>
|
||||
<option value="itemid"></option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_breadcrumbs
|
||||
*
|
||||
* @copyright (C) 2023 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The breadcrumbs module service provider.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Breadcrumbs'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\Breadcrumbs\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_breadcrumbs
|
||||
*
|
||||
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Breadcrumbs\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_breadcrumbs
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
protected function getLayoutData(): array
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
|
||||
$data['list'] = $this->getHelperFactory()->getHelper('BreadcrumbsHelper')->getBreadcrumbs($data['params'], $data['app']);
|
||||
$data['count'] = \count($data['list']);
|
||||
|
||||
if (!$data['params']->get('showHome', 1)) {
|
||||
$data['homeCrumb'] = $this->getHelperFactory()->getHelper('BreadcrumbsHelper')->getHomeItem($data['params'], $data['app']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_breadcrumbs
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Breadcrumbs\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Application\CMSApplication;
|
||||
use Joomla\CMS\Application\SiteApplication;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Helper for mod_breadcrumbs
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class BreadcrumbsHelper
|
||||
{
|
||||
/**
|
||||
* Retrieve breadcrumb items
|
||||
*
|
||||
* @param Registry $params The module parameters
|
||||
* @param SiteApplication $app The application
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
public function getBreadcrumbs(Registry $params, SiteApplication $app): array
|
||||
{
|
||||
// Get the PathWay object from the application
|
||||
$pathway = $app->getPathway();
|
||||
$items = $pathway->getPathway();
|
||||
$count = \count($items);
|
||||
|
||||
// Don't use $items here as it references JPathway properties directly
|
||||
$crumbs = [];
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$crumbs[$i] = new \stdClass();
|
||||
$crumbs[$i]->name = stripslashes(htmlspecialchars($items[$i]->name, ENT_COMPAT, 'UTF-8'));
|
||||
$crumbs[$i]->link = $items[$i]->link;
|
||||
}
|
||||
|
||||
if ($params->get('showHome', 1)) {
|
||||
array_unshift($crumbs, $this->getHomeItem($params, $app));
|
||||
}
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve home item (start page)
|
||||
*
|
||||
* @param Registry $params The module parameters
|
||||
* @param SiteApplication $app The application
|
||||
*
|
||||
* @return object
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
public function getHomeItem(Registry $params, SiteApplication $app): object
|
||||
{
|
||||
$menu = $app->getMenu();
|
||||
|
||||
if (Multilanguage::isEnabled()) {
|
||||
$home = $menu->getDefault($app->getLanguage()->getTag());
|
||||
} else {
|
||||
$home = $menu->getDefault();
|
||||
}
|
||||
|
||||
$item = new \stdClass();
|
||||
$item->name = htmlspecialchars($params->get('homeText', $app->getLanguage()->_('MOD_BREADCRUMBS_HOME')), ENT_COMPAT, 'UTF-8');
|
||||
$item->link = $home->link . '&Itemid=' . $home->id;
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve breadcrumb items
|
||||
*
|
||||
* @param Registry $params The module parameters
|
||||
* @param CMSApplication $app The application
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @deprecated 4.4.0 will be removed in 7.0
|
||||
* Use the non-static method getBreadcrumbs
|
||||
* Example: Factory::getApplication()->bootModule('mod_breadcrumbs', 'site')
|
||||
* ->getHelper('BreadcrumbsHelper')
|
||||
* ->getBreadcrumbs($params, Factory::getApplication())
|
||||
*/
|
||||
public static function getList(Registry $params, CMSApplication $app)
|
||||
{
|
||||
return (new self())->getBreadcrumbs($params, Factory::getApplication());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve home item (start page)
|
||||
*
|
||||
* @param Registry $params The module parameters
|
||||
* @param CMSApplication $app The application
|
||||
*
|
||||
* @return object
|
||||
*
|
||||
* @since 4.2.0
|
||||
*
|
||||
* @deprecated 4.4.0 will be removed in 7.0
|
||||
* Use the non-static method getHomeItem
|
||||
* Example: Factory::getApplication()->bootModule('mod_breadcrumbs', 'site')
|
||||
* ->getHelper('BreadcrumbsHelper')
|
||||
* ->getHomeItem($params, Factory::getApplication())
|
||||
*/
|
||||
public static function getHome(Registry $params, CMSApplication $app)
|
||||
{
|
||||
return (new self())->getHomeItem($params, Factory::getApplication());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_breadcrumbs
|
||||
*
|
||||
* @copyright (C) 2006 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\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
use Joomla\CMS\WebAsset\WebAssetManager;
|
||||
|
||||
?>
|
||||
<nav class="mod-breadcrumbs__wrapper" aria-label="<?php echo htmlspecialchars($module->title, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<ol class="mod-breadcrumbs breadcrumb px-3 py-2">
|
||||
<?php if ($params->get('showHere', 1)) : ?>
|
||||
<li class="mod-breadcrumbs__here float-start">
|
||||
<?php echo Text::_('MOD_BREADCRUMBS_HERE'); ?> 
|
||||
</li>
|
||||
<?php else : ?>
|
||||
<li class="mod-breadcrumbs__divider float-start">
|
||||
<span class="divider icon-location icon-fw" aria-hidden="true"></span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
// Get rid of duplicated entries on trail including home page when using multilanguage
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
if ($i === 1 && !empty($list[$i]->link) && !empty($list[$i - 1]->link) && $list[$i]->link === $list[$i - 1]->link) {
|
||||
unset($list[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Find last and penultimate items in breadcrumbs list
|
||||
end($list);
|
||||
$last_item_key = key($list);
|
||||
prev($list);
|
||||
$penult_item_key = key($list);
|
||||
|
||||
// Make a link if not the last item in the breadcrumbs
|
||||
$show_last = $params->get('showLast', 1);
|
||||
|
||||
$class = null;
|
||||
|
||||
// Generate the trail
|
||||
foreach ($list as $key => $item) :
|
||||
if ($key !== $last_item_key) :
|
||||
if (!empty($item->link)) :
|
||||
$breadcrumbItem = HTMLHelper::_('link', Route::_($item->link), '<span>' . $item->name . '</span>', ['class' => 'pathway']);
|
||||
else :
|
||||
$breadcrumbItem = '<span>' . $item->name . '</span>';
|
||||
endif;
|
||||
echo '<li class="mod-breadcrumbs__item breadcrumb-item' . $class . '">' . $breadcrumbItem . '</li>';
|
||||
elseif ($show_last) :
|
||||
// Render last item if required.
|
||||
$breadcrumbItem = '<span>' . $item->name . '</span>';
|
||||
$class = ' active';
|
||||
echo '<li class="mod-breadcrumbs__item breadcrumb-item' . $class . '">' . $breadcrumbItem . '</li>';
|
||||
endif;
|
||||
endforeach; ?>
|
||||
</ol>
|
||||
<?php
|
||||
|
||||
// Structured data as JSON
|
||||
$data = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'BreadcrumbList',
|
||||
'@id' => Uri::root() . '#/schema/BreadcrumbList/' . (int) $module->id,
|
||||
'itemListElement' => []
|
||||
];
|
||||
|
||||
// Use an independent counter for positions. E.g. if Heading items in pathway.
|
||||
$itemsCounter = 0;
|
||||
|
||||
// If showHome is disabled use the fallback $homeCrumb for startpage at first position.
|
||||
if (isset($homeCrumb)) {
|
||||
$data['itemListElement'][] = [
|
||||
'@type' => 'ListItem',
|
||||
'position' => ++$itemsCounter,
|
||||
'item' => [
|
||||
'@id' => Route::_($homeCrumb->link, true, Route::TLS_IGNORE, true),
|
||||
'name' => $homeCrumb->name,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($list as $key => $item) {
|
||||
// Only add item to JSON if it has a valid link, otherwise skip it.
|
||||
if (!empty($item->link)) {
|
||||
$data['itemListElement'][] = [
|
||||
'@type' => 'ListItem',
|
||||
'position' => ++$itemsCounter,
|
||||
'item' => [
|
||||
'@id' => Route::_($item->link, true, Route::TLS_IGNORE, true),
|
||||
'name' => $item->name,
|
||||
],
|
||||
];
|
||||
} elseif ($key === $last_item_key) {
|
||||
// Add the last item (current page) to JSON, but without a link.
|
||||
// Google accepts items without a URL only as the current page.
|
||||
$data['itemListElement'][] = [
|
||||
'@type' => 'ListItem',
|
||||
'position' => ++$itemsCounter,
|
||||
'item' => [
|
||||
'name' => $item->name,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if ($itemsCounter) {
|
||||
/** @var WebAssetManager $wa */
|
||||
$wa = $app->getDocument()->getWebAssetManager();
|
||||
$prettyPrint = JDEBUG ? JSON_PRETTY_PRINT : 0;
|
||||
$wa->addInline(
|
||||
'script',
|
||||
json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | $prettyPrint),
|
||||
['name' => 'inline.breadcrumbs-schemaorg'],
|
||||
['type' => 'application/ld+json']
|
||||
);
|
||||
}
|
||||
?>
|
||||
</nav>
|
||||
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_custom</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2004-07</creationDate>
|
||||
<copyright>(C) 2005 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>3.0.0</version>
|
||||
<description>MOD_CUSTOM_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\Custom</namespace>
|
||||
<customContent />
|
||||
<files>
|
||||
<folder module="mod_custom">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_custom.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_custom.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Custom" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="options" label="COM_MODULES_BASIC_FIELDSET_LABEL">
|
||||
<field
|
||||
name="prepare_content"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_CUSTOM_FIELD_PREPARE_CONTENT_LABEL"
|
||||
description="MOD_CUSTOM_FIELD_PREPARE_CONTENT_DESC"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="backgroundimage"
|
||||
type="media"
|
||||
schemes="http,https,ftp,ftps,data,file"
|
||||
validate="url"
|
||||
relative="true"
|
||||
label="MOD_CUSTOM_FIELD_BACKGROUNDIMAGE_LABEL"
|
||||
/>
|
||||
</fieldset>
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cache"
|
||||
type="list"
|
||||
label="COM_MODULES_FIELD_CACHING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="cache_time"
|
||||
type="number"
|
||||
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
|
||||
default="900"
|
||||
filter="integer"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cachemode"
|
||||
type="hidden"
|
||||
default="static"
|
||||
>
|
||||
<option value="static"></option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_custom
|
||||
*
|
||||
* @copyright (C) 2023 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\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The module Custom HTML service provider.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Custom'));
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_custom
|
||||
*
|
||||
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Custom\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_custom
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher
|
||||
{
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
protected function getLayoutData()
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
|
||||
if (($data['params'])->get('prepare_content', 1)) {
|
||||
($data['module'])->content = HTMLHelper::_('content.prepare', ($data['module'])->content, '', 'mod_custom.content');
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_custom
|
||||
*
|
||||
* @copyright (C) 2009 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\Uri\Uri;
|
||||
|
||||
$modId = 'mod-custom' . $module->id;
|
||||
|
||||
if ($params->get('backgroundimage')) {
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
|
||||
$wa->addInlineStyle('
|
||||
#' . $modId . '{background-image: url("' . Uri::root(true) . '/' . HTMLHelper::_('cleanImageURL', $params->get('backgroundimage'))->url . '");}
|
||||
', ['name' => $modId]);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div id="<?php echo $modId; ?>" class="mod-custom custom">
|
||||
<?php echo $module->content; ?>
|
||||
</div>
|
||||
@@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_feed</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2005-07</creationDate>
|
||||
<copyright>(C) 2005 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>3.0.0</version>
|
||||
<description>MOD_FEED_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\Feed</namespace>
|
||||
<files>
|
||||
<folder module="mod_feed">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_feed.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_feed.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Feed_Display" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic">
|
||||
<field
|
||||
name="rssurl"
|
||||
type="url"
|
||||
label="MOD_FEED_FIELD_RSSURL_LABEL"
|
||||
filter="url"
|
||||
required="true"
|
||||
validate="url"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="rssrtl"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_FEED_FIELD_RTL_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="rsstitle"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_FEED_FIELD_RSSTITLE_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="rssdesc"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_FEED_FIELD_DESCRIPTION_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="rssdate"
|
||||
type="radio"
|
||||
label="MOD_FEED_FIELD_DATE_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="rssimage"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_FEED_FIELD_IMAGE_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="rssitems"
|
||||
type="number"
|
||||
label="MOD_FEED_FIELD_ITEMS_LABEL"
|
||||
default="3"
|
||||
filter="integer"
|
||||
min="1"
|
||||
validate="number"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="rssitemdesc"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_FEED_FIELD_ITEMDESCRIPTION_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="rssitemdate"
|
||||
type="radio"
|
||||
label="MOD_FEED_FIELD_ITEMDATE_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="word_count"
|
||||
type="text"
|
||||
label="MOD_FEED_FIELD_WORDCOUNT_LABEL"
|
||||
description="MOD_FEED_FIELD_WORDCOUNT_DESC"
|
||||
default="0"
|
||||
filter="integer"
|
||||
/>
|
||||
</fieldset>
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cache"
|
||||
type="list"
|
||||
label="COM_MODULES_FIELD_CACHING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="cache_time"
|
||||
type="number"
|
||||
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
|
||||
default="900"
|
||||
filter="integer"
|
||||
/>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_feed
|
||||
*
|
||||
* @copyright (C) 2023 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The feed module service provider.
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Feed'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\Feed\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_feed
|
||||
*
|
||||
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Feed\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_feed
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
protected function getLayoutData(): array
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
|
||||
$data['rssurl'] = $data['params']->get('rssurl', '');
|
||||
$data['rssrtl'] = $data['params']->get('rssrtl', 0);
|
||||
$data['feed'] = $this->getHelperFactory()->getHelper('FeedHelper')->getFeedInformation($data['params']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_feed
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Feed\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Feed\FeedFactory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Helper for mod_feed
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class FeedHelper
|
||||
{
|
||||
/**
|
||||
* Retrieve feed information
|
||||
*
|
||||
* @param \Joomla\Registry\Registry $params module parameters
|
||||
*
|
||||
* @return \Joomla\CMS\Feed\Feed|string
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
public function getFeedInformation($params)
|
||||
{
|
||||
// Module params
|
||||
$rssurl = $params->get('rssurl', '');
|
||||
|
||||
// Get RSS parsed object
|
||||
try {
|
||||
$feed = new FeedFactory();
|
||||
$rssDoc = $feed->getFeed($rssurl);
|
||||
} catch (\Exception) {
|
||||
return Text::_('MOD_FEED_ERR_FEED_NOT_RETRIEVED');
|
||||
}
|
||||
|
||||
if (empty($rssDoc)) {
|
||||
return Text::_('MOD_FEED_ERR_FEED_NOT_RETRIEVED');
|
||||
}
|
||||
|
||||
if ($rssDoc) {
|
||||
return $rssDoc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve feed information
|
||||
*
|
||||
* @param \Joomla\Registry\Registry $params module parameters
|
||||
*
|
||||
* @return \Joomla\CMS\Feed\Feed|string
|
||||
*
|
||||
* @deprecated 5.1.0 will be removed in 7.0
|
||||
* Use the non-static method getFeedInformation
|
||||
* Example: Factory::getApplication()->bootModule('mod_feed', 'site')
|
||||
* ->getHelper('FeedHelper')
|
||||
* ->getFeedInformation($params, Factory::getApplication())
|
||||
*
|
||||
*/
|
||||
public static function getFeed($params)
|
||||
{
|
||||
return (new self())->getFeedInformation($params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_feed
|
||||
*
|
||||
* @copyright (C) 2006 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\Text;
|
||||
use Joomla\Filter\OutputFilter;
|
||||
|
||||
// Check if feed URL has been set
|
||||
if (empty($rssurl)) {
|
||||
echo '<div>' . Text::_('MOD_FEED_ERR_NO_URL') . '</div>';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!empty($feed) && is_string($feed)) {
|
||||
echo $feed;
|
||||
} else {
|
||||
$lang = $app->getLanguage();
|
||||
$myrtl = $params->get('rssrtl', 0);
|
||||
$direction = ' ';
|
||||
|
||||
$isRtl = $lang->isRtl();
|
||||
|
||||
if ($isRtl && $myrtl == 0) {
|
||||
$direction = ' redirect-rtl';
|
||||
} elseif ($isRtl && $myrtl == 1) {
|
||||
// Feed description
|
||||
$direction = ' redirect-ltr';
|
||||
} elseif ($isRtl && $myrtl == 2) {
|
||||
$direction = ' redirect-rtl';
|
||||
} elseif ($myrtl == 0) {
|
||||
$direction = ' redirect-ltr';
|
||||
} elseif ($myrtl == 1) {
|
||||
$direction = ' redirect-ltr';
|
||||
} elseif ($myrtl == 2) {
|
||||
$direction = ' redirect-rtl';
|
||||
}
|
||||
|
||||
if ($feed !== false) {
|
||||
?>
|
||||
<div style="direction: <?php echo $rssrtl ? 'rtl' : 'ltr'; ?>;" class="text-<?php echo $rssrtl ? 'right' : 'left'; ?> feed">
|
||||
<?php
|
||||
// Feed title
|
||||
if ($feed->title !== null && $params->get('rsstitle', 1)) {
|
||||
?>
|
||||
<h2 class="<?php echo $direction; ?>">
|
||||
<a href="<?php echo htmlspecialchars($rssurl, ENT_QUOTES, 'UTF-8'); ?>" target="_blank" rel="noopener">
|
||||
<?php echo htmlspecialchars($feed->title, ENT_QUOTES, 'UTF-8'); ?></a>
|
||||
</h2>
|
||||
<?php
|
||||
}
|
||||
// Feed date
|
||||
if ($params->get('rssdate', 1) && ($feed->publishedDate !== null)) : ?>
|
||||
<h3>
|
||||
<?php echo HTMLHelper::_('date', $feed->publishedDate, Text::_('DATE_FORMAT_LC3')); ?>
|
||||
</h3>
|
||||
<?php endif;
|
||||
// Feed description
|
||||
if ($params->get('rssdesc', 1)) {
|
||||
?>
|
||||
<?php echo $feed->description; ?>
|
||||
<?php
|
||||
}
|
||||
// Feed image
|
||||
if ($feed->image && $params->get('rssimage', 1)) :
|
||||
?>
|
||||
<?php echo HTMLHelper::_('image', $feed->image->uri, $feed->image->title); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<!-- Show items -->
|
||||
<?php if (!empty($feed)) { ?>
|
||||
<ul class="newsfeed">
|
||||
<?php for ($i = 0, $max = min(count($feed), $params->get('rssitems', 3)); $i < $max; $i++) { ?>
|
||||
<?php
|
||||
$uri = $feed[$i]->uri || !$feed[$i]->isPermaLink ? trim($feed[$i]->uri) : trim($feed[$i]->guid);
|
||||
$uri = !$uri || stripos($uri, 'http') !== 0 ? $rssurl : $uri;
|
||||
$text = $feed[$i]->content !== '' ? trim($feed[$i]->content) : '';
|
||||
?>
|
||||
<li>
|
||||
<?php if (!empty($uri)) : ?>
|
||||
<span class="feed-link">
|
||||
<a href="<?php echo htmlspecialchars($uri, ENT_QUOTES, 'UTF-8'); ?>" target="_blank" rel="noopener">
|
||||
<?php echo htmlspecialchars(trim($feed[$i]->title), ENT_QUOTES, 'UTF-8'); ?></a></span>
|
||||
<?php else : ?>
|
||||
<span class="feed-link"><?php echo htmlspecialchars(trim($feed[$i]->title), ENT_QUOTES, 'UTF-8'); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($params->get('rssitemdate', 0) && $feed[$i]->publishedDate !== null) : ?>
|
||||
<div class="feed-item-date">
|
||||
<?php echo HTMLHelper::_('date', $feed[$i]->publishedDate, Text::_('DATE_FORMAT_LC3')); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($params->get('rssitemdesc', 1) && $text !== '') : ?>
|
||||
<div class="feed-item-description">
|
||||
<?php
|
||||
// Strip the images.
|
||||
$text = OutputFilter::stripImages($text);
|
||||
$text = HTMLHelper::_('string.truncate', $text, $params->get('word_count', 0));
|
||||
echo str_replace(''', "'", $text);
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php }
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_finder</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2011-08</creationDate>
|
||||
<copyright>(C) 2011 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>3.0.0</version>
|
||||
<description>MOD_FINDER_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\Finder</namespace>
|
||||
<files>
|
||||
<folder module="mod_finder">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_finder.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_finder.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Smart_Search" />
|
||||
<config>
|
||||
<fields name="params" addfieldprefix="Joomla\Component\Finder\Administrator\Field">
|
||||
<fieldset name="basic">
|
||||
<field
|
||||
name="searchfilter"
|
||||
type="searchfilter"
|
||||
label="MOD_FINDER_FIELDSET_BASIC_SEARCHFILTER_LABEL"
|
||||
default=""
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_autosuggest"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_FINDER_FIELDSET_BASIC_AUTOSUGGEST_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_advanced"
|
||||
type="list"
|
||||
label="MOD_FINDER_FIELDSET_BASIC_SHOW_ADVANCED_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="2">MOD_FINDER_FIELDSET_BASIC_SHOW_ADVANCED_OPTION_LINK</option>
|
||||
<option value="1">JSHOW</option>
|
||||
<option value="0">JHIDE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_label"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_FINDER_FIELDSET_ADVANCED_SHOW_LABEL_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="alt_label"
|
||||
type="text"
|
||||
label="MOD_FINDER_FIELDSET_ADVANCED_ALT_LABEL"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_button"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_FINDER_FIELDSET_ADVANCED_SHOW_BUTTON_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="opensearch"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_FINDER_FIELD_OPENSEARCH_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="opensearch_name"
|
||||
type="text"
|
||||
label="MOD_FINDER_FIELD_OPENSEARCH_TEXT_LABEL"
|
||||
showon="opensearch:1"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="set_itemid"
|
||||
type="menuitem"
|
||||
label="MOD_FINDER_FIELDSET_ADVANCED_SETITEMID_LABEL"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">MOD_FINDER_SELECT_MENU_ITEMID</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_finder
|
||||
*
|
||||
* @copyright (C) 2025 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The finder module service provider.
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Finder'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\Finder\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_finder
|
||||
*
|
||||
* @copyright (C) 2025 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Finder\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
use Joomla\Component\Finder\Administrator\Helper\LanguageHelper;
|
||||
use Joomla\Component\Finder\Site\Helper\RouteHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_finder
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
protected function getLayoutData()
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
|
||||
$cparams = ComponentHelper::getParams('com_finder');
|
||||
|
||||
// Check for OpenSearch
|
||||
if ($data['params']->get('opensearch', $cparams->get('opensearch', 1))) {
|
||||
$defaultTitle = Text::_('MOD_FINDER_OPENSEARCH_NAME') . ' ' . $data['app']->get('sitename');
|
||||
$ostitle = $data['params']->get('opensearch_name', $cparams->get('opensearch_name', $defaultTitle));
|
||||
$data['app']->getDocument()->addHeadLink(
|
||||
Uri::getInstance()->toString(['scheme', 'host', 'port']) . Route::_('index.php?option=com_finder&view=search&format=opensearch'),
|
||||
'search',
|
||||
'rel',
|
||||
['title' => $ostitle, 'type' => 'application/opensearchdescription+xml']
|
||||
);
|
||||
}
|
||||
|
||||
// Get the route.
|
||||
$data['route'] = RouteHelper::getSearchRoute($data['params']->get('searchfilter', null));
|
||||
|
||||
if ($data['params']->get('set_itemid')) {
|
||||
$uri = Uri::getInstance($data['route']);
|
||||
$uri->setVar('Itemid', $data['params']->get('set_itemid'));
|
||||
$data['route'] = $uri->toString(['path', 'query']);
|
||||
}
|
||||
|
||||
// Load component language file.
|
||||
LanguageHelper::loadComponentLanguage();
|
||||
|
||||
// Load plugin language files.
|
||||
LanguageHelper::loadPluginLanguage();
|
||||
|
||||
// Get Smart Search query object.
|
||||
$data['query'] = $this->getHelperFactory()->getHelper('FinderHelper')->getSearchQuery($data['params'], $data['app']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_finder
|
||||
*
|
||||
* @copyright (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Finder\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Application\CMSApplicationInterface;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Filter\InputFilter;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
use Joomla\Component\Finder\Administrator\Indexer\Query;
|
||||
use Joomla\Database\DatabaseAwareInterface;
|
||||
use Joomla\Database\DatabaseAwareTrait;
|
||||
use Joomla\Registry\Registry;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Finder module helper.
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
class FinderHelper implements DatabaseAwareInterface
|
||||
{
|
||||
use DatabaseAwareTrait;
|
||||
|
||||
/**
|
||||
* Method to get hidden input fields for a get form so that control variables
|
||||
* are not lost upon form submission.
|
||||
*
|
||||
* @param string $route The route to the page. [optional]
|
||||
*
|
||||
* @return string A string of hidden input form fields
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function getHiddenFields($route = null): string
|
||||
{
|
||||
$fields = [];
|
||||
$uri = Uri::getInstance(Route::_($route));
|
||||
$uri->delVar('q');
|
||||
|
||||
// Create hidden input elements for each part of the URI.
|
||||
foreach ($uri->getQuery(true) as $n => $v) {
|
||||
$fields[] = '<input type="hidden" name="' . $n . '" value="' . $v . '">';
|
||||
}
|
||||
|
||||
return implode('', $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Smart Search query object.
|
||||
*
|
||||
* @param Registry $params Module parameters.
|
||||
* @param CMSApplicationInterface $app The application
|
||||
*
|
||||
* @return Query object
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function getSearchQuery(Registry $params, CMSApplicationInterface $app): Query
|
||||
{
|
||||
$request = $app->getInput()->request;
|
||||
$filter = InputFilter::getInstance();
|
||||
|
||||
// Get the static taxonomy filters.
|
||||
$options = [];
|
||||
$options['filter'] = ($request->get('f', 0, 'int') !== 0) ? $request->get('f', '', 'int') : $params->get('searchfilter');
|
||||
$options['filter'] = $filter->clean($options['filter'], 'int');
|
||||
|
||||
// Get the dynamic taxonomy filters.
|
||||
$options['filters'] = $request->get('t', '', 'array');
|
||||
$options['filters'] = $filter->clean($options['filters'], 'array');
|
||||
$options['filters'] = ArrayHelper::toInteger($options['filters']);
|
||||
|
||||
// Instantiate a query object.
|
||||
return new Query($options, $this->getDatabase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get hidden input fields for a get form so that control variables
|
||||
* are not lost upon form submission.
|
||||
*
|
||||
* @param string $route The route to the page. [optional]
|
||||
* @param integer $paramItem The menu item ID. (@since 3.1) [optional]
|
||||
*
|
||||
* @return string A string of hidden input form fields
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @deprecated 5.4.0 will be removed in 7.0
|
||||
* Use the non-static method getFields
|
||||
* Example: Factory::getApplication()->bootModule('mod_finder', 'site')
|
||||
* ->getHelper('FinderHelper')
|
||||
* ->getHiddenFields($route, $paramItem)
|
||||
*/
|
||||
public static function getGetFields($route = null, $paramItem = 0)
|
||||
{
|
||||
return (new self())->getHiddenFields($route);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Smart Search query object.
|
||||
*
|
||||
* @param \Joomla\Registry\Registry $params Module parameters.
|
||||
*
|
||||
* @return Query object
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @deprecated 5.4.0 will be removed in 7.0
|
||||
* Use the non-static method getSearchQuery
|
||||
* Example: Factory::getApplication()->bootModule('mod_finder', 'site')
|
||||
* ->getHelper('FinderHelper')
|
||||
* ->getSearchQuery($params, Factory::getApplication())
|
||||
*/
|
||||
public static function getQuery($params)
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
|
||||
return $app->bootModule('mod_finder', 'site')
|
||||
->getHelper('FinderHelper')
|
||||
->getSearchQuery($params, $app);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_finder
|
||||
*
|
||||
* @copyright (C) 2011 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\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
// Load the smart search component language file.
|
||||
$lang = $app->getLanguage();
|
||||
$lang->load('com_finder', JPATH_SITE);
|
||||
|
||||
$input = '<input type="text" name="q" id="mod-finder-searchword' . $module->id . '" class="js-finder-search-query form-control" value="' . htmlspecialchars($app->getInput()->get('q', '', 'string'), ENT_COMPAT, 'UTF-8') . '"'
|
||||
. ' placeholder="' . Text::_('MOD_FINDER_SEARCH_VALUE') . '">';
|
||||
|
||||
$showLabel = $params->get('show_label', 1);
|
||||
$labelClass = (!$showLabel ? 'visually-hidden ' : '') . 'finder';
|
||||
$label = '<label for="mod-finder-searchword' . $module->id . '" class="' . $labelClass . '">' . $params->get('alt_label', Text::_('JSEARCH_FILTER_SUBMIT')) . '</label>';
|
||||
|
||||
$output = '';
|
||||
|
||||
if ($params->get('show_button', 0)) {
|
||||
$output .= $label;
|
||||
$output .= '<div class="mod-finder__search input-group">';
|
||||
$output .= $input;
|
||||
$output .= '<button class="btn btn-primary" type="submit"><span class="icon-search icon-white" aria-hidden="true"></span> ' . Text::_('JSEARCH_FILTER_SUBMIT') . '</button>';
|
||||
$output .= '</div>';
|
||||
} else {
|
||||
$output .= $label;
|
||||
$output .= $input;
|
||||
}
|
||||
|
||||
Text::script('MOD_FINDER_SEARCH_VALUE');
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $app->getDocument()->getWebAssetManager();
|
||||
$wa->getRegistry()->addExtensionRegistryFile('com_finder');
|
||||
|
||||
/*
|
||||
* This segment of code sets up the autocompleter.
|
||||
*/
|
||||
if ($params->get('show_autosuggest', 1)) {
|
||||
$wa->usePreset('awesomplete');
|
||||
$app->getDocument()->addScriptOptions('finder-search', ['url' => Route::_('index.php?option=com_finder&task=suggestions.suggest&format=json&tmpl=component', false)]);
|
||||
|
||||
Text::script('COM_FINDER_SEARCH_FORM_LIST_LABEL');
|
||||
Text::script('JLIB_JS_AJAX_ERROR_OTHER');
|
||||
Text::script('JLIB_JS_AJAX_ERROR_PARSE');
|
||||
}
|
||||
|
||||
$wa->useScript('com_finder.finder');
|
||||
|
||||
$finderHelper = $app->bootModule('mod_finder', 'site')->getHelper('FinderHelper');
|
||||
|
||||
?>
|
||||
|
||||
<search>
|
||||
<form class="mod-finder js-finder-searchform form-search" action="<?php echo Route::_($route); ?>" method="get" aria-label="search">
|
||||
<?php echo $output; ?>
|
||||
|
||||
<?php $show_advanced = $params->get('show_advanced', 0); ?>
|
||||
<?php if ($show_advanced == 2) : ?>
|
||||
<br>
|
||||
<a href="<?php echo Route::_($route); ?>" class="mod-finder__advanced-link"><?php echo Text::_('COM_FINDER_ADVANCED_SEARCH'); ?></a>
|
||||
<?php elseif ($show_advanced == 1) : ?>
|
||||
<div class="mod-finder__advanced js-finder-advanced">
|
||||
<?php echo HTMLHelper::_('filter.select', $query, $params); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php echo $finderHelper->getHiddenFields($route); ?>
|
||||
</form>
|
||||
</search>
|
||||
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_footer</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2006-07</creationDate>
|
||||
<copyright>(C) 2006 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>3.0.0</version>
|
||||
<description>MOD_FOOTER_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\Footer</namespace>
|
||||
<files>
|
||||
<folder module="mod_footer">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_footer.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_footer.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Footer" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cache"
|
||||
type="list"
|
||||
label="COM_MODULES_FIELD_CACHING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="cache_time"
|
||||
type="number"
|
||||
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
|
||||
default="900"
|
||||
filter="integer"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cachemode"
|
||||
type="hidden"
|
||||
default="static"
|
||||
>
|
||||
<option value="static"></option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_footer
|
||||
*
|
||||
* @copyright (C) 2023 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\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The footer module service provider.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Footer'));
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_footer
|
||||
*
|
||||
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Footer\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_footer
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher
|
||||
{
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
protected function getLayoutData(): array
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
|
||||
$lineOne = $this->getApplication()->getLanguage()->_('MOD_FOOTER_LINE1');
|
||||
$lineOne = str_replace('%date%', HTMLHelper::_('date', 'now', 'Y'), $lineOne);
|
||||
$lineOne = str_replace('%sitename%', $this->getApplication()->get('sitename', ''), $lineOne);
|
||||
|
||||
$data['lineone'] = $lineOne;
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_footer
|
||||
*
|
||||
* @copyright (C) 2006 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;
|
||||
|
||||
?>
|
||||
<div class="mod-footer">
|
||||
<div class="footer1"><?php echo $lineone; ?></div>
|
||||
<div class="footer2"><?php echo Text::_('MOD_FOOTER_LINE2'); ?></div>
|
||||
</div>
|
||||
@@ -0,0 +1,151 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_languages</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2010-02</creationDate>
|
||||
<copyright>(C) 2010 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>3.5.0</version>
|
||||
<description>MOD_LANGUAGES_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\Languages</namespace>
|
||||
<files>
|
||||
<folder module="mod_languages">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_languages.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_languages.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Language_Switcher" />
|
||||
<config>
|
||||
<fieldset>
|
||||
<field
|
||||
name="language"
|
||||
type="list"
|
||||
label="JFIELD_LANGUAGE_LABEL"
|
||||
description="JFIELD_MODULE_LANGUAGE_DESC"
|
||||
validate="options"
|
||||
>
|
||||
<option value="*">JALL</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
<fields name="params">
|
||||
<fieldset name="basic">
|
||||
<field
|
||||
name="header_text"
|
||||
type="textarea"
|
||||
label="MOD_LANGUAGES_FIELD_HEADER_LABEL"
|
||||
filter="safehtml"
|
||||
rows="3"
|
||||
cols="40"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="footer_text"
|
||||
type="textarea"
|
||||
label="MOD_LANGUAGES_FIELD_FOOTER_LABEL"
|
||||
filter="safehtml"
|
||||
rows="3"
|
||||
cols="40"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="dropdown"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_LANGUAGES_FIELD_DROPDOWN_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="dropdownimage"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_LANGUAGES_FIELD_DROPDOWN_IMAGE_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
showon="dropdown:1"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="image"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_LANGUAGES_FIELD_USEIMAGE_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
showon="dropdown:0"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="full_name"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_LANGUAGES_FIELD_FULL_NAME_LABEL"
|
||||
showon="dropdown:1[OR]image:0"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_active"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_LANGUAGES_FIELD_ACTIVE_LABEL"
|
||||
default="1"
|
||||
showon="dropdownimage:1[OR]dropdown:0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="inline"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_LANGUAGES_FIELD_INLINE_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
showon="dropdown:0"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_languages
|
||||
*
|
||||
* @copyright (C) 2024 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The language switcher module service provider.
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Languages'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\Languages\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_languages
|
||||
*
|
||||
* @copyright (C) 2024 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Languages\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_languages
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
protected function getLayoutData()
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
|
||||
$data['headerText'] = $data['params']->get('header_text');
|
||||
$data['footerText'] = $data['params']->get('footer_text');
|
||||
$data['list'] = $this->getHelperFactory()->getHelper('LanguagesHelper')->getLanguages($data['params']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_languages
|
||||
*
|
||||
* @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Languages\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Association\AssociationServiceInterface;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Associations;
|
||||
use Joomla\CMS\Language\LanguageHelper;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
use Joomla\Component\Menus\Administrator\Helper\MenusHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Helper for mod_languages
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class LanguagesHelper
|
||||
{
|
||||
/**
|
||||
* Gets a list of available languages
|
||||
*
|
||||
* @param \Joomla\Registry\Registry &$params module params
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
public function getLanguages(&$params)
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
$user = $app->getIdentity();
|
||||
$lang = $app->getLanguage();
|
||||
$languages = LanguageHelper::getLanguages();
|
||||
|
||||
$menu = $app->getMenu();
|
||||
$active = $menu->getActive();
|
||||
|
||||
// Get menu home items
|
||||
$homes = [];
|
||||
$homes['*'] = $menu->getDefault('*');
|
||||
|
||||
foreach ($languages as $item) {
|
||||
$default = $menu->getDefault($item->lang_code);
|
||||
|
||||
if ($default && $default->language === $item->lang_code) {
|
||||
$homes[$item->lang_code] = $default;
|
||||
}
|
||||
}
|
||||
|
||||
// Load associations
|
||||
$assoc = Associations::isEnabled();
|
||||
$option = $app->getInput()->get('option');
|
||||
$associations = [];
|
||||
|
||||
if ($assoc && $option) {
|
||||
if ($active) {
|
||||
$associations = MenusHelper::getAssociations($active->id);
|
||||
}
|
||||
|
||||
$component = $app->bootComponent($option);
|
||||
|
||||
if ($component instanceof AssociationServiceInterface) {
|
||||
$cassociations = $component->getAssociationsExtension()->getAssociationsForItem();
|
||||
} else {
|
||||
// Load component associations
|
||||
$class = str_replace('com_', '', $option) . 'HelperAssociation';
|
||||
\JLoader::register($class, JPATH_SITE . '/components/' . $option . '/helpers/association.php');
|
||||
|
||||
if (class_exists($class) && \is_callable([$class, 'getAssociations'])) {
|
||||
$cassociations = \call_user_func([$class, 'getAssociations']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$levels = $user->getAuthorisedViewLevels();
|
||||
$sitelangs = LanguageHelper::getInstalledLanguages(0);
|
||||
$multilang = Multilanguage::isEnabled();
|
||||
|
||||
// Filter allowed languages
|
||||
foreach ($languages as $i => &$language) {
|
||||
// Do not display language without frontend UI
|
||||
if (!\array_key_exists($language->lang_code, $sitelangs)) {
|
||||
unset($languages[$i]);
|
||||
} elseif (!isset($homes[$language->lang_code])) {
|
||||
// Do not display language without specific home menu
|
||||
unset($languages[$i]);
|
||||
} elseif (isset($language->access) && $language->access && !\in_array($language->access, $levels)) {
|
||||
// Do not display language without authorized access level
|
||||
unset($languages[$i]);
|
||||
} else {
|
||||
$language->active = ($language->lang_code === $lang->getTag());
|
||||
|
||||
// Fetch language rtl
|
||||
// If loaded language get from current JLanguage metadata
|
||||
if ($language->active) {
|
||||
$language->rtl = $lang->isRtl();
|
||||
} else {
|
||||
// If not loaded language fetch metadata directly for performance
|
||||
$languageMetadata = LanguageHelper::getMetadata($language->lang_code);
|
||||
$language->rtl = $languageMetadata['rtl'];
|
||||
}
|
||||
|
||||
if ($multilang) {
|
||||
if (isset($cassociations[$language->lang_code])) {
|
||||
$language->link = Route::_($cassociations[$language->lang_code]);
|
||||
} elseif (isset($associations[$language->lang_code]) && $menu->getItem($associations[$language->lang_code])) {
|
||||
$itemid = $associations[$language->lang_code];
|
||||
$language->link = Route::_('index.php?lang=' . $language->sef . '&Itemid=' . $itemid);
|
||||
} elseif ($active && $active->language === '*') {
|
||||
$language->link = Route::_('index.php?lang=' . $language->sef . '&Itemid=' . $active->id);
|
||||
} else {
|
||||
if ($language->active) {
|
||||
$language->link = Uri::getInstance()->toString(['path', 'query']);
|
||||
} else {
|
||||
$itemid = isset($homes[$language->lang_code]) ? $homes[$language->lang_code]->id : $homes['*']->id;
|
||||
$language->link = Route::_('index.php?lang=' . $language->sef . '&Itemid=' . $itemid);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$language->link = Route::_('&Itemid=' . $homes['*']->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $languages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of available languages
|
||||
*
|
||||
* @param \Joomla\Registry\Registry &$params module params
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @deprecated 5.1.0 will be removed in 7.0
|
||||
* Use the non-static method getLanguages
|
||||
* Example: Factory::getApplication()->bootModule('mod_languages', 'site')
|
||||
* ->getHelper('LanguagesHelper')
|
||||
* ->getLanguages($params)
|
||||
*/
|
||||
public static function getList(&$params)
|
||||
{
|
||||
return (new self())->getLanguages($params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_languages
|
||||
*
|
||||
* @copyright (C) 2010 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\Text;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $app->getDocument()->getWebAssetManager();
|
||||
$wa->registerAndUseStyle('mod_languages', 'mod_languages/template.css');
|
||||
?>
|
||||
<div class="mod-languages">
|
||||
<p class="visually-hidden" id="language_picker_des_<?php echo $module->id; ?>"><?php echo Text::_('MOD_LANGUAGES_DESC'); ?></p>
|
||||
|
||||
<?php if ($headerText) : ?>
|
||||
<div class="mod-languages__pretext pretext"><p><?php echo $headerText; ?></p></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($params->get('dropdown', 0)) : ?>
|
||||
<?php HTMLHelper::_('bootstrap.dropdown', '.dropdown-toggle'); ?>
|
||||
<div class="mod-languages__select btn-group">
|
||||
<?php foreach ($list as $language) : ?>
|
||||
<?php if ($language->active) : ?>
|
||||
<button id="language_btn_<?php echo $module->id; ?>" type="button" data-bs-toggle="dropdown" class="btn btn-secondary dropdown-toggle" aria-haspopup="listbox" aria-labelledby="language_picker_des_<?php echo $module->id; ?> language_btn_<?php echo $module->id; ?>" aria-expanded="false">
|
||||
<?php if ($params->get('dropdownimage', 1) && ($language->image)) : ?>
|
||||
<?php echo HTMLHelper::_('image', 'mod_languages/' . $language->image . '.gif', $params->get('full_name') ? '' : $language->title_native, null, true); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo $params->get('full_name', 1) ? $language->title_native : strtoupper($language->sef); ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
<ul aria-labelledby="language_picker_des_<?php echo $module->id; ?>" class="lang-block dropdown-menu">
|
||||
|
||||
<?php foreach ($list as $language) : ?>
|
||||
<?php
|
||||
$lbl = '';
|
||||
if ($params->get('full_name') === 0) {
|
||||
$lbl = 'aria-label="' . $language->title_native . '"';
|
||||
}
|
||||
?>
|
||||
<?php if (!$language->active) : ?>
|
||||
<li>
|
||||
<a <?php echo $lbl; ?> href="<?php echo htmlspecialchars_decode(htmlspecialchars($language->link, ENT_QUOTES, 'UTF-8'), ENT_NOQUOTES); ?>">
|
||||
<?php if ($params->get('dropdownimage', 1) && ($language->image)) : ?>
|
||||
<?php echo HTMLHelper::_('image', 'mod_languages/' . $language->image . '.gif', $params->get('full_name') ? '' : $language->title_native, null, true); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo $params->get('full_name', 1) ? $language->title_native : strtoupper($language->sef); ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php elseif ($params->get('show_active', 1)) : ?>
|
||||
<?php $base = Uri::getInstance(); ?>
|
||||
<li class="lang-active">
|
||||
<a aria-current="true" <?php echo $lbl; ?> href="<?php echo htmlspecialchars_decode(htmlspecialchars($base, ENT_QUOTES, 'UTF-8'), ENT_NOQUOTES); ?>">
|
||||
<?php if ($params->get('dropdownimage', 1) && ($language->image)) : ?>
|
||||
<?php echo HTMLHelper::_('image', 'mod_languages/' . $language->image . '.gif', $params->get('full_name') ? '' : $language->title_native, null, true); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo $params->get('full_name', 1) ? $language->title_native : strtoupper($language->sef); ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<ul aria-labelledby="language_picker_des_<?php echo $module->id; ?>" class="mod-languages__list <?php echo $params->get('inline', 1) ? 'lang-inline' : 'lang-block'; ?>">
|
||||
|
||||
<?php foreach ($list as $language) : ?>
|
||||
<?php
|
||||
$lbl = '';
|
||||
if ((($params->get('full_name') === 0) && ($params->get('image') === 0)) || (!$language->image)) {
|
||||
$lbl = 'aria-label="' . $language->title_native . '"';
|
||||
}
|
||||
?>
|
||||
<?php if (!$language->active) : ?>
|
||||
<li>
|
||||
<a <?php echo $lbl; ?> href="<?php echo htmlspecialchars_decode(htmlspecialchars($language->link, ENT_QUOTES, 'UTF-8'), ENT_NOQUOTES); ?>">
|
||||
<?php if ($params->get('image', 1)) : ?>
|
||||
<?php if ($language->image) : ?>
|
||||
<?php echo HTMLHelper::_('image', 'mod_languages/' . $language->image . '.gif', $language->title_native, ['title' => $language->title_native], true); ?>
|
||||
<?php else : ?>
|
||||
<span class="label" title="<?php echo $language->title_native; ?>"><?php echo strtoupper($language->sef); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<?php echo $params->get('full_name', 1) ? $language->title_native : strtoupper($language->sef); ?>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php elseif ($params->get('show_active', 1)) : ?>
|
||||
<?php $base = Uri::getInstance(); ?>
|
||||
<li class="lang-active">
|
||||
<a aria-current="true" <?php echo $lbl; ?> href="<?php echo htmlspecialchars_decode(htmlspecialchars($base, ENT_QUOTES, 'UTF-8'), ENT_NOQUOTES); ?>">
|
||||
<?php if ($params->get('image', 1)) : ?>
|
||||
<?php if ($language->image) : ?>
|
||||
<?php echo HTMLHelper::_('image', 'mod_languages/' . $language->image . '.gif', $language->title_native, ['title' => $language->title_native], true); ?>
|
||||
<?php else : ?>
|
||||
<span class="badge bg-secondary" title="<?php echo $language->title_native; ?>"><?php echo strtoupper($language->sef); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<?php echo $params->get('full_name', 1) ? $language->title_native : strtoupper($language->sef); ?>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($footerText) : ?>
|
||||
<div class="mod-languages__posttext posttext"><p><?php echo $footerText; ?></p></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -0,0 +1,154 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_login</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2006-07</creationDate>
|
||||
<copyright>(C) 2006 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>3.0.0</version>
|
||||
<description>MOD_LOGIN_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\Login</namespace>
|
||||
<files>
|
||||
<folder module="mod_login">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_login.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_login.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Login" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic" addfieldprefix="Joomla\Component\Menus\Administrator\Field">
|
||||
<field
|
||||
name="pretext"
|
||||
type="textarea"
|
||||
label="MOD_LOGIN_FIELD_PRE_TEXT_LABEL"
|
||||
filter="safehtml"
|
||||
cols="30"
|
||||
rows="5"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="posttext"
|
||||
type="textarea"
|
||||
label="MOD_LOGIN_FIELD_POST_TEXT_LABEL"
|
||||
filter="safehtml"
|
||||
cols="30"
|
||||
rows="5"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="login"
|
||||
type="modal_menu"
|
||||
label="MOD_LOGIN_FIELD_LOGIN_REDIRECTURL_LABEL"
|
||||
description="MOD_LOGIN_FIELD_LOGIN_REDIRECTURL_DESC"
|
||||
disable="separator,alias,heading,url"
|
||||
select="true"
|
||||
new="true"
|
||||
edit="true"
|
||||
clear="true"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_MENU_ITEM</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="logout"
|
||||
type="modal_menu"
|
||||
label="MOD_LOGIN_FIELD_LOGOUT_REDIRECTURL_LABEL"
|
||||
description="MOD_LOGIN_FIELD_LOGOUT_REDIRECTURL_DESC"
|
||||
disable="separator,alias,heading,url"
|
||||
select="true"
|
||||
new="true"
|
||||
edit="true"
|
||||
clear="true"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_MENU_ITEM</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="customRegLinkMenu"
|
||||
type="modal_menu"
|
||||
label="MOD_LOGIN_FIELD_REGISTRATION_MENU_LABEL"
|
||||
disable="separator,alias,heading,url"
|
||||
select="true"
|
||||
new="true"
|
||||
edit="true"
|
||||
clear="true"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_MENU_ITEM</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="greeting"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_LOGIN_FIELD_GREETING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="name"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_LOGIN_FIELD_NAME_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
showon="greeting:1"
|
||||
>
|
||||
<option value="0">MOD_LOGIN_VALUE_NAME</option>
|
||||
<option value="1">MOD_LOGIN_VALUE_USERNAME</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="profilelink"
|
||||
type="radio"
|
||||
label="MOD_LOGIN_FIELD_PROFILE_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="usetext"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_LOGIN_FIELD_USETEXT_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">MOD_LOGIN_VALUE_ICONS</option>
|
||||
<option value="1">MOD_LOGIN_VALUE_TEXT</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_login
|
||||
*
|
||||
* @copyright (C) 2025 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The login module service provider.
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Login'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\Login\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_login
|
||||
*
|
||||
* @copyright (C) 2025 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Login\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\AuthenticationHelper;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
use Joomla\CMS\Helper\ModuleHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_login
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Runs the dispatcher.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function dispatch()
|
||||
{
|
||||
$this->loadLanguage();
|
||||
|
||||
$displayData = $this->getLayoutData();
|
||||
|
||||
// Stop when display data is false
|
||||
if ($displayData === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute the layout without the module context
|
||||
$loader = static function (array $displayData) {
|
||||
// If $displayData doesn't exist in extracted data, unset the variable.
|
||||
if (!\array_key_exists('displayData', $displayData)) {
|
||||
extract($displayData);
|
||||
unset($displayData);
|
||||
} else {
|
||||
extract($displayData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracted variables
|
||||
* -----------------
|
||||
* @var \stdClass $module
|
||||
* @var Registry $params
|
||||
*/
|
||||
|
||||
// Logged users must load the logout sublayout
|
||||
if (!$user->guest) {
|
||||
$layout .= '_logout';
|
||||
}
|
||||
|
||||
require ModuleHelper::getLayoutPath('mod_login', $layout);
|
||||
};
|
||||
|
||||
$loader($displayData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
protected function getLayoutData()
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
$helper = $this->getHelperFactory()->getHelper('LoginHelper');
|
||||
|
||||
$data['params']->def('greeting', 1);
|
||||
|
||||
// HTML IDs
|
||||
$formId = 'login-form-' . $data['module']->id;
|
||||
$data['user'] = $data['app']->getIdentity();
|
||||
$type = $helper->getUserType($data['user']);
|
||||
$data['return'] = $helper->getReturnUrlString($data['params'], $type, $data['app']);
|
||||
$data['registerLink'] = $helper->getRegistrationUrlString($data['params'], $data['app']);
|
||||
$data['extraButtons'] = AuthenticationHelper::getLoginButtons($formId);
|
||||
$data['layout'] = $data['params']->get('layout', 'default');
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_login
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Login\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Application\CMSApplicationInterface;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
use Joomla\CMS\User\User;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Helper for mod_login
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class LoginHelper
|
||||
{
|
||||
/**
|
||||
* Retrieve the URL where the user should be returned after logging in
|
||||
*
|
||||
* @param Registry $params module parameters
|
||||
* @param string $type return type
|
||||
* @param CMSApplicationInterface $app The application
|
||||
*
|
||||
* @since 5.4.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getReturnUrlString(Registry $params, $type, CMSApplicationInterface $app): string
|
||||
{
|
||||
// Stay on the same page
|
||||
$url = Uri::getInstance()->toString();
|
||||
|
||||
$returnMenuId = $params->get($type, 0);
|
||||
|
||||
if ($returnMenuId > 0) {
|
||||
$item = $app->getMenu()->getItem($returnMenuId);
|
||||
|
||||
if ($item) {
|
||||
$lang = '';
|
||||
|
||||
if ($item->language !== '*' && Multilanguage::isEnabled()) {
|
||||
$lang = '&lang=' . $item->language;
|
||||
}
|
||||
|
||||
$url = 'index.php?Itemid=' . $item->id . $lang;
|
||||
}
|
||||
}
|
||||
|
||||
return base64_encode($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current users type
|
||||
*
|
||||
* @param User $user The user object
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function getUserType(User $user): string
|
||||
{
|
||||
return (!$user->guest) ? 'logout' : 'login';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the URL for the registration page
|
||||
*
|
||||
* @param Registry $params module parameters
|
||||
*
|
||||
* @since 5.4.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRegistrationUrlString(Registry $params, CMSApplicationInterface $app): string
|
||||
{
|
||||
$regLink = 'index.php?option=com_users&view=registration';
|
||||
$regLinkMenuId = $params->get('customRegLinkMenu');
|
||||
|
||||
// If there is a custom menu item set for registration => override default
|
||||
if ($regLinkMenuId) {
|
||||
$item = $app->getMenu()->getItem($regLinkMenuId);
|
||||
|
||||
if ($item) {
|
||||
$regLink = 'index.php?Itemid=' . $regLinkMenuId;
|
||||
|
||||
if ($item->language !== '*' && Multilanguage::isEnabled()) {
|
||||
$regLink .= '&lang=' . $item->language;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $regLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the URL where the user should be returned after logging in
|
||||
*
|
||||
* @param Registry $params module parameters
|
||||
* @param string $type return type
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @deprecated 5.4.0 will be removed in 7.0
|
||||
* Use the non-static method getReturnUrlString
|
||||
* Example: Factory::getApplication()->bootModule('mod_login', 'site')
|
||||
* ->getHelper('LoginHelper')
|
||||
* ->getReturnUrlString($params, $type, Factory::getApplication())
|
||||
*/
|
||||
public static function getReturnUrl($params, $type)
|
||||
{
|
||||
return (new self())->getReturnUrlString($params, $type, Factory::getApplication());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current users type
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @deprecated 5.4.0 will be removed in 7.0
|
||||
* Use the non-static method getUserType
|
||||
* Example: Factory::getApplication()->bootModule('mod_login', 'site')
|
||||
* ->getHelper('LoginHelper')
|
||||
* ->getUserType(Factory::getApplication())
|
||||
*/
|
||||
public static function getType()
|
||||
{
|
||||
$user = Factory::getApplication()->getIdentity();
|
||||
|
||||
return (new self())->getUserType($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the URL for the registration page
|
||||
*
|
||||
* @param Registry $params module parameters
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @deprecated 5.4.0 will be removed in 7.0
|
||||
* Use the non-static method getRegistrationUrlString
|
||||
* Example: Factory::getApplication()->bootModule('mod_login', 'site')
|
||||
* ->getHelper('LoginHelper')
|
||||
* ->getRegistrationUrlString($params, Factory::getApplication())
|
||||
*/
|
||||
public static function getRegistrationUrl($params)
|
||||
{
|
||||
return (new self())->getRegistrationUrlString($params, Factory::getApplication());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_login
|
||||
*
|
||||
* @copyright (C) 2006 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\Component\ComponentHelper;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
$app->getDocument()->getWebAssetManager()
|
||||
->useScript('core')
|
||||
->useScript('keepalive')
|
||||
->useScript('field.passwordview');
|
||||
|
||||
Text::script('JSHOWPASSWORD');
|
||||
Text::script('JHIDEPASSWORD');
|
||||
?>
|
||||
<form id="login-form-<?php echo $module->id; ?>" class="mod-login" action="<?php echo Route::_('index.php', true); ?>" method="post">
|
||||
|
||||
<?php if ($params->get('pretext')) : ?>
|
||||
<div class="mod-login__pretext pretext">
|
||||
<p><?php echo $params->get('pretext'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="mod-login__userdata userdata">
|
||||
<div class="mod-login__username form-group">
|
||||
<?php if (!$params->get('usetext', 0)) : ?>
|
||||
<div class="input-group">
|
||||
<input id="modlgn-username-<?php echo $module->id; ?>" type="text" name="username" class="form-control" autocomplete="username" placeholder="<?php echo Text::_('MOD_LOGIN_VALUE_USERNAME'); ?>">
|
||||
<label for="modlgn-username-<?php echo $module->id; ?>" class="visually-hidden"><?php echo Text::_('MOD_LOGIN_VALUE_USERNAME'); ?></label>
|
||||
<span class="input-group-text" title="<?php echo Text::_('MOD_LOGIN_VALUE_USERNAME'); ?>">
|
||||
<span class="icon-user icon-fw" aria-hidden="true"></span>
|
||||
</span>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<label for="modlgn-username-<?php echo $module->id; ?>"><?php echo Text::_('MOD_LOGIN_VALUE_USERNAME'); ?></label>
|
||||
<input id="modlgn-username-<?php echo $module->id; ?>" type="text" name="username" class="form-control" autocomplete="username" placeholder="<?php echo Text::_('MOD_LOGIN_VALUE_USERNAME'); ?>">
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="mod-login__password form-group">
|
||||
<?php if (!$params->get('usetext', 0)) : ?>
|
||||
<div class="input-group">
|
||||
<input id="modlgn-passwd-<?php echo $module->id; ?>" type="password" name="password" autocomplete="current-password" class="form-control" placeholder="<?php echo Text::_('JGLOBAL_PASSWORD'); ?>">
|
||||
<label for="modlgn-passwd-<?php echo $module->id; ?>" class="visually-hidden"><?php echo Text::_('JGLOBAL_PASSWORD'); ?></label>
|
||||
<button type="button" class="btn btn-secondary input-password-toggle">
|
||||
<span class="icon-eye icon-fw" aria-hidden="true"></span>
|
||||
<span class="visually-hidden"><?php echo Text::_('JSHOWPASSWORD'); ?></span>
|
||||
</button>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<label for="modlgn-passwd-<?php echo $module->id; ?>"><?php echo Text::_('JGLOBAL_PASSWORD'); ?></label>
|
||||
<div class="input-group">
|
||||
<input id="modlgn-passwd-<?php echo $module->id; ?>" type="password" name="password" autocomplete="current-password" class="form-control" placeholder="<?php echo Text::_('JGLOBAL_PASSWORD'); ?>">
|
||||
<button type="button" class="btn btn-secondary input-password-toggle">
|
||||
<span class="icon-eye icon-fw" aria-hidden="true"></span>
|
||||
<span class="visually-hidden"><?php echo Text::_('JSHOWPASSWORD'); ?></span>
|
||||
</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (PluginHelper::isEnabled('system', 'remember')) : ?>
|
||||
<div class="mod-login__remember form-group">
|
||||
<div id="form-login-remember-<?php echo $module->id; ?>" class="form-check">
|
||||
<input type="checkbox" name="remember" class="form-check-input" value="yes" id="form-login-input-remember-<?php echo $module->id; ?>">
|
||||
<label class="form-check-label" for="form-login-input-remember-<?php echo $module->id; ?>">
|
||||
<?php echo Text::_('MOD_LOGIN_REMEMBER_ME'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php foreach ($extraButtons as $button) :
|
||||
$dataAttributeKeys = array_filter(array_keys($button), function ($key) {
|
||||
return substr($key, 0, 5) == 'data-';
|
||||
});
|
||||
?>
|
||||
<div class="mod-login__submit form-group">
|
||||
<button type="button"
|
||||
class="btn btn-secondary w-100 <?php echo $button['class'] ?? '' ?>"
|
||||
<?php foreach ($dataAttributeKeys as $key) : ?>
|
||||
<?php echo $key ?>="<?php echo $button[$key] ?>"
|
||||
<?php endforeach; ?>
|
||||
<?php if ($button['onclick']) : ?>
|
||||
onclick="<?php echo $button['onclick'] ?>"
|
||||
<?php endif; ?>
|
||||
title="<?php echo Text::_($button['label']) ?>"
|
||||
id="<?php echo $button['id'] ?>"
|
||||
>
|
||||
<?php if (!empty($button['icon'])) : ?>
|
||||
<span class="<?php echo $button['icon'] ?>"></span>
|
||||
<?php elseif (!empty($button['image'])) : ?>
|
||||
<?php echo $button['image']; ?>
|
||||
<?php elseif (!empty($button['svg'])) : ?>
|
||||
<?php echo $button['svg']; ?>
|
||||
<?php endif; ?>
|
||||
<?php echo Text::_($button['label']) ?>
|
||||
</button>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<div class="mod-login__submit form-group">
|
||||
<button type="submit" name="Submit" class="btn btn-primary w-100"><?php echo Text::_('JLOGIN'); ?></button>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$usersConfig = ComponentHelper::getParams('com_users'); ?>
|
||||
<ul class="mod-login__options list-unstyled">
|
||||
<li>
|
||||
<a href="<?php echo Route::_('index.php?option=com_users&view=reset'); ?>">
|
||||
<?php echo Text::_('MOD_LOGIN_FORGOT_YOUR_PASSWORD'); ?></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?php echo Route::_('index.php?option=com_users&view=remind'); ?>">
|
||||
<?php echo Text::_('MOD_LOGIN_FORGOT_YOUR_USERNAME'); ?></a>
|
||||
</li>
|
||||
<?php if ($usersConfig->get('allowUserRegistration')) : ?>
|
||||
<li>
|
||||
<a href="<?php echo Route::_($registerLink); ?>">
|
||||
<?php echo Text::_('MOD_LOGIN_REGISTER'); ?> <span class="icon-register" aria-hidden="true"></span></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
<input type="hidden" name="option" value="com_users">
|
||||
<input type="hidden" name="task" value="user.login">
|
||||
<input type="hidden" name="return" value="<?php echo $return; ?>">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
<?php if ($params->get('posttext')) : ?>
|
||||
<div class="mod-login__posttext posttext">
|
||||
<p><?php echo $params->get('posttext'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_login
|
||||
*
|
||||
* @copyright (C) 2006 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\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = \Joomla\CMS\Factory::getApplication()->getDocument()->getWebAssetManager();
|
||||
$wa->useScript('keepalive');
|
||||
|
||||
?>
|
||||
<form class="mod-login-logout form-vertical" action="<?php echo Route::_('index.php', true); ?>" method="post" id="login-form-<?php echo $module->id; ?>">
|
||||
<?php if ($params->get('greeting', 1)) : ?>
|
||||
<div class="mod-login-logout__login-greeting login-greeting">
|
||||
<?php if (!$params->get('name', 0)) : ?>
|
||||
<?php echo Text::sprintf('MOD_LOGIN_HINAME', htmlspecialchars($user->name, ENT_COMPAT, 'UTF-8')); ?>
|
||||
<?php else : ?>
|
||||
<?php echo Text::sprintf('MOD_LOGIN_HINAME', htmlspecialchars($user->username, ENT_COMPAT, 'UTF-8')); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($params->get('profilelink', 0)) : ?>
|
||||
<ul class="mod-login-logout__options list-unstyled">
|
||||
<li>
|
||||
<a href="<?php echo Route::_('index.php?option=com_users&view=profile'); ?>">
|
||||
<?php echo Text::_('MOD_LOGIN_PROFILE'); ?></a>
|
||||
</li>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
<div class="mod-login-logout__button logout-button">
|
||||
<button type="submit" name="Submit" class="btn btn-primary"><?php echo Text::_('JLOGOUT'); ?></button>
|
||||
<input type="hidden" name="option" value="com_users">
|
||||
<input type="hidden" name="task" value="user.logout">
|
||||
<input type="hidden" name="return" value="<?php echo $return; ?>">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,168 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_menu</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2004-07</creationDate>
|
||||
<copyright>(C) 2005 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>3.0.0</version>
|
||||
<description>MOD_MENU_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\Menu</namespace>
|
||||
<files>
|
||||
<folder module="mod_menu">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_menu.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_menu.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Menu" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic" addfieldprefix="Joomla\Component\Menus\Administrator\Field">
|
||||
<field
|
||||
name="menutype"
|
||||
type="menu"
|
||||
label="MOD_MENU_FIELD_MENUTYPE_LABEL"
|
||||
clientid="0"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="base"
|
||||
type="modal_menu"
|
||||
label="MOD_MENU_FIELD_ACTIVE_LABEL"
|
||||
select="true"
|
||||
new="true"
|
||||
edit="true"
|
||||
clear="true"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="">JCURRENT</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="startLevel"
|
||||
type="list"
|
||||
label="MOD_MENU_FIELD_STARTLEVEL_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">J1</option>
|
||||
<option value="2">J2</option>
|
||||
<option value="3">J3</option>
|
||||
<option value="4">J4</option>
|
||||
<option value="5">J5</option>
|
||||
<option value="6">J6</option>
|
||||
<option value="7">J7</option>
|
||||
<option value="8">J8</option>
|
||||
<option value="9">J9</option>
|
||||
<option value="10">J10</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="endLevel"
|
||||
type="list"
|
||||
label="MOD_MENU_FIELD_ENDLEVEL_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">JALL</option>
|
||||
<option value="1">J1</option>
|
||||
<option value="2">J2</option>
|
||||
<option value="3">J3</option>
|
||||
<option value="4">J4</option>
|
||||
<option value="5">J5</option>
|
||||
<option value="6">J6</option>
|
||||
<option value="7">J7</option>
|
||||
<option value="8">J8</option>
|
||||
<option value="9">J9</option>
|
||||
<option value="10">J10</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="showAllChildren"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_MENU_FIELD_ALLCHILDREN_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="tag_id"
|
||||
type="text"
|
||||
label="MOD_MENU_FIELD_TAG_ID_LABEL"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="class_sfx"
|
||||
type="text"
|
||||
label="MOD_MENU_FIELD_CLASS_LABEL"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="window_open"
|
||||
type="text"
|
||||
label="MOD_MENU_FIELD_TARGET_LABEL"
|
||||
description="MOD_MENU_FIELD_TARGET_DESC"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
default="_:default"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cache"
|
||||
type="list"
|
||||
label="COM_MODULES_FIELD_CACHING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="cache_time"
|
||||
type="number"
|
||||
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
|
||||
default="900"
|
||||
filter="integer"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="cachemode"
|
||||
type="hidden"
|
||||
default="itemid"
|
||||
>
|
||||
<option value="itemid"></option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_menu
|
||||
*
|
||||
* @copyright (C) 2025 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The menu module service provider.
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Menu'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\Menu\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_menu
|
||||
*
|
||||
* @copyright (C) 2025 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Menu\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_menu
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Runs the dispatcher.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function dispatch()
|
||||
{
|
||||
$displayData = $this->getLayoutData();
|
||||
|
||||
if (!$displayData['list']) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent::dispatch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
protected function getLayoutData()
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
|
||||
$menuHelper = $this->getHelperFactory()->getHelper('MenuHelper');
|
||||
|
||||
$data['list'] = $menuHelper->getItems($data['params'], $data['app']);
|
||||
$data['base'] = $menuHelper->getBaseItem($data['params'], $data['app']);
|
||||
$data['active'] = $menuHelper->getActiveItem($data['app']);
|
||||
$data['default'] = $menuHelper->getDefaultItem($data['app']);
|
||||
$data['active_id'] = $data['active']->id;
|
||||
$data['default_id'] = $data['default']->id;
|
||||
$data['path'] = $data['base']->tree;
|
||||
$data['showAll'] = $data['params']->get('showAllChildren', 1);
|
||||
$data['class_sfx'] = htmlspecialchars($data['params']->get('class_sfx', ''), ENT_COMPAT, 'UTF-8');
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_menu
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\Menu\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Application\CMSApplicationInterface;
|
||||
use Joomla\CMS\Cache\CacheControllerFactoryInterface;
|
||||
use Joomla\CMS\Cache\Controller\OutputController;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Helper for mod_menu
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class MenuHelper
|
||||
{
|
||||
/**
|
||||
* Get a list of the menu items.
|
||||
*
|
||||
* @param Registry &$params The module options.
|
||||
* @param CMSApplicationInterface $app The application
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function getItems(Registry &$params, CMSApplicationInterface $app): array
|
||||
{
|
||||
$menu = $app->getMenu();
|
||||
|
||||
// Get active menu item
|
||||
$base = $this->getBaseItem($params, $app);
|
||||
$levels = $app->getIdentity()->getAuthorisedViewLevels();
|
||||
asort($levels);
|
||||
|
||||
// Compose cache key
|
||||
$cacheKey = 'menu_items' . $params . implode(',', $levels) . '.' . $base->id;
|
||||
|
||||
/** @var OutputController $cache */
|
||||
$cache = Factory::getContainer()->get(CacheControllerFactoryInterface::class)
|
||||
->createCacheController('output', ['defaultgroup' => 'mod_menu']);
|
||||
|
||||
if ($cache->contains($cacheKey)) {
|
||||
$items = $cache->get($cacheKey);
|
||||
} else {
|
||||
$path = $base->tree;
|
||||
$start = (int) $params->get('startLevel', 1);
|
||||
$end = (int) $params->get('endLevel', 0);
|
||||
$showAll = $params->get('showAllChildren', 1);
|
||||
$items = $menu->getItems('menutype', $params->get('menutype'));
|
||||
$hidden_parents = [];
|
||||
$lastitem = 0;
|
||||
|
||||
if ($items) {
|
||||
$inputVars = $app->getInput()->getArray();
|
||||
|
||||
foreach ($items as $i => $item) {
|
||||
$item->parent = false;
|
||||
$itemParams = $item->getParams();
|
||||
|
||||
if (isset($items[$lastitem]) && $items[$lastitem]->id == $item->parent_id && $itemParams->get('menu_show', 1) == 1) {
|
||||
$items[$lastitem]->parent = true;
|
||||
}
|
||||
|
||||
if (
|
||||
($start && $start > $item->level)
|
||||
|| ($end && $item->level > $end)
|
||||
|| (!$showAll && $item->level > 1 && !\in_array($item->parent_id, $path))
|
||||
|| ($start > 1 && !\in_array($item->tree[$start - 2], $path))
|
||||
) {
|
||||
unset($items[$i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Exclude item with menu item option set to exclude from menu modules
|
||||
if (($itemParams->get('menu_show', 1) == 0) || \in_array($item->parent_id, $hidden_parents)) {
|
||||
$hidden_parents[] = $item->id;
|
||||
unset($items[$i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$item->current = true;
|
||||
|
||||
foreach ($item->query as $key => $value) {
|
||||
if (!isset($inputVars[$key]) || $inputVars[$key] !== $value) {
|
||||
$item->current = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$item->deeper = false;
|
||||
$item->shallower = false;
|
||||
$item->level_diff = 0;
|
||||
|
||||
if (isset($items[$lastitem])) {
|
||||
$items[$lastitem]->deeper = ($item->level > $items[$lastitem]->level);
|
||||
$items[$lastitem]->shallower = ($item->level < $items[$lastitem]->level);
|
||||
$items[$lastitem]->level_diff = ($items[$lastitem]->level - $item->level);
|
||||
}
|
||||
|
||||
$lastitem = $i;
|
||||
$item->active = false;
|
||||
$item->flink = $item->link;
|
||||
|
||||
// Reverted back for CMS version 2.5.6
|
||||
switch ($item->type) {
|
||||
case 'separator':
|
||||
break;
|
||||
|
||||
case 'heading':
|
||||
// No further action needed.
|
||||
break;
|
||||
|
||||
case 'url':
|
||||
if ((str_starts_with($item->link, 'index.php?')) && (!str_contains($item->link, 'Itemid='))) {
|
||||
// If this is an internal Joomla link, ensure the Itemid is set.
|
||||
$item->flink = $item->link . '&Itemid=' . $item->id;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'alias':
|
||||
$item->flink = 'index.php?Itemid=' . $itemParams->get('aliasoptions');
|
||||
|
||||
// Get the language of the target menu item when site is multilingual
|
||||
if (Multilanguage::isEnabled()) {
|
||||
$newItem = $app->getMenu()->getItem((int) $itemParams->get('aliasoptions'));
|
||||
|
||||
// Use language code if not set to ALL
|
||||
if ($newItem != null && $newItem->language && $newItem->language !== '*') {
|
||||
$item->flink .= '&lang=' . $newItem->language;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$item->flink = 'index.php?Itemid=' . $item->id;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((str_contains($item->flink, 'index.php?')) && strcasecmp(substr($item->flink, 0, 4), 'http')) {
|
||||
$item->flink = Route::_($item->flink, true, $itemParams->get('secure'));
|
||||
} else {
|
||||
$item->flink = Route::_($item->flink);
|
||||
}
|
||||
|
||||
// We prevent the double encoding because for some reason the $item is shared for menu modules and we get double encoding
|
||||
// when the cause of that is found the argument should be removed
|
||||
$item->title = htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8', false);
|
||||
$item->menu_icon = htmlspecialchars($itemParams->get('menu_icon_css', ''), ENT_COMPAT, 'UTF-8', false);
|
||||
$item->anchor_css = htmlspecialchars($itemParams->get('menu-anchor_css', ''), ENT_COMPAT, 'UTF-8', false);
|
||||
$item->anchor_title = htmlspecialchars($itemParams->get('menu-anchor_title', ''), ENT_COMPAT, 'UTF-8', false);
|
||||
$item->anchor_rel = htmlspecialchars($itemParams->get('menu-anchor_rel', ''), ENT_COMPAT, 'UTF-8', false);
|
||||
$item->menu_image = htmlspecialchars($itemParams->get('menu_image', ''), ENT_COMPAT, 'UTF-8', false);
|
||||
$item->menu_image_css = htmlspecialchars($itemParams->get('menu_image_css', ''), ENT_COMPAT, 'UTF-8', false);
|
||||
}
|
||||
|
||||
if (isset($items[$lastitem])) {
|
||||
$items[$lastitem]->deeper = (($start ?: 1) > $items[$lastitem]->level);
|
||||
$items[$lastitem]->shallower = (($start ?: 1) < $items[$lastitem]->level);
|
||||
$items[$lastitem]->level_diff = ($items[$lastitem]->level - ($start ?: 1));
|
||||
}
|
||||
}
|
||||
|
||||
$cache->store($items, $cacheKey);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get base menu item.
|
||||
*
|
||||
* @param Registry &$params The module options.
|
||||
* @param CMSApplicationInterface $app The application
|
||||
*
|
||||
* @return object
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function getBaseItem(Registry &$params, CMSApplicationInterface $app): object
|
||||
{
|
||||
// Get base menu item from parameters
|
||||
if ($params->get('base')) {
|
||||
$base = $app->getMenu()->getItem($params->get('base'));
|
||||
} else {
|
||||
$base = false;
|
||||
}
|
||||
|
||||
// Use active menu item if no base found
|
||||
if (!$base) {
|
||||
$base = $this->getActiveItem($app);
|
||||
}
|
||||
|
||||
return $base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active menu item.
|
||||
*
|
||||
* @param CMSApplicationInterface $app The application
|
||||
*
|
||||
* @return object
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function getActiveItem(CMSApplicationInterface $app): object
|
||||
{
|
||||
$menu = $app->getMenu();
|
||||
|
||||
return $menu->getActive() ?: $this->getDefaultItem($app);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default menu item (home page) for current language.
|
||||
*
|
||||
* @param CMSApplicationInterface $app The application
|
||||
*
|
||||
* @return object
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function getDefaultItem(CMSApplicationInterface $app): object
|
||||
{
|
||||
$menu = $app->getMenu();
|
||||
|
||||
// Look for the home menu
|
||||
if (Multilanguage::isEnabled()) {
|
||||
return $menu->getDefault($app->getLanguage()->getTag());
|
||||
}
|
||||
|
||||
return $menu->getDefault();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of the menu items.
|
||||
*
|
||||
* @param Registry &$params The module options.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @deprecated 5.4.0 will be removed in 7.0
|
||||
* Use the non-static method getItems
|
||||
* Example: Factory::getApplication()->bootModule('mod_menu', 'site')
|
||||
* ->getHelper('MenuHelper')
|
||||
* ->getItems($params, $app)
|
||||
*/
|
||||
public static function getList(&$params)
|
||||
{
|
||||
return (new self())->getItems($params, Factory::getApplication());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get base menu item.
|
||||
*
|
||||
* @param Registry &$params The module options.
|
||||
*
|
||||
* @return object
|
||||
*
|
||||
* @since 3.0.2
|
||||
*
|
||||
* @deprecated 5.4.0 will be removed in 7.0
|
||||
* Use the non-static method getBaseItem
|
||||
* Example: Factory::getApplication()->bootModule('mod_menu', 'site')
|
||||
* ->getHelper('MenuHelper')
|
||||
* ->getBaseItem($params, $app)
|
||||
*/
|
||||
public static function getBase(&$params)
|
||||
{
|
||||
return (new self())->getBaseItem($params, Factory::getApplication());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active menu item.
|
||||
*
|
||||
* @param Registry &$params The module options.
|
||||
*
|
||||
* @return object
|
||||
*
|
||||
* @since 3.0.2
|
||||
*
|
||||
* @deprecated 5.4.0 will be removed in 7.0
|
||||
* Use the non-static method getActiveItem
|
||||
* Example: Factory::getApplication()->bootModule('mod_menu', 'site')
|
||||
* ->getHelper('MenuHelper')
|
||||
* ->getActiveItem($app)
|
||||
*/
|
||||
public static function getActive(&$params)
|
||||
{
|
||||
return (new self())->getActiveItem(Factory::getApplication());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default menu item (home page) for current language.
|
||||
*
|
||||
* @return object
|
||||
*
|
||||
* @deprecated 5.4.0 will be removed in 7.0
|
||||
* Use the non-static method getDefaultItem
|
||||
* Example: Factory::getApplication()->bootModule('mod_menu', 'site')
|
||||
* ->getHelper('MenuHelper')
|
||||
* ->getDefaultItem($app)
|
||||
*/
|
||||
public static function getDefault()
|
||||
{
|
||||
return (new self())->getDefaultItem(Factory::getApplication());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_menu
|
||||
*
|
||||
* @copyright (C) 2021 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\Helper\ModuleHelper;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
HTMLHelper::_('bootstrap.collapse');
|
||||
?>
|
||||
|
||||
<nav class="navbar navbar-expand-md" aria-label="<?php echo htmlspecialchars($module->title, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<button class="navbar-toggler navbar-toggler-right" type="button" data-bs-toggle="collapse" data-bs-target="#navbar<?php echo $module->id; ?>" aria-controls="navbar<?php echo $module->id; ?>" aria-expanded="false" aria-label="<?php echo Text::_('MOD_MENU_TOGGLE'); ?>">
|
||||
<span class="icon-menu" aria-hidden="true"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbar<?php echo $module->id; ?>">
|
||||
<?php require ModuleHelper::getLayoutPath(module: 'mod_menu', layout:'default'); ?>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_menu
|
||||
*
|
||||
* @copyright (C) 2009 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\Helper\ModuleHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $app->getDocument()->getWebAssetManager();
|
||||
$wa->getRegistry()->addExtensionRegistryFile('mod_menu');
|
||||
$wa->usePreset('mod_menu.menu');
|
||||
|
||||
$tagId = $params->get('tag_id', '') ?: 'mod-menu' . $module->id;
|
||||
$id = ' id="' . htmlspecialchars($tagId, ENT_QUOTES, 'UTF-8') . '"';
|
||||
$startLevel = (int) $params->get('startLevel', 1);
|
||||
|
||||
// The menu class is deprecated. Use mod-menu instead
|
||||
?>
|
||||
<ul<?php echo $id; ?> class="mod-menu mod-list nav <?php echo $class_sfx; ?>">
|
||||
<?php foreach ($list as $i => &$item) {
|
||||
$itemParams = $item->getParams();
|
||||
$class = 'nav-item item-' . $item->id;
|
||||
|
||||
if ($item->id == $default_id) {
|
||||
$class .= ' default';
|
||||
}
|
||||
|
||||
if ($item->id == $active_id || ($item->type === 'alias' && $itemParams->get('aliasoptions') == $active_id)) {
|
||||
$class .= ' current';
|
||||
}
|
||||
|
||||
if (in_array($item->id, $path)) {
|
||||
$class .= ' active';
|
||||
} elseif ($item->type === 'alias') {
|
||||
$aliasToId = $itemParams->get('aliasoptions');
|
||||
|
||||
if (count($path) > 0 && $aliasToId == $path[count($path) - 1]) {
|
||||
$class .= ' active';
|
||||
} elseif (in_array($aliasToId, $path)) {
|
||||
$class .= ' alias-parent-active';
|
||||
}
|
||||
}
|
||||
|
||||
if ($item->type === 'separator') {
|
||||
$class .= ' divider';
|
||||
}
|
||||
|
||||
if ($item->deeper) {
|
||||
$class .= ' deeper';
|
||||
}
|
||||
|
||||
if ($item->parent) {
|
||||
$class .= ' parent';
|
||||
}
|
||||
|
||||
echo '<li class="' . $class . '">';
|
||||
|
||||
// The next item is deeper - add toggle only here it is a heading or separator
|
||||
if ($item->deeper && (int) $item->level === $startLevel && in_array($item->type, ['separator', 'heading'])) {
|
||||
// Add a toggle button.
|
||||
echo '<button class="mod-menu__toggle-sub" aria-expanded="false">';
|
||||
}
|
||||
|
||||
switch ($item->type) :
|
||||
case 'separator':
|
||||
case 'component':
|
||||
case 'heading':
|
||||
case 'url':
|
||||
require ModuleHelper::getLayoutPath('mod_menu', 'default_' . $item->type);
|
||||
break;
|
||||
|
||||
default:
|
||||
require ModuleHelper::getLayoutPath('mod_menu', 'default_url');
|
||||
break;
|
||||
endswitch;
|
||||
|
||||
// The next item is deeper.
|
||||
if ($item->deeper) {
|
||||
// Check type - add only on first level
|
||||
// @todo aria-label - set in menu item ???
|
||||
if ((int) $item->level === $startLevel) {
|
||||
switch ($item->type) {
|
||||
case 'heading':
|
||||
case 'separator':
|
||||
echo '<span class="icon-chevron-down" aria-hidden="true">' .
|
||||
'</span></button>';
|
||||
break;
|
||||
|
||||
default:
|
||||
echo '<button class="mod-menu__toggle-sub" aria-expanded="false">' .
|
||||
'<span class="icon-chevron-down" aria-hidden="true"></span>' .
|
||||
'<span class="visually-hidden">' . Text::sprintf('MOD_MENU_TOGGLE_SUBMENU_LABEL', $item->title) . '</span>' .
|
||||
'</button>';
|
||||
}
|
||||
}
|
||||
echo '<ul class="mod-menu__sub list-unstyled small">';
|
||||
} elseif ($item->shallower) {
|
||||
// The next item is shallower.
|
||||
echo '</li>';
|
||||
echo str_repeat('</ul></li>', $item->level_diff);
|
||||
} else {
|
||||
// The next item is on the same level.
|
||||
echo '</li>';
|
||||
}
|
||||
}
|
||||
?></ul>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_menu
|
||||
*
|
||||
* @copyright (C) 2009 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\Filter\OutputFilter;
|
||||
|
||||
$attributes = [];
|
||||
|
||||
if ($item->anchor_title) {
|
||||
$attributes['title'] = $item->anchor_title;
|
||||
}
|
||||
|
||||
if ($item->anchor_css) {
|
||||
$attributes['class'] = $item->anchor_css;
|
||||
}
|
||||
|
||||
if ($item->anchor_rel) {
|
||||
$attributes['rel'] = $item->anchor_rel;
|
||||
}
|
||||
|
||||
if ($item->id == $active_id) {
|
||||
$attributes['aria-current'] = 'location';
|
||||
|
||||
if ($item->current) {
|
||||
$attributes['aria-current'] = 'page';
|
||||
}
|
||||
}
|
||||
|
||||
$linktype = $item->title;
|
||||
|
||||
if ($item->menu_icon) {
|
||||
// The link is an icon
|
||||
if ($itemParams->get('menu_text', 1)) {
|
||||
// If the link text is to be displayed, the icon is added with aria-hidden
|
||||
$linktype = '<span class="p-2 pt-0 ' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
|
||||
} else {
|
||||
// If the icon itself is the link, it needs a visually hidden text
|
||||
$linktype = '<span class="p-2 pt-0 ' . $item->menu_icon . '" aria-hidden="true"></span><span class="visually-hidden">' . $item->title . '</span>';
|
||||
}
|
||||
} elseif ($item->menu_image) {
|
||||
// The link is an image, maybe with its own class
|
||||
$image_attributes = [];
|
||||
|
||||
if ($item->menu_image_css) {
|
||||
$image_attributes['class'] = $item->menu_image_css;
|
||||
}
|
||||
|
||||
$linktype = HTMLHelper::_('image', $item->menu_image, '', $image_attributes);
|
||||
|
||||
$linktype .= '<span class="image-title' . ($itemParams->get('menu_text', 1) ? '' : ' visually-hidden') . '">' . $item->title . '</span>';
|
||||
}
|
||||
|
||||
if ($item->browserNav == 1) {
|
||||
$attributes['target'] = '_blank';
|
||||
} elseif ($item->browserNav == 2) {
|
||||
$options = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes';
|
||||
|
||||
$attributes['onclick'] = "window.open(this.href, 'targetWindow', '" . $options . "'); return false;";
|
||||
}
|
||||
|
||||
echo HTMLHelper::_('link', OutputFilter::ampReplace(htmlspecialchars($item->flink, ENT_COMPAT, 'UTF-8', false)), $linktype, $attributes);
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_menu
|
||||
*
|
||||
* @copyright (C) 2012 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;
|
||||
|
||||
$title = $item->anchor_title ? ' title="' . $item->anchor_title . '"' : '';
|
||||
$anchor_css = $item->anchor_css ?: '';
|
||||
$linktype = $item->title;
|
||||
|
||||
if ($item->menu_icon) {
|
||||
// The link is an icon
|
||||
if ($itemParams->get('menu_text', 1)) {
|
||||
// If the link text is to be displayed, the icon is added with aria-hidden
|
||||
$linktype = '<span class="p-2 pt-0 ' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
|
||||
} else {
|
||||
// If the icon itself is the link, it needs a visually hidden text
|
||||
$linktype = '<span class="p-2 pt-0 ' . $item->menu_icon . '" aria-hidden="true"></span><span class="visually-hidden">' . $item->title . '</span>';
|
||||
}
|
||||
} elseif ($item->menu_image) {
|
||||
// The link is an image, maybe with its own class
|
||||
$image_attributes = [];
|
||||
|
||||
if ($item->menu_image_css) {
|
||||
$image_attributes['class'] = $item->menu_image_css;
|
||||
}
|
||||
|
||||
$linktype = HTMLHelper::_('image', $item->menu_image, '', $image_attributes);
|
||||
|
||||
if ($itemParams->get('menu_text', 1)) {
|
||||
$linktype .= '<span class="image-title">' . $item->title . '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<span class="mod-menu__heading nav-header <?php echo $anchor_css; ?>"<?php echo $title; ?>><?php echo $linktype; ?></span>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_menu
|
||||
*
|
||||
* @copyright (C) 2009 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;
|
||||
|
||||
$title = $item->anchor_title ? ' title="' . $item->anchor_title . '"' : '';
|
||||
$anchor_css = $item->anchor_css ?: '';
|
||||
$linktype = $item->title;
|
||||
|
||||
if ($item->menu_icon) {
|
||||
// The link is an icon
|
||||
if ($itemParams->get('menu_text', 1)) {
|
||||
// If the link text is to be displayed, the icon is added with aria-hidden
|
||||
$linktype = '<span class="p-2 pt-0 ' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
|
||||
} else {
|
||||
// If the icon itself is the link, it needs a visually hidden text
|
||||
$linktype = '<span class="p-2 pt-0 ' . $item->menu_icon . '" aria-hidden="true"></span><span class="visually-hidden">' . $item->title . '</span>';
|
||||
}
|
||||
} elseif ($item->menu_image) {
|
||||
// The link is an image, maybe with its own class
|
||||
$image_attributes = [];
|
||||
|
||||
if ($item->menu_image_css) {
|
||||
$image_attributes['class'] = $item->menu_image_css;
|
||||
}
|
||||
|
||||
$linktype = HTMLHelper::_('image', $item->menu_image, '', $image_attributes);
|
||||
|
||||
if ($itemParams->get('menu_text', 1)) {
|
||||
$linktype .= '<span class="image-title">' . $item->title . '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<span class="mod-menu__separator separator <?php echo $anchor_css; ?>"<?php echo $title; ?>><?php echo $linktype; ?></span>
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_menu
|
||||
*
|
||||
* @copyright (C) 2009 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\Filter\OutputFilter;
|
||||
|
||||
$attributes = [];
|
||||
|
||||
if ($item->anchor_title) {
|
||||
$attributes['title'] = $item->anchor_title;
|
||||
}
|
||||
|
||||
if ($item->anchor_css) {
|
||||
$attributes['class'] = $item->anchor_css;
|
||||
}
|
||||
|
||||
if ($item->anchor_rel) {
|
||||
$attributes['rel'] = $item->anchor_rel;
|
||||
}
|
||||
|
||||
$linktype = $item->title;
|
||||
|
||||
if ($item->menu_icon) {
|
||||
// The link is an icon
|
||||
if ($itemParams->get('menu_text', 1)) {
|
||||
// If the link text is to be displayed, the icon is added with aria-hidden
|
||||
$linktype = '<span class="p-2 pt-0 ' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
|
||||
} else {
|
||||
// If the icon itself is the link, it needs a visually hidden text
|
||||
$linktype = '<span class="p-2 pt-0 ' . $item->menu_icon . '" aria-hidden="true"></span><span class="visually-hidden">' . $item->title . '</span>';
|
||||
}
|
||||
} elseif ($item->menu_image) {
|
||||
// The link is an image, maybe with an own class
|
||||
$image_attributes = [];
|
||||
|
||||
if ($item->menu_image_css) {
|
||||
$image_attributes['class'] = $item->menu_image_css;
|
||||
}
|
||||
|
||||
$linktype = HTMLHelper::_('image', $item->menu_image, '', $image_attributes);
|
||||
|
||||
$linktype .= '<span class="image-title' . ($itemParams->get('menu_text', 1) ? '' : ' visually-hidden') . '">' . $item->title . '</span>';
|
||||
}
|
||||
|
||||
if ($item->browserNav == 1) {
|
||||
$attributes['target'] = '_blank';
|
||||
$attributes['rel'] = 'noopener noreferrer';
|
||||
|
||||
if ($item->anchor_rel == 'nofollow') {
|
||||
$attributes['rel'] .= ' nofollow';
|
||||
}
|
||||
} elseif ($item->browserNav == 2) {
|
||||
$options = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,' . $params->get('window_open');
|
||||
|
||||
$attributes['onclick'] = "window.open(this.href, 'targetWindow', '" . $options . "'); return false;";
|
||||
}
|
||||
|
||||
echo HTMLHelper::_('link', OutputFilter::ampReplace(htmlspecialchars($item->flink, ENT_COMPAT, 'UTF-8', false)), $linktype, $attributes);
|
||||
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_random_image</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2006-07</creationDate>
|
||||
<copyright>(C) 2006 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>3.0.0</version>
|
||||
<description>MOD_RANDOM_IMAGE_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\RandomImage</namespace>
|
||||
<files>
|
||||
<folder module="mod_random_image">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_random_image.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_random_image.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Random_Image" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic">
|
||||
<field
|
||||
name="type"
|
||||
type="text"
|
||||
label="MOD_RANDOM_IMAGE_FIELD_TYPE_LABEL"
|
||||
default="jpg"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="folder"
|
||||
type="text"
|
||||
label="MOD_RANDOM_IMAGE_FIELD_FOLDER_LABEL"
|
||||
validate="filePath"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="link"
|
||||
type="text"
|
||||
label="MOD_RANDOM_IMAGE_FIELD_LINK_LABEL"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="width"
|
||||
type="number"
|
||||
label="MOD_RANDOM_IMAGE_FIELD_WIDTH_LABEL"
|
||||
default="100"
|
||||
filter="integer"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="height"
|
||||
type="number"
|
||||
label="MOD_RANDOM_IMAGE_FIELD_HEIGHT_LABEL"
|
||||
filter="integer"
|
||||
/>
|
||||
|
||||
</fieldset>
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_random_image
|
||||
*
|
||||
* @copyright (C) 2025 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The random image module service provider.
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\RandomImage'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\RandomImage\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_random_image
|
||||
*
|
||||
* @copyright (C) 2025 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\RandomImage\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_random_image
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
protected function getLayoutData()
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
|
||||
$helper = $this->getHelperFactory()->getHelper('RandomImageHelper');
|
||||
$data['link'] = $data['params']->get('link');
|
||||
$folder = $helper->getSanitizedFolder($data['params']);
|
||||
$data['images'] = $helper->getImagesFromFolder($data['params'], $folder);
|
||||
$data['image'] = $helper->getImage($data['params'], $data['images']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_random_image
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\RandomImage\Site\Helper;
|
||||
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
use Joomla\Registry\Registry;
|
||||
use Joomla\String\StringHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Helper for mod_random_image
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class RandomImageHelper
|
||||
{
|
||||
/**
|
||||
* Retrieves a random image
|
||||
*
|
||||
* @param Registry &$params module parameters object
|
||||
* @param array $images list of images
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function getImage(Registry &$params, array $images): mixed
|
||||
{
|
||||
$width = $params->get('width', 100);
|
||||
$height = $params->get('height', null);
|
||||
|
||||
$i = \count($images);
|
||||
|
||||
if ($i === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$random = mt_rand(0, $i - 1);
|
||||
$image = $images[$random];
|
||||
$size = getimagesize(JPATH_BASE . '/' . $image->folder . '/' . $image->name);
|
||||
|
||||
if ($size[0] < $width) {
|
||||
$width = $size[0];
|
||||
}
|
||||
|
||||
$coeff = $size[0] / $size[1];
|
||||
|
||||
if ($height === null) {
|
||||
$height = (int) ($width / $coeff);
|
||||
} else {
|
||||
$newheight = min($height, (int) ($width / $coeff));
|
||||
|
||||
if ($newheight < $height) {
|
||||
$height = $newheight;
|
||||
} else {
|
||||
$width = $height * $coeff;
|
||||
}
|
||||
}
|
||||
|
||||
$image->width = $width;
|
||||
$image->height = $height;
|
||||
$image->folder = str_replace('\\', '/', $image->folder);
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves images from a specific folder
|
||||
*
|
||||
* @param Registry &$params module params
|
||||
* @param string $folder folder to get the images from
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function getImagesFromFolder(Registry &$params, string $folder): array
|
||||
{
|
||||
$type = $params->get('type', 'jpg');
|
||||
$extensions = array_map('trim', explode(',', $type));
|
||||
|
||||
// Normalize to lowercase and strip leading dots
|
||||
$extensions = array_map(function ($ext) {
|
||||
return ltrim(strtolower($ext), '.');
|
||||
}, $extensions);
|
||||
|
||||
$files = [];
|
||||
$images = [];
|
||||
|
||||
$dir = JPATH_BASE . '/' . $folder;
|
||||
|
||||
// Check if directory exists
|
||||
if (is_dir($dir)) {
|
||||
if ($handle = opendir($dir)) {
|
||||
while (false !== ($file = readdir($handle))) {
|
||||
if ($file !== '.' && $file !== '..' && $file !== 'CVS' && $file !== 'index.html') {
|
||||
$files[] = $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir($handle);
|
||||
|
||||
$i = 0;
|
||||
|
||||
foreach ($files as $img) {
|
||||
if (is_dir($dir . '/' . $img)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ext = pathinfo($img, PATHINFO_EXTENSION);
|
||||
|
||||
if (\in_array(strtolower($ext), $extensions, true)) {
|
||||
$images[$i] = new \stdClass();
|
||||
$images[$i]->name = $img;
|
||||
$images[$i]->folder = $folder;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $images;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sanitized folder
|
||||
*
|
||||
* @param Registry &$params module params objects
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function getSanitizedFolder(Registry &$params): mixed
|
||||
{
|
||||
$folder = $params->get('folder');
|
||||
$liveSite = Uri::base();
|
||||
|
||||
// If folder includes livesite info, remove
|
||||
if (StringHelper::strpos($folder, $liveSite) === 0) {
|
||||
$folder = str_replace($liveSite, '', $folder);
|
||||
}
|
||||
|
||||
// If folder includes absolute path, remove
|
||||
if (StringHelper::strpos($folder, JPATH_SITE) === 0) {
|
||||
$folder = str_replace(JPATH_BASE, '', $folder);
|
||||
}
|
||||
|
||||
return str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a random image
|
||||
*
|
||||
* @param Registry &$params module parameters object
|
||||
* @param array $images list of images
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @deprecated 5.4.0 will be removed in 7.0
|
||||
* Use the non-static method getImage
|
||||
* Example: Factory::getApplication()->bootModule('mod_random_image', 'site')
|
||||
* ->getHelper('RandomImageHelper')
|
||||
* ->getImage($params, $images)
|
||||
*/
|
||||
public static function getRandomImage(&$params, $images)
|
||||
{
|
||||
return (new self())->getImage($params, $images);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves images from a specific folder
|
||||
*
|
||||
* @param Registry &$params module params
|
||||
* @param string $folder folder to get the images from
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @deprecated 5.4.0 will be removed in 7.0
|
||||
* Use the non-static method getImagesFromFolder
|
||||
* Example: Factory::getApplication()->bootModule('mod_random_image', 'site')
|
||||
* ->getHelper('RandomImageHelper')
|
||||
* ->getImagesFromFolder($params, $folder)
|
||||
*/
|
||||
public static function getImages(&$params, $folder)
|
||||
{
|
||||
return (new self())->getImagesFromFolder($params, $folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sanitized folder
|
||||
*
|
||||
* @param Registry &$params module params objects
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @deprecated 5.4.0 will be removed in 7.0
|
||||
* Use the non-static method getSanitizedFolder
|
||||
* Example: Factory::getApplication()->bootModule('mod_random_image', 'site')
|
||||
* ->getHelper('RandomImageHelper')
|
||||
* ->getSanitizedFolder($params)
|
||||
*/
|
||||
public static function getFolder(&$params)
|
||||
{
|
||||
return (new self())->getSanitizedFolder($params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_random_image
|
||||
*
|
||||
* @copyright (C) 2006 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\Text;
|
||||
|
||||
if (!count($images)) {
|
||||
echo Text::_('MOD_RANDOM_IMAGE_NO_IMAGES');
|
||||
|
||||
return;
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="mod-randomimage random-image">
|
||||
<?php if ($link) : ?>
|
||||
<a href="<?php echo htmlspecialchars($link, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<?php endif; ?>
|
||||
<?php echo HTMLHelper::_('image', $image->folder . '/' . htmlspecialchars($image->name, ENT_COMPAT, 'UTF-8'), '', ['width' => $image->width, 'height' => $image->height]); ?>
|
||||
<?php if ($link) : ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="module" client="site" method="upgrade">
|
||||
<name>mod_related_items</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2004-07</creationDate>
|
||||
<copyright>(C) 2005 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>3.0.0</version>
|
||||
<description>MOD_RELATED_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Module\RelatedItems</namespace>
|
||||
<files>
|
||||
<folder module="mod_related_items">services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/mod_related_items.ini</language>
|
||||
<language tag="en-GB">language/en-GB/mod_related_items.sys.ini</language>
|
||||
</languages>
|
||||
<help key="Site_Modules:_Articles_-_Related" />
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic">
|
||||
<field
|
||||
name="showDate"
|
||||
type="radio"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
label="MOD_RELATED_FIELD_SHOWDATE_LABEL"
|
||||
default="0"
|
||||
filter="integer"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="maximum"
|
||||
type="number"
|
||||
label="MOD_RELATED_FIELD_MAX_LABEL"
|
||||
default="5"
|
||||
filter="integer"
|
||||
min="1"
|
||||
validate="number"
|
||||
/>
|
||||
</fieldset>
|
||||
<fieldset name="advanced">
|
||||
<field
|
||||
name="layout"
|
||||
type="modulelayout"
|
||||
label="JFIELD_ALT_LAYOUT_LABEL"
|
||||
class="form-select"
|
||||
validate="moduleLayout"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="moduleclass_sfx"
|
||||
type="textarea"
|
||||
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
|
||||
rows="3"
|
||||
validate="CssIdentifier"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="owncache"
|
||||
type="list"
|
||||
label="COM_MODULES_FIELD_CACHING_LABEL"
|
||||
default="1"
|
||||
filter="integer"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="cache_time"
|
||||
type="number"
|
||||
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
|
||||
default="900"
|
||||
filter="integer"
|
||||
/>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_related_items
|
||||
*
|
||||
* @copyright (C) 2022 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\Extension\Service\Provider\HelperFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\Module;
|
||||
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The articles related module service provider.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\RelatedItems'));
|
||||
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\RelatedItems\\Site\\Helper'));
|
||||
|
||||
$container->registerServiceProvider(new Module());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage mod_related_items
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Module\RelatedItems\Site\Dispatcher;
|
||||
|
||||
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
|
||||
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
|
||||
use Joomla\CMS\Helper\ModuleHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Dispatcher class for mod_articles_related_items
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
|
||||
{
|
||||
use HelperFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Returns the layout data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
protected function getLayoutData(): array
|
||||
{
|
||||
$data = parent::getLayoutData();
|
||||
$params = $data['params'];
|
||||
|
||||
$cacheParams = new \stdClass();
|
||||
$cacheParams->cachemode = 'safeuri';
|
||||
$cacheParams->class = $this->getHelperFactory()->getHelper('RelatedItemsHelper');
|
||||
$cacheParams->method = 'getRelatedArticles';
|
||||
$cacheParams->methodparams = [$params, $data['app']];
|
||||
$cacheParams->modeparams = ['id' => 'int', 'Itemid' => 'int'];
|
||||
|
||||
$data['list'] = ModuleHelper::moduleCache($this->module, $params, $cacheParams);
|
||||
$data['showDate'] = $params->get('showDate', 0);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user