first commit
This commit is contained in:
13
administrator/components/com_guidedtours/access.xml
Normal file
13
administrator/components/com_guidedtours/access.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<access component="com_guidedtours">
|
||||
<section name="component">
|
||||
<action name="core.admin" title="JACTION_ADMIN" />
|
||||
<action name="core.options" title="JACTION_OPTIONS" />
|
||||
<action name="core.manage" title="JACTION_MANAGE" />
|
||||
<action name="core.create" title="JACTION_CREATE" />
|
||||
<action name="core.delete" title="JACTION_DELETE" />
|
||||
<action name="core.edit" title="JACTION_EDIT" />
|
||||
<action name="core.edit.state" title="JACTION_EDITSTATE" />
|
||||
<action name="core.edit.own" title="JACTION_EDITOWN" />
|
||||
</section>
|
||||
</access>
|
||||
17
administrator/components/com_guidedtours/config.xml
Normal file
17
administrator/components/com_guidedtours/config.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<config>
|
||||
<fieldset
|
||||
name="permissions"
|
||||
label="JCONFIG_PERMISSIONS_LABEL"
|
||||
>
|
||||
<field
|
||||
name="rules"
|
||||
type="rules"
|
||||
label="JCONFIG_PERMISSIONS_LABEL"
|
||||
validate="rules"
|
||||
filter="rules"
|
||||
component="com_guidedtours"
|
||||
section="component"
|
||||
/>
|
||||
</fieldset>
|
||||
</config>
|
||||
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fields name="filter">
|
||||
<field
|
||||
name="search"
|
||||
type="text"
|
||||
label="COM_GUIDEDTOURS_STEP_FILTER_SEARCH_LABEL"
|
||||
description="COM_GUIDEDTOURS_STEP_FILTER_SEARCH_DESC"
|
||||
inputmode="search"
|
||||
hint="JSEARCH_FILTER"
|
||||
/>
|
||||
<field
|
||||
name="published"
|
||||
type="status"
|
||||
label="JOPTION_SELECT_PUBLISHED"
|
||||
class="js-select-submit-on-change"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_PUBLISHED</option>
|
||||
</field>
|
||||
</fields>
|
||||
|
||||
<fields name="list">
|
||||
<field
|
||||
name="fullordering"
|
||||
type="list"
|
||||
label="JGLOBAL_SORT_BY"
|
||||
class="js-select-submit-on-change"
|
||||
default="a.ordering ASC"
|
||||
validate="options"
|
||||
>
|
||||
<option value="">JGLOBAL_SORT_BY</option>
|
||||
<option value="a.ordering ASC">JGRID_HEADING_ORDERING_ASC</option>
|
||||
<option value="a.ordering DESC">JGRID_HEADING_ORDERING_DESC</option>
|
||||
<option value="a.published ASC">JSTATUS_ASC</option>
|
||||
<option value="a.published DESC">JSTATUS_DESC</option>
|
||||
<option value="a.type ASC">COM_GUIDEDTOURS_ORDER_TYPE_ASC</option>
|
||||
<option value="a.type DESC">COM_GUIDEDTOURS_ORDER_TYPE_DESC</option>
|
||||
<option value="a.id ASC">JGRID_HEADING_ID_ASC</option>
|
||||
<option value="a.id DESC">JGRID_HEADING_ID_DESC</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="limit"
|
||||
type="limitbox"
|
||||
label="JGLOBAL_LIST_LIMIT"
|
||||
default="25"
|
||||
class="js-select-submit-on-change"
|
||||
/>
|
||||
</fields>
|
||||
</form>
|
||||
@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fields name="filter">
|
||||
<field
|
||||
name="search"
|
||||
type="text"
|
||||
label="COM_GUIDEDTOURS_FILTER_SEARCH_LABEL"
|
||||
description="COM_GUIDEDTOURS_FILTER_SEARCH_DESC"
|
||||
inputmode="search"
|
||||
hint="JSEARCH_FILTER"
|
||||
/>
|
||||
<field
|
||||
name="published"
|
||||
type="status"
|
||||
label="JOPTION_SELECT_PUBLISHED"
|
||||
class="js-select-submit-on-change"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_PUBLISHED</option>
|
||||
</field>
|
||||
<field
|
||||
name="access"
|
||||
type="accesslevel"
|
||||
label="JGRID_HEADING_ACCESS"
|
||||
class="js-select-submit-on-change"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_ACCESS</option>
|
||||
</field>
|
||||
<field
|
||||
name="language"
|
||||
type="contentlanguage"
|
||||
label="JGRID_HEADING_LANGUAGE"
|
||||
class="js-select-submit-on-change"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_LANGUAGE</option>
|
||||
<option value="*">JALL</option>
|
||||
</field>
|
||||
</fields>
|
||||
|
||||
<fields name="list">
|
||||
<field
|
||||
name="fullordering"
|
||||
type="list"
|
||||
label="JGLOBAL_SORT_BY"
|
||||
class="js-select-submit-on-change"
|
||||
default="a.ordering ASC"
|
||||
validate="options"
|
||||
>
|
||||
<option value="">JGLOBAL_SORT_BY</option>
|
||||
<option value="a.ordering ASC">JGRID_HEADING_ORDERING_ASC</option>
|
||||
<option value="a.ordering DESC">JGRID_HEADING_ORDERING_DESC</option>
|
||||
<option value="a.published ASC">JSTATUS_ASC</option>
|
||||
<option value="a.published DESC">JSTATUS_DESC</option>
|
||||
<option value="a.access ASC">JGRID_HEADING_ACCESS_ASC</option>
|
||||
<option value="a.access DESC">JGRID_HEADING_ACCESS_DESC</option>
|
||||
<option value="a.language ASC" requires="multilanguage">JGRID_HEADING_LANGUAGE_ASC</option>
|
||||
<option value="a.language DESC" requires="multilanguage">JGRID_HEADING_LANGUAGE_DESC</option>
|
||||
<option value="a.id ASC">JGRID_HEADING_ID_ASC</option>
|
||||
<option value="a.id DESC">JGRID_HEADING_ID_DESC</option>
|
||||
</field>
|
||||
<field
|
||||
name="limit"
|
||||
type="limitbox"
|
||||
label="JGLOBAL_LIST_LIMIT"
|
||||
default="25"
|
||||
class="js-select-submit-on-change"
|
||||
/>
|
||||
</fields>
|
||||
</form>
|
||||
192
administrator/components/com_guidedtours/forms/step.xml
Normal file
192
administrator/components/com_guidedtours/forms/step.xml
Normal file
@ -0,0 +1,192 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form addfieldprefix="Joomla\Component\Guidedtours\Administrator\Field">
|
||||
<config>
|
||||
<inlinehelp button="show"/>
|
||||
</config>
|
||||
<field
|
||||
name="id"
|
||||
type="text"
|
||||
label="JGLOBAL_FIELD_ID_LABEL"
|
||||
default="0"
|
||||
class="readonly"
|
||||
readonly="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="position"
|
||||
type="list"
|
||||
label="COM_GUIDEDTOURS_STEP_POSITION_LABEL"
|
||||
description="COM_GUIDEDTOURS_STEP_POSITION_DESC"
|
||||
default="center"
|
||||
validate="options"
|
||||
>
|
||||
<option value="bottom">JGLOBAL_BOTTOM</option>
|
||||
<option value="center">JGLOBAL_CENTER</option>
|
||||
<option value="left">JGLOBAL_LEFT</option>
|
||||
<option value="right">JGLOBAL_RIGHT</option>
|
||||
<option value="top">JGLOBAL_TOP</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="target"
|
||||
type="text"
|
||||
label="COM_GUIDEDTOURS_STEP_TARGET_LABEL"
|
||||
description="COM_GUIDEDTOURS_STEP_TARGET_DESC"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="tour_id"
|
||||
type="hidden"
|
||||
class="readonly"
|
||||
readonly="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="title"
|
||||
type="text"
|
||||
label="COM_GUIDEDTOURS_STEP_TITLE"
|
||||
required="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="title_translation"
|
||||
type="text"
|
||||
label="JGLOBAL_TITLE"
|
||||
readonly="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="description"
|
||||
type="editor"
|
||||
label="JGLOBAL_DESCRIPTION"
|
||||
filter="\Joomla\CMS\Component\ComponentHelper::filterText"
|
||||
buttons="true"
|
||||
hide="readmore,pagebreak,module,menu,fields,contact,article"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="description_translation"
|
||||
type="editor"
|
||||
label="JGLOBAL_DESCRIPTION"
|
||||
filter="\Joomla\CMS\Component\ComponentHelper::filterText"
|
||||
buttons="false"
|
||||
readonly="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="published"
|
||||
type="list"
|
||||
label="JSTATUS"
|
||||
default="1"
|
||||
class="form-select-color-state"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JPUBLISHED</option>
|
||||
<option value="0">JUNPUBLISHED</option>
|
||||
<option value="2">JARCHIVED</option>
|
||||
<option value="-2">JTRASHED</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="type"
|
||||
type="list"
|
||||
label="COM_GUIDEDTOURS_STEP_TYPE_LABEL"
|
||||
description="COM_GUIDEDTOURS_STEP_TYPE_DESC"
|
||||
default="0"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">COM_GUIDEDTOURS_FIELD_VALUE_STEP_TYPE_NEXT</option>
|
||||
<option value="1">COM_GUIDEDTOURS_FIELD_VALUE_STEP_TYPE_REDIRECT</option>
|
||||
<option value="2">COM_GUIDEDTOURS_FIELD_VALUE_STEP_TYPE_INTERACTIVE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="url"
|
||||
type="url"
|
||||
label="COM_GUIDEDTOURS_TYPE_REDIRECT_URL_LABEL"
|
||||
description="COM_GUIDEDTOURS_TYPE_REDIRECT_URL_DESC"
|
||||
showon="type:1"
|
||||
filter="string"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="interactive_type"
|
||||
type="list"
|
||||
label="COM_GUIDEDTOURS_TYPE_INTERACTIVE_STEP_LABEL"
|
||||
description="COM_GUIDEDTOURS_TYPE_INTERACTIVE_STEP_DESC"
|
||||
showon="type:2"
|
||||
filter="string"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">COM_GUIDEDTOURS_FIELD_VALUE_INTERACTIVESTEP_TYPE_FORM_SUBMIT</option>
|
||||
<option value="2">COM_GUIDEDTOURS_FIELD_VALUE_INTERACTIVESTEP_TYPE_TEXT_FIELD</option>
|
||||
<option value="4">COM_GUIDEDTOURS_FIELD_VALUE_INTERACTIVESTEP_TYPE_BUTTON</option>
|
||||
<option value="3">COM_GUIDEDTOURS_FIELD_VALUE_INTERACTIVESTEP_TYPE_OTHER</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="checked_out"
|
||||
type="hidden"
|
||||
filter="unset"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="checked_out_time"
|
||||
type="hidden"
|
||||
filter="unset"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="created_by"
|
||||
type="user"
|
||||
label="JGLOBAL_FIELD_CREATED_BY_LABEL"
|
||||
validate="UserId"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="created"
|
||||
type="calendar"
|
||||
label="JGLOBAL_CREATED_DATE"
|
||||
translateformat="true"
|
||||
showtime="true"
|
||||
filter="user_utc"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="modified_by"
|
||||
type="user"
|
||||
label="JGLOBAL_FIELD_MODIFIED_BY_LABEL"
|
||||
class="readonly"
|
||||
readonly="true"
|
||||
filter="unset"
|
||||
validate="UserId"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="modified"
|
||||
type="calendar"
|
||||
label="JGLOBAL_FIELD_MODIFIED_LABEL"
|
||||
class="readonly"
|
||||
readonly="true"
|
||||
translateformat="true"
|
||||
showtime="true"
|
||||
filter="user_utc"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="language"
|
||||
type="contentlanguage"
|
||||
label="JFIELD_LANGUAGE_LABEL"
|
||||
default="*"
|
||||
>
|
||||
<option value="*">JALL</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="note"
|
||||
type="text"
|
||||
label="COM_GUIDEDTOURS_FIELD_NOTE_LABEL"
|
||||
maxlength="255"
|
||||
/>
|
||||
|
||||
</form>
|
||||
163
administrator/components/com_guidedtours/forms/tour.xml
Normal file
163
administrator/components/com_guidedtours/forms/tour.xml
Normal file
@ -0,0 +1,163 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form addfieldprefix="Joomla\Component\Guidedtours\Administrator\Field">
|
||||
<config>
|
||||
<inlinehelp button="show"/>
|
||||
</config>
|
||||
<field
|
||||
name="id"
|
||||
type="text"
|
||||
label="JGLOBAL_FIELD_ID_LABEL"
|
||||
class="readonly"
|
||||
readonly="true"
|
||||
default="0"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="title"
|
||||
type="text"
|
||||
label="COM_GUIDEDTOURS_TITLE"
|
||||
required="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="title_translation"
|
||||
type="text"
|
||||
label="JGLOBAL_TITLE"
|
||||
readonly="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="uid"
|
||||
type="text"
|
||||
label="COM_GUIDEDTOURS_TOUR_UID_LABEL"
|
||||
description="COM_GUIDEDTOURS_TOUR_UID_DESC"
|
||||
hint="COM_GUIDEDTOURS_TOUR_UID_HINT"
|
||||
required="false"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="description"
|
||||
type="editor"
|
||||
label="JGLOBAL_DESCRIPTION"
|
||||
filter="\Joomla\CMS\Component\ComponentHelper::filterText"
|
||||
buttons="true"
|
||||
hide="readmore,pagebreak,module,menu,fields,contact,article"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="description_translation"
|
||||
type="editor"
|
||||
label="JGLOBAL_DESCRIPTION"
|
||||
filter="\Joomla\CMS\Component\ComponentHelper::filterText"
|
||||
buttons="false"
|
||||
readonly="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="published"
|
||||
type="list"
|
||||
label="JSTATUS"
|
||||
default="1"
|
||||
class="form-select-color-state"
|
||||
validate="options"
|
||||
>
|
||||
<option value="1">JPUBLISHED</option>
|
||||
<option value="0">JUNPUBLISHED</option>
|
||||
<option value="2">JARCHIVED</option>
|
||||
<option value="-2">JTRASHED</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="checked_out"
|
||||
type="hidden"
|
||||
filter="unset"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="checked_out_time"
|
||||
type="hidden"
|
||||
filter="unset"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="access"
|
||||
type="accesslevel"
|
||||
label="JFIELD_ACCESS_LABEL"
|
||||
filter="UINT"
|
||||
validate="options"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="created_by"
|
||||
type="user"
|
||||
label="JGLOBAL_FIELD_CREATED_BY_LABEL"
|
||||
validate="UserId"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="created"
|
||||
type="calendar"
|
||||
label="JGLOBAL_CREATED_DATE"
|
||||
translateformat="true"
|
||||
showtime="true"
|
||||
filter="user_utc"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="modified_by"
|
||||
type="user"
|
||||
label="JGLOBAL_FIELD_MODIFIED_BY_LABEL"
|
||||
class="readonly"
|
||||
readonly="true"
|
||||
filter="unset"
|
||||
validate="UserId"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="modified"
|
||||
type="calendar"
|
||||
label="JGLOBAL_FIELD_MODIFIED_LABEL"
|
||||
class="readonly"
|
||||
readonly="true"
|
||||
translateformat="true"
|
||||
showtime="true"
|
||||
filter="user_utc"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="language"
|
||||
type="contentlanguage"
|
||||
label="JFIELD_LANGUAGE_LABEL"
|
||||
default="*"
|
||||
>
|
||||
<option value="*">JALL</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="note"
|
||||
type="text"
|
||||
label="COM_GUIDEDTOURS_FIELD_NOTE_LABEL"
|
||||
maxlength="255"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="url"
|
||||
type="url"
|
||||
label="COM_GUIDEDTOURS_URL_LABEL"
|
||||
description="COM_GUIDEDTOURS_URL_DESC"
|
||||
required="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="extensions"
|
||||
type="components"
|
||||
label="COM_GUIDEDTOURS_EXTENSIONS_LABEL"
|
||||
description="COM_GUIDEDTOURS_EXTENSIONS_DESC"
|
||||
required="true"
|
||||
multiple="multiple"
|
||||
layout="joomla.form.field.list-fancy-select"
|
||||
default="*"
|
||||
>
|
||||
<option value="*">JALL</option>
|
||||
</field>
|
||||
</form>
|
||||
26
administrator/components/com_guidedtours/guidedtours.xml
Normal file
26
administrator/components/com_guidedtours/guidedtours.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="component" method="upgrade">
|
||||
<name>com_guidedtours</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2023-02</creationDate>
|
||||
<copyright>(C) 2023 Open Source Matters, Inc.</copyright>
|
||||
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
|
||||
<authorEmail>admin@joomla.org</authorEmail>
|
||||
<authorUrl>www.joomla.org</authorUrl>
|
||||
<version>4.3.0</version>
|
||||
<description>COM_GUIDEDTOURS_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Component\Guidedtours</namespace>
|
||||
<administration>
|
||||
<filename>access.xml</filename>
|
||||
<filename>config.xml</filename>
|
||||
<filename>guidedtours.xml</filename>
|
||||
<folder>forms</folder>
|
||||
<folder>services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
<languages folder="administrator">
|
||||
<language tag="en-GB">language/en-GB/com_guidedtours.ini</language>
|
||||
<language tag="en-GB">language/en-GB/com_guidedtours.sys.ini</language>
|
||||
</languages>
|
||||
</administration>
|
||||
</extension>
|
||||
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Dispatcher\ComponentDispatcherFactoryInterface;
|
||||
use Joomla\CMS\Extension\ComponentInterface;
|
||||
use Joomla\CMS\Extension\Service\Provider\ComponentDispatcherFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\MVCFactory;
|
||||
use Joomla\CMS\HTML\Registry;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\Component\Guidedtours\Administrator\Extension\GuidedtoursComponent;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* The Guidedtours 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 MVCFactory('\\Joomla\\Component\\Guidedtours'));
|
||||
$container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\Guidedtours'));
|
||||
|
||||
$container->set(
|
||||
ComponentInterface::class,
|
||||
function (Container $container) {
|
||||
$component = new GuidedtoursComponent($container->get(ComponentDispatcherFactoryInterface::class));
|
||||
|
||||
$component->setRegistry($container->get(Registry::class));
|
||||
$component->setMVCFactory($container->get(MVCFactoryInterface::class));
|
||||
|
||||
return $component;
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Component Controller
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class DisplayController extends BaseController
|
||||
{
|
||||
/**
|
||||
* The default view.
|
||||
*
|
||||
* @var string
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected $default_view = 'tours';
|
||||
|
||||
/**
|
||||
* Method to display a view.
|
||||
*
|
||||
* @param boolean $cachable If true, the view output will be cached
|
||||
* @param array $urlparams An array of safe URL parameters and their variable types.
|
||||
* @see \Joomla\CMS\Filter\InputFilter::clean() for valid values.
|
||||
*
|
||||
* @return static |boolean This object to support chaining. False on failure.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function display($cachable = false, $urlparams = [])
|
||||
{
|
||||
$view = $this->input->get('view', $this->default_view);
|
||||
$layout = $this->input->get('layout', 'default');
|
||||
$id = $this->input->getInt('id');
|
||||
|
||||
// Show messages about the disabled plugin
|
||||
if ($view === 'tours' && !PluginHelper::isEnabled('system', 'guidedtours')) {
|
||||
$this->app->enqueueMessage(Text::_('COM_GUIDEDTOURS_PLUGIN_DISABLED'), 'error');
|
||||
}
|
||||
|
||||
if ($view === 'tour' && $layout === 'edit' && !$this->checkEditId('com_guidedtours.edit.tour', $id)) {
|
||||
$this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error');
|
||||
$this->setRedirect(Route::_('index.php?option=com_guidedtours&view=tours', false));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($view === 'step' && $layout === 'edit' && !$this->checkEditId('com_guidedtours.edit.step', $id)) {
|
||||
$this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error');
|
||||
$this->setRedirect(Route::_('index.php?option=com_guidedtours&view=steps', false));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::display();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\MVC\Controller\FormController;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Controller for a single step
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class StepController extends FormController
|
||||
{
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\MVC\Controller\AdminController;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Component Controller
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
|
||||
class StepsController extends AdminController
|
||||
{
|
||||
/**
|
||||
* Proxy for getModel.
|
||||
*
|
||||
* @param string $name The model name. Optional.
|
||||
* @param string $prefix The class prefix. Optional.
|
||||
* @param array $config The array of possible config values. Optional.
|
||||
*
|
||||
* @return \Joomla\CMS\MVC\Model\BaseDatabaseModel
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function getModel($name = 'Step', $prefix = 'Administrator', $config = ['ignore_request' => true])
|
||||
{
|
||||
return parent::getModel($name, $prefix, $config);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\MVC\Controller\FormController;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Controller for a single Tour
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class TourController extends FormController
|
||||
{
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Controller\AdminController;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Guidedtours list controller class.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
|
||||
class ToursController extends AdminController
|
||||
{
|
||||
/**
|
||||
* Proxy for getModel.
|
||||
*
|
||||
* @param string $name The model name. Optional.
|
||||
* @param string $prefix The class prefix. Optional.
|
||||
* @param array $config The array of possible config values. Optional.
|
||||
*
|
||||
* @return \Joomla\CMS\MVC\Model\BaseDatabaseModel
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function getModel($name = 'Tour', $prefix = 'Administrator', $config = ['ignore_request' => true])
|
||||
{
|
||||
return parent::getModel($name, $prefix, $config);
|
||||
}
|
||||
|
||||
public function duplicate()
|
||||
{
|
||||
$this->checkToken();
|
||||
$pks = (array) $this->input->post->get('cid', [], 'int');
|
||||
$pks = array_filter($pks);
|
||||
try {
|
||||
if (empty($pks)) {
|
||||
throw new \Exception(Text::_('COM_GUIDEDTOURS_ERROR_NO_GUIDEDTOURS_SELECTED'));
|
||||
}
|
||||
$model = $this->getModel();
|
||||
$model->duplicate($pks);
|
||||
$this->setMessage(Text::plural('COM_GUIDEDTOURS_TOURS_DUPLICATED', \count($pks)));
|
||||
} catch (\Exception $e) {
|
||||
$this->app->enqueueMessage($e->getMessage(), 'warning');
|
||||
}
|
||||
$this->setRedirect(Route::_('index.php?option=com_guidedtours&view=tours' . $this->getRedirectToListAppend(), false));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\Extension;
|
||||
|
||||
use Joomla\CMS\Extension\BootableExtensionInterface;
|
||||
use Joomla\CMS\Extension\MVCComponent;
|
||||
use Joomla\CMS\HTML\HTMLRegistryAwareTrait;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Component class for com_guidedtours
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class GuidedtoursComponent extends MVCComponent implements BootableExtensionInterface
|
||||
{
|
||||
use HTMLRegistryAwareTrait;
|
||||
|
||||
/**
|
||||
* The step type
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public const STEP_TYPE_NAMES = [
|
||||
self::STEP_NEXT => 'COM_GUIDEDTOURS_FIELD_VALUE_STEP_TYPE_NEXT',
|
||||
self::STEP_REDIRECT => 'COM_GUIDEDTOURS_FIELD_VALUE_STEP_TYPE_REDIRECT',
|
||||
self::STEP_INTERACTIVE => 'COM_GUIDEDTOURS_FIELD_VALUE_STEP_TYPE_INTERACTIVE',
|
||||
];
|
||||
|
||||
/**
|
||||
* A regular step.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public const STEP_NEXT = 0;
|
||||
|
||||
/**
|
||||
* A step that redirects to another page.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public const STEP_REDIRECT = 1;
|
||||
|
||||
/**
|
||||
* A step that allows interactions from the user.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public const STEP_INTERACTIVE = 2;
|
||||
|
||||
/**
|
||||
* The step interactive type names
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public const STEP_INTERACTIVETYPE_NAMES = [
|
||||
self::STEP_INTERACTIVETYPE_FORM_SUBMIT => 'COM_GUIDEDTOURS_FIELD_VALUE_INTERACTIVESTEP_TYPE_FORM_SUBMIT',
|
||||
self::STEP_INTERACTIVETYPE_TEXT => 'COM_GUIDEDTOURS_FIELD_VALUE_INTERACTIVESTEP_TYPE_TEXT_FIELD',
|
||||
self::STEP_INTERACTIVETYPE_BUTTON => 'COM_GUIDEDTOURS_FIELD_VALUE_INTERACTIVESTEP_TYPE_BUTTON',
|
||||
self::STEP_INTERACTIVETYPE_OTHER => 'COM_GUIDEDTOURS_FIELD_VALUE_INTERACTIVESTEP_TYPE_OTHER',
|
||||
];
|
||||
|
||||
/**
|
||||
* An interactive step where a user clicks on a form button.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public const STEP_INTERACTIVETYPE_FORM_SUBMIT = 1;
|
||||
|
||||
/**
|
||||
* An interactive step where a user enters text.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public const STEP_INTERACTIVETYPE_TEXT = 2;
|
||||
|
||||
/**
|
||||
* An interactive step where a user clicks on a button.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public const STEP_INTERACTIVETYPE_BUTTON = 4;
|
||||
|
||||
/**
|
||||
* An interactive step for other fields.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public const STEP_INTERACTIVETYPE_OTHER = 3;
|
||||
|
||||
/**
|
||||
* Booting the extension. This is the function to set up the environment of the extension like
|
||||
* registering new class loaders, etc.
|
||||
*
|
||||
* If required, some initial set up can be done from services of the container, eg.
|
||||
* registering HTML services.
|
||||
*
|
||||
* @param ContainerInterface $container The container
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function boot(ContainerInterface $container)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\Helper;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Guidedtours component helper.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*/
|
||||
class GuidedtoursHelper
|
||||
{
|
||||
/**
|
||||
* Load the translation files for an Guided Tour
|
||||
*
|
||||
* @param string $uid Guided Tour Unique Identifier
|
||||
* @param boolean $steps Should tour steps language file be loaded
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public static function loadTranslationFiles($uid, bool $steps = false)
|
||||
{
|
||||
static $cache = [];
|
||||
$uid = strtolower($uid);
|
||||
|
||||
if (isset($cache[$uid])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$lang = Factory::getLanguage();
|
||||
|
||||
// The uid has an extension separator so we need to check the extension language files
|
||||
if (strpos($uid, '.') > 0) {
|
||||
list($extension, $tourid) = explode('.', $uid, 2);
|
||||
|
||||
$source = '';
|
||||
|
||||
switch (substr($extension, 0, 3)) {
|
||||
case 'com':
|
||||
$source = JPATH_ADMINISTRATOR . '/components/' . $extension;
|
||||
break;
|
||||
|
||||
case 'lib':
|
||||
$source = JPATH_LIBRARIES . '/' . substr($extension, 4);
|
||||
break;
|
||||
|
||||
case 'mod':
|
||||
$source = JPATH_SITE . '/modules/' . $extension;
|
||||
break;
|
||||
|
||||
case 'plg':
|
||||
$parts = explode('_', $extension, 3);
|
||||
|
||||
if (\count($parts) > 2) {
|
||||
$source = JPATH_PLUGINS . '/' . $parts[1] . '/' . $parts[2];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'pkg':
|
||||
$source = JPATH_SITE;
|
||||
break;
|
||||
|
||||
case 'tpl':
|
||||
$source = JPATH_BASE . '/templates/' . substr($extension, 4);
|
||||
break;
|
||||
|
||||
default:
|
||||
$source = JPATH_ADMINISTRATOR . '/components/com_' . $extension;
|
||||
break;
|
||||
}
|
||||
|
||||
$lang->load($extension . '.' . str_replace('-', '_', $tourid), JPATH_ADMINISTRATOR)
|
||||
|| $lang->load($extension . '.' . str_replace('-', '_', $tourid), $source);
|
||||
if ($steps) {
|
||||
$lang->load($extension . '.' . str_replace('-', '_', $tourid) . '_steps', JPATH_ADMINISTRATOR)
|
||||
|| $lang->load($extension . '.' . str_replace('-', '_', $tourid) . '_steps', $source);
|
||||
}
|
||||
} else {
|
||||
$lang->load('guidedtours.' . str_replace('-', '_', $uid), JPATH_ADMINISTRATOR);
|
||||
if ($steps) {
|
||||
$lang->load('guidedtours.' . str_replace('-', '_', $uid) . '_steps', JPATH_ADMINISTRATOR);
|
||||
}
|
||||
}
|
||||
|
||||
$cache[$uid] = true;
|
||||
}
|
||||
}
|
||||
271
administrator/components/com_guidedtours/src/Model/StepModel.php
Normal file
271
administrator/components/com_guidedtours/src/Model/StepModel.php
Normal file
@ -0,0 +1,271 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\Model;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Model\AdminModel;
|
||||
use Joomla\CMS\Object\CMSObject;
|
||||
use Joomla\CMS\Table\Table;
|
||||
use Joomla\Component\Guidedtours\Administrator\Helper\GuidedtoursHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Item Model for a single tour.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
|
||||
class StepModel extends AdminModel
|
||||
{
|
||||
/**
|
||||
* The prefix to use with controller messages.
|
||||
*
|
||||
* @var string
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected $text_prefix = 'COM_GUIDEDTOURS';
|
||||
|
||||
/**
|
||||
* Type alias for content type
|
||||
*
|
||||
* @var string
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public $typeAlias = 'com_guidedtours.step';
|
||||
|
||||
/**
|
||||
* Method to test whether a record can be deleted.
|
||||
*
|
||||
* @param object $record A record object.
|
||||
*
|
||||
* @return boolean True if allowed to delete the record. Defaults to the permission for the component.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function canDelete($record)
|
||||
{
|
||||
if (empty($record->id) || $record->published != -2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::canDelete($record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to save the form data.
|
||||
*
|
||||
* @param array $data The form data.
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function save($data)
|
||||
{
|
||||
$table = $this->getTable();
|
||||
$input = Factory::getApplication()->getInput();
|
||||
|
||||
$tour = $this->getTable('Tour');
|
||||
|
||||
$tour->load($data['tour_id']);
|
||||
|
||||
// Language keys must include GUIDEDTOUR to prevent save issues
|
||||
if (strpos($data['description'], 'GUIDEDTOUR') !== false) {
|
||||
$data['description'] = strip_tags($data['description']);
|
||||
}
|
||||
|
||||
// Make sure we use the correct extension when editing an existing tour
|
||||
$key = $table->getKeyName();
|
||||
$pk = $data[$key] ?? (int) $this->getState($this->getName() . '.id');
|
||||
|
||||
if ($pk > 0) {
|
||||
$table->load($pk);
|
||||
|
||||
if ((int) $table->tour_id) {
|
||||
$data['tour_id'] = (int) $table->tour_id;
|
||||
}
|
||||
}
|
||||
|
||||
if ($input->get('task') == 'save2copy') {
|
||||
$origTable = clone $this->getTable();
|
||||
$origTable->load($input->getInt('id'));
|
||||
|
||||
$data['published'] = 0;
|
||||
}
|
||||
|
||||
return parent::save($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare and sanitise the table prior to saving.
|
||||
*
|
||||
* @param \Joomla\CMS\Table\Table $table The Table object
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function prepareTable($table)
|
||||
{
|
||||
$date = Factory::getDate()->toSql();
|
||||
|
||||
$table->title = htmlspecialchars_decode($table->title, ENT_QUOTES);
|
||||
|
||||
if (empty($table->id)) {
|
||||
// Set the values
|
||||
$table->created = $date;
|
||||
|
||||
// Set ordering to the last item if not set
|
||||
if (empty($table->ordering)) {
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true)
|
||||
->select('MAX(ordering)')
|
||||
->from($db->quoteName('#__guidedtour_steps'));
|
||||
$db->setQuery($query);
|
||||
$max = $db->loadResult();
|
||||
|
||||
$table->ordering = $max + 1;
|
||||
}
|
||||
} else {
|
||||
// Set the values
|
||||
$table->modified = $date;
|
||||
$table->modified_by = $this->getCurrentUser()->id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a table object, load it if necessary.
|
||||
*
|
||||
* @param string $type The table name. Optional.
|
||||
* @param string $prefix The class prefix. Optional.
|
||||
* @param array $config Configuration array for model. Optional.
|
||||
*
|
||||
* @return Table A Table object
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getTable($type = 'Step', $prefix = 'Administrator', $config = [])
|
||||
{
|
||||
return parent::getTable($type, $prefix, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method for getting the form from the model.
|
||||
*
|
||||
* @param array $data Data for the form.
|
||||
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
|
||||
*
|
||||
* @return \JForm|boolean A JForm object on success, false on failure
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function getForm($data = [], $loadData = true)
|
||||
{
|
||||
// Get the form.
|
||||
$form = $this->loadForm(
|
||||
'com_guidedtours.step',
|
||||
'step',
|
||||
[
|
||||
'control' => 'jform',
|
||||
'load_data' => $loadData,
|
||||
]
|
||||
);
|
||||
|
||||
if (empty($form)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$id = $data['id'] ?? $form->getValue('id');
|
||||
|
||||
$item = $this->getItem($id);
|
||||
|
||||
// Modify the form based on access controls.
|
||||
if (!$this->canEditState((object) $item)) {
|
||||
$form->setFieldAttribute('published', 'disabled', 'true');
|
||||
$form->setFieldAttribute('published', 'required', 'false');
|
||||
$form->setFieldAttribute('published', 'filter', 'unset');
|
||||
}
|
||||
|
||||
// Disables language field selection
|
||||
$form->setFieldAttribute('language', 'readonly', 'true');
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the data that should be injected in the form.
|
||||
*
|
||||
* @return mixed The data for the form.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function loadFormData()
|
||||
{
|
||||
// Check the session for previously entered form data.
|
||||
$data = Factory::getApplication()->getUserState(
|
||||
'com_guidedtours.edit.step.data',
|
||||
[]
|
||||
);
|
||||
|
||||
if (empty($data)) {
|
||||
$data = $this->getItem();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a single record.
|
||||
*
|
||||
* @param integer $pk The id of the primary key.
|
||||
*
|
||||
* @return CMSObject|boolean Object on success, false on failure.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function getItem($pk = null)
|
||||
{
|
||||
if ($result = parent::getItem($pk)) {
|
||||
$app = Factory::getApplication();
|
||||
|
||||
/** @var \Joomla\Component\Guidedtours\Administrator\Model\TourModel $tourModel */
|
||||
$tourModel = $app->bootComponent('com_guidedtours')
|
||||
->getMVCFactory()->createModel('Tour', 'Administrator', ['ignore_request' => true]);
|
||||
|
||||
if (!empty($result->id)) {
|
||||
// Editing an existing step
|
||||
$tour = $tourModel->getItem($result->tour_id);
|
||||
|
||||
GuidedtoursHelper::loadTranslationFiles($tour->uid, true);
|
||||
|
||||
$result->title_translation = Text::_($result->title);
|
||||
$result->description_translation = Text::_($result->description);
|
||||
} else {
|
||||
// Creating a new step so we get the tour id from the session data
|
||||
$tourId = $app->getUserState('com_guidedtours.tour_id');
|
||||
$tour = $tourModel->getItem($tourId);
|
||||
|
||||
// Sets step language to parent tour language
|
||||
$result->language = !empty($tour->language) ? $tour->language : '*';
|
||||
|
||||
// Set the step's tour id
|
||||
$result->tour_id = $tourId;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,255 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\Model;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Model\ListModel;
|
||||
use Joomla\Component\Guidedtours\Administrator\Helper\GuidedtoursHelper;
|
||||
use Joomla\Database\DatabaseQuery;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Methods supporting a list of steps records.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class StepsModel extends ListModel
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config An optional associative array of configuration settings.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @see \Joomla\CMS\MVC\Controller\BaseController
|
||||
*/
|
||||
public function __construct($config = [])
|
||||
{
|
||||
if (empty($config['filter_fields'])) {
|
||||
$config['filter_fields'] = [
|
||||
'id', 'a.id',
|
||||
'tour_id', 'a.tour_id',
|
||||
'title', 'a.title',
|
||||
'type', 'a.type',
|
||||
'description', 'a.description',
|
||||
'published', 'a.published',
|
||||
'ordering', 'a.ordering',
|
||||
'created_by', 'a.created_by',
|
||||
'modified', 'a.modified',
|
||||
'modified_by', 'a.modified_by',
|
||||
'note', 'a.note',
|
||||
];
|
||||
}
|
||||
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a query to be used to evaluate if this is an Empty State, can be overridden in the model to provide granular control.
|
||||
*
|
||||
* @return DatabaseQuery
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function getEmptyStateQuery()
|
||||
{
|
||||
$query = parent::getEmptyStateQuery();
|
||||
|
||||
$tourId = $this->getState('filter.tour_id');
|
||||
|
||||
if ($tourId) {
|
||||
$tourId = (int) $tourId;
|
||||
$query->where($this->getDatabase()->quoteName('a.tour_id') . ' = :tour_id')
|
||||
->bind(':tour_id', $tourId, ParameterType::INTEGER);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @param string $ordering An optional ordering field.
|
||||
* @param string $direction An optional direction (asc|desc).
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function populateState($ordering = 'a.ordering', $direction = 'ASC')
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
|
||||
$tourId = $app->getUserStateFromRequest($this->context . '.filter.tour_id', 'tour_id', 0, 'int');
|
||||
|
||||
if (empty($tourId)) {
|
||||
$tourId = $app->getUserState('com_guidedtours.tour_id');
|
||||
}
|
||||
|
||||
$this->setState('filter.tour_id', $tourId);
|
||||
|
||||
// Keep the tour_id for adding new visits
|
||||
$app->setUserState('com_guidedtours.tour_id', $tourId);
|
||||
|
||||
// List state information.
|
||||
parent::populateState($ordering, $direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a store id based on model configuration state.
|
||||
*
|
||||
* This is necessary because the model is used by the component and
|
||||
* different modules that might need different sets of data or different
|
||||
* ordering requirements.
|
||||
*
|
||||
* @param string $id A prefix for the store id.
|
||||
*
|
||||
* @return string A store id.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function getStoreId($id = '')
|
||||
{
|
||||
// Compile the store id.
|
||||
$id .= ':' . $this->getState('filter.tour_id');
|
||||
$id .= ':' . $this->getState('filter.search');
|
||||
$id .= ':' . $this->getState('filter.published');
|
||||
|
||||
return parent::getStoreId($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an SQL query to load the list data.
|
||||
*
|
||||
* @return \Joomla\Database\DatabaseQuery
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function getListQuery()
|
||||
{
|
||||
// Create a new query object.
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
// Select the required fields from the table.
|
||||
$query->select(
|
||||
$this->getState(
|
||||
'list.select',
|
||||
'a.*'
|
||||
)
|
||||
);
|
||||
|
||||
$query->from($db->quoteName('#__guidedtour_steps', 'a'));
|
||||
|
||||
// Join with user table
|
||||
$query->select(
|
||||
[
|
||||
$db->quoteName('uc.name', 'editor'),
|
||||
]
|
||||
)
|
||||
->join('LEFT', $db->quoteName('#__users', 'uc'), $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out'));
|
||||
|
||||
$tourId = $this->getState('filter.tour_id');
|
||||
|
||||
if (is_numeric($tourId)) {
|
||||
$tourId = (int) $tourId;
|
||||
$query->where($db->quoteName('a.tour_id') . ' = :tour_id')
|
||||
->bind(':tour_id', $tourId, ParameterType::INTEGER);
|
||||
} elseif (\is_array($tourId)) {
|
||||
$tourId = ArrayHelper::toInteger($tourId);
|
||||
$query->whereIn($db->quoteName('a.tour_id'), $tourId);
|
||||
}
|
||||
|
||||
// Published state
|
||||
$published = (string) $this->getState('filter.published');
|
||||
|
||||
if (is_numeric($published)) {
|
||||
$query->where($db->quoteName('a.published') . ' = :published');
|
||||
$query->bind(':published', $published, ParameterType::INTEGER);
|
||||
} elseif ($published === '') {
|
||||
$query->where('(' . $db->quoteName('a.published') . ' = 0 OR ' . $db->quoteName('a.published') . ' = 1)');
|
||||
}
|
||||
|
||||
// Filter by search in title.
|
||||
$search = $this->getState('filter.search');
|
||||
|
||||
if (!empty($search)) {
|
||||
if (stripos($search, 'id:') === 0) {
|
||||
$search = (int) substr($search, 3);
|
||||
$query->where($db->quoteName('a.id') . ' = :search')
|
||||
->bind(':search', $search, ParameterType::INTEGER);
|
||||
} elseif (stripos($search, 'description:') === 0) {
|
||||
$search = '%' . substr($search, 12) . '%';
|
||||
$query->where('(' . $db->quoteName('a.description') . ' LIKE :search1)')
|
||||
->bind([':search1'], $search);
|
||||
} else {
|
||||
$search = '%' . str_replace(' ', '%', trim($search)) . '%';
|
||||
$query->where(
|
||||
'(' . $db->quoteName('a.title') . ' LIKE :search1'
|
||||
. ' OR ' . $db->quoteName('a.description') . ' LIKE :search2'
|
||||
. ' OR ' . $db->quoteName('a.note') . ' LIKE :search3)'
|
||||
)
|
||||
->bind([':search1', ':search2', ':search3'], $search);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the list ordering clause.
|
||||
$orderCol = $this->state->get('list.ordering', 'a.ordering');
|
||||
$orderDirn = $this->state->get('list.direction', 'ASC');
|
||||
|
||||
$query->order($db->escape($orderCol) . ' ' . $db->escape($orderDirn));
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get an array of data items.
|
||||
*
|
||||
* @return mixed An array of data items on success, false on failure.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function getItems()
|
||||
{
|
||||
$items = parent::getItems();
|
||||
|
||||
$tourLanguageLoaded = false;
|
||||
foreach ($items as $item) {
|
||||
if (!$tourLanguageLoaded) {
|
||||
$app = Factory::getApplication();
|
||||
$tourId = $item->tour_id;
|
||||
|
||||
/** @var \Joomla\Component\Guidedtours\Administrator\Model\TourModel $tourModel */
|
||||
$tourModel = $app->bootComponent('com_guidedtours')
|
||||
->getMVCFactory()->createModel('Tour', 'Administrator', [ 'ignore_request' => true ]);
|
||||
|
||||
$tour = $tourModel->getItem($tourId);
|
||||
|
||||
GuidedtoursHelper::loadTranslationFiles($tour->uid, true);
|
||||
|
||||
$tourLanguageLoaded = true;
|
||||
}
|
||||
|
||||
$item->title = Text::_($item->title);
|
||||
$item->description = Text::_($item->description);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
}
|
||||
500
administrator/components/com_guidedtours/src/Model/TourModel.php
Normal file
500
administrator/components/com_guidedtours/src/Model/TourModel.php
Normal file
@ -0,0 +1,500 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\Model;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Log\Log;
|
||||
use Joomla\CMS\MVC\Model\AdminModel;
|
||||
use Joomla\CMS\Object\CMSObject;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\Component\Guidedtours\Administrator\Helper\GuidedtoursHelper;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Registry\Registry;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Model class for tour
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class TourModel extends AdminModel
|
||||
{
|
||||
/**
|
||||
* The prefix to use with controller messages.
|
||||
*
|
||||
* @var string
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected $text_prefix = 'COM_GUIDEDTOURS';
|
||||
|
||||
/**
|
||||
* Type alias for content type
|
||||
*
|
||||
* @var string
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public $typeAlias = 'com_guidedtours.tour';
|
||||
|
||||
/**
|
||||
* Method to save the form data.
|
||||
*
|
||||
* @param array $data The form data.
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function save($data)
|
||||
{
|
||||
$input = Factory::getApplication()->getInput();
|
||||
|
||||
// Language keys must include GUIDEDTOUR to prevent save issues
|
||||
if (strpos($data['description'], 'GUIDEDTOUR') !== false) {
|
||||
$data['description'] = strip_tags($data['description']);
|
||||
}
|
||||
|
||||
if ($input->get('task') == 'save2copy') {
|
||||
$origTable = clone $this->getTable();
|
||||
$origTable->load($input->getInt('id'));
|
||||
|
||||
$data['published'] = 0;
|
||||
}
|
||||
|
||||
// Set step language to parent tour language on save.
|
||||
$id = $data['id'];
|
||||
$lang = $data['language'];
|
||||
|
||||
$this->setStepsLanguage($id, $lang);
|
||||
|
||||
return parent::save($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare and sanitise the table prior to saving.
|
||||
*
|
||||
* @param \Joomla\CMS\Table\Table $table The Table object
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function prepareTable($table)
|
||||
{
|
||||
$date = Factory::getDate()->toSql();
|
||||
|
||||
$table->title = htmlspecialchars_decode($table->title, ENT_QUOTES);
|
||||
|
||||
if (empty($table->id)) {
|
||||
// Set the values
|
||||
$table->created = $date;
|
||||
|
||||
// Set ordering to the last item if not set
|
||||
if (empty($table->ordering)) {
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true)
|
||||
->select('MAX(ordering)')
|
||||
->from($db->quoteName('#__guidedtours'));
|
||||
$db->setQuery($query);
|
||||
$max = $db->loadResult();
|
||||
|
||||
$table->ordering = $max + 1;
|
||||
}
|
||||
} else {
|
||||
// Set the values
|
||||
$table->modified = $date;
|
||||
$table->modified_by = $this->getCurrentUser()->id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method for getting the form from the model.
|
||||
*
|
||||
* @param array $data Data for the form.
|
||||
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
|
||||
*
|
||||
* @return \JForm|boolean A JForm object on success, false on failure
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function getForm($data = [], $loadData = true)
|
||||
{
|
||||
// Get the form.
|
||||
$form = $this->loadForm(
|
||||
'com_guidedtours.tour',
|
||||
'tour',
|
||||
[
|
||||
'control' => 'jform',
|
||||
'load_data' => $loadData,
|
||||
]
|
||||
);
|
||||
|
||||
if (empty($form)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$id = $data['id'] ?? $form->getValue('id');
|
||||
|
||||
$item = $this->getItem($id);
|
||||
|
||||
// Modify the form based on access controls.
|
||||
if (!$this->canEditState((object) $item)) {
|
||||
$form->setFieldAttribute('published', 'disabled', 'true');
|
||||
$form->setFieldAttribute('published', 'required', 'false');
|
||||
$form->setFieldAttribute('published', 'filter', 'unset');
|
||||
}
|
||||
|
||||
$currentDate = Factory::getDate()->toSql();
|
||||
|
||||
$form->setFieldAttribute('created', 'default', $currentDate);
|
||||
$form->setFieldAttribute('modified', 'default', $currentDate);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the data that should be injected in the form.
|
||||
*
|
||||
* @return mixed The data for the form.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function loadFormData()
|
||||
{
|
||||
// Check the session for previously entered form data.
|
||||
$data = Factory::getApplication()->getUserState(
|
||||
'com_guidedtours.edit.tour.data',
|
||||
[]
|
||||
);
|
||||
|
||||
if (empty($data)) {
|
||||
$data = $this->getItem();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a single record by id or uid
|
||||
*
|
||||
* @param integer|string $pk The id or uid of the tour.
|
||||
*
|
||||
* @return CMSObject|boolean Object on success, false on failure.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function getItem($pk = null)
|
||||
{
|
||||
$pk = (!empty($pk)) ? $pk : (int) $this->getState($this->getName() . '.id');
|
||||
|
||||
$table = $this->getTable();
|
||||
if (\is_integer($pk)) {
|
||||
$result = $table->load((int) $pk);
|
||||
} else {
|
||||
// Attempt to load the row by uid.
|
||||
$result = $table->load([ 'uid' => $pk ]);
|
||||
}
|
||||
|
||||
// Check for a table object error.
|
||||
if ($result === false) {
|
||||
// If there was no underlying error, then the false means there simply was not a row in the db for this $pk.
|
||||
if (!$table->getError()) {
|
||||
$this->setError(Text::_('JLIB_APPLICATION_ERROR_NOT_EXIST'));
|
||||
} else {
|
||||
$this->setError($table->getError());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert to the CMSObject before adding other data.
|
||||
$properties = $table->getProperties(1);
|
||||
$item = ArrayHelper::toObject($properties, CMSObject::class);
|
||||
|
||||
if (property_exists($item, 'params')) {
|
||||
$registry = new Registry($item->params);
|
||||
$item->params = $registry->toArray();
|
||||
}
|
||||
|
||||
if (!empty($item->uid)) {
|
||||
GuidedtoursHelper::loadTranslationFiles($item->uid, true);
|
||||
}
|
||||
|
||||
if (!empty($item->id)) {
|
||||
$item->title_translation = Text::_($item->title);
|
||||
$item->description_translation = Text::_($item->description);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all steps if a tour is deleted
|
||||
*
|
||||
* @param object $pks The primary key related to the tours.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function delete(&$pks)
|
||||
{
|
||||
$pks = ArrayHelper::toInteger((array) $pks);
|
||||
$table = $this->getTable();
|
||||
|
||||
// Include the plugins for the delete events.
|
||||
PluginHelper::importPlugin($this->events_map['delete']);
|
||||
|
||||
// Iterate the items to delete each one.
|
||||
foreach ($pks as $i => $pk) {
|
||||
if ($table->load($pk)) {
|
||||
if ($this->canDelete($table)) {
|
||||
$context = $this->option . '.' . $this->name;
|
||||
|
||||
// Trigger the before delete event.
|
||||
$result = Factory::getApplication()->triggerEvent($this->event_before_delete, [$context, $table]);
|
||||
|
||||
if (\in_array(false, $result, true)) {
|
||||
$this->setError($table->getError());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$tourId = $table->id;
|
||||
|
||||
if (!$table->delete($pk)) {
|
||||
$this->setError($table->getError());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Delete of the tour has been successful, now delete the steps
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true)
|
||||
->delete($db->quoteName('#__guidedtour_steps'))
|
||||
->where($db->quoteName('tour_id') . '=' . $tourId);
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
|
||||
// Trigger the after event.
|
||||
Factory::getApplication()->triggerEvent($this->event_after_delete, [$context, $table]);
|
||||
} else {
|
||||
// Prune items that you can't change.
|
||||
unset($pks[$i]);
|
||||
$error = $this->getError();
|
||||
|
||||
if ($error) {
|
||||
Log::add($error, Log::WARNING, 'jerror');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Log::add(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), Log::WARNING, 'jerror');
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->setError($table->getError());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the component's cache
|
||||
$this->cleanCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate all steps if a tour is duplicated
|
||||
*
|
||||
* @param object $pks The primary key related to the tours.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function duplicate(&$pks)
|
||||
{
|
||||
$user = $this->getCurrentUser();
|
||||
$db = $this->getDatabase();
|
||||
|
||||
// Access checks.
|
||||
if (!$user->authorise('core.create', 'com_guidedtours')) {
|
||||
throw new \Exception(Text::_('JERROR_CORE_CREATE_NOT_PERMITTED'));
|
||||
}
|
||||
|
||||
$table = $this->getTable();
|
||||
|
||||
$date = Factory::getDate()->toSql();
|
||||
|
||||
foreach ($pks as $pk) {
|
||||
if ($table->load($pk, true)) {
|
||||
// Reset the id to create a new record.
|
||||
$table->id = 0;
|
||||
|
||||
$table->published = 0;
|
||||
|
||||
if (!$table->check() || !$table->store()) {
|
||||
throw new \Exception($table->getError());
|
||||
}
|
||||
|
||||
$pk = (int) $pk;
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select(
|
||||
$db->quoteName(
|
||||
[
|
||||
'title',
|
||||
'description',
|
||||
'ordering',
|
||||
'position',
|
||||
'target',
|
||||
'type',
|
||||
'interactive_type',
|
||||
'url',
|
||||
'created',
|
||||
'modified',
|
||||
'checked_out_time',
|
||||
'checked_out',
|
||||
'language',
|
||||
'note',
|
||||
]
|
||||
)
|
||||
)
|
||||
->from($db->quoteName('#__guidedtour_steps'))
|
||||
->where($db->quoteName('tour_id') . ' = :id')
|
||||
->bind(':id', $pk, ParameterType::INTEGER);
|
||||
|
||||
$db->setQuery($query);
|
||||
$rows = $db->loadObjectList();
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->insert($db->quoteName('#__guidedtour_steps'))
|
||||
->columns(
|
||||
[
|
||||
$db->quoteName('tour_id'),
|
||||
$db->quoteName('title'),
|
||||
$db->quoteName('description'),
|
||||
$db->quoteName('ordering'),
|
||||
$db->quoteName('position'),
|
||||
$db->quoteName('target'),
|
||||
$db->quoteName('type'),
|
||||
$db->quoteName('interactive_type'),
|
||||
$db->quoteName('url'),
|
||||
$db->quoteName('created'),
|
||||
$db->quoteName('created_by'),
|
||||
$db->quoteName('modified'),
|
||||
$db->quoteName('modified_by'),
|
||||
$db->quoteName('language'),
|
||||
$db->quoteName('note'),
|
||||
]
|
||||
);
|
||||
|
||||
foreach ($rows as $step) {
|
||||
$dataTypes = [
|
||||
ParameterType::INTEGER,
|
||||
ParameterType::STRING,
|
||||
ParameterType::STRING,
|
||||
ParameterType::INTEGER,
|
||||
ParameterType::STRING,
|
||||
ParameterType::STRING,
|
||||
ParameterType::INTEGER,
|
||||
ParameterType::INTEGER,
|
||||
ParameterType::STRING,
|
||||
ParameterType::STRING,
|
||||
ParameterType::INTEGER,
|
||||
ParameterType::STRING,
|
||||
ParameterType::INTEGER,
|
||||
ParameterType::STRING,
|
||||
ParameterType::STRING,
|
||||
];
|
||||
|
||||
$query->values(
|
||||
implode(
|
||||
',',
|
||||
$query->bindArray(
|
||||
[
|
||||
$table->id,
|
||||
$step->title,
|
||||
$step->description,
|
||||
$step->ordering,
|
||||
$step->position,
|
||||
$step->target,
|
||||
$step->type,
|
||||
$step->interactive_type,
|
||||
$step->url,
|
||||
$date,
|
||||
$user->id,
|
||||
$date,
|
||||
$user->id,
|
||||
$step->language,
|
||||
$step->note,
|
||||
],
|
||||
$dataTypes
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
$db->execute();
|
||||
} catch (\RuntimeException $e) {
|
||||
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
throw new \Exception($table->getError());
|
||||
}
|
||||
}
|
||||
|
||||
// Clear tours cache
|
||||
$this->cleanCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a tour's steps language
|
||||
*
|
||||
* @param int $id Id of a tour
|
||||
* @param string $language The language to apply to the steps belong the tour
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function setStepsLanguage(int $id, string $language = '*'): bool
|
||||
{
|
||||
if ($id <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true)
|
||||
->update($db->quoteName('#__guidedtour_steps'))
|
||||
->set($db->quoteName('language') . ' = :language')
|
||||
->where($db->quoteName('tour_id') . ' = :tourId')
|
||||
->bind(':language', $language)
|
||||
->bind(':tourId', $id, ParameterType::INTEGER);
|
||||
|
||||
return $db->setQuery($query)
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,264 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\Model;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Model\ListModel;
|
||||
use Joomla\Component\Guidedtours\Administrator\Helper\GuidedtoursHelper;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Registry\Registry;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Model class for Tours
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class ToursModel extends ListModel
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config An optional associative array of configuration settings.
|
||||
*
|
||||
* @see JController
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function __construct($config = [])
|
||||
{
|
||||
if (empty($config['filter_fields'])) {
|
||||
$config['filter_fields'] = [
|
||||
'id', 'a.id',
|
||||
'title', 'a.title',
|
||||
'access', 'a.access', 'access_level',
|
||||
'description', 'a.description',
|
||||
'published', 'a.published',
|
||||
'language', 'a.language',
|
||||
'ordering', 'a.ordering',
|
||||
'extensions', 'a.extensions',
|
||||
'created_by', 'a.created_by',
|
||||
'modified', 'a.modified',
|
||||
'modified_by', 'a.modified_by',
|
||||
'note', 'a.note',
|
||||
];
|
||||
}
|
||||
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* This method should only be called once per instantiation and is designed
|
||||
* to be called on the first call to the getState() method unless the model
|
||||
* configuration flag to ignore the request is set.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @param string $ordering An optional ordering field.
|
||||
* @param string $direction An optional direction (asc|desc).
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function populateState($ordering = 'a.ordering', $direction = 'ASC')
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
$extension = $app->getUserStateFromRequest($this->context . '.filter.extension', 'extension', null, 'cmd');
|
||||
|
||||
$this->setState('filter.extension', $extension);
|
||||
|
||||
parent::populateState($ordering, $direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filter form
|
||||
*
|
||||
* @param array $data data
|
||||
* @param boolean $loadData load current data
|
||||
*
|
||||
* @return \JForm|false the JForm object or false
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function getFilterForm($data = [], $loadData = true)
|
||||
{
|
||||
$form = parent::getFilterForm($data, $loadData);
|
||||
|
||||
if ($form) {
|
||||
$form->setValue('extension', null, $this->getState('filter.extension'));
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
/**
|
||||
* Method to get the data that should be injected in the form.
|
||||
*
|
||||
* @return string The query to database.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function getListQuery()
|
||||
{
|
||||
// Create a new query object.
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
// Select the required fields from the table.
|
||||
$query->select(
|
||||
$this->getState(
|
||||
'list.select',
|
||||
'a.*'
|
||||
)
|
||||
);
|
||||
|
||||
$subQuery = $db->getQuery(true)
|
||||
->select('COUNT(' . $db->quoteName('s.id') . ')')
|
||||
->from($db->quoteName('#__guidedtour_steps', 's'))
|
||||
->where(
|
||||
[
|
||||
$db->quoteName('s.tour_id') . ' = ' . $db->quoteName('a.id'),
|
||||
$db->quoteName('s.published') . ' = 1',
|
||||
]
|
||||
);
|
||||
|
||||
$query->select('(' . $subQuery . ') AS ' . $db->quoteName('steps_count'))
|
||||
->from($db->quoteName('#__guidedtours', 'a'));
|
||||
|
||||
// Join with user table
|
||||
$query->select(
|
||||
[
|
||||
$db->quoteName('uc.name', 'editor'),
|
||||
]
|
||||
)
|
||||
->join('LEFT', $db->quoteName('#__users', 'uc'), $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out'));
|
||||
|
||||
// Join with language table
|
||||
$query->select(
|
||||
[
|
||||
$db->quoteName('l.title', 'language_title'),
|
||||
$db->quoteName('l.image', 'language_image'),
|
||||
]
|
||||
)
|
||||
->join('LEFT', $db->quoteName('#__languages', 'l'), $db->quoteName('l.lang_code') . ' = ' . $db->quoteName('a.language'));
|
||||
|
||||
// Join access table
|
||||
$query->select(
|
||||
[
|
||||
$db->quoteName('ag.title', 'access_level'),
|
||||
]
|
||||
)
|
||||
->join('LEFT', $db->quoteName('#__viewlevels', 'ag'), $db->quoteName('ag.id') . ' = ' . $db->quoteName('a.access'));
|
||||
|
||||
// Filter by extension
|
||||
if ($extension = $this->getState('filter.extension')) {
|
||||
$extension = '%' . $extension . '%';
|
||||
$all = '%*%';
|
||||
$query->where(
|
||||
'(' . $db->quoteName('a.extensions') . ' LIKE :all OR ' .
|
||||
$db->quoteName('a.extensions') . ' LIKE :extensions)'
|
||||
)
|
||||
->bind([':all'], $all)
|
||||
->bind([':extensions'], $extension);
|
||||
}
|
||||
|
||||
$status = (string) $this->getState('filter.published');
|
||||
|
||||
// Filter by status
|
||||
if (is_numeric($status)) {
|
||||
$status = (int) $status;
|
||||
$query->where($db->quoteName('a.published') . ' = :published')
|
||||
->bind(':published', $status, ParameterType::INTEGER);
|
||||
} elseif ($status === '') {
|
||||
$query->where($db->quoteName('a.published') . ' IN (0, 1)');
|
||||
}
|
||||
|
||||
// Filter by access level.
|
||||
$access = $this->getState('filter.access');
|
||||
|
||||
if (is_numeric($access)) {
|
||||
$access = (int) $access;
|
||||
$query->where($db->quoteName('a.access') . ' = :access')
|
||||
->bind(':access', $access, ParameterType::INTEGER);
|
||||
} elseif (\is_array($access)) {
|
||||
$access = ArrayHelper::toInteger($access);
|
||||
$query->whereIn($db->quoteName('a.access'), $access);
|
||||
}
|
||||
|
||||
// Filter on the language, or all.
|
||||
if ($language = $this->getState('filter.language')) {
|
||||
$language = (array) $language;
|
||||
|
||||
$query->whereIn($db->quoteName('a.language'), $language, ParameterType::STRING);
|
||||
}
|
||||
|
||||
// Filter by search in title.
|
||||
$search = $this->getState('filter.search');
|
||||
|
||||
if (!empty($search)) {
|
||||
if (stripos($search, 'id:') === 0) {
|
||||
$search = (int) substr($search, 3);
|
||||
$query->where($db->quoteName('a.id') . ' = :search')
|
||||
->bind(':search', $search, ParameterType::INTEGER);
|
||||
} elseif (stripos($search, 'description:') === 0) {
|
||||
$search = '%' . substr($search, 12) . '%';
|
||||
$query->where('(' . $db->quoteName('a.description') . ' LIKE :search1)')
|
||||
->bind([':search1'], $search);
|
||||
} else {
|
||||
$search = '%' . str_replace(' ', '%', trim($search)) . '%';
|
||||
$query->where(
|
||||
'(' . $db->quoteName('a.title') . ' LIKE :search1'
|
||||
. ' OR ' . $db->quoteName('a.description') . ' LIKE :search2'
|
||||
. ' OR ' . $db->quoteName('a.note') . ' LIKE :search3)'
|
||||
)
|
||||
->bind([':search1', ':search2', ':search3'], $search);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the list ordering clause.
|
||||
$orderCol = $this->state->get('list.ordering', 'a.ordering');
|
||||
$orderDirn = strtoupper($this->state->get('list.direction', 'ASC'));
|
||||
|
||||
$query->order($db->escape($orderCol) . ' ' . ($orderDirn === 'DESC' ? 'DESC' : 'ASC'));
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get an array of data items.
|
||||
*
|
||||
* @return mixed An array of data items on success, false on failure.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function getItems()
|
||||
{
|
||||
$items = parent::getItems();
|
||||
|
||||
foreach ($items as & $item) {
|
||||
if (!empty($item->uid)) {
|
||||
GuidedtoursHelper::loadTranslationFiles($item->uid, false);
|
||||
}
|
||||
$item->title = Text::_($item->title);
|
||||
$item->description = Text::_($item->description);
|
||||
$item->extensions = (new Registry($item->extensions))->toArray();
|
||||
}
|
||||
unset($item);
|
||||
|
||||
return $items;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\Table;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Table\Table;
|
||||
use Joomla\CMS\User\CurrentUserInterface;
|
||||
use Joomla\CMS\User\CurrentUserTrait;
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Step table class.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class StepTable extends Table implements CurrentUserInterface
|
||||
{
|
||||
use CurrentUserTrait;
|
||||
|
||||
/**
|
||||
* Indicates that columns fully support the NULL value in the database
|
||||
*
|
||||
* @var boolean
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected $_supportNullValue = true;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param DatabaseDriver $db Database connector object
|
||||
* @param ?DispatcherInterface $dispatcher Event dispatcher for this table
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db, DispatcherInterface $dispatcher = null)
|
||||
{
|
||||
parent::__construct('#__guidedtour_steps', 'id', $db, $dispatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a step.
|
||||
*
|
||||
* @param boolean $updateNulls True to update fields even if they are null.
|
||||
*
|
||||
* @return boolean True on success, false on failure.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function store($updateNulls = true)
|
||||
{
|
||||
$date = Factory::getDate()->toSql();
|
||||
$userId = $this->getCurrentUser()->id;
|
||||
|
||||
// Set created date if not set.
|
||||
if (!(int) $this->created) {
|
||||
$this->created = $date;
|
||||
}
|
||||
|
||||
if ($this->id) {
|
||||
// Existing item
|
||||
$this->modified_by = $userId;
|
||||
$this->modified = $date;
|
||||
} else {
|
||||
// Field created_by field can be set by the user, so we don't touch it if it's set.
|
||||
if (empty($this->created_by)) {
|
||||
$this->created_by = $userId;
|
||||
}
|
||||
|
||||
if (!(int) $this->modified) {
|
||||
$this->modified = $date;
|
||||
}
|
||||
|
||||
if (empty($this->modified_by)) {
|
||||
$this->modified_by = $userId;
|
||||
}
|
||||
}
|
||||
|
||||
return parent::store($updateNulls);
|
||||
}
|
||||
}
|
||||
193
administrator/components/com_guidedtours/src/Table/TourTable.php
Normal file
193
administrator/components/com_guidedtours/src/Table/TourTable.php
Normal file
@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\Table;
|
||||
|
||||
use Joomla\CMS\Application\ApplicationHelper;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Table\Table;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
use Joomla\CMS\User\CurrentUserInterface;
|
||||
use Joomla\CMS\User\CurrentUserTrait;
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
use Joomla\String\StringHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Tours table class.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class TourTable extends Table implements CurrentUserInterface
|
||||
{
|
||||
use CurrentUserTrait;
|
||||
|
||||
/**
|
||||
* Indicates that columns fully support the NULL value in the database
|
||||
*
|
||||
* @var boolean
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected $_supportNullValue = true;
|
||||
|
||||
/**
|
||||
* An array of key names to be json encoded in the bind function
|
||||
*
|
||||
* @var array
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected $_jsonEncode = ['extensions'];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param DatabaseDriver $db Database connector object
|
||||
* @param ?DispatcherInterface $dispatcher Event dispatcher for this table
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db, DispatcherInterface $dispatcher = null)
|
||||
{
|
||||
parent::__construct('#__guidedtours', 'id', $db, $dispatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a tour.
|
||||
*
|
||||
* @param boolean $updateNulls True to update extensions even if they are null.
|
||||
*
|
||||
* @return boolean True on success, false on failure.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function store($updateNulls = true)
|
||||
{
|
||||
$date = Factory::getDate()->toSql();
|
||||
$userId = $this->getCurrentUser()->id;
|
||||
|
||||
// Set created date if not set.
|
||||
if (!(int) $this->created) {
|
||||
$this->created = $date;
|
||||
}
|
||||
|
||||
if ($this->id) {
|
||||
// Existing item
|
||||
$this->modified_by = $userId;
|
||||
$this->modified = $date;
|
||||
} else {
|
||||
// Field created_by field can be set by the user, so we don't touch it if it's set.
|
||||
if (empty($this->created_by)) {
|
||||
$this->created_by = $userId;
|
||||
}
|
||||
|
||||
if (!(int) $this->modified) {
|
||||
$this->modified = $date;
|
||||
}
|
||||
|
||||
if (empty($this->modified_by)) {
|
||||
$this->modified_by = $userId;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->extensions)) {
|
||||
$this->extensions = ["*"];
|
||||
}
|
||||
|
||||
// set missing Uid
|
||||
if (empty($this->uid)) {
|
||||
$this->setTourUid();
|
||||
}
|
||||
|
||||
// make sure the uid is unique
|
||||
$this->ensureUniqueUid();
|
||||
|
||||
return parent::store($updateNulls);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to set the uid when empty
|
||||
*
|
||||
* @return string $uid Contains the non-empty uid.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*/
|
||||
protected function setTourUid()
|
||||
{
|
||||
// Tour follows Joomla naming convention
|
||||
if (str_starts_with($this->title, 'COM_GUIDEDTOURS_TOUR_') && str_ends_with($this->title, '_TITLE')) {
|
||||
$uidTitle = 'joomla_' . str_replace('COM_GUIDEDTOURS_TOUR_', '', $this->title);
|
||||
|
||||
// Remove the last _TITLE part
|
||||
$pos = strrpos($uidTitle, "_TITLE");
|
||||
if ($pos !== false) {
|
||||
$uidTitle = substr($uidTitle, 0, $pos);
|
||||
}
|
||||
} elseif (preg_match('#COM_(\w+)_TOUR_#', $this->title) && str_ends_with($this->title, '_TITLE')) {
|
||||
// Tour follows component naming pattern
|
||||
$uidTitle = preg_replace('#COM_(\w+)_TOUR_#', '$1.', $this->title);
|
||||
|
||||
// Remove the last _TITLE part
|
||||
$pos = strrpos($uidTitle, "_TITLE");
|
||||
if ($pos !== false) {
|
||||
$uidTitle = substr($uidTitle, 0, $pos);
|
||||
}
|
||||
} else {
|
||||
$uri = Uri::getInstance();
|
||||
$host = $uri->toString(['host']);
|
||||
$host = ApplicationHelper::stringURLSafe($host, $this->language);
|
||||
$uidTitle = $host . ' ' . str_replace('COM_GUIDEDTOURS_TOUR_', '', $this->title);
|
||||
// Remove the last _TITLE part
|
||||
if (str_ends_with($uidTitle, '_TITLE')) {
|
||||
$pos = strrpos($uidTitle, '_TITLE');
|
||||
$uidTitle = substr($uidTitle, 0, $pos);
|
||||
}
|
||||
}
|
||||
// ApplicationHelper::stringURLSafe will replace a period (.) separator so we split the construction into multiple parts
|
||||
$uidTitleParts = explode('.', $uidTitle);
|
||||
array_walk($uidTitleParts, function (&$value, $key, $tourLanguage) {
|
||||
$value = ApplicationHelper::stringURLSafe($value, $tourLanguage);
|
||||
}, $this->language);
|
||||
$this->uid = implode('.', $uidTitleParts);
|
||||
|
||||
$this->store();
|
||||
|
||||
return $this->uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to change the uid when not unique.
|
||||
*
|
||||
* @return string $uid Contains the modified uid.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*/
|
||||
protected function ensureUniqueUid()
|
||||
{
|
||||
$table = new TourTable($this->_db);
|
||||
$unique = false;
|
||||
// Alter the title & uid
|
||||
while (!$unique) {
|
||||
// Attempt to load the row by uid.
|
||||
$uidItem = $table->load([ 'uid' => $this->uid ]);
|
||||
if ($uidItem && $table->id > 0 && $table->id != $this->id) {
|
||||
$this->uid = StringHelper::increment($this->uid, 'dash');
|
||||
} else {
|
||||
$unique = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->uid;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\View\Step;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Helper\ContentHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* View to edit an Step
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* The \JForm object
|
||||
*
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* The active item
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $item;
|
||||
|
||||
/**
|
||||
* The model state
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* The actions the user is authorised to perform
|
||||
*
|
||||
* @var \Joomla\CMS\Object\CMSObject
|
||||
*/
|
||||
protected $canDo;
|
||||
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->form = $this->get('Form');
|
||||
$this->item = $this->get('Item');
|
||||
$this->state = $this->get('State');
|
||||
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
$this->addToolbar();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the page title and toolbar.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function addToolbar()
|
||||
{
|
||||
Factory::getApplication()->getInput()->set('hidemainmenu', true);
|
||||
|
||||
$user = $this->getCurrentUser();
|
||||
$userId = $user->id;
|
||||
$isNew = empty($this->item->id);
|
||||
|
||||
$canDo = ContentHelper::getActions('com_guidedtours');
|
||||
|
||||
ToolbarHelper::title(Text::_($isNew ? 'COM_GUIDEDTOURS_MANAGER_STEP_NEW' : 'COM_GUIDEDTOURS_MANAGER_STEP_EDIT'), 'map-signs');
|
||||
|
||||
$toolbarButtons = [];
|
||||
|
||||
if ($isNew) {
|
||||
// For new records, check the create permission.
|
||||
if ($canDo->get('core.create')) {
|
||||
ToolbarHelper::apply('step.apply');
|
||||
$toolbarButtons = [['save', 'step.save'], ['save2new', 'step.save2new']];
|
||||
}
|
||||
|
||||
ToolbarHelper::saveGroup(
|
||||
$toolbarButtons,
|
||||
'btn-success'
|
||||
);
|
||||
|
||||
ToolbarHelper::cancel(
|
||||
'step.cancel'
|
||||
);
|
||||
} else {
|
||||
// Since it's an existing record, check the edit permission, or fall back to edit own if the owner.
|
||||
$itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId);
|
||||
|
||||
if ($itemEditable) {
|
||||
ToolbarHelper::apply('step.apply');
|
||||
$toolbarButtons = [['save', 'step.save']];
|
||||
|
||||
// We can save this record, but check the create permission to see if we can return to make a new one.
|
||||
if ($canDo->get('core.create')) {
|
||||
$toolbarButtons[] = ['save2new', 'step.save2new'];
|
||||
$toolbarButtons[] = ['save2copy', 'step.save2copy'];
|
||||
}
|
||||
|
||||
ToolbarHelper::saveGroup(
|
||||
$toolbarButtons,
|
||||
'btn-success'
|
||||
);
|
||||
|
||||
ToolbarHelper::cancel(
|
||||
'step.cancel',
|
||||
'JTOOLBAR_CLOSE'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ToolbarHelper::divider();
|
||||
$inlinehelp = (string) $this->form->getXml()->config->inlinehelp['button'] === 'show';
|
||||
$targetClass = (string) $this->form->getXml()->config->inlinehelp['targetclass'] ?: 'hide-aware-inline-help';
|
||||
|
||||
if ($inlinehelp) {
|
||||
ToolbarHelper::inlinehelp($targetClass);
|
||||
}
|
||||
ToolbarHelper::help('Guided_Tours:_New_or_Edit_Step');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\View\Steps;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Helper\ContentHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Toolbar\Toolbar;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* View class for a list of guidedtour_steps.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* An array of items
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $items;
|
||||
|
||||
/**
|
||||
* The pagination object
|
||||
*
|
||||
* @var \Joomla\CMS\Pagination\Pagination
|
||||
*/
|
||||
protected $pagination;
|
||||
|
||||
/**
|
||||
* The model state
|
||||
*
|
||||
* @var \Joomla\Registry\Registry
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* Form object for search filters
|
||||
*
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*/
|
||||
public $filterForm;
|
||||
|
||||
/**
|
||||
* The active search filters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $activeFilters;
|
||||
|
||||
/**
|
||||
* Is this view an Empty State
|
||||
*
|
||||
* @var boolean
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
private $isEmptyState = false;
|
||||
|
||||
/**
|
||||
* Display the view.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->items = $this->get('Items');
|
||||
$this->pagination = $this->get('Pagination');
|
||||
$this->state = $this->get('State');
|
||||
$this->filterForm = $this->get('FilterForm');
|
||||
$this->activeFilters = $this->get('ActiveFilters');
|
||||
|
||||
if (!\count($this->items) && $this->isEmptyState = $this->get('IsEmptyState')) {
|
||||
$this->setLayout('emptystate');
|
||||
}
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
if ($this->state->get('filter.tour_id', -1) < 0) {
|
||||
// This arises when you are logged out and return to the steps view after logging back in
|
||||
// We redirect back to the tour lists view
|
||||
$app = Factory::getApplication();
|
||||
$app->enqueueMessage(Text::_('COM_GUIDEDTOURS_STEPS_UNKNOWN_TOUR'), 'notice');
|
||||
$app->redirect(Route::_('index.php?option=com_guidedtours&view=tours', false), 300);
|
||||
return;
|
||||
}
|
||||
|
||||
// Unset the tour_id field from activeFilters as we don't filter by tour here.
|
||||
unset($this->activeFilters['tour_id']);
|
||||
|
||||
$this->addToolbar();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the page title and toolbar.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function addToolbar()
|
||||
{
|
||||
// Get the toolbar object instance
|
||||
$toolbar = Toolbar::getInstance('toolbar');
|
||||
|
||||
$canDo = ContentHelper::getActions('com_guidedtours');
|
||||
$app = Factory::getApplication();
|
||||
$user = $app->getIdentity();
|
||||
|
||||
/** @var \Joomla\Component\Guidedtours\Administrator\Model\TourModel $tourModel */
|
||||
$tourModel = $app->bootComponent('com_guidedtours')
|
||||
->getMVCFactory()->createModel('Tour', 'Administrator', ['ignore_request' => true]);
|
||||
|
||||
$tour = $tourModel->getItem($this->state->get('filter.tour_id', -1));
|
||||
$title = !empty($tour->title) ? $tour->title : '';
|
||||
|
||||
ToolbarHelper::title(Text::sprintf('COM_GUIDEDTOURS_STEPS_LIST', Text::_($title)), 'map-signs');
|
||||
$arrow = $this->getLanguage()->isRtl() ? 'arrow-right' : 'arrow-left';
|
||||
|
||||
ToolbarHelper::link(
|
||||
Route::_('index.php?option=com_guidedtours&view=tours'),
|
||||
'JTOOLBAR_BACK',
|
||||
$arrow
|
||||
);
|
||||
|
||||
if ($canDo->get('core.create')) {
|
||||
$toolbar->addNew('step.add');
|
||||
}
|
||||
|
||||
if (!$this->isEmptyState && $canDo->get('core.edit.state')) {
|
||||
$dropdown = $toolbar->dropdownButton('status-group')
|
||||
->text('JTOOLBAR_CHANGE_STATUS')
|
||||
->toggleSplit(false)
|
||||
->icon('icon-ellipsis-h')
|
||||
->buttonClass('btn btn-action')
|
||||
->listCheck(true);
|
||||
|
||||
$childBar = $dropdown->getChildToolbar();
|
||||
|
||||
$childBar->publish('steps.publish')->listCheck(true);
|
||||
|
||||
$childBar->unpublish('steps.unpublish')->listCheck(true);
|
||||
|
||||
$childBar->archive('steps.archive')->listCheck(true);
|
||||
|
||||
$childBar->checkin('steps.checkin')->listCheck(true);
|
||||
|
||||
if ($this->state->get('filter.published') != -2) {
|
||||
$childBar->trash('steps.trash')->listCheck(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->isEmptyState && $this->state->get('filter.published') == -2 && $canDo->get('core.delete')) {
|
||||
$toolbar->delete('steps.delete')
|
||||
->text('JTOOLBAR_EMPTY_TRASH')
|
||||
->message('JGLOBAL_CONFIRM_DELETE')
|
||||
->listCheck(true);
|
||||
}
|
||||
|
||||
if ($user->authorise('core.admin', 'com_guidedtours') || $user->authorise('core.options', 'com_guidedtours')) {
|
||||
$toolbar->preferences('com_guidedtours');
|
||||
}
|
||||
|
||||
ToolbarHelper::help('Guided_Tours:_Steps');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of fields the table can be sorted by
|
||||
*
|
||||
* @return array Array containing the field name to sort by as the key and display text as value
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function getSortFields()
|
||||
{
|
||||
return [
|
||||
'a.id' => Text::_('JGRID_HEADING_ID'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\View\Tour;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Helper\ContentHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Toolbar\Toolbar;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* View to edit an tour.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* The \JForm object
|
||||
*
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* The active item
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $item;
|
||||
|
||||
/**
|
||||
* The model state
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* The actions the user is authorised to perform
|
||||
*
|
||||
* @var \Joomla\Registry\Registry
|
||||
*/
|
||||
protected $canDo;
|
||||
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->form = $this->get('Form');
|
||||
$this->item = $this->get('Item');
|
||||
$this->state = $this->get('State');
|
||||
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
$this->addToolbar();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the page title and toolbar.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function addToolbar()
|
||||
{
|
||||
Factory::getApplication()->getInput()->set('hidemainmenu', true);
|
||||
|
||||
$user = $this->getCurrentUser();
|
||||
$userId = $user->id;
|
||||
$isNew = empty($this->item->id);
|
||||
|
||||
$canDo = ContentHelper::getActions('com_guidedtours');
|
||||
|
||||
ToolbarHelper::title(Text::_($isNew ? 'COM_GUIDEDTOURS_MANAGER_TOUR_NEW' : 'COM_GUIDEDTOURS_MANAGER_TOUR_EDIT'), 'map-signs');
|
||||
|
||||
$toolbarButtons = [];
|
||||
|
||||
if ($isNew) {
|
||||
// For new records, check the create permission.
|
||||
if ($canDo->get('core.create')) {
|
||||
ToolbarHelper::apply('tour.apply');
|
||||
$toolbarButtons = [['save', 'tour.save'], ['save2new', 'tour.save2new']];
|
||||
}
|
||||
|
||||
ToolbarHelper::saveGroup(
|
||||
$toolbarButtons,
|
||||
'btn-success'
|
||||
);
|
||||
|
||||
ToolbarHelper::cancel(
|
||||
'tour.cancel'
|
||||
);
|
||||
} else {
|
||||
// Since it's an existing record, check the edit permission, or fall back to edit own if the owner.
|
||||
$itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId);
|
||||
|
||||
if ($itemEditable) {
|
||||
ToolbarHelper::apply('tour.apply');
|
||||
$toolbarButtons = [['save', 'tour.save']];
|
||||
|
||||
// We can save this record, but check the create permission to see if we can return to make a new one.
|
||||
if ($canDo->get('core.create')) {
|
||||
$toolbarButtons[] = ['save2new', 'tour.save2new'];
|
||||
$toolbarButtons[] = ['save2copy', 'tour.save2copy'];
|
||||
}
|
||||
|
||||
ToolbarHelper::saveGroup(
|
||||
$toolbarButtons,
|
||||
'btn-success'
|
||||
);
|
||||
|
||||
ToolbarHelper::cancel(
|
||||
'tour.cancel',
|
||||
'JTOOLBAR_CLOSE'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ToolbarHelper::divider();
|
||||
|
||||
$inlinehelp = (string) $this->form->getXml()->config->inlinehelp['button'] === 'show';
|
||||
$targetClass = (string) $this->form->getXml()->config->inlinehelp['targetclass'] ?: 'hide-aware-inline-help';
|
||||
|
||||
if ($inlinehelp) {
|
||||
ToolbarHelper::inlinehelp($targetClass);
|
||||
}
|
||||
ToolbarHelper::help('Guided_Tours:_New_or_Edit_Tour');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Component\Guidedtours\Administrator\View\Tours;
|
||||
|
||||
use Joomla\CMS\Helper\ContentHelper;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Toolbar\Toolbar;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* View class for a list of guidedtours.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* An array of items
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $items;
|
||||
|
||||
/**
|
||||
* The pagination object
|
||||
*
|
||||
* @var \Joomla\CMS\Pagination\Pagination
|
||||
*/
|
||||
protected $pagination;
|
||||
|
||||
/**
|
||||
* The model state
|
||||
*
|
||||
* @var \Joomla\Registry\Registry
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* Form object for search filters
|
||||
*
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*/
|
||||
public $filterForm;
|
||||
|
||||
/**
|
||||
* The active search filters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $activeFilters;
|
||||
|
||||
/**
|
||||
* Is this view an Empty State
|
||||
*
|
||||
* @var boolean
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
private $isEmptyState = false;
|
||||
|
||||
/**
|
||||
* Display the view.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->items = $this->get('Items');
|
||||
$this->pagination = $this->get('Pagination');
|
||||
$this->state = $this->get('State');
|
||||
$this->filterForm = $this->get('FilterForm');
|
||||
$this->activeFilters = $this->get('ActiveFilters');
|
||||
|
||||
if (!\count($this->items) && $this->isEmptyState = $this->get('IsEmptyState')) {
|
||||
$this->setLayout('emptystate');
|
||||
}
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
$this->addToolbar();
|
||||
|
||||
// We do not need to filter by language when multilingual is disabled
|
||||
if (!Multilanguage::isEnabled()) {
|
||||
unset($this->activeFilters['language']);
|
||||
$this->filterForm->removeField('language', 'filter');
|
||||
}
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the page title and toolbar.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function addToolbar()
|
||||
{
|
||||
// Get the toolbar object instance
|
||||
$toolbar = Toolbar::getInstance('toolbar');
|
||||
|
||||
ToolbarHelper::title(Text::_('COM_GUIDEDTOURS_TOURS_LIST'), 'map-signs');
|
||||
|
||||
$canDo = ContentHelper::getActions('com_guidedtours');
|
||||
$user = $this->getCurrentUser();
|
||||
|
||||
if ($canDo->get('core.create')) {
|
||||
$toolbar->addNew('tour.add');
|
||||
}
|
||||
|
||||
if (!$this->isEmptyState && $canDo->get('core.edit.state')) {
|
||||
$dropdown = $toolbar->dropdownButton('status-group')
|
||||
->text('JTOOLBAR_CHANGE_STATUS')
|
||||
->toggleSplit(false)
|
||||
->icon('icon-ellipsis-h')
|
||||
->buttonClass('btn btn-action')
|
||||
->listCheck(true);
|
||||
|
||||
$childBar = $dropdown->getChildToolbar();
|
||||
|
||||
$childBar->publish('tours.publish')->listCheck(true);
|
||||
|
||||
$childBar->unpublish('tours.unpublish')->listCheck(true);
|
||||
|
||||
$childBar->archive('tours.archive')->listCheck(true);
|
||||
|
||||
$childBar->checkin('tours.checkin')->listCheck(true);
|
||||
|
||||
if ($this->state->get('filter.published') != -2) {
|
||||
$childBar->trash('tours.trash')->listCheck(true);
|
||||
}
|
||||
if ($canDo->get('core.create')) {
|
||||
$childBar->standardButton('copy')
|
||||
->text('JTOOLBAR_DUPLICATE')
|
||||
->task('tours.duplicate')
|
||||
->listCheck(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->isEmptyState && $this->state->get('filter.published') == -2 && $canDo->get('core.delete')) {
|
||||
$toolbar->delete('tours.delete')
|
||||
->text('JTOOLBAR_EMPTY_TRASH')
|
||||
->message('JGLOBAL_CONFIRM_DELETE')
|
||||
->listCheck(true);
|
||||
}
|
||||
|
||||
if ($user->authorise('core.admin', 'com_guidedtours') || $user->authorise('core.options', 'com_guidedtours')) {
|
||||
$toolbar->preferences('com_guidedtours');
|
||||
}
|
||||
|
||||
ToolbarHelper::help('Guided_Tours');
|
||||
}
|
||||
}
|
||||
103
administrator/components/com_guidedtours/tmpl/step/edit.php
Normal file
103
administrator/components/com_guidedtours/tmpl/step/edit.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('keepalive')
|
||||
->useScript('form.validate');
|
||||
|
||||
if (empty($this->item->tour_id)) {
|
||||
throw new GenericDataException("\nThe Tour id was not set!\n", 500);
|
||||
}
|
||||
|
||||
$lang = $this->getLanguage()->getTag();
|
||||
?>
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_guidedtours&view=step&layout=edit&id=' .
|
||||
(int) $this->item->id); ?>" method="post" name="adminForm" id="guidedtour-dates-form" class="form-validate">
|
||||
|
||||
<?php echo LayoutHelper::render('joomla.edit.title_alias', $this); ?>
|
||||
|
||||
<?php if ($this->item->id != 0 && strpos($this->item->title, 'GUIDEDTOUR') !== false) : ?>
|
||||
<div class="row title-alias form-vertical mb-3">
|
||||
<div class="col-12">
|
||||
<?php $this->form->setFieldAttribute('title_translation', 'label', Text::sprintf('COM_GUIDEDTOURS_STEP_TITLE_TRANSLATION', $lang)); ?>
|
||||
<?php echo $this->form->renderField('title_translation'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="main-card">
|
||||
<?php echo HTMLHelper::_('uitab.startTabSet', 'myTab', ['active' => 'details', 'recall' => true, 'breakpoint' => 768]); ?>
|
||||
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'details', empty($this->item->id) ? Text::_('COM_GUIDEDTOURS_STEP_NEW_STEP') : Text::_('COM_GUIDEDTOURS_STEP_EDIT_STEP')); ?>
|
||||
<div class="row">
|
||||
<div class="col-lg-9">
|
||||
<?php echo $this->form->renderField('description'); ?>
|
||||
|
||||
<?php if ($this->item->id != 0 && strpos($this->item->description, 'GUIDEDTOUR') !== false) : ?>
|
||||
<?php $this->form->setFieldAttribute('description_translation', 'label', Text::sprintf('COM_GUIDEDTOURS_STEP_DESCRIPTION_TRANSLATION', $lang)); ?>
|
||||
<?php echo $this->form->renderField('description_translation'); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3">
|
||||
<?php
|
||||
// Set main fields.
|
||||
$this->fields = [
|
||||
'published',
|
||||
'language',
|
||||
'position',
|
||||
'target',
|
||||
'type',
|
||||
'url',
|
||||
'interactive_type',
|
||||
'note',
|
||||
];
|
||||
|
||||
$this->hidden_fields = [
|
||||
'tour_id',
|
||||
];
|
||||
|
||||
echo LayoutHelper::render('joomla.edit.global', $this); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'publishing', Text::_('JGLOBAL_FIELDSET_PUBLISHING')); ?>
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-8">
|
||||
<fieldset id="fieldset-publishingdata" class="options-form">
|
||||
<legend><?php echo Text::_('JGLOBAL_FIELDSET_PUBLISHING'); ?></legend>
|
||||
<div>
|
||||
<?php
|
||||
$this->fields = [];
|
||||
$this->hidden_fields = [];
|
||||
echo LayoutHelper::render('joomla.edit.publishingdata', $this); ?>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
|
||||
<?php echo HTMLHelper::_('uitab.endTabSet'); ?>
|
||||
</div>
|
||||
<input type="hidden" name="task" value="">
|
||||
<?php echo $this->form->getInput('tour_id'); ?>
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
234
administrator/components/com_guidedtours/tmpl/steps/default.php
Normal file
234
administrator/components/com_guidedtours/tmpl/steps/default.php
Normal file
@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\HTML\Helpers\StringHelper;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Session\Session;
|
||||
use Joomla\Component\Guidedtours\Administrator\Extension\GuidedtoursComponent;
|
||||
use Joomla\Component\Guidedtours\Administrator\View\Steps\HtmlView;
|
||||
|
||||
/** @var HtmlView $this */
|
||||
|
||||
/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('table.columns')
|
||||
->useScript('multiselect');
|
||||
|
||||
$user = $this->getCurrentUser();
|
||||
$userId = $user->get('id');
|
||||
$listOrder = $this->escape($this->state->get('list.ordering'));
|
||||
$listDirn = $this->escape($this->state->get('list.direction'));
|
||||
$saveOrder = $listOrder == 'a.ordering';
|
||||
$section = null;
|
||||
$mode = false;
|
||||
$tourId = $this->state->get('filter.tour_id');
|
||||
|
||||
$canEdit = $user->authorise('core.edit', 'com_guidedtours');
|
||||
$canEditOwnTour = $user->authorise('core.edit.own', 'com_guidedtours');
|
||||
$canEditStateTour = $user->authorise('core.edit.state', 'com_guidedtours');
|
||||
$hasCheckinPermission = $user->authorise('core.manage', 'com_checkin');
|
||||
|
||||
if ($saveOrder && !empty($this->items)) {
|
||||
$saveOrderingUrl = 'index.php?option=com_guidedtours&task=steps.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1';
|
||||
HTMLHelper::_('draggablelist.draggable');
|
||||
}
|
||||
?>
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_guidedtours&view=steps&tour_id=' . $tourId); ?>"
|
||||
method="post" name="adminForm" id="adminForm">
|
||||
<div id="j-main-container" class="j-main-container">
|
||||
<?php
|
||||
// Search tools bar
|
||||
echo LayoutHelper::render('joomla.searchtools.default', ['view' => $this]);
|
||||
?>
|
||||
|
||||
<!-- If no steps -->
|
||||
<?php if (empty($this->items)) :
|
||||
?>
|
||||
<!-- No steps -->
|
||||
<div class="alert alert-info">
|
||||
<span class="icon-info-circle" aria-hidden="true"></span>
|
||||
<span class="visually-hidden"><?php echo Text::_('INFO'); ?></span>
|
||||
<?php echo Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- If there are steps, we start with the table -->
|
||||
<?php if (!empty($this->items)) :
|
||||
?>
|
||||
<!-- Steps table starts here -->
|
||||
<table class="table" id="stepsList">
|
||||
|
||||
<caption class="visually-hidden">
|
||||
<?php echo Text::_('COM_GUIDEDTOURS_STEPS_TABLE_CAPTION'); ?>,
|
||||
<span id="orderedBy"><?php echo Text::_('JGLOBAL_SORTED_BY'); ?></span>,
|
||||
<span id="filteredBy"><?php echo Text::_('JGLOBAL_FILTERED_BY'); ?></span>
|
||||
</caption>
|
||||
|
||||
<!-- Steps table header -->
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="w-1 text-center">
|
||||
<?php echo HTMLHelper::_('grid.checkall'); ?>
|
||||
</td>
|
||||
<!-- Ordering?-->
|
||||
<th scope="col" class="w-3 text-center d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_(
|
||||
'searchtools.sort',
|
||||
'',
|
||||
'a.ordering',
|
||||
$listDirn,
|
||||
$listOrder,
|
||||
null,
|
||||
'asc',
|
||||
'JGRID_HEADING_ORDERING',
|
||||
'icon-sort'
|
||||
); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-1 text-center">
|
||||
<?php echo HTMLHelper::_(
|
||||
'searchtools.sort',
|
||||
'JSTATUS',
|
||||
'a.published',
|
||||
$listDirn,
|
||||
$listOrder
|
||||
); ?>
|
||||
</th>
|
||||
<th scope="col">
|
||||
<?php echo Text::_('COM_GUIDEDTOURS_STEP_TITLE'); ?>
|
||||
</th>
|
||||
<th scope="col" class="d-none d-md-table-cell">
|
||||
<?php echo Text::_('COM_GUIDEDTOURS_DESCRIPTION'); ?>
|
||||
</th>
|
||||
<th scope="col" class="d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_(
|
||||
'searchtools.sort',
|
||||
'COM_GUIDEDTOURS_STEP_TYPE',
|
||||
'a.type',
|
||||
$listDirn,
|
||||
$listOrder
|
||||
); ?>
|
||||
</th>
|
||||
|
||||
<th scope="col" class="w-10 text-center d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_(
|
||||
'searchtools.sort',
|
||||
'JGRID_HEADING_ID',
|
||||
'a.id',
|
||||
$listDirn,
|
||||
$listOrder
|
||||
); ?>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<!-- Table body begins -->
|
||||
<tbody <?php if ($saveOrder) : ?>
|
||||
class="js-draggable" data-url="<?php echo $saveOrderingUrl; ?>" data-direction="<?php echo strtolower($listDirn); ?>" data-nested="true" <?php
|
||||
endif; ?>>
|
||||
<?php foreach ($this->items as $i => $item) :
|
||||
$canEditOwn = $canEditOwnTour && $item->created_by == $userId;
|
||||
$canCheckin = $hasCheckinPermission || $item->checked_out == $userId || is_null($item->checked_out);
|
||||
$canChange = $canEditStateTour && $canCheckin;
|
||||
?>
|
||||
|
||||
<!-- Row begins -->
|
||||
<tr class="row<?php echo $i % 2; ?>" data-draggable-group="none">
|
||||
<!-- Item Checkbox -->
|
||||
<td class="text-center">
|
||||
<?php echo HTMLHelper::_('grid.id', $i, $item->id, false, 'cid', 'cb', $item->title); ?>
|
||||
</td>
|
||||
|
||||
<!-- Draggable handle -->
|
||||
<td class="text-center d-none d-md-table-cell">
|
||||
<?php
|
||||
$iconClass = '';
|
||||
|
||||
if (!$canChange) {
|
||||
$iconClass = ' inactive';
|
||||
} elseif (!$saveOrder) {
|
||||
$iconClass = ' inactive" title="' . Text::_('JORDERINGDISABLED');
|
||||
}
|
||||
?>
|
||||
|
||||
<span class="sortable-handler <?php echo $iconClass; ?>">
|
||||
<span class="icon-ellipsis-v" aria-hidden="true"></span>
|
||||
</span>
|
||||
|
||||
<?php if ($canChange && $saveOrder) : ?>
|
||||
<input type="text" class="hidden text-area-order" name="order[]" size="5" value="<?php echo $item->ordering; ?>">
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
|
||||
<!-- Step State -->
|
||||
<td class="text-center">
|
||||
<?php echo HTMLHelper::_(
|
||||
'jgrid.published',
|
||||
$item->published,
|
||||
$i,
|
||||
'steps.',
|
||||
$canChange
|
||||
); ?>
|
||||
</td>
|
||||
|
||||
<!-- Step name, edit link, and note -->
|
||||
<th scope="row">
|
||||
<div>
|
||||
<?php if ($item->checked_out) : ?>
|
||||
<?php echo HTMLHelper::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'steps.', $canCheckin); ?>
|
||||
<?php endif; ?>
|
||||
<?php if ($canEdit || $canEditOwn) : ?>
|
||||
<a href="<?php echo Route::_('index.php?option=com_guidedtours&task=step.edit&id=' . $item->id); ?> " title="<?php echo Text::_('JACTION_EDIT'); ?> <?php echo $this->escape($item->title); ?>">
|
||||
<?php echo $this->escape($item->title); ?>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<?php echo $this->escape($item->title); ?>
|
||||
<?php endif; ?>
|
||||
<?php if ($item->note) : ?>
|
||||
<div class="small break-word">
|
||||
<?php echo Text::sprintf('JGLOBAL_LIST_NOTE', $this->escape($item->note)); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</th>
|
||||
<td class="d-none d-md-table-cell">
|
||||
<?php echo StringHelper::truncate($item->description, 200, true, false); ?>
|
||||
</td>
|
||||
|
||||
<!-- Step Type -->
|
||||
<td class="d-none d-md-table-cell">
|
||||
<?php echo Text::_(GuidedtoursComponent::STEP_TYPE_NAMES[$item->type]) ?>
|
||||
</td>
|
||||
|
||||
<!-- Step ID -->
|
||||
<td class="d-none d-md-table-cell text-center">
|
||||
<?php echo (int) $item->id; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php
|
||||
// Load the pagination
|
||||
echo $this->pagination->getListFooter();
|
||||
?>
|
||||
<?php endif; ?>
|
||||
|
||||
<input type="hidden" name="task" value="">
|
||||
<input type="hidden" name="boxchecked" value="0">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
</form>
|
||||
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Layout\LayoutHelper;
|
||||
|
||||
$displayData = [
|
||||
'textPrefix' => 'COM_GUIDEDTOURS_STEPS',
|
||||
'formURL' => 'index.php?option=com_guidedtours&view=steps',
|
||||
'helpURL' => 'https://docs.joomla.org/Special:MyLanguage/Help4.x:Guided_Tours:_Steps',
|
||||
'icon' => 'icon-map-signs',
|
||||
];
|
||||
|
||||
$user = $this->getCurrentUser();
|
||||
|
||||
if ($user->authorise('core.create', 'com_guidedtours')) {
|
||||
$displayData['createURL'] = 'index.php?option=com_guidedtours&task=step.add';
|
||||
}
|
||||
|
||||
echo LayoutHelper::render('joomla.content.emptystate', $displayData);
|
||||
102
administrator/components/com_guidedtours/tmpl/tour/edit.php
Normal file
102
administrator/components/com_guidedtours/tmpl/tour/edit.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
$app = Factory::getApplication();
|
||||
$user = $app->getIdentity();
|
||||
$input = $app->getInput();
|
||||
$lang = $this->getLanguage()->getTag();
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('keepalive')
|
||||
->useScript('form.validate');
|
||||
?>
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_guidedtours&view=tour&layout=edit&id=' .
|
||||
(int) $this->item->id); ?>" method="post" name="adminForm" id="guidedtours-form" class="form-validate">
|
||||
|
||||
<div class="row title-alias form-vertical mb-3">
|
||||
<div class="col-12 col-md-6">
|
||||
<?php echo $this->form->renderField('title'); ?>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<?php echo $this->form->renderField('uid'); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($this->item->id != 0 && strpos($this->item->title, 'GUIDEDTOUR') !== false) : ?>
|
||||
<div class="row title-alias form-vertical mb-3">
|
||||
<div class="col-12">
|
||||
<?php $this->form->setFieldAttribute('title_translation', 'label', Text::sprintf('COM_GUIDEDTOURS_TITLE_TRANSLATION', $lang)); ?>
|
||||
<?php echo $this->form->renderField('title_translation'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="main-card">
|
||||
<?php echo HTMLHelper::_('uitab.startTabSet', 'myTab', ['active' => 'details', 'recall' => true, 'breakpoint' => 768]); ?>
|
||||
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'details', empty($this->item->id) ? Text::_('COM_GUIDEDTOURS_NEW_TOUR') : Text::_('COM_GUIDEDTOURS_EDIT_TOUR')); ?>
|
||||
<div class="row">
|
||||
<div class="col-lg-9">
|
||||
<?php echo $this->form->renderField('url'); ?>
|
||||
<?php echo $this->form->renderField('description'); ?>
|
||||
|
||||
<?php if ($this->item->id != 0 && strpos($this->item->description, 'GUIDEDTOUR') !== false) : ?>
|
||||
<?php $this->form->setFieldAttribute('description_translation', 'label', Text::sprintf('COM_GUIDEDTOURS_DESCRIPTION_TRANSLATION', $lang)); ?>
|
||||
<?php echo $this->form->renderField('description_translation'); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3">
|
||||
<?php
|
||||
// Set main fields.
|
||||
$this->fields = [
|
||||
'published',
|
||||
'access',
|
||||
'language',
|
||||
'extensions',
|
||||
'note',
|
||||
];
|
||||
|
||||
echo LayoutHelper::render('joomla.edit.global', $this); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'publishing', Text::_('JGLOBAL_FIELDSET_PUBLISHING')); ?>
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-8">
|
||||
<fieldset id="fieldset-publishingdata" class="options-form">
|
||||
<legend><?php echo Text::_('JGLOBAL_FIELDSET_PUBLISHING'); ?></legend>
|
||||
<div>
|
||||
<?php
|
||||
$this->fields = [];
|
||||
echo LayoutHelper::render('joomla.edit.publishingdata', $this); ?>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
|
||||
<?php echo HTMLHelper::_('uitab.endTabSet'); ?>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="task" value="">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
259
administrator/components/com_guidedtours/tmpl/tours/default.php
Normal file
259
administrator/components/com_guidedtours/tmpl/tours/default.php
Normal file
@ -0,0 +1,259 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Factory;
|
||||
use Joomla\CMS\HTML\Helpers\StringHelper;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Session\Session;
|
||||
use Joomla\Component\Guidedtours\Administrator\View\Tours\HtmlView;
|
||||
|
||||
/** @var HtmlView $this */
|
||||
|
||||
/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('table.columns')
|
||||
->useScript('multiselect');
|
||||
|
||||
try {
|
||||
$app = Factory::getApplication();
|
||||
} catch (Exception $e) {
|
||||
die('Failed to get app');
|
||||
}
|
||||
|
||||
$user = $app->getIdentity();
|
||||
$userId = $user->get('id');
|
||||
$listOrder = $this->escape($this->state->get('list.ordering'));
|
||||
$listDirn = $this->escape($this->state->get('list.direction'));
|
||||
$saveOrder = $listOrder == 'a.ordering';
|
||||
$section = null;
|
||||
$mode = false;
|
||||
|
||||
$canEdit = $user->authorise('core.edit', 'com_guidedtours');
|
||||
$canEditOwnTour = $user->authorise('core.edit.own', 'com_guidedtours');
|
||||
$canEditStateTour = $user->authorise('core.edit.state', 'com_guidedtours');
|
||||
$hasCheckinPermission = $user->authorise('core.manage', 'com_checkin');
|
||||
|
||||
if ($saveOrder && !empty($this->items)) {
|
||||
$saveOrderingUrl =
|
||||
'index.php?option=com_guidedtours&task=tours.saveOrderAjax&tmpl=component&'
|
||||
. Session::getFormToken() . '=1';
|
||||
HTMLHelper::_('draggablelist.draggable');
|
||||
}
|
||||
?>
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_guidedtours&view=tours'); ?>"
|
||||
method="post" name="adminForm" id="adminForm">
|
||||
<div id="j-main-container" class="j-main-container">
|
||||
<?php
|
||||
// Search tools bar
|
||||
echo LayoutHelper::render('joomla.searchtools.default', ['view' => $this]);
|
||||
?>
|
||||
|
||||
<!-- If no tours -->
|
||||
<?php if (empty($this->items)) :
|
||||
?>
|
||||
<!-- No tours -->
|
||||
<div class="alert alert-info">
|
||||
<span class="icon-info-circle" aria-hidden="true"></span>
|
||||
<span class="visually-hidden"><?php echo Text::_('INFO'); ?></span>
|
||||
<?php echo Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- If there are tours, we start with the table -->
|
||||
<?php if (!empty($this->items)) :
|
||||
?>
|
||||
<!-- Tours table starts here -->
|
||||
<table class="table" id="toursList">
|
||||
|
||||
<caption class="visually-hidden">
|
||||
<?php echo Text::_('COM_GUIDEDTOURS_GUIDEDTOURS_TABLE_CAPTION'); ?>,
|
||||
<span id="orderedBy"><?php echo Text::_('JGLOBAL_SORTED_BY'); ?> </span>,
|
||||
<span id="filteredBy"><?php echo Text::_('JGLOBAL_FILTERED_BY'); ?></span>
|
||||
</caption>
|
||||
|
||||
<!-- Tours table header -->
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="w-1 text-center">
|
||||
<?php echo HTMLHelper::_('grid.checkall'); ?>
|
||||
</td>
|
||||
<!-- Ordering?-->
|
||||
<th scope="col" class="w-3 text-center d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_(
|
||||
'searchtools.sort',
|
||||
'',
|
||||
'a.ordering',
|
||||
$listDirn,
|
||||
$listOrder,
|
||||
null,
|
||||
'asc',
|
||||
'JGRID_HEADING_ORDERING',
|
||||
'icon-sort'
|
||||
); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-1 text-center">
|
||||
<?php echo HTMLHelper::_(
|
||||
'searchtools.sort',
|
||||
'JSTATUS',
|
||||
'a.published',
|
||||
$listDirn,
|
||||
$listOrder
|
||||
); ?>
|
||||
</th>
|
||||
|
||||
<th scope="col">
|
||||
<?php echo Text::_('COM_GUIDEDTOURS_TITLE'); ?>
|
||||
</th>
|
||||
<th scope="col" class="d-none d-md-table-cell">
|
||||
<?php echo Text::_('COM_GUIDEDTOURS_DESCRIPTION'); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-10 text-center d-none d-md-table-cell">
|
||||
<?php echo Text::_('COM_GUIDEDTOURS_STEPS'); ?>
|
||||
</th>
|
||||
<th scope="col" class="text-center w-10 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_ACCESS', 'a.access', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
|
||||
<!-- Add language types if multi-language enabled -->
|
||||
<?php if (Multilanguage::isEnabled()) : ?>
|
||||
<th scope="col" class="text-center w-10 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_LANGUAGE', 'a.language', $this->state->get('list.direction'), $this->state->get('list.ordering')); ?>
|
||||
</th>
|
||||
<?php endif; ?>
|
||||
|
||||
<th scope="col" class="w-10 text-center d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_(
|
||||
'searchtools.sort',
|
||||
'JGRID_HEADING_ID',
|
||||
'a.id',
|
||||
$listDirn,
|
||||
$listOrder
|
||||
); ?>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<!-- Table body begins -->
|
||||
<tbody <?php if ($saveOrder) : ?>
|
||||
class="js-draggable" data-url="<?php echo $saveOrderingUrl; ?>" data-direction="<?php echo strtolower($listDirn); ?>" data-nested="true" <?php
|
||||
endif; ?>>
|
||||
<?php foreach ($this->items as $i => $item) :
|
||||
$canEditOwn = $canEditOwnTour && $item->created_by == $userId;
|
||||
$canCheckin = $hasCheckinPermission || $item->checked_out == $userId || is_null($item->checked_out);
|
||||
$canChange = $canEditStateTour && $canCheckin;
|
||||
?>
|
||||
|
||||
<!-- Row begins -->
|
||||
<tr class="row<?php echo $i % 2; ?>" data-draggable-group="none">
|
||||
<!-- Item Checkbox -->
|
||||
<td class="text-center">
|
||||
<?php echo HTMLHelper::_('grid.id', $i, $item->id, false, 'cid', 'cb', $item->title); ?>
|
||||
</td>
|
||||
|
||||
<!-- Draggable handle -->
|
||||
<td class="text-center d-none d-md-table-cell">
|
||||
<?php
|
||||
$iconClass = '';
|
||||
|
||||
if (!$canChange) {
|
||||
$iconClass = ' inactive';
|
||||
} elseif (!$saveOrder) {
|
||||
$iconClass = ' inactive" title="' . Text::_('JORDERINGDISABLED');
|
||||
}
|
||||
?>
|
||||
|
||||
<span class="sortable-handler <?php echo $iconClass; ?>">
|
||||
<span class="icon-ellipsis-v" aria-hidden="true"></span>
|
||||
</span>
|
||||
|
||||
<?php if ($canChange && $saveOrder) : ?>
|
||||
<input type="text" class="hidden text-area-order" name="order[]" size="5" value="<?php echo $item->ordering; ?>">
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
|
||||
<!-- Item State -->
|
||||
<td class="text-center">
|
||||
<?php echo HTMLHelper::_(
|
||||
'jgrid.published',
|
||||
$item->published,
|
||||
$i,
|
||||
'tours.',
|
||||
$canChange
|
||||
); ?>
|
||||
</td>
|
||||
|
||||
<th scope="row" class="has-context">
|
||||
<div>
|
||||
<?php if ($item->checked_out) : ?>
|
||||
<?php echo HTMLHelper::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'tours.', $canCheckin); ?>
|
||||
<?php endif; ?>
|
||||
<?php if ($canEdit || $canEditOwn) : ?>
|
||||
<a href="<?php echo Route::_('index.php?option=com_guidedtours&task=tour.edit&id=' . $item->id); ?>" title="<?php echo Text::_('JACTION_EDIT'); ?> <?php echo $this->escape($item->title); ?>">
|
||||
<?php echo $this->escape($item->title); ?>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<?php echo $this->escape($item->title); ?>
|
||||
<?php endif; ?>
|
||||
<?php if ($item->note) : ?>
|
||||
<div class="small break-word">
|
||||
<?php echo Text::sprintf('JGLOBAL_LIST_NOTE', $this->escape($item->note)); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</th>
|
||||
|
||||
<td class="d-none d-md-table-cell">
|
||||
<?php echo StringHelper::truncate($item->description, 200, true, false); ?>
|
||||
</td>
|
||||
|
||||
<td class="text-center btns d-none d-md-table-cell itemnumber">
|
||||
<a class="btn btn-info" href="index.php?option=com_guidedtours&view=steps&tour_id=<?php echo $item->id; ?>">
|
||||
<?php echo $item->steps_count; ?>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<!-- Adds access labels -->
|
||||
<td class="small text-center d-none d-md-table-cell">
|
||||
<?php echo $this->escape($item->access_level); ?>
|
||||
</td>
|
||||
|
||||
<?php if (Multilanguage::isEnabled()) : ?>
|
||||
<td class="text-center small d-none d-md-table-cell">
|
||||
<?php echo LayoutHelper::render('joomla.content.language', $item); ?>
|
||||
</td>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Tour ID -->
|
||||
<td class="d-none d-md-table-cell text-center">
|
||||
<?php echo (int) $item->id; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php
|
||||
// Load the pagination.
|
||||
echo $this->pagination->getListFooter();
|
||||
?>
|
||||
<?php endif; ?>
|
||||
|
||||
<input type="hidden" name="task" value="">
|
||||
<input type="hidden" name="boxchecked" value="0">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
</form>
|
||||
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<layout title="COM_GUIDEDTOURS_TOURS_VIEW_DEFAULT_TITLE">
|
||||
<message>
|
||||
<![CDATA[COM_GUIDEDTOURS_TOURS_VIEW_DEFAULT_DESC]]>
|
||||
</message>
|
||||
</layout>
|
||||
</metadata>
|
||||
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_guidedtours
|
||||
*
|
||||
* @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\Layout\LayoutHelper;
|
||||
|
||||
$displayData = [
|
||||
'textPrefix' => 'COM_GUIDEDTOURS_TOURS_LIST',
|
||||
'formURL' => 'index.php?option=com_guidedtours&view=tours',
|
||||
'helpURL' => 'https://docs.joomla.org/Special:MyLanguage/Help4.x:Guided_Tours',
|
||||
'icon' => 'icon-map-signs',
|
||||
];
|
||||
|
||||
$user = $this->getCurrentUser();
|
||||
|
||||
if ($user->authorise('core.create', 'com_guidedtours')) {
|
||||
$displayData['createURL'] = 'index.php?option=com_guidedtours&task=tour.add';
|
||||
}
|
||||
|
||||
echo LayoutHelper::render('joomla.content.emptystate', $displayData);
|
||||
Reference in New Issue
Block a user