first commit

This commit is contained in:
2025-06-17 11:53:18 +02:00
commit 9f0f7ba12b
8804 changed files with 1369176 additions and 0 deletions

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<access component="com_messages">
<section name="component">
<action name="core.admin" title="JACTION_ADMIN" />
<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.state" title="JACTION_EDITSTATE" />
</section>
</access>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<config>
<help key="Messages:_Options"/>
<fieldset
name="permissions"
label="JCONFIG_PERMISSIONS_LABEL"
>
<field
name="rules"
type="rules"
label="JCONFIG_PERMISSIONS_LABEL"
filter="rules"
validate="rules"
component="com_messages"
section="component"
/>
</fieldset>
</config>

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<form>
<fieldset>
<field
name="lock"
type="radio"
label="COM_MESSAGES_FIELD_LOCK_LABEL"
layout="joomla.form.field.radio.switcher"
default="0"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="mail_on_new"
type="radio"
label="COM_MESSAGES_FIELD_MAIL_ON_NEW_LABEL"
layout="joomla.form.field.radio.switcher"
default="1"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="auto_purge"
type="number"
label="COM_MESSAGES_FIELD_AUTO_PURGE_LABEL"
filter="integer"
default="7"
/>
</fieldset>
</form>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<form addfieldprefix="Joomla\Component\Messages\Administrator\Field">
<fields name="filter">
<field
name="search"
type="text"
inputmode="search"
label="COM_MESSAGES_FILTER_SEARCH_LABEL"
description="COM_MESSAGES_SEARCH_IN_SUBJECT"
hint="JSEARCH_FILTER"
/>
<field
name="state"
type="MessageStates"
label="JSTATUS"
class="js-select-submit-on-change"
>
<option value="">JOPTION_SELECT_PUBLISHED</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.date_time DESC"
validate="options"
>
<option value="">JGLOBAL_SORT_BY</option>
<option value="a.subject ASC">COM_MESSAGES_HEADING_SUBJECT_ASC</option>
<option value="a.subject DESC">COM_MESSAGES_HEADING_SUBJECT_DESC</option>
<option value="a.state ASC">COM_MESSAGES_HEADING_READ_ASC</option>
<option value="a.state DESC">COM_MESSAGES_HEADING_READ_DESC</option>
<option value="a.user_id_from ASC">COM_MESSAGES_HEADING_FROM_ASC</option>
<option value="a.user_id_from DESC">COM_MESSAGES_HEADING_FROM_DESC</option>
<option value="a.date_time ASC">JDATE_ASC</option>
<option value="a.date_time DESC">JDATE_DESC</option>
</field>
<field
name="limit"
type="limitbox"
label="JGLOBAL_LIST_LIMIT"
default="5"
class="js-select-submit-on-change"
/>
</fields>
</form>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<form addfieldprefix="Joomla\Component\Messages\Administrator\Field">
<fieldset>
<field
name="user_id_to"
type="UserMessages"
label="COM_MESSAGES_FIELD_USER_ID_TO_LABEL"
default="0"
required="true"
/>
<field
name="subject"
type="text"
label="COM_MESSAGES_FIELD_SUBJECT_LABEL"
required="true"
/>
<field
name="message"
type="editor"
label="COM_MESSAGES_FIELD_MESSAGE_LABEL"
required="true"
filter="\Joomla\CMS\Component\ComponentHelper::filterText"
buttons="false"
/>
</fieldset>
</form>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="component" method="upgrade">
<name>com_messages</name>
<author>Joomla! Project</author>
<creationDate>2006-04</creationDate>
<copyright>(C) 2006 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>4.0.0</version>
<description>COM_MESSAGES_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Component\Messages</namespace>
<languages folder="site">
<language tag="en-GB">language/en-GB/com_messages.ini</language>
</languages>
<administration>
<files folder="admin">
<filename>access.xml</filename>
<filename>config.xml</filename>
<filename>messages.xml</filename>
<folder>forms</folder>
<folder>services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages folder="admin">
<language tag="en-GB">language/en-GB/com_messages.ini</language>
<language tag="en-GB">language/en-GB/com_messages.sys.ini</language>
</languages>
</administration>
</extension>

View File

@ -0,0 +1,54 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
\defined('_JEXEC') or die;
use Joomla\CMS\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\Messages\Administrator\Extension\MessagesComponent;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
/**
* The messages service provider.
*
* @since 4.0.0
*/
return new class () implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*
* @since 4.0.0
*/
public function register(Container $container)
{
$container->registerServiceProvider(new MVCFactory('\\Joomla\\Component\\Messages'));
$container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\Messages'));
$container->set(
ComponentInterface::class,
function (Container $container) {
$component = new MessagesComponent($container->get(ComponentDispatcherFactoryInterface::class));
$component->setMVCFactory($container->get(MVCFactoryInterface::class));
$component->setRegistry($container->get(Registry::class));
return $component;
}
);
}
};

View File

@ -0,0 +1,99 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\Controller;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Router\Route;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Messages Component Message Model
*
* @since 1.6
*/
class ConfigController extends BaseController
{
/**
* Method to save a record.
*
* @return boolean
*
* @since 1.6
*/
public function save()
{
// Check for request forgeries.
$this->checkToken();
$model = $this->getModel('Config');
$data = $this->input->post->get('jform', [], 'array');
// Validate the posted data.
$form = $model->getForm();
if (!$form) {
throw new \Exception($model->getError(), 500);
}
$data = $model->validate($form, $data);
// Check for validation errors.
if ($data === false) {
// Get the validation messages.
$errors = $model->getErrors();
// Push up to three validation messages out to the user.
for ($i = 0, $n = \count($errors); $i < $n && $i < 3; $i++) {
if ($errors[$i] instanceof \Exception) {
$this->app->enqueueMessage($errors[$i]->getMessage(), 'warning');
} else {
$this->app->enqueueMessage($errors[$i], 'warning');
}
}
// Redirect back to the main list.
$this->setRedirect(Route::_('index.php?option=com_messages&view=messages', false));
return false;
}
// Attempt to save the data.
if (!$model->save($data)) {
// Redirect back to the main list.
$this->setMessage(Text::sprintf('JERROR_SAVE_FAILED', $model->getError()), 'warning');
$this->setRedirect(Route::_('index.php?option=com_messages&view=messages', false));
return false;
}
// Redirect to the list screen.
$this->setMessage(Text::_('COM_MESSAGES_CONFIG_SAVED'));
$this->setRedirect(Route::_('index.php?option=com_messages&view=messages', false));
return true;
}
/**
* Cancel operation.
*
* @return void
*
* @since 4.0.0
*/
public function cancel()
{
$this->setRedirect(Route::_('index.php?option=com_messages&view=messages', false));
}
}

View File

@ -0,0 +1,67 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\Controller;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Router\Route;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Messages display controller.
*
* @since 1.6
*/
class DisplayController extends BaseController
{
/**
* The default view.
*
* @var string
* @since 1.6
*/
protected $default_view = 'messages';
/**
* 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 or false on failure.
*
* @since 1.5
*/
public function display($cachable = false, $urlparams = false)
{
$view = $this->input->get('view', 'messages');
$layout = $this->input->get('layout', 'default');
$id = $this->input->getInt('id');
// Check for edit form.
if ($view == 'message' && $layout == 'edit' && !$this->checkEditId('com_messages.edit.message', $id)) {
// Somehow the person just went to the form - we don't allow that.
if (!\count($this->app->getMessageQueue())) {
$this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error');
}
$this->setRedirect(Route::_('index.php?option=com_messages&view=messages', false));
return false;
}
return parent::display();
}
}

View File

@ -0,0 +1,62 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\Controller;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\FormController;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Messages Component Message Model
*
* @since 1.6
*/
class MessageController extends FormController
{
/**
* Method (override) to check if you can save a new or existing record.
*
* Adjusts for the primary key name and hands off to the parent class.
*
* @param array $data An array of input data.
* @param string $key The name of the key for the primary key.
*
* @return boolean
*
* @since 1.6
*/
protected function allowSave($data, $key = 'message_id')
{
return parent::allowSave($data, $key);
}
/**
* Reply to an existing message.
*
* This is a simple redirect to the compose form.
*
* @return void
*
* @since 1.6
*/
public function reply()
{
if ($replyId = $this->input->getInt('reply_id')) {
$this->setRedirect('index.php?option=com_messages&view=message&layout=edit&reply_id=' . $replyId);
} else {
$this->setMessage(Text::_('COM_MESSAGES_INVALID_REPLY_ID'));
$this->setRedirect('index.php?option=com_messages&view=messages');
}
}
}

View File

@ -0,0 +1,41 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\Controller;
use Joomla\CMS\MVC\Controller\AdminController;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Messages list controller class.
*
* @since 1.6
*/
class MessagesController extends AdminController
{
/**
* Method to get a model object, loading it if required.
*
* @param string $name The model name. Optional.
* @param string $prefix The class prefix. Optional.
* @param array $config Configuration array for model. Optional.
*
* @return object The model.
*
* @since 1.6
*/
public function getModel($name = 'Message', $prefix = 'Administrator', $config = ['ignore_request' => true])
{
return parent::getModel($name, $prefix, $config);
}
}

View File

@ -0,0 +1,49 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\Extension;
use Joomla\CMS\Extension\BootableExtensionInterface;
use Joomla\CMS\Extension\MVCComponent;
use Joomla\CMS\HTML\HTMLRegistryAwareTrait;
use Joomla\Component\Messages\Administrator\Service\HTML\Messages;
use Psr\Container\ContainerInterface;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Component class for com_messages
*
* @since 4.0.0
*/
class MessagesComponent extends MVCComponent implements BootableExtensionInterface
{
use HTMLRegistryAwareTrait;
/**
* 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.0.0
*/
public function boot(ContainerInterface $container)
{
$this->getRegistry()->register('messages', new Messages());
}
}

View File

@ -0,0 +1,47 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\Field;
use Joomla\CMS\Form\Field\ListField;
use Joomla\Component\Messages\Administrator\Helper\MessagesHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Message States field.
*
* @since 3.6.0
*/
class MessageStatesField extends ListField
{
/**
* The form field type.
*
* @var string
* @since 3.6.0
*/
protected $type = 'MessageStates';
/**
* Method to get the field options.
*
* @return array The field option objects.
*
* @since 3.6.0
*/
protected function getOptions()
{
// Merge state options with any additional options in the XML definition.
return array_merge(parent::getOptions(), MessagesHelper::getStateOptions());
}
}

View File

@ -0,0 +1,89 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\Field;
use Joomla\CMS\Access\Access;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Field\UserField;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Supports a modal select of users that have access to com_messages
*
* @since 1.6
*/
class UserMessagesField extends UserField
{
/**
* The form field type.
*
* @var string
* @since 1.6
*/
public $type = 'UserMessages';
/**
* Method to get the filtering groups (null means no filtering)
*
* @return array|null array of filtering groups or null.
*
* @since 1.6
*/
protected function getGroups()
{
// Compute usergroups
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select('id')
->from('#__usergroups');
$db->setQuery($query);
try {
$groups = $db->loadColumn();
} catch (\RuntimeException $e) {
Factory::getApplication()->enqueueMessage($e->getMessage(), 'notice');
return null;
}
foreach ($groups as $i => $group) {
if (Access::checkGroup($group, 'core.admin')) {
continue;
}
if (!Access::checkGroup($group, 'core.manage', 'com_messages')) {
unset($groups[$i]);
continue;
}
if (!Access::checkGroup($group, 'core.login.admin')) {
unset($groups[$i]);
}
}
return array_values($groups);
}
/**
* Method to get the users to exclude from the list of users
*
* @return array|null array of users to exclude or null to to not exclude them
*
* @since 1.6
*/
protected function getExcluded()
{
return [$this->getCurrentUser()->id];
}
}

View File

@ -0,0 +1,44 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\Helper;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Messages helper class.
*
* @since 1.6
*/
class MessagesHelper
{
/**
* Get a list of filter options for the state of a module.
*
* @return array An array of \JHtmlOption elements.
*
* @since 1.6
*/
public static function getStateOptions()
{
// Build the filter options.
$options = [];
$options[] = HTMLHelper::_('select.option', '1', Text::_('COM_MESSAGES_OPTION_READ'));
$options[] = HTMLHelper::_('select.option', '0', Text::_('COM_MESSAGES_OPTION_UNREAD'));
$options[] = HTMLHelper::_('select.option', '-2', Text::_('JTRASHED'));
return $options;
}
}

View File

@ -0,0 +1,187 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\Model;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\MVC\Model\FormModel;
use Joomla\CMS\Object\CMSObject;
use Joomla\Database\ParameterType;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Message configuration model.
*
* @since 1.6
*/
class ConfigModel extends FormModel
{
/**
* 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.
*
* @return void
*
* @since 1.6
*/
protected function populateState()
{
$user = $this->getCurrentUser();
$this->setState('user.id', $user->get('id'));
// Load the parameters.
$params = ComponentHelper::getParams('com_messages');
$this->setState('params', $params);
}
/**
* Method to get a single record.
*
* @return mixed Object on success, false on failure.
*
* @since 1.6
*/
public function &getItem()
{
$item = new CMSObject();
$userid = (int) $this->getState('user.id');
$db = $this->getDatabase();
$query = $db->getQuery(true);
$query->select(
[
$db->quoteName('cfg_name'),
$db->quoteName('cfg_value'),
]
)
->from($db->quoteName('#__messages_cfg'))
->where($db->quoteName('user_id') . ' = :userid')
->bind(':userid', $userid, ParameterType::INTEGER);
$db->setQuery($query);
try {
$rows = $db->loadObjectList();
} catch (\RuntimeException $e) {
$this->setError($e->getMessage());
return false;
}
foreach ($rows as $row) {
$item->set($row->cfg_name, $row->cfg_value);
}
$this->preprocessData('com_messages.config', $item);
return $item;
}
/**
* Method to get the record form.
*
* @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 \Joomla\CMS\Form\Form|bool A Form object on success, false on failure
*
* @since 1.6
*/
public function getForm($data = [], $loadData = true)
{
// Get the form.
$form = $this->loadForm('com_messages.config', 'config', ['control' => 'jform', 'load_data' => $loadData]);
if (empty($form)) {
return false;
}
return $form;
}
/**
* Method to save the form data.
*
* @param array $data The form data.
*
* @return boolean True on success.
*
* @since 1.6
*/
public function save($data)
{
$db = $this->getDatabase();
if ($userId = (int) $this->getState('user.id')) {
$query = $db->getQuery(true)
->delete($db->quoteName('#__messages_cfg'))
->where($db->quoteName('user_id') . ' = :userid')
->bind(':userid', $userId, ParameterType::INTEGER);
$db->setQuery($query);
try {
$db->execute();
} catch (\RuntimeException $e) {
$this->setError($e->getMessage());
return false;
}
if (\count($data)) {
$query = $db->getQuery(true)
->insert($db->quoteName('#__messages_cfg'))
->columns(
[
$db->quoteName('user_id'),
$db->quoteName('cfg_name'),
$db->quoteName('cfg_value'),
]
);
foreach ($data as $k => $v) {
$query->values(
implode(
',',
$query->bindArray(
[$userId , $k, $v],
[ParameterType::INTEGER, ParameterType::STRING, ParameterType::STRING]
)
)
);
}
$db->setQuery($query);
try {
$db->execute();
} catch (\RuntimeException $e) {
$this->setError($e->getMessage());
return false;
}
}
return true;
}
$this->setError('COM_MESSAGES_ERR_INVALID_USER');
return false;
}
}

View File

@ -0,0 +1,505 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\Model;
use Joomla\CMS\Access\Access;
use Joomla\CMS\Access\Rule;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Language;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Mail\Exception\MailDisabledException;
use Joomla\CMS\Mail\MailTemplate;
use Joomla\CMS\MVC\Model\AdminModel;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Table\Asset;
use Joomla\CMS\Table\Table;
use Joomla\CMS\User\User;
use Joomla\CMS\User\UserFactoryAwareInterface;
use Joomla\CMS\User\UserFactoryAwareTrait;
use Joomla\Database\ParameterType;
use PHPMailer\PHPMailer\Exception as phpMailerException;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Private Message model.
*
* @since 1.6
*/
class MessageModel extends AdminModel implements UserFactoryAwareInterface
{
use UserFactoryAwareTrait;
/**
* Message
*
* @var \stdClass
*/
protected $item;
/**
* 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.
*
* @return void
*
* @since 1.6
*/
protected function populateState()
{
parent::populateState();
$input = Factory::getApplication()->getInput();
$user = $this->getCurrentUser();
$this->setState('user.id', $user->get('id'));
$messageId = (int) $input->getInt('message_id');
$this->setState('message.id', $messageId);
$replyId = (int) $input->getInt('reply_id');
$this->setState('reply.id', $replyId);
}
/**
* Check that recipient user is the one trying to delete and then call parent delete method
*
* @param array &$pks An array of record primary keys.
*
* @return boolean True if successful, false if an error occurs.
*
* @since 3.1
*/
public function delete(&$pks)
{
$pks = (array) $pks;
$table = $this->getTable();
$user = $this->getCurrentUser();
// Iterate the items to delete each one.
foreach ($pks as $i => $pk) {
if ($table->load($pk)) {
if ($table->user_id_to != $user->id) {
// Prune items that you can't change.
unset($pks[$i]);
try {
Log::add(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), Log::WARNING, 'jerror');
} catch (\RuntimeException $exception) {
Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 'warning');
}
return false;
}
} else {
$this->setError($table->getError());
return false;
}
}
return parent::delete($pks);
}
/**
* Method to get a single record.
*
* @param integer $pk The id of the primary key.
*
* @return mixed Object on success, false on failure.
*
* @since 1.6
*/
public function getItem($pk = null)
{
if (!isset($this->item)) {
if ($this->item = parent::getItem($pk)) {
// Invalid message_id returns 0
if ($this->item->user_id_to === '0') {
$this->setError(Text::_('JERROR_ALERTNOAUTHOR'));
return false;
}
// Prime required properties.
if (empty($this->item->message_id)) {
// Prepare data for a new record.
if ($replyId = (int) $this->getState('reply.id')) {
// If replying to a message, preload some data.
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select($db->quoteName(['subject', 'user_id_from', 'user_id_to']))
->from($db->quoteName('#__messages'))
->where($db->quoteName('message_id') . ' = :messageid')
->bind(':messageid', $replyId, ParameterType::INTEGER);
try {
$message = $db->setQuery($query)->loadObject();
} catch (\RuntimeException $e) {
$this->setError($e->getMessage());
return false;
}
if (!$message || $message->user_id_to != $this->getCurrentUser()->id) {
$this->setError(Text::_('JERROR_ALERTNOAUTHOR'));
return false;
}
$this->item->set('user_id_to', $message->user_id_from);
$re = Text::_('COM_MESSAGES_RE');
if (stripos($message->subject, $re) !== 0) {
$this->item->set('subject', $re . ' ' . $message->subject);
}
}
} elseif ($this->item->user_id_to != $this->getCurrentUser()->id) {
$this->setError(Text::_('JERROR_ALERTNOAUTHOR'));
return false;
} else {
// Mark message read
$db = $this->getDatabase();
$query = $db->getQuery(true)
->update($db->quoteName('#__messages'))
->set($db->quoteName('state') . ' = 1')
->where($db->quoteName('message_id') . ' = :messageid')
->bind(':messageid', $this->item->message_id, ParameterType::INTEGER);
$db->setQuery($query)->execute();
}
}
// Get the user name for an existing message.
if ($this->item->user_id_from && $fromUser = new User($this->item->user_id_from)) {
$this->item->set('from_user_name', $fromUser->name);
}
}
return $this->item;
}
/**
* Method to get the record form.
*
* @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 \Joomla\CMS\Form\Form|bool A Form object on success, false on failure
*
* @since 1.6
*/
public function getForm($data = [], $loadData = true)
{
// Get the form.
$form = $this->loadForm('com_messages.message', 'message', ['control' => 'jform', 'load_data' => $loadData]);
if (empty($form)) {
return false;
}
return $form;
}
/**
* Method to get the data that should be injected in the form.
*
* @return mixed The data for the form.
*
* @since 1.6
*/
protected function loadFormData()
{
// Check the session for previously entered form data.
$data = Factory::getApplication()->getUserState('com_messages.edit.message.data', []);
if (empty($data)) {
$data = $this->getItem();
}
$this->preprocessData('com_messages.message', $data);
return $data;
}
/**
* Checks that the current user matches the message recipient and calls the parent publish method
*
* @param array &$pks A list of the primary keys to change.
* @param integer $value The value of the published state.
*
* @return boolean True on success.
*
* @since 3.1
*/
public function publish(&$pks, $value = 1)
{
$user = $this->getCurrentUser();
$table = $this->getTable();
$pks = (array) $pks;
// Check that the recipient matches the current user
foreach ($pks as $i => $pk) {
$table->reset();
if ($table->load($pk)) {
if ($table->user_id_to != $user->id) {
// Prune items that you can't change.
unset($pks[$i]);
try {
Log::add(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), Log::WARNING, 'jerror');
} catch (\RuntimeException $exception) {
Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 'warning');
}
return false;
}
}
}
return parent::publish($pks, $value);
}
/**
* Method to save the form data.
*
* @param array $data The form data.
*
* @return boolean True on success.
*
* @since 1.6
*/
public function save($data)
{
$table = $this->getTable();
// Bind the data.
if (!$table->bind($data)) {
$this->setError($table->getError());
return false;
}
// Assign empty values.
if (empty($table->user_id_from)) {
$table->user_id_from = $this->getCurrentUser()->get('id');
}
if ((int) $table->date_time == 0) {
$table->date_time = Factory::getDate()->toSql();
}
// Check the data.
if (!$table->check()) {
$this->setError($table->getError());
return false;
}
// Load the user details (already valid from table check).
$toUser = $this->getUserFactory()->loadUserById($table->user_id_to);
// Check if recipient can access com_messages.
if (!$toUser->authorise('core.login.admin') || !$toUser->authorise('core.manage', 'com_messages')) {
$this->setError(Text::_('COM_MESSAGES_ERROR_RECIPIENT_NOT_AUTHORISED'));
return false;
}
// Load the recipient user configuration.
$model = $this->bootComponent('com_messages')
->getMVCFactory()->createModel('Config', 'Administrator', ['ignore_request' => true]);
$model->setState('user.id', $table->user_id_to);
$config = $model->getItem();
if (empty($config)) {
$this->setError($model->getError());
return false;
}
if ($config->get('lock', false)) {
$this->setError(Text::_('COM_MESSAGES_ERR_SEND_FAILED'));
return false;
}
// Store the data.
if (!$table->store()) {
$this->setError($table->getError());
return false;
}
$key = $table->getKeyName();
if (isset($table->$key)) {
$this->setState($this->getName() . '.id', $table->$key);
}
if ($config->get('mail_on_new', true)) {
$fromUser = $this->getUserFactory()->loadUserById($table->user_id_from);
$debug = Factory::getApplication()->get('debug_lang');
$default_language = ComponentHelper::getParams('com_languages')->get('administrator');
$lang = Language::getInstance($toUser->getParam('admin_language', $default_language), $debug);
$lang->load('com_messages', JPATH_ADMINISTRATOR);
// Build the email subject and message
$app = Factory::getApplication();
$linkMode = $app->get('force_ssl', 0) >= 1 ? Route::TLS_FORCE : Route::TLS_IGNORE;
$sitename = $app->get('sitename');
$fromName = $fromUser->get('name');
$siteURL = Route::link(
'administrator',
'index.php?option=com_messages&view=message&message_id=' . $table->message_id,
false,
$linkMode,
true
);
$subject = html_entity_decode($table->subject, ENT_COMPAT, 'UTF-8');
$message = strip_tags(html_entity_decode($table->message, ENT_COMPAT, 'UTF-8'));
// Send the email
$mailer = new MailTemplate('com_messages.new_message', $lang->getTag());
$data = [
'subject' => $subject,
'message' => $message,
'fromname' => $fromName,
'sitename' => $sitename,
'siteurl' => $siteURL,
'fromemail' => $fromUser->email,
'toname' => $toUser->name,
'toemail' => $toUser->email,
];
$mailer->addTemplateData($data);
$mailer->setReplyTo($fromUser->email, $fromUser->name);
$mailer->addRecipient($toUser->email, $toUser->name);
try {
$mailer->send();
} catch (MailDisabledException | phpMailerException $exception) {
try {
Log::add(Text::_($exception->getMessage()), Log::WARNING, 'jerror');
$this->setError(Text::_('COM_MESSAGES_ERROR_MAIL_FAILED'));
return false;
} catch (\RuntimeException $exception) {
Factory::getApplication()->enqueueMessage(Text::_($exception->errorMessage()), 'warning');
$this->setError(Text::_('COM_MESSAGES_ERROR_MAIL_FAILED'));
return false;
}
}
}
return true;
}
/**
* Sends a message to the site's super users
*
* @param string $subject The message subject
* @param string $message The message
*
* @return boolean
*
* @since 3.9.0
*/
public function notifySuperUsers($subject, $message, $fromUser = null)
{
$db = $this->getDatabase();
try {
/** @var Asset $table */
$table = Table::getInstance('Asset');
$rootId = $table->getRootId();
/** @var Rule[] $rules */
$rules = Access::getAssetRules($rootId)->getData();
$rawGroups = $rules['core.admin']->getData();
if (empty($rawGroups)) {
$this->setError(Text::_('COM_MESSAGES_ERROR_MISSING_ROOT_ASSET_GROUPS'));
return false;
}
$groups = [];
foreach ($rawGroups as $g => $enabled) {
if ($enabled) {
$groups[] = $g;
}
}
if (empty($groups)) {
$this->setError(Text::_('COM_MESSAGES_ERROR_NO_GROUPS_SET_AS_SUPER_USER'));
return false;
}
$query = $db->getQuery(true)
->select($db->quoteName('map.user_id'))
->from($db->quoteName('#__user_usergroup_map', 'map'))
->join(
'LEFT',
$db->quoteName('#__users', 'u'),
$db->quoteName('u.id') . ' = ' . $db->quoteName('map.user_id')
)
->whereIn($db->quoteName('map.group_id'), $groups)
->where($db->quoteName('u.block') . ' = 0')
->where($db->quoteName('u.sendEmail') . ' = 1');
$userIDs = $db->setQuery($query)->loadColumn(0);
if (empty($userIDs)) {
$this->setError(Text::_('COM_MESSAGES_ERROR_NO_USERS_SET_AS_SUPER_USER'));
return false;
}
foreach ($userIDs as $id) {
/*
* All messages must have a valid from user, we have use cases where an unauthenticated user may trigger this
* so we will set the from user as the to user
*/
$data = [
'user_id_from' => $id,
'user_id_to' => $id,
'subject' => $subject,
'message' => $message,
];
if (!$this->save($data)) {
return false;
}
}
return true;
} catch (\Exception $exception) {
$this->setError($exception->getMessage());
return false;
}
}
}

View File

@ -0,0 +1,223 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\Model;
use Joomla\CMS\Factory;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\MVC\Model\ListModel;
use Joomla\Database\ParameterType;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Messages Component Messages Model
*
* @since 1.6
*/
class MessagesModel extends ListModel
{
/**
* Override parent constructor.
*
* @param array $config An optional associative array of configuration settings.
* @param MVCFactoryInterface $factory The factory.
*
* @see \Joomla\CMS\MVC\Model\BaseDatabaseModel
* @since 3.2
*/
public function __construct($config = [], MVCFactoryInterface $factory = null)
{
if (empty($config['filter_fields'])) {
$config['filter_fields'] = [
'message_id', 'a.id',
'subject', 'a.subject',
'state', 'a.state',
'user_id_from', 'a.user_id_from',
'user_id_to', 'a.user_id_to',
'date_time', 'a.date_time',
'priority', 'a.priority',
];
}
parent::__construct($config, $factory);
}
/**
* Method to auto-populate the model state.
*
* This method should only be called once per instantiation and is designed
* to be called on the first call to the getState() method unless the model
* configuration flag to ignore the request is set.
*
* Note. Calling getState in this method will result in recursion.
*
* @param string $ordering An optional ordering field.
* @param string $direction An optional direction (asc|desc).
*
* @return void
*
* @since 1.6
*/
protected function populateState($ordering = 'a.date_time', $direction = 'desc')
{
// 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 1.6
*/
protected function getStoreId($id = '')
{
// Compile the store id.
$id .= ':' . $this->getState('filter.search');
$id .= ':' . $this->getState('filter.state');
return parent::getStoreId($id);
}
/**
* Build an SQL query to load the list data.
*
* @return \Joomla\Database\DatabaseQuery
*
* @since 1.6
*/
protected function getListQuery()
{
// Create a new query object.
$db = $this->getDatabase();
$query = $db->getQuery(true);
$user = $this->getCurrentUser();
$id = (int) $user->get('id');
// Select the required fields from the table.
$query->select(
$this->getState(
'list.select',
[
$db->quoteName('a') . '.*',
$db->quoteName('u.name', 'user_from'),
]
)
);
$query->from($db->quoteName('#__messages', 'a'));
// Join over the users for message owner.
$query->join(
'INNER',
$db->quoteName('#__users', 'u'),
$db->quoteName('u.id') . ' = ' . $db->quoteName('a.user_id_from')
)
->where($db->quoteName('a.user_id_to') . ' = :id')
->bind(':id', $id, ParameterType::INTEGER);
// Filter by published state.
$state = $this->getState('filter.state');
if (is_numeric($state)) {
$state = (int) $state;
$query->where($db->quoteName('a.state') . ' = :state')
->bind(':state', $state, ParameterType::INTEGER);
} elseif ($state !== '*') {
$query->whereIn($db->quoteName('a.state'), [0, 1]);
}
// Filter by search in subject or message.
$search = $this->getState('filter.search');
if (!empty($search)) {
$search = '%' . str_replace(' ', '%', trim($search)) . '%';
$query->extendWhere(
'AND',
[
$db->quoteName('a.subject') . ' LIKE :subject',
$db->quoteName('a.message') . ' LIKE :message',
],
'OR'
)
->bind(':subject', $search)
->bind(':message', $search);
}
// Add the list ordering clause.
$query->order($db->escape($this->getState('list.ordering', 'a.date_time')) . ' ' . $db->escape($this->getState('list.direction', 'DESC')));
return $query;
}
/**
* Purge the messages table of old messages for the given user ID.
*
* @param int $userId The user id
*
* @return void
*
* @since 4.2.0
*/
public function purge(int $userId): void
{
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select($db->quoteName(['cfg_name', 'cfg_value']))
->from($db->quoteName('#__messages_cfg'))
->where(
[
$db->quoteName('user_id') . ' = :userId',
$db->quoteName('cfg_name') . ' = ' . $db->quote('auto_purge'),
]
)
->bind(':userId', $userId, ParameterType::INTEGER);
$db->setQuery($query);
$config = $db->loadObject();
// Default is 7 days
$purge = 7;
// Check if auto_purge value set
if (\is_object($config) && $config->cfg_name === 'auto_purge') {
$purge = $config->cfg_value;
}
// If purge value is not 0, then allow purging of old messages
if ($purge > 0) {
// Purge old messages at day set in message configuration
$past = Factory::getDate(time() - $purge * 86400)->toSql();
$query = $db->getQuery(true)
->delete($db->quoteName('#__messages'))
->where(
[
$db->quoteName('date_time') . ' < :past',
$db->quoteName('user_id_to') . ' = :userId',
]
)
->bind(':past', $past)
->bind(':userId', $userId, ParameterType::INTEGER);
$db->setQuery($query);
$db->execute();
}
}
}

View File

@ -0,0 +1,63 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\Service\HTML;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\Utilities\ArrayHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* JHtml administrator messages class.
*
* @since 1.6
*/
class Messages
{
/**
* Get the HTML code of the state switcher
*
* @param int $i Row number
* @param int $value The state value
* @param boolean $canChange Can the user change the state?
*
* @return string
*
* @since 3.4
*/
public function status($i, $value = 0, $canChange = false)
{
Factory::getDocument()->getWebAssetManager()->useScript('list-view');
// Array of image, task, title, action.
$states = [
-2 => ['trash', 'messages.unpublish', 'JTRASHED', 'COM_MESSAGES_MARK_AS_UNREAD'],
1 => ['publish', 'messages.unpublish', 'COM_MESSAGES_OPTION_READ', 'COM_MESSAGES_MARK_AS_UNREAD'],
0 => ['unpublish', 'messages.publish', 'COM_MESSAGES_OPTION_UNREAD', 'COM_MESSAGES_MARK_AS_READ'],
];
$state = ArrayHelper::getValue($states, (int) $value, $states[0]);
$icon = $state[0];
if ($canChange) {
$html = '<a href="#" class="js-grid-item-action tbody-icon'
. ($value == 1 ? ' active' : '') . '" aria-labelledby="cb' . $state[0] . $i . '-desc"'
. ' data-item-id="cb' . $i . '" data-item-task="' . $state[1] . '"><span class="icon-'
. $icon . '" aria-hidden="true"></span></a><div role="tooltip" id="cb' . $state[0] . $i
. '-desc">' . Text::_($state[3]) . '</div>';
}
return $html;
}
}

View File

@ -0,0 +1,93 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\Table;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Table\Table;
use Joomla\CMS\User\User;
use Joomla\Database\DatabaseDriver;
use Joomla\Event\DispatcherInterface;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Message Table class
*
* @since 1.5
*/
class MessageTable extends Table
{
/**
* Constructor
*
* @param DatabaseDriver $db Database connector object
* @param ?DispatcherInterface $dispatcher Event dispatcher for this table
*
* @since 1.5
*/
public function __construct(DatabaseDriver $db, DispatcherInterface $dispatcher = null)
{
parent::__construct('#__messages', 'message_id', $db, $dispatcher);
$this->setColumnAlias('published', 'state');
}
/**
* Validation and filtering.
*
* @return boolean
*
* @since 1.5
*/
public function check()
{
try {
parent::check();
} catch (\Exception $e) {
$this->setError($e->getMessage());
return false;
}
// Check the to and from users.
$user = new User($this->user_id_from);
if (empty($user->id)) {
$this->setError(Text::_('COM_MESSAGES_ERROR_INVALID_FROM_USER'));
return false;
}
$user = new User($this->user_id_to);
if (empty($user->id)) {
$this->setError(Text::_('COM_MESSAGES_ERROR_INVALID_TO_USER'));
return false;
}
if (empty($this->subject)) {
$this->setError(Text::_('COM_MESSAGES_ERROR_INVALID_SUBJECT'));
return false;
}
if (empty($this->message)) {
$this->setError(Text::_('COM_MESSAGES_ERROR_INVALID_MESSAGE'));
return false;
}
return true;
}
}

View File

@ -0,0 +1,97 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\View\Config;
use Joomla\CMS\Factory;
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 messages user configuration.
*
* @since 1.6
*/
class HtmlView extends BaseHtmlView
{
/**
* The Form object
*
* @var \Joomla\CMS\Form\Form
*/
protected $form;
/**
* The active item
*
* @var object
*/
protected $item;
/**
* The model state
*
* @var \Joomla\Registry\Registry
*/
protected $state;
/**
* Execute and display a template script.
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return void
*
* @since 1.6
*/
public function display($tpl = null)
{
$this->form = $this->get('Form');
$this->item = $this->get('Item');
$this->state = $this->get('State');
// Check for errors.
if (\count($errors = $this->get('Errors'))) {
throw new GenericDataException(implode("\n", $errors), 500);
}
// Bind the record to the form.
$this->form->bind($this->item);
$this->addToolbar();
parent::display($tpl);
}
/**
* Add the page title and toolbar.
*
* @return void
*
* @since 4.0.0
*/
protected function addToolbar()
{
Factory::getApplication()->getInput()->set('hidemainmenu', true);
ToolbarHelper::title(Text::_('COM_MESSAGES_TOOLBAR_MY_SETTINGS'), 'envelope');
$toolbar = Toolbar::getInstance();
$toolbar->apply('config.save', 'JSAVE');
$toolbar->cancel('config.cancel', 'JCANCEL');
}
}

View File

@ -0,0 +1,122 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\View\Message;
use Joomla\CMS\Factory;
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;
use Joomla\CMS\User\UserFactoryAwareInterface;
use Joomla\CMS\User\UserFactoryAwareTrait;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* HTML View class for the Messages component
*
* @since 1.6
*/
class HtmlView extends BaseHtmlView implements UserFactoryAwareInterface
{
use UserFactoryAwareTrait;
/**
* The Form object
*
* @var \Joomla\CMS\Form\Form
*/
protected $form;
/**
* The active item
*
* @var object
*/
protected $item;
/**
* The model state
*
* @var \Joomla\Registry\Registry
*/
protected $state;
/**
* Execute and display a template script.
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return void
*
* @since 1.6
*/
public function display($tpl = null)
{
$this->form = $this->get('Form');
$this->item = $this->get('Item');
$this->state = $this->get('State');
// Check for errors.
if (\count($errors = $this->get('Errors'))) {
throw new GenericDataException(implode("\n", $errors), 500);
}
if ($this->getLayout() !== 'edit' && empty($this->item->message_id)) {
throw new GenericDataException(Text::_('JERROR_ALERTNOAUTHOR'), 403);
}
parent::display($tpl);
$this->addToolbar();
}
/**
* Add the page title and toolbar.
*
* @return void
*
* @since 1.6
*/
protected function addToolbar()
{
$app = Factory::getApplication();
$toolbar = Toolbar::getInstance();
if ($this->getLayout() == 'edit') {
$app->getInput()->set('hidemainmenu', true);
ToolbarHelper::title(Text::_('COM_MESSAGES_WRITE_PRIVATE_MESSAGE'), 'envelope-open-text new-privatemessage');
$toolbar->standardButton('save', 'COM_MESSAGES_TOOLBAR_SEND', 'message.save')
->icon('icon-envelope')
->listCheck(false);
$toolbar->cancel('message.cancel');
$toolbar->help('Private_Messages:_Write');
} else {
ToolbarHelper::title(Text::_('COM_MESSAGES_VIEW_PRIVATE_MESSAGE'), 'envelope inbox');
$sender = $this->getUserFactory()->loadUserById($this->item->user_id_from);
if (
$sender->id !== $app->getIdentity()->get('id') && ($sender->authorise('core.admin')
|| $sender->authorise('core.manage', 'com_messages') && $sender->authorise('core.login.admin'))
&& $app->getIdentity()->authorise('core.manage', 'com_users')
) {
$toolbar->standardButton('reply', 'COM_MESSAGES_TOOLBAR_REPLY', 'message.reply')
->icon('icon-redo')
->listCheck(false);
}
$toolbar->cancel('message.cancel');
$toolbar->help('Private_Messages:_Read');
}
}
}

View File

@ -0,0 +1,171 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Messages\Administrator\View\Messages;
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 class for a list of messages.
*
* @since 1.6
*/
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
*
* @since 4.0.0
*/
public $filterForm;
/**
* The active search filters
*
* @var array
* @since 4.0.0
*/
public $activeFilters;
/**
* Is this view an Empty State
*
* @var boolean
* @since 4.0.0
*/
private $isEmptyState = false;
/**
* Execute and display a template script.
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return void
*
* @since 1.6
*/
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();
parent::display($tpl);
}
/**
* Add the page title and toolbar.
*
* @return void
*
* @since 1.6
*/
protected function addToolbar()
{
$state = $this->get('State');
$canDo = ContentHelper::getActions('com_messages');
$user = $this->getCurrentUser();
// Get the toolbar object instance
$toolbar = Toolbar::getInstance('toolbar');
ToolbarHelper::title(Text::_('COM_MESSAGES_MANAGER_MESSAGES'), 'envelope inbox');
// Only display the New button if the user has the access level to create a message and if they have access to the list of users
if ($canDo->get('core.create') && $user->authorise('core.manage', 'com_users')) {
$toolbar->addNew('message.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('messages.publish')
->text('COM_MESSAGES_TOOLBAR_MARK_AS_READ')
->listCheck(true);
$childBar->unpublish('messages.unpublish')
->text('COM_MESSAGES_TOOLBAR_MARK_AS_UNREAD')
->listCheck(true);
if ($this->state->get('filter.state') != -2) {
$childBar->trash('messages.trash')->listCheck(true);
}
}
$toolbar->linkButton('cog', 'COM_MESSAGES_TOOLBAR_MY_SETTINGS')
->url('index.php?option=com_messages&amp;view=config');
$toolbar->divider();
if (!$this->isEmptyState && $this->state->get('filter.state') == -2 && $canDo->get('core.delete')) {
$toolbar->delete('messages.delete')
->text('JTOOLBAR_EMPTY_TRASH')
->message('JGLOBAL_CONFIRM_DELETE')
->listCheck(true);
}
if ($canDo->get('core.admin')) {
$toolbar->preferences('com_messages');
}
$toolbar->help('Private_Messages');
}
}

View File

@ -0,0 +1,39 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
/** @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_messages&view=config'); ?>" method="post" name="adminForm" id="message-form" class="form-validate">
<div class="form-grid">
<div class="card">
<div class="card-body">
<fieldset class="options-form">
<legend><?php echo Text::_('COM_MESSAGES_CONFIG_FORM'); ?></legend>
<?php echo $this->form->renderField('lock'); ?>
<?php echo $this->form->renderField('mail_on_new'); ?>
<?php echo $this->form->renderField('auto_purge'); ?>
</fieldset>
</div>
</div>
</div>
<input type="hidden" name="task" value="">
<?php echo HTMLHelper::_('form.token'); ?>
</form>

View File

@ -0,0 +1,64 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('core');
?>
<form action="<?php echo Route::_('index.php?option=com_messages'); ?>" method="post" name="adminForm" id="adminForm">
<div class="card">
<div class="card-body">
<fieldset>
<div class="form-group">
<div class="control-label">
<?php echo Text::_('COM_MESSAGES_FIELD_USER_ID_FROM_LABEL'); ?>
</div>
<div class="p-3 bg-light border rounded">
<?php echo $this->item->get('from_user_name'); ?>
</div>
</div>
<div class="form-group">
<div class="control-label">
<?php echo Text::_('COM_MESSAGES_FIELD_DATE_TIME_LABEL'); ?>
</div>
<div class="p-3 bg-light border rounded">
<?php echo HTMLHelper::_('date', $this->item->date_time, Text::_('DATE_FORMAT_LC2')); ?>
</div>
</div>
<div class="form-group">
<div class="control-label">
<?php echo Text::_('COM_MESSAGES_FIELD_SUBJECT_LABEL'); ?>
</div>
<div class="p-3 bg-light border rounded">
<?php echo $this->item->subject; ?>
</div>
</div>
<div class="form-group">
<div class="control-label">
<?php echo Text::_('COM_MESSAGES_FIELD_MESSAGE_LABEL'); ?>
</div>
<div class="p-3 bg-light border rounded">
<?php echo $this->item->message; ?>
</div>
</div>
<input type="hidden" name="task" value="">
<input type="hidden" name="reply_id" value="<?php echo $this->item->message_id; ?>">
<?php echo HTMLHelper::_('form.token'); ?>
</fieldset>
</div>
</div>
</form>

View File

@ -0,0 +1,44 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
/** @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_messages'); ?>" method="post" name="adminForm" id="message-form" aria-label="<?php echo Text::_('COM_MESSAGES_FORM_NEW'); ?>" class="form-validate">
<div class="adminform mt-2">
<div class="card">
<div class="card-body">
<div class="form-group">
<?php echo $this->form->getLabel('user_id_to'); ?>
<?php echo $this->form->getInput('user_id_to'); ?>
</div>
<div class="form-group">
<?php echo $this->form->getLabel('subject'); ?>
<?php echo $this->form->getInput('subject'); ?>
</div>
<div class="form-group">
<?php echo $this->form->getLabel('message'); ?>
<?php echo $this->form->getInput('message'); ?>
</div>
</div>
</div>
</div>
<input type="hidden" name="task" value="">
<?php echo HTMLHelper::_('form.token'); ?>
</form>

View File

@ -0,0 +1,96 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2008 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;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('multiselect');
$user = $this->getCurrentUser();
$listOrder = $this->escape($this->state->get('list.ordering'));
$listDirn = $this->escape($this->state->get('list.direction'));
?>
<form action="<?php echo Route::_('index.php?option=com_messages&view=messages'); ?>" method="post" name="adminForm" id="adminForm">
<div id="j-main-container" class="j-main-container">
<?php echo LayoutHelper::render('joomla.searchtools.default', ['view' => $this]); ?>
<?php if (empty($this->items)) : ?>
<div class="alert alert-info">
<span class="icon-info-circle" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('INFO'); ?></span>
<?php echo Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
</div>
<?php else : ?>
<table class="table">
<caption class="visually-hidden">
<?php echo Text::_('COM_MESSAGES_TABLE_CAPTION'); ?>,
<span id="orderedBy"><?php echo Text::_('JGLOBAL_SORTED_BY'); ?> </span>,
<span id="filteredBy"><?php echo Text::_('JGLOBAL_FILTERED_BY'); ?></span>
</caption>
<thead>
<tr>
<td class="w-1 text-center">
<?php echo HTMLHelper::_('grid.checkall'); ?>
</td>
<th scope="col" class="title">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_MESSAGES_HEADING_SUBJECT', 'a.subject', $listDirn, $listOrder); ?>
</th>
<th scope="col" class="w-1 text-center">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_MESSAGES_HEADING_READ', 'a.state', $listDirn, $listOrder); ?>
</th>
<th scope="col" class="w-15">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_MESSAGES_HEADING_FROM', 'a.user_id_from', $listDirn, $listOrder); ?>
</th>
<th scope="col" class="w-20 d-none d-md-table-cell">
<?php echo HTMLHelper::_('searchtools.sort', 'JDATE', 'a.date_time', $listDirn, $listOrder); ?>
</th>
</tr>
</thead>
<tbody>
<?php foreach ($this->items as $i => $item) :
$canChange = $user->authorise('core.edit.state', 'com_messages');
?>
<tr class="row<?php echo $i % 2; ?>">
<td class="text-center">
<?php echo HTMLHelper::_('grid.id', $i, $item->message_id, false, 'cid', 'cb', $item->subject); ?>
</td>
<th scope="row">
<a href="<?php echo Route::_('index.php?option=com_messages&view=message&message_id=' . (int) $item->message_id); ?>">
<?php echo $this->escape($item->subject); ?></a>
</th>
<td class="text-center">
<?php echo HTMLHelper::_('messages.status', $i, $item->state, $canChange); ?>
</td>
<td>
<?php echo $item->user_from; ?>
</td>
<td class="d-none d-md-table-cell">
<?php echo HTMLHelper::_('date', $item->date_time, Text::_('DATE_FORMAT_LC2')); ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php // load the pagination. ?>
<?php echo $this->pagination->getListFooter(); ?>
<?php endif; ?>
<div>
<input type="hidden" name="task" value="">
<input type="hidden" name="boxchecked" value="0">
<?php echo HTMLHelper::_('form.token'); ?>
</div>
</div>
</form>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<layout title="COM_MESSAGES_MESSAGES_VIEW_DEFAULT_TITLE">
<message>
<![CDATA[COM_MESSAGES_MESSAGES_VIEW_DEFAULT_DESC]]>
</message>
</layout>
</metadata>

View File

@ -0,0 +1,29 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_messages
*
* @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Layout\LayoutHelper;
$displayData = [
'textPrefix' => 'COM_MESSAGES',
'formURL' => 'index.php?option=com_messages&view=messages',
'helpURL' => 'https://docs.joomla.org/Special:MyLanguage/Help40:Private_Messages',
'icon' => 'icon-envelope inbox',
];
if (
$this->getCurrentUser()->authorise('core.create', 'com_messages')
&& $this->getCurrentUser()->authorise('core.manage', 'com_users')
) {
$displayData['createURL'] = 'index.php?option=com_messages&task=message.add';
}
echo LayoutHelper::render('joomla.content.emptystate', $displayData);