primo commit
This commit is contained in:
		| @ -0,0 +1,84 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @copyright   (C) 2005 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Contact\Administrator\Controller; | ||||
|  | ||||
| use Joomla\CMS\Language\Associations; | ||||
| use Joomla\CMS\Language\LanguageHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\Controller\BaseController; | ||||
| use Joomla\CMS\Response\JsonResponse; | ||||
| use Joomla\CMS\Session\Session; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * The contact controller for ajax requests | ||||
|  * | ||||
|  * @since  3.9.0 | ||||
|  */ | ||||
| class AjaxController extends BaseController | ||||
| { | ||||
|     /** | ||||
|      * Method to fetch associations of a contact | ||||
|      * | ||||
|      * The method assumes that the following http parameters are passed in an Ajax Get request: | ||||
|      * token: the form token | ||||
|      * assocId: the id of the contact whose associations are to be returned | ||||
|      * excludeLang: the association for this language is to be excluded | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since  3.9.0 | ||||
|      */ | ||||
|     public function fetchAssociations() | ||||
|     { | ||||
|         if (!Session::checkToken('get')) { | ||||
|             echo new JsonResponse(null, Text::_('JINVALID_TOKEN'), true); | ||||
|         } else { | ||||
|             $assocId = $this->input->getInt('assocId', 0); | ||||
|  | ||||
|             if ($assocId == 0) { | ||||
|                 echo new JsonResponse(null, Text::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', 'assocId'), true); | ||||
|  | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             $excludeLang = $this->input->get('excludeLang', '', 'STRING'); | ||||
|  | ||||
|             $associations = Associations::getAssociations('com_contact', '#__contact_details', 'com_contact.item', (int) $assocId); | ||||
|  | ||||
|             unset($associations[$excludeLang]); | ||||
|  | ||||
|             // Add the title to each of the associated records | ||||
|             $contactTable = $this->factory->createTable('Contact', 'Administrator'); | ||||
|  | ||||
|             foreach ($associations as $association) { | ||||
|                 $contactTable->load($association->id); | ||||
|                 $association->title = $contactTable->name; | ||||
|             } | ||||
|  | ||||
|             $countContentLanguages = \count(LanguageHelper::getContentLanguages([0, 1], false)); | ||||
|  | ||||
|             if (\count($associations) == 0) { | ||||
|                 $message = Text::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_NONE'); | ||||
|             } elseif ($countContentLanguages > \count($associations) + 2) { | ||||
|                 $tags    = implode(', ', array_keys($associations)); | ||||
|                 $message = Text::sprintf('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_SOME', $tags); | ||||
|             } else { | ||||
|                 $message = Text::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_ALL'); | ||||
|             } | ||||
|  | ||||
|             echo new JsonResponse($associations, $message); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,184 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @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\Contact\Administrator\Controller; | ||||
|  | ||||
| use Joomla\CMS\MVC\Controller\FormController; | ||||
| use Joomla\CMS\MVC\Model\BaseDatabaseModel; | ||||
| use Joomla\CMS\Router\Route; | ||||
| use Joomla\CMS\Versioning\VersionableControllerTrait; | ||||
| use Joomla\Utilities\ArrayHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Controller for a single contact | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class ContactController extends FormController | ||||
| { | ||||
|     use VersionableControllerTrait; | ||||
|  | ||||
|     /** | ||||
|      * Method override to check if you can add a new record. | ||||
|      * | ||||
|      * @param   array  $data  An array of input data. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function allowAdd($data = []) | ||||
|     { | ||||
|         $categoryId = ArrayHelper::getValue($data, 'catid', $this->input->getInt('filter_category_id'), 'int'); | ||||
|  | ||||
|         if ($categoryId) { | ||||
|             // If the category has been passed in the URL check it. | ||||
|             return $this->app->getIdentity()->authorise('core.create', $this->option . '.category.' . $categoryId); | ||||
|         } | ||||
|  | ||||
|         // In the absence of better information, revert to the component permissions. | ||||
|         return parent::allowAdd($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method override to check if you can edit an existing record. | ||||
|      * | ||||
|      * @param   array   $data  An array of input data. | ||||
|      * @param   string  $key   The name of the key for the primary key. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function allowEdit($data = [], $key = 'id') | ||||
|     { | ||||
|         $recordId = (int) isset($data[$key]) ? $data[$key] : 0; | ||||
|  | ||||
|         // Since there is no asset tracking, fallback to the component permissions. | ||||
|         if (!$recordId) { | ||||
|             return parent::allowEdit($data, $key); | ||||
|         } | ||||
|  | ||||
|         // Get the item. | ||||
|         $item = $this->getModel()->getItem($recordId); | ||||
|  | ||||
|         // Since there is no item, return false. | ||||
|         if (empty($item)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $user = $this->app->getIdentity(); | ||||
|  | ||||
|         // Check if can edit own core.edit.own. | ||||
|         $canEditOwn = $user->authorise('core.edit.own', $this->option . '.category.' . (int) $item->catid) && $item->created_by == $user->id; | ||||
|  | ||||
|         // Check the category core.edit permissions. | ||||
|         return $canEditOwn || $user->authorise('core.edit', $this->option . '.category.' . (int) $item->catid); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to run batch operations. | ||||
|      * | ||||
|      * @param   object  $model  The model. | ||||
|      * | ||||
|      * @return  boolean   True if successful, false otherwise and internal error is set. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function batch($model = null) | ||||
|     { | ||||
|         $this->checkToken(); | ||||
|  | ||||
|         // Set the model | ||||
|         /** @var \Joomla\Component\Contact\Administrator\Model\ContactModel $model */ | ||||
|         $model = $this->getModel('Contact', 'Administrator', []); | ||||
|  | ||||
|         // Preset the redirect | ||||
|         $this->setRedirect(Route::_('index.php?option=com_contact&view=contacts' . $this->getRedirectToListAppend(), false)); | ||||
|  | ||||
|         return parent::batch($model); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Function that allows child controller access to model data | ||||
|      * after the data has been saved. | ||||
|      * | ||||
|      * @param   BaseDatabaseModel  $model      The data model object. | ||||
|      * @param   array              $validData  The validated data. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   4.1.0 | ||||
|      */ | ||||
|     protected function postSaveHook(BaseDatabaseModel $model, $validData = []) | ||||
|     { | ||||
|         if ($this->getTask() === 'save2menu') { | ||||
|             $editState = []; | ||||
|  | ||||
|             $id = $model->getState('contact.id'); | ||||
|  | ||||
|             $link = 'index.php?option=com_contact&view=contact'; | ||||
|             $type = 'component'; | ||||
|  | ||||
|             $editState['id']            = $id; | ||||
|             $editState['link']          = $link; | ||||
|             $editState['title']         = $model->getItem($id)->name; | ||||
|             $editState['type']          = $type; | ||||
|             $editState['request']['id'] = $id; | ||||
|  | ||||
|             $this->app->setUserState( | ||||
|                 'com_menus.edit.item', | ||||
|                 [ | ||||
|                     'data' => $editState, | ||||
|                     'type' => $type, | ||||
|                     'link' => $link, | ||||
|                 ] | ||||
|             ); | ||||
|  | ||||
|             $this->setRedirect(Route::_('index.php?option=com_menus&view=item&client_id=0&menutype=mainmenu&layout=edit', false)); | ||||
|         } elseif ($this->input->get('layout') === 'modal' && $this->task === 'save') { | ||||
|             // When editing in modal then redirect to modalreturn layout | ||||
|             $id     = $model->getState('contact.id', ''); | ||||
|             $return = 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($id) | ||||
|                 . '&layout=modalreturn&from-task=save'; | ||||
|  | ||||
|             $this->setRedirect(Route::_($return, false)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to cancel an edit. | ||||
|      * | ||||
|      * @param   string  $key  The name of the primary key of the URL variable. | ||||
|      * | ||||
|      * @return  boolean  True if access level checks pass, false otherwise. | ||||
|      * | ||||
|      * @since   5.1.0 | ||||
|      */ | ||||
|     public function cancel($key = null) | ||||
|     { | ||||
|         $result = parent::cancel($key); | ||||
|  | ||||
|         // When editing in modal then redirect to modalreturn layout | ||||
|         if ($result && $this->input->get('layout') === 'modal') { | ||||
|             $id     = $this->input->get('id'); | ||||
|             $return = 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($id) | ||||
|                 . '&layout=modalreturn&from-task=cancel'; | ||||
|  | ||||
|             $this->setRedirect(Route::_($return, false)); | ||||
|         } | ||||
|  | ||||
|         return $result; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,149 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @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\Contact\Administrator\Controller; | ||||
|  | ||||
| use Joomla\CMS\Application\CMSApplication; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\Controller\AdminController; | ||||
| use Joomla\CMS\MVC\Factory\MVCFactoryInterface; | ||||
| use Joomla\CMS\Response\JsonResponse; | ||||
| use Joomla\Input\Input; | ||||
| use Joomla\Utilities\ArrayHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Contacts list controller class. | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class ContactsController extends AdminController | ||||
| { | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param   array                 $config   An optional associative array of configuration settings. | ||||
|      *                                          Recognized key values include 'name', 'default_task', 'model_path', and | ||||
|      *                                          'view_path' (this list is not meant to be comprehensive). | ||||
|      * @param   ?MVCFactoryInterface  $factory  The factory. | ||||
|      * @param   ?CMSApplication       $app      The Application for the dispatcher | ||||
|      * @param   ?Input                $input    Input | ||||
|      * | ||||
|      * @since   3.0 | ||||
|      */ | ||||
|     public function __construct($config = [], ?MVCFactoryInterface $factory = null, $app = null, $input = null) | ||||
|     { | ||||
|         parent::__construct($config, $factory, $app, $input); | ||||
|  | ||||
|         $this->registerTask('unfeatured', 'featured'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to toggle the featured setting of a list of contacts. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function featured() | ||||
|     { | ||||
|         // Check for request forgeries | ||||
|         $this->checkToken(); | ||||
|  | ||||
|         $ids    = (array) $this->input->get('cid', [], 'int'); | ||||
|         $values = ['featured' => 1, 'unfeatured' => 0]; | ||||
|         $task   = $this->getTask(); | ||||
|         $value  = ArrayHelper::getValue($values, $task, 0, 'int'); | ||||
|  | ||||
|         // Get the model. | ||||
|         /** @var \Joomla\Component\Contact\Administrator\Model\ContactModel $model */ | ||||
|         $model  = $this->getModel(); | ||||
|  | ||||
|         // Access checks. | ||||
|         foreach ($ids as $i => $id) { | ||||
|             // Remove zero value resulting from input filter | ||||
|             if ($id === 0) { | ||||
|                 unset($ids[$i]); | ||||
|  | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             $item = $model->getItem($id); | ||||
|  | ||||
|             if (!$this->app->getIdentity()->authorise('core.edit.state', 'com_contact.category.' . (int) $item->catid)) { | ||||
|                 // Prune items that you can't change. | ||||
|                 unset($ids[$i]); | ||||
|                 $this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 'notice'); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (empty($ids)) { | ||||
|             $message = null; | ||||
|  | ||||
|             $this->app->enqueueMessage(Text::_('COM_CONTACT_NO_ITEM_SELECTED'), 'warning'); | ||||
|         } else { | ||||
|             // Publish the items. | ||||
|             if (!$model->featured($ids, $value)) { | ||||
|                 $this->app->enqueueMessage($model->getError(), 'warning'); | ||||
|             } | ||||
|  | ||||
|             if ($value == 1) { | ||||
|                 $message = Text::plural('COM_CONTACT_N_ITEMS_FEATURED', \count($ids)); | ||||
|             } else { | ||||
|                 $message = Text::plural('COM_CONTACT_N_ITEMS_UNFEATURED', \count($ids)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $this->setRedirect('index.php?option=com_contact&view=contacts', $message); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Proxy for getModel. | ||||
|      * | ||||
|      * @param   string  $name    The name of the model. | ||||
|      * @param   string  $prefix  The prefix for the PHP class name. | ||||
|      * @param   array   $config  Array of configuration parameters. | ||||
|      * | ||||
|      * @return  \Joomla\CMS\MVC\Model\BaseDatabaseModel | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function getModel($name = 'Contact', $prefix = 'Administrator', $config = ['ignore_request' => true]) | ||||
|     { | ||||
|         return parent::getModel($name, $prefix, $config); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the number of published contacts for quickicons | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   4.3.0 | ||||
|      */ | ||||
|     public function getQuickiconContent() | ||||
|     { | ||||
|         $model = $this->getModel('contacts'); | ||||
|  | ||||
|         $model->setState('filter.published', 1); | ||||
|  | ||||
|         $amount = (int) $model->getTotal(); | ||||
|  | ||||
|         $result = []; | ||||
|  | ||||
|         $result['amount'] = $amount; | ||||
|         $result['sronly'] = Text::plural('COM_CONTACT_N_QUICKICON_SRONLY', $amount); | ||||
|         $result['name']   = Text::plural('COM_CONTACT_N_QUICKICON', $amount); | ||||
|  | ||||
|         echo new JsonResponse($result); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,67 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @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\Contact\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 | ||||
|  | ||||
| /** | ||||
|  * Component Controller | ||||
|  * | ||||
|  * @since  1.5 | ||||
|  */ | ||||
| class DisplayController extends BaseController | ||||
| { | ||||
|     /** | ||||
|      * The default view. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.6 | ||||
|      */ | ||||
|     protected $default_view = 'contacts'; | ||||
|  | ||||
|     /** | ||||
|      * Method to display a view. | ||||
|      * | ||||
|      * @param   boolean  $cachable   If true, the view output will be cached | ||||
|      * @param   array    $urlparams  An array of safe URL parameters and their variable types. | ||||
|      *                   @see        \Joomla\CMS\Filter\InputFilter::clean() for valid values. | ||||
|      * | ||||
|      * @return  static |boolean  This object to support chaining. False on failure. | ||||
|      * | ||||
|      * @since   1.5 | ||||
|      */ | ||||
|     public function display($cachable = false, $urlparams = []) | ||||
|     { | ||||
|         $view   = $this->input->get('view', $this->default_view); | ||||
|         $layout = $this->input->get('layout', 'default'); | ||||
|         $id     = $this->input->getInt('id'); | ||||
|  | ||||
|         // Check for edit form. | ||||
|         if ($view == 'contact' && $layout == 'edit' && !$this->checkEditId('com_contact.edit.contact', $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_contact&view=contacts', false)); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return parent::display(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,179 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @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\Contact\Administrator\Extension; | ||||
|  | ||||
| use Joomla\CMS\Association\AssociationServiceInterface; | ||||
| use Joomla\CMS\Association\AssociationServiceTrait; | ||||
| use Joomla\CMS\Categories\CategoryServiceInterface; | ||||
| use Joomla\CMS\Categories\CategoryServiceTrait; | ||||
| use Joomla\CMS\Component\Router\RouterServiceInterface; | ||||
| use Joomla\CMS\Component\Router\RouterServiceTrait; | ||||
| use Joomla\CMS\Extension\BootableExtensionInterface; | ||||
| use Joomla\CMS\Extension\MVCComponent; | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Fields\FieldsFormServiceInterface; | ||||
| use Joomla\CMS\Fields\FieldsServiceTrait; | ||||
| use Joomla\CMS\Form\Form; | ||||
| use Joomla\CMS\HTML\HTMLRegistryAwareTrait; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\Schemaorg\SchemaorgServiceInterface; | ||||
| use Joomla\CMS\Schemaorg\SchemaorgServiceTrait; | ||||
| use Joomla\CMS\Tag\TagServiceInterface; | ||||
| use Joomla\CMS\Tag\TagServiceTrait; | ||||
| use Joomla\CMS\User\UserFactoryInterface; | ||||
| use Joomla\Component\Contact\Administrator\Service\HTML\AdministratorService; | ||||
| use Joomla\Component\Contact\Administrator\Service\HTML\Icon; | ||||
| use Psr\Container\ContainerInterface; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Component class for com_contact | ||||
|  * | ||||
|  * @since  4.0.0 | ||||
|  */ | ||||
| class ContactComponent extends MVCComponent implements | ||||
|     BootableExtensionInterface, | ||||
|     CategoryServiceInterface, | ||||
|     FieldsFormServiceInterface, | ||||
|     SchemaorgServiceInterface, | ||||
|     AssociationServiceInterface, | ||||
|     RouterServiceInterface, | ||||
|     TagServiceInterface | ||||
| { | ||||
|     use AssociationServiceTrait; | ||||
|     use HTMLRegistryAwareTrait; | ||||
|     use RouterServiceTrait; | ||||
|     use SchemaorgServiceTrait; | ||||
|     use CategoryServiceTrait, TagServiceTrait, FieldsServiceTrait { | ||||
|         CategoryServiceTrait::getTableNameForSection insteadof TagServiceTrait; | ||||
|         CategoryServiceTrait::getStateColumnForSection insteadof TagServiceTrait; | ||||
|         CategoryServiceTrait::prepareForm insteadof FieldsServiceTrait; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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('contactadministrator', new AdministratorService()); | ||||
|         $this->getRegistry()->register('contacticon', new Icon($container->get(UserFactoryInterface::class))); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a valid section for the given section. If it is not valid then null | ||||
|      * is returned. | ||||
|      * | ||||
|      * @param   string  $section  The section to get the mapping for | ||||
|      * @param   object  $item     The item | ||||
|      * | ||||
|      * @return  string|null  The new section | ||||
|      * | ||||
|      * @since   4.0.0 | ||||
|      */ | ||||
|     public function validateSection($section, $item = null) | ||||
|     { | ||||
|         if (Factory::getApplication()->isClient('site') && $section == 'contact' && $item instanceof Form) { | ||||
|             // The contact form needs to be the mail section | ||||
|             $section = 'mail'; | ||||
|         } | ||||
|  | ||||
|         if (Factory::getApplication()->isClient('site') && ($section === 'category' || $section === 'form')) { | ||||
|             // The contact form needs to be the mail section | ||||
|             $section = 'contact'; | ||||
|         } | ||||
|  | ||||
|         if ($section !== 'mail' && $section !== 'contact') { | ||||
|             // We don't know other sections | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         return $section; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns valid contexts | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   4.0.0 | ||||
|      */ | ||||
|     public function getContexts(): array | ||||
|     { | ||||
|         Factory::getLanguage()->load('com_contact', JPATH_ADMINISTRATOR); | ||||
|  | ||||
|         $contexts = [ | ||||
|             'com_contact.contact'    => Text::_('COM_CONTACT_FIELDS_CONTEXT_CONTACT'), | ||||
|             'com_contact.mail'       => Text::_('COM_CONTACT_FIELDS_CONTEXT_MAIL'), | ||||
|             'com_contact.categories' => Text::_('JCATEGORY'), | ||||
|         ]; | ||||
|  | ||||
|         return $contexts; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the table for the count items functions for the given section. | ||||
|      * | ||||
|      * @param   ?string  $section  The section | ||||
|      * | ||||
|      * @return  string|null | ||||
|      * | ||||
|      * @since   4.0.0 | ||||
|      */ | ||||
|     protected function getTableNameForSection(?string $section = null) | ||||
|     { | ||||
|         return ($section === 'category' ? 'categories' : 'contact_details'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the state column for the count items functions for the given section. | ||||
|      * | ||||
|      * @param   ?string  $section  The section | ||||
|      * | ||||
|      * @return  string|null | ||||
|      * | ||||
|      * @since   4.0.0 | ||||
|      */ | ||||
|     protected function getStateColumnForSection(?string $section = null) | ||||
|     { | ||||
|         return 'published'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns valid contexts for schemaorg | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since  5.0.0 | ||||
|      */ | ||||
|     public function getSchemaorgContexts(): array | ||||
|     { | ||||
|         Factory::getLanguage()->load('com_content', JPATH_ADMINISTRATOR); | ||||
|  | ||||
|         $contexts = [ | ||||
|             'com_contact.contact' => Text::_('COM_CONTACT'), | ||||
|         ]; | ||||
|  | ||||
|         return $contexts; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,189 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @copyright   (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Contact\Administrator\Field\Modal; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Form\Field\ModalSelectField; | ||||
| use Joomla\CMS\Language\LanguageHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\Layout\FileLayout; | ||||
| use Joomla\CMS\Session\Session; | ||||
| use Joomla\CMS\Uri\Uri; | ||||
| use Joomla\Database\ParameterType; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Supports a modal contact picker. | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class ContactField extends ModalSelectField | ||||
| { | ||||
|     /** | ||||
|      * The form field type. | ||||
|      * | ||||
|      * @var     string | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected $type = 'Modal_Contact'; | ||||
|  | ||||
|     /** | ||||
|      * Method to attach a Form object to the field. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $element  The SimpleXMLElement object representing the `<field>` tag for the form field object. | ||||
|      * @param   mixed              $value    The form field value to validate. | ||||
|      * @param   string             $group    The field name group control value. | ||||
|      * | ||||
|      * @return  boolean  True on success. | ||||
|      * | ||||
|      * @see     FormField::setup() | ||||
|      * @since   5.1.0 | ||||
|      */ | ||||
|     public function setup(\SimpleXMLElement $element, $value, $group = null) | ||||
|     { | ||||
|         // Check if the value consist with id:alias, extract the id only | ||||
|         if ($value && str_contains($value, ':')) { | ||||
|             [$id]  = explode(':', $value, 2); | ||||
|             $value = (int) $id; | ||||
|         } | ||||
|  | ||||
|         $result = parent::setup($element, $value, $group); | ||||
|  | ||||
|         if (!$result) { | ||||
|             return $result; | ||||
|         } | ||||
|  | ||||
|         Factory::getApplication()->getLanguage()->load('com_contact', JPATH_ADMINISTRATOR); | ||||
|  | ||||
|         $languages = LanguageHelper::getContentLanguages([0, 1], false); | ||||
|         $language  = (string) $this->element['language']; | ||||
|  | ||||
|         // Prepare enabled actions | ||||
|         $this->canDo['propagate']  = ((string) $this->element['propagate'] == 'true') && \count($languages) > 2; | ||||
|  | ||||
|         // Prepare Urls | ||||
|         $linkItems = (new Uri())->setPath(Uri::base(true) . '/index.php'); | ||||
|         $linkItems->setQuery([ | ||||
|             'option'                => 'com_contact', | ||||
|             'view'                  => 'contacts', | ||||
|             'layout'                => 'modal', | ||||
|             'tmpl'                  => 'component', | ||||
|             Session::getFormToken() => 1, | ||||
|         ]); | ||||
|         $linkItem = clone $linkItems; | ||||
|         $linkItem->setVar('view', 'contact'); | ||||
|         $linkCheckin = (new Uri())->setPath(Uri::base(true) . '/index.php'); | ||||
|         $linkCheckin->setQuery([ | ||||
|             'option'                => 'com_contact', | ||||
|             'task'                  => 'contacts.checkin', | ||||
|             'format'                => 'json', | ||||
|             Session::getFormToken() => 1, | ||||
|         ]); | ||||
|  | ||||
|         if ($language) { | ||||
|             $linkItems->setVar('forcedLanguage', $language); | ||||
|             $linkItem->setVar('forcedLanguage', $language); | ||||
|  | ||||
|             $modalTitle = Text::_('COM_CONTACT_SELECT_A_CONTACT') . ' — ' . $this->getTitle(); | ||||
|  | ||||
|             $this->dataAttributes['data-language'] = $language; | ||||
|         } else { | ||||
|             $modalTitle = Text::_('COM_CONTACT_SELECT_A_CONTACT'); | ||||
|         } | ||||
|  | ||||
|         $urlSelect = $linkItems; | ||||
|         $urlEdit   = clone $linkItem; | ||||
|         $urlEdit->setVar('task', 'contact.edit'); | ||||
|         $urlNew    = clone $linkItem; | ||||
|         $urlNew->setVar('task', 'contact.add'); | ||||
|  | ||||
|         $this->urls['select']  = (string) $urlSelect; | ||||
|         $this->urls['new']     = (string) $urlNew; | ||||
|         $this->urls['edit']    = (string) $urlEdit; | ||||
|         $this->urls['checkin'] = (string) $linkCheckin; | ||||
|  | ||||
|         // Prepare titles | ||||
|         $this->modalTitles['select']  = $modalTitle; | ||||
|         $this->modalTitles['new']     = Text::_('COM_CONTACT_NEW_CONTACT'); | ||||
|         $this->modalTitles['edit']    = Text::_('COM_CONTACT_EDIT_CONTACT'); | ||||
|  | ||||
|         $this->hint = $this->hint ?: Text::_('COM_CONTACT_SELECT_A_CONTACT'); | ||||
|  | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to retrieve the title of selected item. | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @since   5.1.0 | ||||
|      */ | ||||
|     protected function getValueTitle() | ||||
|     { | ||||
|         $value = (int) $this->value ?: ''; | ||||
|         $title = ''; | ||||
|  | ||||
|         if ($value) { | ||||
|             try { | ||||
|                 $db    = $this->getDatabase(); | ||||
|                 $query = $db->getQuery(true) | ||||
|                     ->select($db->quoteName('name')) | ||||
|                     ->from($db->quoteName('#__contact_details')) | ||||
|                     ->where($db->quoteName('id') . ' = :value') | ||||
|                     ->bind(':value', $value, ParameterType::INTEGER); | ||||
|                 $db->setQuery($query); | ||||
|  | ||||
|                 $title = $db->loadResult(); | ||||
|             } catch (\Throwable $e) { | ||||
|                 Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $title ?: $value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the data to be passed to the layout for rendering. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since 5.1.0 | ||||
|      */ | ||||
|     protected function getLayoutData() | ||||
|     { | ||||
|         $data             = parent::getLayoutData(); | ||||
|         $data['language'] = (string) $this->element['language']; | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the renderer | ||||
|      * | ||||
|      * @param   string  $layoutId  Id to load | ||||
|      * | ||||
|      * @return  FileLayout | ||||
|      * | ||||
|      * @since   5.1.0 | ||||
|      */ | ||||
|     protected function getRenderer($layoutId = 'default') | ||||
|     { | ||||
|         $layout = parent::getRenderer($layoutId); | ||||
|         $layout->setComponent('com_contact'); | ||||
|         $layout->setClient(1); | ||||
|  | ||||
|         return $layout; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,209 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @copyright   (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Contact\Administrator\Helper; | ||||
|  | ||||
| use Joomla\CMS\Association\AssociationExtensionHelper; | ||||
| use Joomla\CMS\Language\Associations; | ||||
| use Joomla\CMS\Table\Table; | ||||
| use Joomla\Component\Contact\Site\Helper\AssociationHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Content associations helper. | ||||
|  * | ||||
|  * @since  3.7.0 | ||||
|  */ | ||||
| class AssociationsHelper extends AssociationExtensionHelper | ||||
| { | ||||
|     /** | ||||
|      * The extension name | ||||
|      * | ||||
|      * @var     array   $extension | ||||
|      * | ||||
|      * @since   3.7.0 | ||||
|      */ | ||||
|     protected $extension = 'com_contact'; | ||||
|  | ||||
|     /** | ||||
|      * Array of item types | ||||
|      * | ||||
|      * @var     array   $itemTypes | ||||
|      * | ||||
|      * @since   3.7.0 | ||||
|      */ | ||||
|     protected $itemTypes = ['contact', 'category']; | ||||
|  | ||||
|     /** | ||||
|      * Has the extension association support | ||||
|      * | ||||
|      * @var     boolean   $associationsSupport | ||||
|      * | ||||
|      * @since   3.7.0 | ||||
|      */ | ||||
|     protected $associationsSupport = true; | ||||
|  | ||||
|     /** | ||||
|      * Method to get the associations for a given item. | ||||
|      * | ||||
|      * @param   integer  $id    Id of the item | ||||
|      * @param   string   $view  Name of the view | ||||
|      * | ||||
|      * @return  array   Array of associations for the item | ||||
|      * | ||||
|      * @since  4.0.0 | ||||
|      */ | ||||
|     public function getAssociationsForItem($id = 0, $view = null) | ||||
|     { | ||||
|         return AssociationHelper::getAssociations($id, $view); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the associated items for an item | ||||
|      * | ||||
|      * @param   string  $typeName  The item type | ||||
|      * @param   int     $id        The id of item for which we need the associated items | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   3.7.0 | ||||
|      */ | ||||
|     public function getAssociations($typeName, $id) | ||||
|     { | ||||
|         $type = $this->getType($typeName); | ||||
|  | ||||
|         $context    = $this->extension . '.item'; | ||||
|         $catidField = 'catid'; | ||||
|  | ||||
|         if ($typeName === 'category') { | ||||
|             $context    = 'com_categories.item'; | ||||
|             $catidField = ''; | ||||
|         } | ||||
|  | ||||
|         // Get the associations. | ||||
|         $associations = Associations::getAssociations( | ||||
|             $this->extension, | ||||
|             $type['tables']['a'], | ||||
|             $context, | ||||
|             $id, | ||||
|             'id', | ||||
|             'alias', | ||||
|             $catidField | ||||
|         ); | ||||
|  | ||||
|         return $associations; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get item information | ||||
|      * | ||||
|      * @param   string  $typeName  The item type | ||||
|      * @param   int     $id        The id of item for which we need the associated items | ||||
|      * | ||||
|      * @return  Table|null | ||||
|      * | ||||
|      * @since   3.7.0 | ||||
|      */ | ||||
|     public function getItem($typeName, $id) | ||||
|     { | ||||
|         if (empty($id)) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         $table = null; | ||||
|  | ||||
|         switch ($typeName) { | ||||
|             case 'contact': | ||||
|                 $table = Table::getInstance('ContactTable', 'Joomla\\Component\\Contact\\Administrator\\Table\\'); | ||||
|                 break; | ||||
|  | ||||
|             case 'category': | ||||
|                 $table = Table::getInstance('Category'); | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         if (empty($table)) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         $table->load($id); | ||||
|  | ||||
|         return $table; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get information about the type | ||||
|      * | ||||
|      * @param   string  $typeName  The item type | ||||
|      * | ||||
|      * @return  array  Array of item types | ||||
|      * | ||||
|      * @since   3.7.0 | ||||
|      */ | ||||
|     public function getType($typeName = '') | ||||
|     { | ||||
|         $fields  = $this->getFieldsTemplate(); | ||||
|         $tables  = []; | ||||
|         $joins   = []; | ||||
|         $support = $this->getSupportTemplate(); | ||||
|         $title   = ''; | ||||
|  | ||||
|         if (\in_array($typeName, $this->itemTypes)) { | ||||
|             switch ($typeName) { | ||||
|                 case 'contact': | ||||
|                     $fields['title'] = 'a.name'; | ||||
|                     $fields['state'] = 'a.published'; | ||||
|  | ||||
|                     $support['state']     = true; | ||||
|                     $support['acl']       = true; | ||||
|                     $support['checkout']  = true; | ||||
|                     $support['category']  = true; | ||||
|                     $support['save2copy'] = true; | ||||
|  | ||||
|                     $tables = [ | ||||
|                         'a' => '#__contact_details', | ||||
|                     ]; | ||||
|  | ||||
|                     $title = 'contact'; | ||||
|                     break; | ||||
|  | ||||
|                 case 'category': | ||||
|                     $fields['created_user_id'] = 'a.created_user_id'; | ||||
|                     $fields['ordering']        = 'a.lft'; | ||||
|                     $fields['level']           = 'a.level'; | ||||
|                     $fields['catid']           = ''; | ||||
|                     $fields['state']           = 'a.published'; | ||||
|  | ||||
|                     $support['state']    = true; | ||||
|                     $support['acl']      = true; | ||||
|                     $support['checkout'] = true; | ||||
|                     $support['level']    = true; | ||||
|  | ||||
|                     $tables = [ | ||||
|                         'a' => '#__categories', | ||||
|                     ]; | ||||
|  | ||||
|                     $title = 'category'; | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return [ | ||||
|             'fields'  => $fields, | ||||
|             'support' => $support, | ||||
|             'tables'  => $tables, | ||||
|             'joins'   => $joins, | ||||
|             'title'   => $title, | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,26 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @copyright   (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Contact\Administrator\Helper; | ||||
|  | ||||
| use Joomla\CMS\Helper\ContentHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Contact component helper. | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class ContactHelper extends ContentHelper | ||||
| { | ||||
| } | ||||
							
								
								
									
										516
									
								
								administrator/components/com_contact/src/Model/ContactModel.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										516
									
								
								administrator/components/com_contact/src/Model/ContactModel.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,516 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @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\Contact\Administrator\Model; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Form\Form; | ||||
| use Joomla\CMS\Helper\TagsHelper; | ||||
| use Joomla\CMS\Language\Associations; | ||||
| use Joomla\CMS\Language\LanguageHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\Model\AdminModel; | ||||
| use Joomla\CMS\String\PunycodeHelper; | ||||
| use Joomla\CMS\Versioning\VersionableModelTrait; | ||||
| use Joomla\Component\Categories\Administrator\Helper\CategoriesHelper; | ||||
| use Joomla\Database\ParameterType; | ||||
| use Joomla\Registry\Registry; | ||||
| use Joomla\Utilities\ArrayHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Item Model for a Contact. | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class ContactModel extends AdminModel | ||||
| { | ||||
|     use VersionableModelTrait; | ||||
|  | ||||
|     /** | ||||
|      * The type alias for this content type. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  3.2 | ||||
|      */ | ||||
|     public $typeAlias = 'com_contact.contact'; | ||||
|  | ||||
|     /** | ||||
|      * The context used for the associations table | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  3.4.4 | ||||
|      */ | ||||
|     protected $associationsContext = 'com_contact.item'; | ||||
|  | ||||
|     /** | ||||
|      * Batch copy/move command. If set to false, the batch copy/move command is not supported | ||||
|      * | ||||
|      * @var  string | ||||
|      */ | ||||
|     protected $batch_copymove = 'category_id'; | ||||
|  | ||||
|     /** | ||||
|      * Allowed batch commands | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $batch_commands = [ | ||||
|         'assetgroup_id' => 'batchAccess', | ||||
|         'language_id'   => 'batchLanguage', | ||||
|         'tag'           => 'batchTag', | ||||
|         'user_id'       => 'batchUser', | ||||
|     ]; | ||||
|  | ||||
|     /** | ||||
|      * Name of the form | ||||
|      * | ||||
|      * @var string | ||||
|      * @since  4.0.0 | ||||
|      */ | ||||
|     protected $formName = 'contact'; | ||||
|  | ||||
|     /** | ||||
|      * Batch change a linked user. | ||||
|      * | ||||
|      * @param   integer  $value     The new value matching a User ID. | ||||
|      * @param   array    $pks       An array of row IDs. | ||||
|      * @param   array    $contexts  An array of item contexts. | ||||
|      * | ||||
|      * @return  boolean  True if successful, false otherwise and internal error is set. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     protected function batchUser($value, $pks, $contexts) | ||||
|     { | ||||
|         foreach ($pks as $pk) { | ||||
|             if ($this->user->authorise('core.edit', $contexts[$pk])) { | ||||
|                 $this->table->reset(); | ||||
|                 $this->table->load($pk); | ||||
|                 $this->table->user_id = (int) $value; | ||||
|  | ||||
|                 if (!$this->table->store()) { | ||||
|                     $this->setError($this->table->getError()); | ||||
|  | ||||
|                     return false; | ||||
|                 } | ||||
|             } else { | ||||
|                 $this->setError(Text::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); | ||||
|  | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Clean the cache | ||||
|         $this->cleanCache(); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to test whether a record can be deleted. | ||||
|      * | ||||
|      * @param   object  $record  A record object. | ||||
|      * | ||||
|      * @return  boolean  True if allowed to delete the record. Defaults to the permission set in the component. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function canDelete($record) | ||||
|     { | ||||
|         if (empty($record->id) || $record->published != -2) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return $this->getCurrentUser()->authorise('core.delete', 'com_contact.category.' . (int) $record->catid); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to test whether a record can have its state edited. | ||||
|      * | ||||
|      * @param   object  $record  A record object. | ||||
|      * | ||||
|      * @return  boolean  True if allowed to change the state of the record. Defaults to the permission set in the component. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function canEditState($record) | ||||
|     { | ||||
|         // Check against the category. | ||||
|         if (!empty($record->catid)) { | ||||
|             return $this->getCurrentUser()->authorise('core.edit.state', 'com_contact.category.' . (int) $record->catid); | ||||
|         } | ||||
|  | ||||
|         // Default to component settings if category not known. | ||||
|         return parent::canEditState($record); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the row 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  Form|boolean  A Form object on success, false on failure | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function getForm($data = [], $loadData = true) | ||||
|     { | ||||
|         Form::addFieldPath(JPATH_ADMINISTRATOR . '/components/com_users/models/fields'); | ||||
|  | ||||
|         // Get the form. | ||||
|         $form = $this->loadForm('com_contact.' . $this->formName, $this->formName, ['control' => 'jform', 'load_data' => $loadData]); | ||||
|  | ||||
|         if (empty($form)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Modify the form based on access controls. | ||||
|         if (!$this->canEditState((object) $data)) { | ||||
|             // Disable fields for display. | ||||
|             $form->setFieldAttribute('featured', 'disabled', 'true'); | ||||
|             $form->setFieldAttribute('ordering', 'disabled', 'true'); | ||||
|             $form->setFieldAttribute('published', 'disabled', 'true'); | ||||
|  | ||||
|             // Disable fields while saving. | ||||
|             // The controller has already verified this is a record you can edit. | ||||
|             $form->setFieldAttribute('featured', 'filter', 'unset'); | ||||
|             $form->setFieldAttribute('ordering', 'filter', 'unset'); | ||||
|             $form->setFieldAttribute('published', 'filter', 'unset'); | ||||
|         } | ||||
|  | ||||
|         // Don't allow to change the created_by user if not allowed to access com_users. | ||||
|         if (!$this->getCurrentUser()->authorise('core.manage', 'com_users')) { | ||||
|             $form->setFieldAttribute('created_by', 'filter', 'unset'); | ||||
|         } | ||||
|  | ||||
|         return $form; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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 ($item = parent::getItem($pk)) { | ||||
|             // Convert the metadata field to an array. | ||||
|             $registry       = new Registry($item->metadata); | ||||
|             $item->metadata = $registry->toArray(); | ||||
|         } | ||||
|  | ||||
|         // Load associated contact items | ||||
|         $assoc = Associations::isEnabled(); | ||||
|  | ||||
|         if ($assoc) { | ||||
|             $item->associations = []; | ||||
|  | ||||
|             if ($item->id != null) { | ||||
|                 $associations = Associations::getAssociations('com_contact', '#__contact_details', 'com_contact.item', $item->id); | ||||
|  | ||||
|                 foreach ($associations as $tag => $association) { | ||||
|                     $item->associations[$tag] = $association->id; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Load item tags | ||||
|         if (!empty($item->id)) { | ||||
|             $item->tags = new TagsHelper(); | ||||
|             $item->tags->getTagIds($item->id, 'com_contact.contact'); | ||||
|         } | ||||
|  | ||||
|         return $item; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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() | ||||
|     { | ||||
|         $app = Factory::getApplication(); | ||||
|  | ||||
|         // Check the session for previously entered form data. | ||||
|         $data = $app->getUserState('com_contact.edit.contact.data', []); | ||||
|  | ||||
|         if (empty($data)) { | ||||
|             $data = $this->getItem(); | ||||
|  | ||||
|             // Prime some default values. | ||||
|             if ($this->getState('contact.id') == 0) { | ||||
|                 $data->set('catid', $app->getInput()->get('catid', $app->getUserState('com_contact.contacts.filter.category_id'), 'int')); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $this->preprocessData('com_contact.contact', $data); | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to save the form data. | ||||
|      * | ||||
|      * @param   array  $data  The form data. | ||||
|      * | ||||
|      * @return  boolean  True on success. | ||||
|      * | ||||
|      * @since   3.0 | ||||
|      */ | ||||
|     public function save($data) | ||||
|     { | ||||
|         $input = Factory::getApplication()->getInput(); | ||||
|  | ||||
|         // Create new category, if needed. | ||||
|         $createCategory = true; | ||||
|  | ||||
|         // If category ID is provided, check if it's valid. | ||||
|         if (is_numeric($data['catid']) && $data['catid']) { | ||||
|             $createCategory = !CategoriesHelper::validateCategoryId($data['catid'], 'com_contact'); | ||||
|         } | ||||
|  | ||||
|         // Save New Category | ||||
|         if ($createCategory && $this->canCreateCategory()) { | ||||
|             $category = [ | ||||
|                 // Remove #new# prefix, if exists. | ||||
|                 'title'     => strpos($data['catid'], '#new#') === 0 ? substr($data['catid'], 5) : $data['catid'], | ||||
|                 'parent_id' => 1, | ||||
|                 'extension' => 'com_contact', | ||||
|                 'language'  => $data['language'], | ||||
|                 'published' => 1, | ||||
|             ]; | ||||
|  | ||||
|             /** @var \Joomla\Component\Categories\Administrator\Model\CategoryModel $categoryModel */ | ||||
|             $categoryModel = Factory::getApplication()->bootComponent('com_categories') | ||||
|                 ->getMVCFactory()->createModel('Category', 'Administrator', ['ignore_request' => true]); | ||||
|  | ||||
|             // Create new category. | ||||
|             if (!$categoryModel->save($category)) { | ||||
|                 $this->setError($categoryModel->getError()); | ||||
|  | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             // Get the Category ID. | ||||
|             $data['catid'] = $categoryModel->getState('category.id'); | ||||
|         } | ||||
|  | ||||
|         // Alter the name for save as copy | ||||
|         if ($input->get('task') == 'save2copy') { | ||||
|             $origTable = clone $this->getTable(); | ||||
|             $origTable->load($input->getInt('id')); | ||||
|  | ||||
|             if ($data['name'] == $origTable->name) { | ||||
|                 list($name, $alias) = $this->generateNewTitle($data['catid'], $data['alias'], $data['name']); | ||||
|                 $data['name']       = $name; | ||||
|                 $data['alias']      = $alias; | ||||
|             } else { | ||||
|                 if ($data['alias'] == $origTable->alias) { | ||||
|                     $data['alias'] = ''; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             $data['published'] = 0; | ||||
|         } | ||||
|  | ||||
|         $links = ['linka', 'linkb', 'linkc', 'linkd', 'linke']; | ||||
|  | ||||
|         foreach ($links as $link) { | ||||
|             if (!empty($data['params'][$link])) { | ||||
|                 $data['params'][$link] = PunycodeHelper::urlToPunycode($data['params'][$link]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return parent::save($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Prepare and sanitise the table prior to saving. | ||||
|      * | ||||
|      * @param   \Joomla\CMS\Table\Table  $table  The Table object | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function prepareTable($table) | ||||
|     { | ||||
|         $date = Factory::getDate()->toSql(); | ||||
|  | ||||
|         $table->name = htmlspecialchars_decode($table->name, ENT_QUOTES); | ||||
|  | ||||
|         $table->generateAlias(); | ||||
|  | ||||
|         if (empty($table->id)) { | ||||
|             // Set the values | ||||
|             $table->created = $date; | ||||
|  | ||||
|             // Set ordering to the last item if not set | ||||
|             if (empty($table->ordering)) { | ||||
|                 $db    = $this->getDatabase(); | ||||
|                 $query = $db->getQuery(true) | ||||
|                     ->select('MAX(ordering)') | ||||
|                     ->from($db->quoteName('#__contact_details')); | ||||
|                 $db->setQuery($query); | ||||
|                 $max = $db->loadResult(); | ||||
|  | ||||
|                 $table->ordering = $max + 1; | ||||
|             } | ||||
|         } else { | ||||
|             // Set the values | ||||
|             $table->modified    = $date; | ||||
|             $table->modified_by = $this->getCurrentUser()->id; | ||||
|         } | ||||
|  | ||||
|         // Increment the content version number. | ||||
|         $table->version++; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * A protected method to get a set of ordering conditions. | ||||
|      * | ||||
|      * @param   \Joomla\CMS\Table\Table  $table  A record object. | ||||
|      * | ||||
|      * @return  array  An array of conditions to add to ordering queries. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function getReorderConditions($table) | ||||
|     { | ||||
|         return [ | ||||
|             $this->getDatabase()->quoteName('catid') . ' = ' . (int) $table->catid, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Preprocess the form. | ||||
|      * | ||||
|      * @param   Form    $form   Form object. | ||||
|      * @param   object  $data   Data object. | ||||
|      * @param   string  $group  Group name. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   3.0.3 | ||||
|      */ | ||||
|     protected function preprocessForm(Form $form, $data, $group = 'content') | ||||
|     { | ||||
|         if ($this->canCreateCategory()) { | ||||
|             $form->setFieldAttribute('catid', 'allowAdd', 'true'); | ||||
|  | ||||
|             // Add a prefix for categories created on the fly. | ||||
|             $form->setFieldAttribute('catid', 'customPrefix', '#new#'); | ||||
|         } | ||||
|  | ||||
|         // Association contact items | ||||
|         if (Associations::isEnabled()) { | ||||
|             $languages = LanguageHelper::getContentLanguages(false, false, null, 'ordering', 'asc'); | ||||
|  | ||||
|             if (\count($languages) > 1) { | ||||
|                 $addform = new \SimpleXMLElement('<form />'); | ||||
|                 $fields  = $addform->addChild('fields'); | ||||
|                 $fields->addAttribute('name', 'associations'); | ||||
|                 $fieldset = $fields->addChild('fieldset'); | ||||
|                 $fieldset->addAttribute('name', 'item_associations'); | ||||
|  | ||||
|                 foreach ($languages as $language) { | ||||
|                     $field = $fieldset->addChild('field'); | ||||
|                     $field->addAttribute('name', $language->lang_code); | ||||
|                     $field->addAttribute('type', 'modal_contact'); | ||||
|                     $field->addAttribute('language', $language->lang_code); | ||||
|                     $field->addAttribute('label', $language->title); | ||||
|                     $field->addAttribute('translate_label', 'false'); | ||||
|                     $field->addAttribute('select', 'true'); | ||||
|                     $field->addAttribute('new', 'true'); | ||||
|                     $field->addAttribute('edit', 'true'); | ||||
|                     $field->addAttribute('clear', 'true'); | ||||
|                     $field->addAttribute('propagate', 'true'); | ||||
|                 } | ||||
|  | ||||
|                 $form->load($addform, false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         parent::preprocessForm($form, $data, $group); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to toggle the featured setting of contacts. | ||||
|      * | ||||
|      * @param   array    $pks    The ids of the items to toggle. | ||||
|      * @param   integer  $value  The value to toggle to. | ||||
|      * | ||||
|      * @return  boolean  True on success. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function featured($pks, $value = 0) | ||||
|     { | ||||
|         // Sanitize the ids. | ||||
|         $pks = ArrayHelper::toInteger((array) $pks); | ||||
|  | ||||
|         if (empty($pks)) { | ||||
|             $this->setError(Text::_('COM_CONTACT_NO_ITEM_SELECTED')); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $table = $this->getTable(); | ||||
|  | ||||
|         try { | ||||
|             $db = $this->getDatabase(); | ||||
|  | ||||
|             $query = $db->getQuery(true); | ||||
|             $query->update($db->quoteName('#__contact_details')); | ||||
|             $query->set($db->quoteName('featured') . ' = :featured'); | ||||
|             $query->whereIn($db->quoteName('id'), $pks); | ||||
|             $query->bind(':featured', $value, ParameterType::INTEGER); | ||||
|  | ||||
|             $db->setQuery($query); | ||||
|  | ||||
|             $db->execute(); | ||||
|         } catch (\Exception $e) { | ||||
|             $this->setError($e->getMessage()); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $table->reorder(); | ||||
|  | ||||
|         // Clean component's cache | ||||
|         $this->cleanCache(); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Is the user allowed to create an on the fly category? | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   3.6.1 | ||||
|      */ | ||||
|     private function canCreateCategory() | ||||
|     { | ||||
|         return $this->getCurrentUser()->authorise('core.create', 'com_contact'); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										358
									
								
								administrator/components/com_contact/src/Model/ContactsModel.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										358
									
								
								administrator/components/com_contact/src/Model/ContactsModel.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,358 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @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\Contact\Administrator\Model; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Language\Associations; | ||||
| use Joomla\CMS\MVC\Model\ListModel; | ||||
| use Joomla\CMS\Table\Table; | ||||
| use Joomla\Database\ParameterType; | ||||
| use Joomla\Database\QueryInterface; | ||||
| use Joomla\Utilities\ArrayHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Methods supporting a list of contact records. | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class ContactsModel extends ListModel | ||||
| { | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param   array  $config  An optional associative array of configuration settings. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function __construct($config = []) | ||||
|     { | ||||
|         if (empty($config['filter_fields'])) { | ||||
|             $config['filter_fields'] = [ | ||||
|                 'id', 'a.id', | ||||
|                 'name', 'a.name', | ||||
|                 'alias', 'a.alias', | ||||
|                 'checked_out', 'a.checked_out', | ||||
|                 'checked_out_time', 'a.checked_out_time', | ||||
|                 'catid', 'a.catid', 'category_id', 'category_title', | ||||
|                 'user_id', 'a.user_id', | ||||
|                 'published', 'a.published', | ||||
|                 'access', 'a.access', 'access_level', | ||||
|                 'created', 'a.created', | ||||
|                 'created_by', 'a.created_by', | ||||
|                 'ordering', 'a.ordering', | ||||
|                 'featured', 'a.featured', | ||||
|                 'language', 'a.language', 'language_title', | ||||
|                 'publish_up', 'a.publish_up', | ||||
|                 'publish_down', 'a.publish_down', | ||||
|                 'ul.name', 'linked_user', | ||||
|                 'tag', | ||||
|                 'level', 'c.level', | ||||
|             ]; | ||||
|  | ||||
|             if (Associations::isEnabled()) { | ||||
|                 $config['filter_fields'][] = 'association'; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         parent::__construct($config); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to auto-populate the model state. | ||||
|      * | ||||
|      * Note. Calling getState in this method will result in recursion. | ||||
|      * | ||||
|      * @param   string  $ordering   An optional ordering field. | ||||
|      * @param   string  $direction  An optional direction (asc|desc). | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function populateState($ordering = 'a.name', $direction = 'asc') | ||||
|     { | ||||
|         $app = Factory::getApplication(); | ||||
|  | ||||
|         $forcedLanguage = $app->getInput()->get('forcedLanguage', '', 'cmd'); | ||||
|  | ||||
|         // Adjust the context to support modal layouts. | ||||
|         if ($layout = $app->getInput()->get('layout')) { | ||||
|             $this->context .= '.' . $layout; | ||||
|         } | ||||
|  | ||||
|         // Adjust the context to support forced languages. | ||||
|         if ($forcedLanguage) { | ||||
|             $this->context .= '.' . $forcedLanguage; | ||||
|         } | ||||
|  | ||||
|         // List state information. | ||||
|         parent::populateState($ordering, $direction); | ||||
|  | ||||
|         // Force a language. | ||||
|         if (!empty($forcedLanguage)) { | ||||
|             $this->setState('filter.language', $forcedLanguage); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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.published'); | ||||
|         $id .= ':' . serialize($this->getState('filter.category_id')); | ||||
|         $id .= ':' . $this->getState('filter.access'); | ||||
|         $id .= ':' . $this->getState('filter.language'); | ||||
|         $id .= ':' . serialize($this->getState('filter.tag')); | ||||
|         $id .= ':' . $this->getState('filter.level'); | ||||
|  | ||||
|         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(); | ||||
|  | ||||
|         // Select the required fields from the table. | ||||
|         $query->select( | ||||
|             $db->quoteName( | ||||
|                 explode( | ||||
|                     ', ', | ||||
|                     $this->getState( | ||||
|                         'list.select', | ||||
|                         'a.id, a.name, a.alias, a.checked_out, a.checked_out_time, a.catid, a.user_id' . | ||||
|                         ', a.published, a.access, a.created, a.created_by, a.ordering, a.featured, a.language' . | ||||
|                         ', a.publish_up, a.publish_down' | ||||
|                     ) | ||||
|                 ) | ||||
|             ) | ||||
|         ); | ||||
|         $query->from($db->quoteName('#__contact_details', 'a')); | ||||
|  | ||||
|         // Join over the users for the linked user. | ||||
|         $query->select( | ||||
|             [ | ||||
|                 $db->quoteName('ul.name', 'linked_user'), | ||||
|                 $db->quoteName('ul.email'), | ||||
|             ] | ||||
|         ) | ||||
|             ->join( | ||||
|                 'LEFT', | ||||
|                 $db->quoteName('#__users', 'ul') . ' ON ' . $db->quoteName('ul.id') . ' = ' . $db->quoteName('a.user_id') | ||||
|             ); | ||||
|  | ||||
|         // Join over the language | ||||
|         $query->select($db->quoteName('l.title', 'language_title')) | ||||
|             ->select($db->quoteName('l.image', 'language_image')) | ||||
|             ->join( | ||||
|                 'LEFT', | ||||
|                 $db->quoteName('#__languages', 'l') . ' ON ' . $db->quoteName('l.lang_code') . ' = ' . $db->quoteName('a.language') | ||||
|             ); | ||||
|  | ||||
|         // Join over the users for the checked out user. | ||||
|         $query->select($db->quoteName('uc.name', 'editor')) | ||||
|             ->join( | ||||
|                 'LEFT', | ||||
|                 $db->quoteName('#__users', 'uc') . ' ON ' . $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out') | ||||
|             ); | ||||
|  | ||||
|         // Join over the asset groups. | ||||
|         $query->select($db->quoteName('ag.title', 'access_level')) | ||||
|             ->join( | ||||
|                 'LEFT', | ||||
|                 $db->quoteName('#__viewlevels', 'ag') . ' ON ' . $db->quoteName('ag.id') . ' = ' . $db->quoteName('a.access') | ||||
|             ); | ||||
|  | ||||
|         // Join over the categories. | ||||
|         $query->select($db->quoteName('c.title', 'category_title')) | ||||
|             ->join( | ||||
|                 'LEFT', | ||||
|                 $db->quoteName('#__categories', 'c') . ' ON ' . $db->quoteName('c.id') . ' = ' . $db->quoteName('a.catid') | ||||
|             ); | ||||
|  | ||||
|         // Join over the associations. | ||||
|         if (Associations::isEnabled()) { | ||||
|             $subQuery = $db->getQuery(true) | ||||
|                 ->select('COUNT(' . $db->quoteName('asso1.id') . ') > 1') | ||||
|                 ->from($db->quoteName('#__associations', 'asso1')) | ||||
|                 ->join('INNER', $db->quoteName('#__associations', 'asso2'), $db->quoteName('asso1.key') . ' = ' . $db->quoteName('asso2.key')) | ||||
|                 ->where( | ||||
|                     [ | ||||
|                         $db->quoteName('asso1.id') . ' = ' . $db->quoteName('a.id'), | ||||
|                         $db->quoteName('asso1.context') . ' = ' . $db->quote('com_contact.item'), | ||||
|                     ] | ||||
|                 ); | ||||
|  | ||||
|             $query->select('(' . $subQuery . ') AS ' . $db->quoteName('association')); | ||||
|         } | ||||
|  | ||||
|         // Filter by featured. | ||||
|         $featured = (string) $this->getState('filter.featured'); | ||||
|  | ||||
|         if (\in_array($featured, ['0','1'])) { | ||||
|             $query->where($db->quoteName('a.featured') . ' = ' . (int) $featured); | ||||
|         } | ||||
|  | ||||
|         // Filter by access level. | ||||
|         if ($access = $this->getState('filter.access')) { | ||||
|             $query->where($db->quoteName('a.access') . ' = :access'); | ||||
|             $query->bind(':access', $access, ParameterType::INTEGER); | ||||
|         } | ||||
|  | ||||
|         // Implement View Level Access | ||||
|         if (!$user->authorise('core.admin')) { | ||||
|             $query->whereIn($db->quoteName('a.access'), $user->getAuthorisedViewLevels()); | ||||
|         } | ||||
|  | ||||
|         // Filter by published state | ||||
|         $published = (string) $this->getState('filter.published'); | ||||
|  | ||||
|         if (is_numeric($published)) { | ||||
|             $query->where($db->quoteName('a.published') . ' = :published'); | ||||
|             $query->bind(':published', $published, ParameterType::INTEGER); | ||||
|         } elseif ($published === '') { | ||||
|             $query->where('(' . $db->quoteName('a.published') . ' = 0 OR ' . $db->quoteName('a.published') . ' = 1)'); | ||||
|         } | ||||
|  | ||||
|         // Filter by search in name. | ||||
|         $search = $this->getState('filter.search'); | ||||
|  | ||||
|         if (!empty($search)) { | ||||
|             if (stripos($search, 'id:') === 0) { | ||||
|                 $search = substr($search, 3); | ||||
|                 $query->where($db->quoteName('a.id') . ' = :id'); | ||||
|                 $query->bind(':id', $search, ParameterType::INTEGER); | ||||
|             } else { | ||||
|                 $search = '%' . trim($search) . '%'; | ||||
|                 $query->where( | ||||
|                     '(' . $db->quoteName('a.name') . ' LIKE :name OR ' . $db->quoteName('a.alias') . ' LIKE :alias)' | ||||
|                 ); | ||||
|                 $query->bind(':name', $search); | ||||
|                 $query->bind(':alias', $search); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Filter on the language. | ||||
|         if ($language = $this->getState('filter.language')) { | ||||
|             $query->where($db->quoteName('a.language') . ' = :language'); | ||||
|             $query->bind(':language', $language); | ||||
|         } | ||||
|  | ||||
|         // Filter by a single or group of tags. | ||||
|         $tag = $this->getState('filter.tag'); | ||||
|  | ||||
|         // Run simplified query when filtering by one tag. | ||||
|         if (\is_array($tag) && \count($tag) === 1) { | ||||
|             $tag = $tag[0]; | ||||
|         } | ||||
|  | ||||
|         if ($tag && \is_array($tag)) { | ||||
|             $tag = ArrayHelper::toInteger($tag); | ||||
|  | ||||
|             $subQuery = $db->getQuery(true) | ||||
|                 ->select('DISTINCT ' . $db->quoteName('content_item_id')) | ||||
|                 ->from($db->quoteName('#__contentitem_tag_map')) | ||||
|                 ->where( | ||||
|                     [ | ||||
|                         $db->quoteName('tag_id') . ' IN (' . implode(',', $query->bindArray($tag)) . ')', | ||||
|                         $db->quoteName('type_alias') . ' = ' . $db->quote('com_contact.contact'), | ||||
|                     ] | ||||
|                 ); | ||||
|  | ||||
|             $query->join( | ||||
|                 'INNER', | ||||
|                 '(' . $subQuery . ') AS ' . $db->quoteName('tagmap'), | ||||
|                 $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id') | ||||
|             ); | ||||
|         } elseif ($tag = (int) $tag) { | ||||
|             $query->join( | ||||
|                 'INNER', | ||||
|                 $db->quoteName('#__contentitem_tag_map', 'tagmap'), | ||||
|                 $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id') | ||||
|             ) | ||||
|                 ->where( | ||||
|                     [ | ||||
|                         $db->quoteName('tagmap.tag_id') . ' = :tag', | ||||
|                         $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_contact.contact'), | ||||
|                     ] | ||||
|                 ) | ||||
|                 ->bind(':tag', $tag, ParameterType::INTEGER); | ||||
|         } | ||||
|  | ||||
|         // Filter by categories and by level | ||||
|         $categoryId = $this->getState('filter.category_id', []); | ||||
|         $level      = $this->getState('filter.level'); | ||||
|  | ||||
|         if (!\is_array($categoryId)) { | ||||
|             $categoryId = $categoryId ? [$categoryId] : []; | ||||
|         } | ||||
|  | ||||
|         // Case: Using both categories filter and by level filter | ||||
|         if (\count($categoryId)) { | ||||
|             $categoryId       = ArrayHelper::toInteger($categoryId); | ||||
|             $categoryTable    = Table::getInstance('Category', '\\Joomla\\CMS\\Table\\'); | ||||
|             $subCatItemsWhere = []; | ||||
|  | ||||
|             // @todo: Convert to prepared statement | ||||
|             foreach ($categoryId as $filter_catid) { | ||||
|                 $categoryTable->load($filter_catid); | ||||
|                 $subCatItemsWhere[] = '(' . | ||||
|                     ($level ? 'c.level <= ' . ((int) $level + (int) $categoryTable->level - 1) . ' AND ' : '') . | ||||
|                     'c.lft >= ' . (int) $categoryTable->lft . ' AND ' . | ||||
|                     'c.rgt <= ' . (int) $categoryTable->rgt . ')'; | ||||
|             } | ||||
|  | ||||
|             $query->where('(' . implode(' OR ', $subCatItemsWhere) . ')'); | ||||
|         } elseif ($level) { | ||||
|             // Case: Using only the by level filter | ||||
|             $query->where($db->quoteName('c.level') . ' <= :level'); | ||||
|             $query->bind(':level', $level, ParameterType::INTEGER); | ||||
|         } | ||||
|  | ||||
|         // Add the list ordering clause. | ||||
|         $orderCol  = $this->state->get('list.ordering', 'a.name'); | ||||
|         $orderDirn = $this->state->get('list.direction', 'asc'); | ||||
|  | ||||
|         if ($orderCol == 'a.ordering' || $orderCol == 'category_title') { | ||||
|             $orderCol = $db->quoteName('c.title') . ' ' . $orderDirn . ', ' . $db->quoteName('a.ordering'); | ||||
|         } | ||||
|  | ||||
|         $query->order($db->escape($orderCol . ' ' . $orderDirn)); | ||||
|  | ||||
|         return $query; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,144 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @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\Contact\Administrator\Service\HTML; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Language\Associations; | ||||
| use Joomla\CMS\Language\LanguageHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\Layout\LayoutHelper; | ||||
| use Joomla\CMS\Router\Route; | ||||
| use Joomla\Database\ParameterType; | ||||
| use Joomla\Utilities\ArrayHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Contact HTML helper class. | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class AdministratorService | ||||
| { | ||||
|     /** | ||||
|      * Get the associated language flags | ||||
|      * | ||||
|      * @param   integer  $contactid  The item id to search associations | ||||
|      * | ||||
|      * @return  string  The language HTML | ||||
|      * | ||||
|      * @throws  \Exception | ||||
|      */ | ||||
|     public function association($contactid) | ||||
|     { | ||||
|         // Defaults | ||||
|         $html = ''; | ||||
|  | ||||
|         // Get the associations | ||||
|         if ($associations = Associations::getAssociations('com_contact', '#__contact_details', 'com_contact.item', $contactid)) { | ||||
|             foreach ($associations as $tag => $associated) { | ||||
|                 $associations[$tag] = (int) $associated->id; | ||||
|             } | ||||
|  | ||||
|             // Get the associated contact items | ||||
|             $db    = Factory::getDbo(); | ||||
|             $query = $db->getQuery(true) | ||||
|                 ->select( | ||||
|                     [ | ||||
|                         $db->quoteName('c.id'), | ||||
|                         $db->quoteName('c.name', 'title'), | ||||
|                         $db->quoteName('l.sef', 'lang_sef'), | ||||
|                         $db->quoteName('lang_code'), | ||||
|                         $db->quoteName('cat.title', 'category_title'), | ||||
|                         $db->quoteName('l.image'), | ||||
|                         $db->quoteName('l.title', 'language_title'), | ||||
|                     ] | ||||
|                 ) | ||||
|                 ->from($db->quoteName('#__contact_details', 'c')) | ||||
|                 ->join('LEFT', $db->quoteName('#__categories', 'cat'), $db->quoteName('cat.id') . ' = ' . $db->quoteName('c.catid')) | ||||
|                 ->join('LEFT', $db->quoteName('#__languages', 'l'), $db->quoteName('c.language') . ' = ' . $db->quoteName('l.lang_code')) | ||||
|                 ->whereIn($db->quoteName('c.id'), array_values($associations)) | ||||
|                 ->where($db->quoteName('c.id') . ' != :id') | ||||
|                 ->bind(':id', $contactid, ParameterType::INTEGER); | ||||
|             $db->setQuery($query); | ||||
|  | ||||
|             try { | ||||
|                 $items = $db->loadObjectList('id'); | ||||
|             } catch (\RuntimeException $e) { | ||||
|                 throw new \Exception($e->getMessage(), 500, $e); | ||||
|             } | ||||
|  | ||||
|             if ($items) { | ||||
|                 $languages         = LanguageHelper::getContentLanguages([0, 1]); | ||||
|                 $content_languages = array_column($languages, 'lang_code'); | ||||
|  | ||||
|                 foreach ($items as &$item) { | ||||
|                     if (\in_array($item->lang_code, $content_languages)) { | ||||
|                         $text    = $item->lang_code; | ||||
|                         $url     = Route::_('index.php?option=com_contact&task=contact.edit&id=' . (int) $item->id); | ||||
|                         $tooltip = '<strong>' . htmlspecialchars($item->language_title, ENT_QUOTES, 'UTF-8') . '</strong><br>' | ||||
|                             . htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8') . '<br>' . Text::sprintf('JCATEGORY_SPRINTF', $item->category_title); | ||||
|                         $classes = 'badge bg-secondary'; | ||||
|  | ||||
|                         $item->link = '<a href="' . $url . '" class="' . $classes . '">' . $text . '</a>' | ||||
|                             . '<div role="tooltip" id="tip-' . (int) $contactid . '-' . (int) $item->id . '">' . $tooltip . '</div>'; | ||||
|                     } else { | ||||
|                         // Display warning if Content Language is trashed or deleted | ||||
|                         Factory::getApplication()->enqueueMessage(Text::sprintf('JGLOBAL_ASSOCIATIONS_CONTENTLANGUAGE_WARNING', $item->lang_code), 'warning'); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             $html = LayoutHelper::render('joomla.content.associations', $items); | ||||
|         } | ||||
|  | ||||
|         return $html; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show the featured/not-featured icon. | ||||
|      * | ||||
|      * @param   integer  $value      The featured value. | ||||
|      * @param   integer  $i          Id of the item. | ||||
|      * @param   boolean  $canChange  Whether the value can be changed or not. | ||||
|      * | ||||
|      * @return  string  The anchor tag to toggle featured/unfeatured contacts. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function featured($value, $i, $canChange = true) | ||||
|     { | ||||
|         Factory::getDocument()->getWebAssetManager()->useScript('list-view'); | ||||
|  | ||||
|         // Array of image, task, title, action | ||||
|         $states = [ | ||||
|             0 => ['unfeatured', 'contacts.featured', 'COM_CONTACT_UNFEATURED', 'JGLOBAL_ITEM_FEATURE'], | ||||
|             1 => ['featured', 'contacts.unfeatured', 'JFEATURED', 'JGLOBAL_ITEM_UNFEATURE'], | ||||
|         ]; | ||||
|         $state       = ArrayHelper::getValue($states, (int) $value, $states[1]); | ||||
|         $icon        = $state[0] === 'featured' ? 'star featured' : 'circle'; | ||||
|         $tooltipText = Text::_($state[3]); | ||||
|  | ||||
|         if (!$canChange) { | ||||
|             $tooltipText = Text::_($state[2]); | ||||
|         } | ||||
|  | ||||
|         $html = '<button type="button" class="js-grid-item-action tbody-icon' . ($value == 1 ? ' active' : '') . '"' | ||||
|             . ' aria-labelledby="cb' . $i . '-desc" data-item-id="cb' . $i . '" data-item-task="' .  $state[1] . '">' | ||||
|             . '<span class="icon-' . $icon . '" aria-hidden="true"></span>' | ||||
|             . '</button>' | ||||
|             . '<div role="tooltip" id="cb' . $i . '-desc">' . $tooltipText . '</div>'; | ||||
|  | ||||
|         return $html; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										166
									
								
								administrator/components/com_contact/src/Service/HTML/Icon.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								administrator/components/com_contact/src/Service/HTML/Icon.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,166 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Site | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @copyright   (C) 2020 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Contact\Administrator\Service\HTML; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\HTML\HTMLHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\Layout\LayoutHelper; | ||||
| use Joomla\CMS\Router\Route; | ||||
| use Joomla\CMS\Uri\Uri; | ||||
| use Joomla\CMS\User\UserFactoryAwareTrait; | ||||
| use Joomla\CMS\User\UserFactoryInterface; | ||||
| use Joomla\Component\Contact\Site\Helper\RouteHelper; | ||||
| use Joomla\Registry\Registry; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Content Component HTML Helper | ||||
|  * | ||||
|  * @since  4.0.0 | ||||
|  */ | ||||
| class Icon | ||||
| { | ||||
|     use UserFactoryAwareTrait; | ||||
|  | ||||
|     /** | ||||
|      * Service constructor | ||||
|      * | ||||
|      * @param   UserFactoryInterface  $userFactory  The userFactory | ||||
|      * | ||||
|      * @since   4.0.0 | ||||
|      */ | ||||
|     public function __construct(UserFactoryInterface $userFactory) | ||||
|     { | ||||
|         $this->setUserFactory($userFactory); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to generate a link to the create item page for the given category | ||||
|      * | ||||
|      * @param   object    $category  The category information | ||||
|      * @param   Registry  $params    The item parameters | ||||
|      * @param   array     $attribs   Optional attributes for the link | ||||
|      * | ||||
|      * @return  string  The HTML markup for the create item link | ||||
|      * | ||||
|      * @since  4.0.0 | ||||
|      */ | ||||
|     public function create($category, $params, $attribs = []) | ||||
|     { | ||||
|         $uri = Uri::getInstance(); | ||||
|  | ||||
|         $url = 'index.php?option=com_contact&task=contact.add&return=' . base64_encode($uri) . '&id=0&catid=' . $category->id; | ||||
|  | ||||
|         $text = ''; | ||||
|  | ||||
|         if ($params->get('show_icons')) { | ||||
|             $text .= '<span class="icon-plus icon-fw" aria-hidden="true"></span>'; | ||||
|         } | ||||
|  | ||||
|         $text .= Text::_('COM_CONTACT_NEW_CONTACT'); | ||||
|  | ||||
|         // Add the button classes to the attribs array | ||||
|         if (isset($attribs['class'])) { | ||||
|             $attribs['class'] .= ' btn btn-primary'; | ||||
|         } else { | ||||
|             $attribs['class'] = 'btn btn-primary'; | ||||
|         } | ||||
|  | ||||
|         $button = HTMLHelper::_('link', Route::_($url), $text, $attribs); | ||||
|  | ||||
|         return $button; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display an edit icon for the contact. | ||||
|      * | ||||
|      * This icon will not display in a popup window, nor if the contact is trashed. | ||||
|      * Edit access checks must be performed in the calling code. | ||||
|      * | ||||
|      * @param   object    $contact  The contact information | ||||
|      * @param   Registry  $params   The item parameters | ||||
|      * @param   array     $attribs  Optional attributes for the link | ||||
|      * @param   boolean   $legacy   True to use legacy images, false to use icomoon based graphic | ||||
|      * | ||||
|      * @return  string   The HTML for the contact edit icon. | ||||
|      * | ||||
|      * @since   4.0.0 | ||||
|      */ | ||||
|     public function edit($contact, $params, $attribs = [], $legacy = false) | ||||
|     { | ||||
|         $user = Factory::getUser(); | ||||
|         $uri  = Uri::getInstance(); | ||||
|  | ||||
|         // Ignore if in a popup window. | ||||
|         if ($params && $params->get('popup')) { | ||||
|             return ''; | ||||
|         } | ||||
|  | ||||
|         // Ignore if the state is negative (trashed). | ||||
|         if ($contact->published < 0) { | ||||
|             return ''; | ||||
|         } | ||||
|  | ||||
|         // Show checked_out icon if the contact is checked out by a different user | ||||
|         if ( | ||||
|             property_exists($contact, 'checked_out') | ||||
|             && property_exists($contact, 'checked_out_time') | ||||
|             && !\is_null($contact->checked_out) | ||||
|             && $contact->checked_out !== $user->id | ||||
|         ) { | ||||
|             $checkoutUser = $this->getUserFactory()->loadUserById($contact->checked_out); | ||||
|             $date         = HTMLHelper::_('date', $contact->checked_out_time); | ||||
|             $tooltip      = Text::sprintf('COM_CONTACT_CHECKED_OUT_BY', $checkoutUser->name) | ||||
|                 . ' <br> ' . $date; | ||||
|  | ||||
|             $text = LayoutHelper::render('joomla.content.icons.edit_lock', ['contact' => $contact, 'tooltip' => $tooltip, 'legacy' => $legacy]); | ||||
|  | ||||
|             $attribs['aria-describedby'] = 'editcontact-' . (int) $contact->id; | ||||
|             $output                      = HTMLHelper::_('link', '#', $text, $attribs); | ||||
|  | ||||
|             return $output; | ||||
|         } | ||||
|  | ||||
|         $contactUrl = RouteHelper::getContactRoute($contact->slug, $contact->catid, $contact->language); | ||||
|         $url        = $contactUrl . '&task=contact.edit&id=' . $contact->id . '&return=' . base64_encode($uri); | ||||
|  | ||||
|         if ((int) $contact->published === 0) { | ||||
|             $tooltip = Text::_('COM_CONTACT_EDIT_UNPUBLISHED_CONTACT'); | ||||
|         } else { | ||||
|             $tooltip = Text::_('COM_CONTACT_EDIT_PUBLISHED_CONTACT'); | ||||
|         } | ||||
|  | ||||
|         $nowDate = strtotime(Factory::getDate()); | ||||
|         $icon    = $contact->published ? 'edit' : 'eye-slash'; | ||||
|  | ||||
|         if ( | ||||
|             ($contact->publish_up !== null && strtotime($contact->publish_up) > $nowDate) | ||||
|             || ($contact->publish_down !== null && strtotime($contact->publish_down) < $nowDate) | ||||
|         ) { | ||||
|             $icon = 'eye-slash'; | ||||
|         } | ||||
|  | ||||
|         $aria_described = 'editcontact-' . (int) $contact->id; | ||||
|  | ||||
|         $text = '<span class="icon-' . $icon . '" aria-hidden="true"></span>'; | ||||
|         $text .= Text::_('JGLOBAL_EDIT'); | ||||
|         $text .= '<div role="tooltip" id="' . $aria_described . '">' . $tooltip . '</div>'; | ||||
|  | ||||
|         $attribs['aria-describedby'] = $aria_described; | ||||
|         $output                      = HTMLHelper::_('link', Route::_($url), $text, $attribs); | ||||
|  | ||||
|         return $output; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										274
									
								
								administrator/components/com_contact/src/Table/ContactTable.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								administrator/components/com_contact/src/Table/ContactTable.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,274 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @copyright   (C) 2005 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Contact\Administrator\Table; | ||||
|  | ||||
| use Joomla\CMS\Application\ApplicationHelper; | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Filter\InputFilter; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\String\PunycodeHelper; | ||||
| use Joomla\CMS\Table\Table; | ||||
| use Joomla\CMS\Tag\TaggableTableInterface; | ||||
| use Joomla\CMS\Tag\TaggableTableTrait; | ||||
| use Joomla\CMS\User\CurrentUserInterface; | ||||
| use Joomla\CMS\User\CurrentUserTrait; | ||||
| use Joomla\CMS\Versioning\VersionableTableInterface; | ||||
| use Joomla\Database\DatabaseDriver; | ||||
| use Joomla\Event\DispatcherInterface; | ||||
| use Joomla\String\StringHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Contact Table class. | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class ContactTable extends Table implements VersionableTableInterface, TaggableTableInterface, CurrentUserInterface | ||||
| { | ||||
|     use TaggableTableTrait; | ||||
|     use CurrentUserTrait; | ||||
|  | ||||
|     /** | ||||
|      * Indicates that columns fully support the NULL value in the database | ||||
|      * | ||||
|      * @var    boolean | ||||
|      * @since  4.0.0 | ||||
|      */ | ||||
|     protected $_supportNullValue = true; | ||||
|  | ||||
|     /** | ||||
|      * Ensure the params and metadata are json encoded in the bind method | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  3.3 | ||||
|      */ | ||||
|     protected $_jsonEncode = ['params', 'metadata']; | ||||
|  | ||||
|     /** | ||||
|      * Constructor | ||||
|      * | ||||
|      * @param   DatabaseDriver        $db          Database connector object | ||||
|      * @param   ?DispatcherInterface  $dispatcher  Event dispatcher for this table | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __construct(DatabaseDriver $db, ?DispatcherInterface $dispatcher = null) | ||||
|     { | ||||
|         $this->typeAlias = 'com_contact.contact'; | ||||
|  | ||||
|         parent::__construct('#__contact_details', 'id', $db, $dispatcher); | ||||
|  | ||||
|         $this->setColumnAlias('title', 'name'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Stores a contact. | ||||
|      * | ||||
|      * @param   boolean  $updateNulls  True to update fields even if they are null. | ||||
|      * | ||||
|      * @return  boolean  True on success, false on failure. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function store($updateNulls = true) | ||||
|     { | ||||
|         $date   = Factory::getDate()->toSql(); | ||||
|         $userId = $this->getCurrentUser()->id; | ||||
|  | ||||
|         // Set created date if not set. | ||||
|         if (!(int) $this->created) { | ||||
|             $this->created = $date; | ||||
|         } | ||||
|  | ||||
|         if ($this->id) { | ||||
|             // Existing item | ||||
|             $this->modified_by = $userId; | ||||
|             $this->modified    = $date; | ||||
|         } else { | ||||
|             // Field created_by field can be set by the user, so we don't touch it if it's set. | ||||
|             if (empty($this->created_by)) { | ||||
|                 $this->created_by = $userId; | ||||
|             } | ||||
|  | ||||
|             if (!(int) $this->modified) { | ||||
|                 $this->modified = $date; | ||||
|             } | ||||
|  | ||||
|             if (empty($this->modified_by)) { | ||||
|                 $this->modified_by = $userId; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Store utf8 email as punycode | ||||
|         if ($this->email_to !== null) { | ||||
|             $this->email_to = PunycodeHelper::emailToPunycode($this->email_to); | ||||
|         } | ||||
|  | ||||
|         // Convert IDN urls to punycode | ||||
|         if ($this->webpage !== null) { | ||||
|             $this->webpage = PunycodeHelper::urlToPunycode($this->webpage); | ||||
|         } | ||||
|  | ||||
|         // Verify that the alias is unique | ||||
|         $table = new self($this->getDbo(), $this->getDispatcher()); | ||||
|  | ||||
|         if ($table->load(['alias' => $this->alias, 'catid' => $this->catid]) && ($table->id != $this->id || $this->id == 0)) { | ||||
|             // Is the existing contact trashed? | ||||
|             $this->setError(Text::_('COM_CONTACT_ERROR_UNIQUE_ALIAS')); | ||||
|  | ||||
|             if ($table->published === -2) { | ||||
|                 $this->setError(Text::_('COM_CONTACT_ERROR_UNIQUE_ALIAS_TRASHED')); | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return parent::store($updateNulls); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Overloaded check function | ||||
|      * | ||||
|      * @return  boolean  True on success, false on failure | ||||
|      * | ||||
|      * @see     \Joomla\CMS\Table\Table::check | ||||
|      * @since   1.5 | ||||
|      */ | ||||
|     public function check() | ||||
|     { | ||||
|         try { | ||||
|             parent::check(); | ||||
|         } catch (\Exception $e) { | ||||
|             $this->setError($e->getMessage()); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $this->default_con = (int) $this->default_con; | ||||
|  | ||||
|         if ($this->webpage !== null && InputFilter::checkAttribute(['href', $this->webpage])) { | ||||
|             $this->setError(Text::_('COM_CONTACT_WARNING_PROVIDE_VALID_URL')); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Check for valid name | ||||
|         if (trim($this->name) == '') { | ||||
|             $this->setError(Text::_('COM_CONTACT_WARNING_PROVIDE_VALID_NAME')); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Generate a valid alias | ||||
|         $this->generateAlias(); | ||||
|  | ||||
|         // Check for a valid category. | ||||
|         if (!$this->catid = (int) $this->catid) { | ||||
|             $this->setError(Text::_('JLIB_DATABASE_ERROR_CATEGORY_REQUIRED')); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Sanity check for user_id | ||||
|         if (!$this->user_id) { | ||||
|             $this->user_id = 0; | ||||
|         } | ||||
|  | ||||
|         // Check the publish down date is not earlier than publish up. | ||||
|         if ((int) $this->publish_down > 0 && $this->publish_down < $this->publish_up) { | ||||
|             $this->setError(Text::_('JGLOBAL_START_PUBLISH_AFTER_FINISH')); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if (!$this->id) { | ||||
|             // Hits must be zero on a new item | ||||
|             $this->hits = 0; | ||||
|         } | ||||
|  | ||||
|         // Clean up description -- eliminate quotes and <> brackets | ||||
|         if (!empty($this->metadesc)) { | ||||
|             // Only process if not empty | ||||
|             $badCharacters  = ["\"", '<', '>']; | ||||
|             $this->metadesc = StringHelper::str_ireplace($badCharacters, '', $this->metadesc); | ||||
|         } else { | ||||
|             $this->metadesc = ''; | ||||
|         } | ||||
|  | ||||
|         if (empty($this->params)) { | ||||
|             $this->params = '{}'; | ||||
|         } | ||||
|  | ||||
|         if (empty($this->metadata)) { | ||||
|             $this->metadata = '{}'; | ||||
|         } | ||||
|  | ||||
|         // Set publish_up, publish_down to null if not set | ||||
|         if (!$this->publish_up) { | ||||
|             $this->publish_up = null; | ||||
|         } | ||||
|  | ||||
|         if (!$this->publish_down) { | ||||
|             $this->publish_down = null; | ||||
|         } | ||||
|  | ||||
|         if (!$this->modified) { | ||||
|             $this->modified = $this->created; | ||||
|         } | ||||
|  | ||||
|         if (empty($this->modified_by)) { | ||||
|             $this->modified_by = $this->created_by; | ||||
|         } | ||||
|  | ||||
|         if (empty($this->hits)) { | ||||
|             $this->hits = 0; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Generate a valid alias from title / date. | ||||
|      * Remains public to be able to check for duplicated alias before saving | ||||
|      * | ||||
|      * @return  string | ||||
|      */ | ||||
|     public function generateAlias() | ||||
|     { | ||||
|         if (empty($this->alias)) { | ||||
|             $this->alias = $this->name; | ||||
|         } | ||||
|  | ||||
|         $this->alias = ApplicationHelper::stringURLSafe($this->alias, $this->language); | ||||
|  | ||||
|         if (trim(str_replace('-', '', $this->alias)) == '') { | ||||
|             $this->alias = Factory::getDate()->format('Y-m-d-H-i-s'); | ||||
|         } | ||||
|  | ||||
|         return $this->alias; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Get the type alias for the history and tags mapping table | ||||
|      * | ||||
|      * @return  string  The alias as described above | ||||
|      * | ||||
|      * @since   4.0.0 | ||||
|      */ | ||||
|     public function getTypeAlias() | ||||
|     { | ||||
|         return $this->typeAlias; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,239 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @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\Contact\Administrator\View\Contact; | ||||
|  | ||||
| use Joomla\CMS\Component\ComponentHelper; | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Helper\ContentHelper; | ||||
| use Joomla\CMS\Language\Associations; | ||||
| 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 a contact. | ||||
|  * | ||||
|  * @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; | ||||
|  | ||||
|     /** | ||||
|      * Array of fieldsets not to display | ||||
|      * | ||||
|      * @var    string[] | ||||
|      * | ||||
|      * @since  5.2.0 | ||||
|      */ | ||||
|     public $ignore_fieldsets = []; | ||||
|  | ||||
|     /** | ||||
|      * Display the view. | ||||
|      * | ||||
|      * @param   string  $tpl  The name of the template file to parse; automatically searches through the template paths. | ||||
|      * | ||||
|      * @return  void | ||||
|      */ | ||||
|     public function display($tpl = null) | ||||
|     { | ||||
|         // Initialise variables. | ||||
|         $this->form  = $this->get('Form'); | ||||
|         $this->item  = $this->get('Item'); | ||||
|         $this->state = $this->get('State'); | ||||
|  | ||||
|         if ($this->getLayout() === 'modalreturn') { | ||||
|             parent::display($tpl); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Check for errors. | ||||
|         if (\count($errors = $this->get('Errors'))) { | ||||
|             throw new GenericDataException(implode("\n", $errors), 500); | ||||
|         } | ||||
|  | ||||
|         // If we are forcing a language in modal (used for associations). | ||||
|         if ($this->getLayout() === 'modal' && $forcedLanguage = Factory::getApplication()->getInput()->get('forcedLanguage', '', 'cmd')) { | ||||
|             // Set the language field to the forcedLanguage and disable changing it. | ||||
|             $this->form->setValue('language', null, $forcedLanguage); | ||||
|             $this->form->setFieldAttribute('language', 'readonly', 'true'); | ||||
|  | ||||
|             // Only allow to select categories with All language or with the forced language. | ||||
|             $this->form->setFieldAttribute('catid', 'language', '*,' . $forcedLanguage); | ||||
|  | ||||
|             // Only allow to select tags with All language or with the forced language. | ||||
|             $this->form->setFieldAttribute('tags', 'language', '*,' . $forcedLanguage); | ||||
|         } | ||||
|  | ||||
|         if ($this->getLayout() !== 'modal') { | ||||
|             $this->addToolbar(); | ||||
|         } else { | ||||
|             $this->addModalToolbar(); | ||||
|         } | ||||
|  | ||||
|         parent::display($tpl); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add the page title and toolbar. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function addToolbar() | ||||
|     { | ||||
|         Factory::getApplication()->getInput()->set('hidemainmenu', true); | ||||
|  | ||||
|         $user       = $this->getCurrentUser(); | ||||
|         $userId     = $user->id; | ||||
|         $isNew      = ($this->item->id == 0); | ||||
|         $checkedOut = !(\is_null($this->item->checked_out) || $this->item->checked_out == $userId); | ||||
|         $toolbar    = $this->getDocument()->getToolbar(); | ||||
|  | ||||
|         // Since we don't track these assets at the item level, use the category id. | ||||
|         $canDo = ContentHelper::getActions('com_contact', 'category', $this->item->catid); | ||||
|  | ||||
|         ToolbarHelper::title($isNew ? Text::_('COM_CONTACT_MANAGER_CONTACT_NEW') : Text::_('COM_CONTACT_MANAGER_CONTACT_EDIT'), 'address-book contact'); | ||||
|  | ||||
|         // Build the actions for new and existing records. | ||||
|         if ($isNew) { | ||||
|             // For new records, check the create permission. | ||||
|             if (\count($user->getAuthorisedCategories('com_contact', 'core.create')) > 0) { | ||||
|                 $toolbar->apply('contact.apply'); | ||||
|  | ||||
|                 $saveGroup = $toolbar->dropdownButton('save-group'); | ||||
|  | ||||
|                 $saveGroup->configure( | ||||
|                     function (Toolbar $childBar) use ($user) { | ||||
|                         $childBar->save('contact.save'); | ||||
|  | ||||
|                         if ($user->authorise('core.create', 'com_menus.menu')) { | ||||
|                             $childBar->save('contact.save2menu', 'JTOOLBAR_SAVE_TO_MENU'); | ||||
|                         } | ||||
|  | ||||
|                         $childBar->save2new('contact.save2new'); | ||||
|                     } | ||||
|                 ); | ||||
|             } | ||||
|  | ||||
|             $toolbar->cancel('contact.cancel', 'JTOOLBAR_CANCEL'); | ||||
|         } else { | ||||
|             // Since it's an existing record, check the edit permission, or fall back to edit own if the owner. | ||||
|             $itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId); | ||||
|  | ||||
|             // Can't save the record if it's checked out and editable | ||||
|             if (!$checkedOut && $itemEditable) { | ||||
|                 $toolbar->apply('contact.apply'); | ||||
|             } | ||||
|  | ||||
|             $saveGroup = $toolbar->dropdownButton('save-group'); | ||||
|  | ||||
|             $saveGroup->configure( | ||||
|                 function (Toolbar $childBar) use ($checkedOut, $itemEditable, $canDo, $user) { | ||||
|                     // Can't save the record if it's checked out and editable | ||||
|                     if (!$checkedOut && $itemEditable) { | ||||
|                         $childBar->save('contact.save'); | ||||
|  | ||||
|                         // We can save this record, but check the create permission to see if we can return to make a new one. | ||||
|                         if ($canDo->get('core.create')) { | ||||
|                             $childBar->save2new('contact.save2new'); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     // If checked out, we can still save2menu | ||||
|                     if ($user->authorise('core.create', 'com_menus.menu')) { | ||||
|                         $childBar->save('contact.save2menu', 'JTOOLBAR_SAVE_TO_MENU'); | ||||
|                     } | ||||
|  | ||||
|                     // If checked out, we can still save | ||||
|                     if ($canDo->get('core.create')) { | ||||
|                         $childBar->save2copy('contact.save2copy'); | ||||
|                     } | ||||
|                 } | ||||
|             ); | ||||
|  | ||||
|             $toolbar->cancel('contact.cancel'); | ||||
|  | ||||
|             if (ComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $itemEditable) { | ||||
|                 $toolbar->versions('com_contact.contact', $this->item->id); | ||||
|             } | ||||
|  | ||||
|             if (Associations::isEnabled() && ComponentHelper::isEnabled('com_associations')) { | ||||
|                 $toolbar->standardButton('contract', 'JTOOLBAR_ASSOCIATIONS', 'contact.editAssociations') | ||||
|                     ->icon('icon-contract') | ||||
|                     ->listCheck(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $toolbar->divider(); | ||||
|         $toolbar->help('Contacts:_Edit'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add the modal toolbar. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   5.1.0 | ||||
|      * | ||||
|      * @throws  \Exception | ||||
|      */ | ||||
|     protected function addModalToolbar() | ||||
|     { | ||||
|         $user       = $this->getCurrentUser(); | ||||
|         $userId     = $user->id; | ||||
|         $isNew      = ($this->item->id == 0); | ||||
|         $toolbar    = $this->getDocument()->getToolbar(); | ||||
|  | ||||
|         // Since we don't track these assets at the item level, use the category id. | ||||
|         $canDo = ContentHelper::getActions('com_contact', 'category', $this->item->catid); | ||||
|  | ||||
|         ToolbarHelper::title($isNew ? Text::_('COM_CONTACT_MANAGER_CONTACT_NEW') : Text::_('COM_CONTACT_MANAGER_CONTACT_EDIT'), 'address-book contact'); | ||||
|  | ||||
|         $canCreate = $isNew && (\count($user->getAuthorisedCategories('com_contact', 'core.create')) > 0); | ||||
|         $canEdit   = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId); | ||||
|  | ||||
|         // For new records, check the create permission. | ||||
|         if ($canCreate || $canEdit) { | ||||
|             $toolbar->apply('contact.apply'); | ||||
|             $toolbar->save('contact.save'); | ||||
|         } | ||||
|  | ||||
|         $toolbar->cancel('contact.cancel'); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,204 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_contact | ||||
|  * | ||||
|  * @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\Contact\Administrator\View\Contacts; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Helper\ContentHelper; | ||||
| use Joomla\CMS\Language\Multilanguage; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\View\GenericDataException; | ||||
| use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; | ||||
| use Joomla\CMS\Toolbar\Button\DropdownButton; | ||||
| 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 contacts. | ||||
|  * | ||||
|  * @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 | ||||
|      */ | ||||
|     public $filterForm; | ||||
|  | ||||
|     /** | ||||
|      * The active search filters | ||||
|      * | ||||
|      * @var  array | ||||
|      */ | ||||
|     public $activeFilters; | ||||
|  | ||||
|     /** | ||||
|      * Is this view an Empty State | ||||
|      * | ||||
|      * @var   boolean | ||||
|      * | ||||
|      * @since 4.0.0 | ||||
|      */ | ||||
|     private $isEmptyState = false; | ||||
|  | ||||
|     /** | ||||
|      * Display the view. | ||||
|      * | ||||
|      * @param   string  $tpl  The name of the template file to parse; automatically searches through the template paths. | ||||
|      * | ||||
|      * @return  void | ||||
|      */ | ||||
|     public function display($tpl = null) | ||||
|     { | ||||
|         $this->items         = $this->get('Items'); | ||||
|         $this->pagination    = $this->get('Pagination'); | ||||
|         $this->state         = $this->get('State'); | ||||
|         $this->filterForm    = $this->get('FilterForm'); | ||||
|         $this->activeFilters = $this->get('ActiveFilters'); | ||||
|  | ||||
|         if (!\count($this->items) && $this->isEmptyState = $this->get('IsEmptyState')) { | ||||
|             $this->setLayout('emptystate'); | ||||
|         } | ||||
|  | ||||
|         // Check for errors. | ||||
|         if (\count($errors = $this->get('Errors'))) { | ||||
|             throw new GenericDataException(implode("\n", $errors), 500); | ||||
|         } | ||||
|  | ||||
|         // We don't need toolbar in the modal window. | ||||
|         if ($this->getLayout() !== 'modal') { | ||||
|             $this->addToolbar(); | ||||
|  | ||||
|             // We do not need to filter by language when multilingual is disabled | ||||
|             if (!Multilanguage::isEnabled()) { | ||||
|                 unset($this->activeFilters['language']); | ||||
|                 $this->filterForm->removeField('language', 'filter'); | ||||
|             } | ||||
|         } else { | ||||
|             // In article associations modal we need to remove language filter if forcing a language. | ||||
|             // We also need to change the category filter to show show categories with All or the forced language. | ||||
|             if ($forcedLanguage = Factory::getApplication()->getInput()->get('forcedLanguage', '', 'CMD')) { | ||||
|                 // If the language is forced we can't allow to select the language, so transform the language selector filter into a hidden field. | ||||
|                 $languageXml = new \SimpleXMLElement('<field name="language" type="hidden" default="' . $forcedLanguage . '" />'); | ||||
|                 $this->filterForm->setField($languageXml, 'filter', true); | ||||
|  | ||||
|                 // Also, unset the active language filter so the search tools is not open by default with this filter. | ||||
|                 unset($this->activeFilters['language']); | ||||
|  | ||||
|                 // One last changes needed is to change the category filter to just show categories with All language or with the forced language. | ||||
|                 $this->filterForm->setFieldAttribute('category_id', 'language', '*,' . $forcedLanguage, 'filter'); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         parent::display($tpl); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add the page title and toolbar. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function addToolbar() | ||||
|     { | ||||
|         $canDo = ContentHelper::getActions('com_contact', 'category', $this->state->get('filter.category_id')); | ||||
|         $user  = $this->getCurrentUser(); | ||||
|  | ||||
|         // Get the toolbar object instance | ||||
|         $toolbar = $this->getDocument()->getToolbar(); | ||||
|  | ||||
|         ToolbarHelper::title(Text::_('COM_CONTACT_MANAGER_CONTACTS'), 'address-book contact'); | ||||
|  | ||||
|         if ($canDo->get('core.create') || \count($user->getAuthorisedCategories('com_contact', 'core.create')) > 0) { | ||||
|             $toolbar->addNew('contact.add'); | ||||
|         } | ||||
|  | ||||
|         if (!$this->isEmptyState && $canDo->get('core.edit.state')) { | ||||
|             /** @var  DropdownButton $dropdown */ | ||||
|             $dropdown = $toolbar->dropdownButton('status-group', 'JTOOLBAR_CHANGE_STATUS') | ||||
|                 ->toggleSplit(false) | ||||
|                 ->icon('icon-ellipsis-h') | ||||
|                 ->buttonClass('btn btn-action') | ||||
|                 ->listCheck(true); | ||||
|  | ||||
|             $childBar = $dropdown->getChildToolbar(); | ||||
|  | ||||
|             $childBar->publish('contacts.publish')->listCheck(true); | ||||
|             $childBar->unpublish('contacts.unpublish')->listCheck(true); | ||||
|             $childBar->standardButton('featured', 'JFEATURE', 'contacts.featured') | ||||
|                 ->listCheck(true); | ||||
|             $childBar->standardButton('unfeatured', 'JUNFEATURE', 'contacts.unfeatured') | ||||
|                 ->listCheck(true); | ||||
|             $childBar->archive('contacts.archive')->listCheck(true); | ||||
|  | ||||
|             if ($user->authorise('core.admin')) { | ||||
|                 $childBar->checkin('contacts.checkin'); | ||||
|             } | ||||
|  | ||||
|             if ($this->state->get('filter.published') != -2) { | ||||
|                 $childBar->trash('contacts.trash')->listCheck(true); | ||||
|             } | ||||
|  | ||||
|             // Add a batch button | ||||
|             if ( | ||||
|                 $user->authorise('core.create', 'com_contact') | ||||
|                 && $user->authorise('core.edit', 'com_contact') | ||||
|                 && $user->authorise('core.edit.state', 'com_contact') | ||||
|             ) { | ||||
|                 $childBar->popupButton('batch', 'JTOOLBAR_BATCH') | ||||
|                     ->popupType('inline') | ||||
|                     ->textHeader(Text::_('COM_CONTACT_BATCH_OPTIONS')) | ||||
|                     ->url('#joomla-dialog-batch') | ||||
|                     ->modalWidth('800px') | ||||
|                     ->modalHeight('fit-content') | ||||
|                     ->listCheck(true); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!$this->isEmptyState && $this->state->get('filter.published') == -2 && $canDo->get('core.delete')) { | ||||
|             $toolbar->delete('contacts.delete', 'JTOOLBAR_DELETE_FROM_TRASH') | ||||
|                 ->message('JGLOBAL_CONFIRM_DELETE') | ||||
|                 ->listCheck(true); | ||||
|         } | ||||
|  | ||||
|         if ($user->authorise('core.admin', 'com_contact') || $user->authorise('core.options', 'com_contact')) { | ||||
|             $toolbar->preferences('com_contact'); | ||||
|         } | ||||
|  | ||||
|         $toolbar->help('Contacts'); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user