primo commit
This commit is contained in:
@ -0,0 +1,100 @@
|
||||
<?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\Application\CMSWebApplicationInterface;
|
||||
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(), CMSWebApplicationInterface::MSG_ERROR);
|
||||
} else {
|
||||
$this->app->enqueueMessage($errors[$i], CMSWebApplicationInterface::MSG_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
@ -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 not exclude them
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function getExcluded()
|
||||
{
|
||||
return [$this->getCurrentUser()->id];
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
187
administrator/components/com_messages/src/Model/ConfigModel.php
Normal file
187
administrator/components/com_messages/src/Model/ConfigModel.php
Normal 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->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;
|
||||
}
|
||||
}
|
||||
505
administrator/components/com_messages/src/Model/MessageModel.php
Normal file
505
administrator/components/com_messages/src/Model/MessageModel.php
Normal 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->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()->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->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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,224 @@
|
||||
<?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;
|
||||
use Joomla\Database\QueryInterface;
|
||||
|
||||
// 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 QueryInterface
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function getListQuery()
|
||||
{
|
||||
// Create a new query object.
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true);
|
||||
$user = $this->getCurrentUser();
|
||||
$id = (int) $user->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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
<?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\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 = $this->getDocument()->getToolbar();
|
||||
$toolbar->apply('config.save', 'JSAVE');
|
||||
$toolbar->cancel('config.cancel', 'JCANCEL');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,121 @@
|
||||
<?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\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 = $this->getDocument()->getToolbar();
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,170 @@
|
||||
<?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\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 = $this->getDocument()->getToolbar();
|
||||
|
||||
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&view=config');
|
||||
$toolbar->divider();
|
||||
|
||||
if (!$this->isEmptyState && $this->state->get('filter.state') == -2 && $canDo->get('core.delete')) {
|
||||
$toolbar->delete('messages.delete')
|
||||
->text('JTOOLBAR_DELETE_FROM_TRASH')
|
||||
->message('JGLOBAL_CONFIRM_DELETE')
|
||||
->listCheck(true);
|
||||
}
|
||||
|
||||
if ($canDo->get('core.admin')) {
|
||||
$toolbar->preferences('com_messages');
|
||||
}
|
||||
|
||||
$toolbar->help('Private_Messages');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user