diff --git a/administrator/components/com_actionlogs/actionlogs.php b/administrator/components/com_actionlogs/actionlogs.php new file mode 100644 index 0000000000000..1a9fd3dfa433d --- /dev/null +++ b/administrator/components/com_actionlogs/actionlogs.php @@ -0,0 +1,19 @@ +authorise('core.manage', 'com_actionlogs')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = JControllerLegacy::getInstance('Actionlogs'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/administrator/components/com_actionlogs/actionlogs.xml b/administrator/components/com_actionlogs/actionlogs.xml new file mode 100644 index 0000000000000..a1361cebe8a51 --- /dev/null +++ b/administrator/components/com_actionlogs/actionlogs.xml @@ -0,0 +1,29 @@ + + + com_actionlogs + Joomla! Project + May 2018 + Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + __DEPLOY_VERSION__ + COM_ACTIONLOGS_XML_DESCRIPTION + + COM_ACTIONLOGS + + actionlogs.php + config.xml + access.xml + controller.php + controllers + helpers + models + views + + + language/en-GB.com_actionlogs.ini + language/en-GB.com_actionlogs.sys.ini + + + diff --git a/administrator/components/com_actionlogs/config.xml b/administrator/components/com_actionlogs/config.xml new file mode 100644 index 0000000000000..e6d1d16305fc1 --- /dev/null +++ b/administrator/components/com_actionlogs/config.xml @@ -0,0 +1,35 @@ + + +
+ + + + + + + + + +
+
diff --git a/administrator/components/com_actionlogs/controller.php b/administrator/components/com_actionlogs/controller.php new file mode 100644 index 0000000000000..f1e3b5c9ee24f --- /dev/null +++ b/administrator/components/com_actionlogs/controller.php @@ -0,0 +1,19 @@ +registerTask('exportSelectedLogs', 'exportLogs'); + } + + /** + * Method to get a model object, loading it if required. + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return object The model. + * + * @since __DEPLOY_VERSION__ + */ + public function getModel($name = 'Actionlogs', $prefix = 'ActionlogsModel', $config = array('ignore_request' => true)) + { + // Return the model + return parent::getModel($name, $prefix, $config); + } + + /** + * Method to export logs + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function exportLogs() + { + // Check for request forgeries. + JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); + + // Get selected logs + $pks = ArrayHelper::toInteger($this->input->post->get('cid', array(), 'array')); + + // Get the logs data + $data = $this->getModel()->getLogsData($pks); + + if (count($data)) + { + $rows = ActionlogsHelper::getCsvData($data); + $filename = 'logs_' . JFactory::getDate()->format('Y-m-d_His_T'); + $csvDelimiter = ComponentHelper::getComponent('com_actionlogs')->getParams()->get('csv_delimiter', ','); + + $app = JFactory::getApplication(); + $app->setHeader('Content-Type', 'application/csv', true) + ->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '.csv"', true) + ->setHeader('Cache-Control', 'must-revalidate', true) + ->sendHeaders(); + + $output = fopen("php://output", "w"); + + foreach ($rows as $row) + { + fputcsv($output, $row, $csvDelimiter); + } + + fclose($output); + + $app->close(); + } + else + { + $this->setMessage(JText::_('COM_ACTIONLOGS_NO_LOGS_TO_EXPORT')); + $this->setRedirect(JRoute::_('index.php?option=com_actionlogs&view=actionlogs', false)); + } + } + + /** + * Clean out the logs + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function purge() + { + $model = $this->getModel(); + + if ($model->purge()) + { + $message = JText::_('COM_ACTIONLOGS_PURGE_SUCCESS'); + } + else + { + $message = JText::_('COM_ACTIONLOGS_PURGE_FAIL'); + } + + $this->setRedirect(JRoute::_('index.php?option=com_actionlogs&view=actionlogs', false), $message); + } +} diff --git a/administrator/components/com_actionlogs/helpers/actionlogs.php b/administrator/components/com_actionlogs/helpers/actionlogs.php new file mode 100644 index 0000000000000..0a6f6931ac11e --- /dev/null +++ b/administrator/components/com_actionlogs/helpers/actionlogs.php @@ -0,0 +1,281 @@ +extension, '.'); + static::loadTranslationFiles($extension); + $row = array(); + $row['id'] = $log->id; + $row['message'] = strip_tags(static::getHumanReadableLogMessage($log)); + $row['date'] = JHtml::_('date', $log->log_date, JText::_('DATE_FORMAT_LC6')); + $row['extension'] = JText::_($extension); + $row['name'] = $log->name; + $row['ip_address'] = JText::_($log->ip_address); + + $rows[] = $row; + } + + return $rows; + } + + /** + * Load the translation files for an extension + * + * @param string $extension Extension name + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public static function loadTranslationFiles($extension) + { + static $cache = array(); + + if (isset($cache[$extension])) + { + return; + } + + $lang = JFactory::getLanguage(); + + switch (substr($extension, 0, 3)) + { + case 'com': + default: + $source = JPATH_ADMINISTRATOR . '/components/' . $extension; + break; + + case 'lib': + $source = JPATH_LIBRARIES . '/' . substr($extension, 4); + break; + + case 'mod': + $source = JPATH_SITE . '/modules/' . $extension; + break; + + case 'plg': + $parts = explode('_', $extension, 3); + $source = JPATH_PLUGINS . '/' . $parts[1] . '/' . $parts[2]; + break; + + case 'tpl': + $source = JPATH_BASE . '/templates/' . substr($extension, 4); + break; + + } + + $lang->load(strtolower($extension), JPATH_ADMINISTRATOR, null, false, true) + || $lang->load(strtolower($extension), $source, null, false, true); + + $cache[$extension] = true; + } + + /** + * Get parameters to be + * + * @param string $context The context of the content + * + * @return mixed An object contains content type parameters, or null if not found + * + * @since __DEPLOY_VERSION__ + */ + public static function getLogContentTypeParams($context) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('a.*') + ->from($db->quoteName('#__action_log_config', 'a')) + ->where($db->quoteName('a.type_alias') . ' = ' . $db->quote($context)); + + $db->setQuery($query); + + return $db->loadObject(); + } + + /** + * Get human readable log message for a User Action Log + * + * @param stdClass $log A User Action log message record + * + * @return string + * + * @since __DEPLOY_VERSION__ + */ + public static function getHumanReadableLogMessage($log) + { + $message = JText::_($log->message_language_key); + $messageData = json_decode($log->message, true); + + // Special handling for translation extension name + if (isset($messageData['extension_name'])) + { + static::loadTranslationFiles($messageData['extension_name']); + $messageData['extension_name'] = JText::_($messageData['extension_name']); + } + + $linkMode = JFactory::getApplication()->get('force_ssl', 0) >= 1 ? 1 : -1; + + foreach ($messageData as $key => $value) + { + // Convert relative url to absolute url so that it is clickable in action logs notification email + if (StringHelper::strpos($value, 'index.php?') === 0) + { + $value = JRoute::link('administrator', $value, false, $linkMode); + } + + $message = str_replace('{' . $key . '}', JText::_($value), $message); + } + + return $message; + } + + /** + * Get link to an item of given content type + * + * @param string $component + * @param string $contentType + * @param integer $id + * @param string $urlVar + * + * @return string Link to the content item + * + * @since __DEPLOY_VERSION__ + */ + public static function getContentTypeLink($component, $contentType, $id, $urlVar = 'id') + { + // Try to find the component helper. + $eName = str_replace('com_', '', $component); + $file = Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/helpers/' . $eName . '.php'); + + if (file_exists($file)) + { + $prefix = ucfirst(str_replace('com_', '', $component)); + $cName = $prefix . 'Helper'; + + JLoader::register($cName, $file); + + if (class_exists($cName) && is_callable(array($cName, 'getContentTypeLink'))) + { + return $cName::getContentTypeLink($contentType, $id); + } + } + + if (empty($urlVar)) + { + $urlVar = 'id'; + } + + // Return default link to avoid having to implement getContentTypeLink in most of our components + return 'index.php?option=' . $component . '&task=' . $contentType . '.edit&' . $urlVar . '=' . $id; + } + + /** + * Load both enabled and disabled actionlog plugins language file. + * + * It is used to make sure actions log is displayed properly instead of only language items displayed when a plugin is disabled. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public static function loadActionLogPluginsLanguage() + { + $lang = JFactory::getLanguage(); + $db = JFactory::getDbo(); + + // Get all (both enabled and disabled) actionlog plugins + $query = $db->getQuery(true) + ->select( + $db->quoteName( + array( + 'folder', + 'element', + 'params', + 'extension_id' + ), + array( + 'type', + 'name', + 'params', + 'id' + ) + ) + ) + ->from('#__extensions') + ->where('type = ' . $db->quote('plugin')) + ->where('folder = ' . $db->quote('actionlog')) + ->where('state IN (0,1)') + ->order('ordering'); + $db->setQuery($query); + + try + { + $rows = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + $rows = array(); + } + + if (empty($rows)) + { + return; + } + + foreach ($rows as $row) + { + $name = $row->name; + $type = $row->type; + $extension = 'Plg_' . $type . '_' . $name; + $extension = strtolower($extension); + + // If language already loaded, don't load it again. + if ($lang->getPaths($extension)) + { + continue; + } + + $lang->load($extension, JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($extension, JPATH_PLUGINS . '/' . $type . '/' . $name, null, false, true); + } + + // Load com_privacy too. + $lang->load('com_privacy', JPATH_ADMINISTRATOR, null, false, true); + } +} diff --git a/administrator/components/com_actionlogs/layouts/logstable.php b/administrator/components/com_actionlogs/layouts/logstable.php new file mode 100644 index 0000000000000..26952302b8492 --- /dev/null +++ b/administrator/components/com_actionlogs/layouts/logstable.php @@ -0,0 +1,46 @@ +load("com_actionlogs", JPATH_ADMINISTRATOR, null, false, true); + +$messages = $displayData['messages']; +$showIpColumn = $displayData['showIpColumn']; +?> +

+ +

+

+ +

+ + + + + + + + + + + + + + + + + + + + + + + +
message; ?>log_date; ?>extension; ?>ip_address); ?>
diff --git a/administrator/components/com_actionlogs/models/actionlog.php b/administrator/components/com_actionlogs/models/actionlog.php new file mode 100644 index 0000000000000..5a69b28143eb7 --- /dev/null +++ b/administrator/components/com_actionlogs/models/actionlog.php @@ -0,0 +1,167 @@ +getDbo(); + $date = JFactory::getDate(); + $params = ComponentHelper::getComponent('com_actionlogs')->getParams(); + + if ($params->get('ip_logging', 0)) + { + $ip = JFactory::getApplication()->input->server->get('REMOTE_ADDR', null, 'raw'); + + if (!filter_var($ip, FILTER_VALIDATE_IP)) + { + $ip = 'COM_ACTIONLOGS_IP_INVALID'; + } + } + else + { + $ip = 'COM_ACTIONLOGS_DISABLED'; + } + + $loggedMessages = array(); + + foreach ($messages as $message) + { + $logMessage = new stdClass; + $logMessage->message_language_key = $messageLanguageKey; + $logMessage->message = json_encode($message); + $logMessage->log_date = (string) $date; + $logMessage->extension = $context; + $logMessage->user_id = $user->id; + $logMessage->ip_address = $ip; + $logMessage->item_id = isset($message['id']) ? (int) $message['id'] : 0; + + try + { + $db->insertObject('#__action_logs', $logMessage); + $loggedMessages[] = $logMessage; + } + catch (RuntimeException $e) + { + // Ignore it + } + } + + // Send notification email to users who choose to be notified about the action logs + $this->sendNotificationEmails($loggedMessages, $user->name, $context); + } + + /** + * Send notification emails about the action log + * + * @param array $messages The logged messages + * @param string $username The username + * @param string $context The Context + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function sendNotificationEmails($messages, $username, $context) + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + $params = ComponentHelper::getParams('com_actionlogs'); + $showIpColumn = (bool) $params->get('ip_logging', 0); + + $query->select($db->quoteName(array('email', 'params'))) + ->from($db->quoteName('#__users')) + ->where($db->quoteName('params') . ' LIKE ' . $db->quote('%"logs_notification_option":1%')); + + $db->setQuery($query); + + try + { + $users = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + + return; + } + + $recipients = array(); + + foreach ($users as $user) + { + $userParams = json_decode($user->params, true); + $extensions = $userParams['logs_notification_extensions']; + + if (in_array(strtok($context, '.'), $extensions)) + { + $recipients[] = $user->email; + } + } + + if (empty($recipients)) + { + return; + } + + $layout = new JLayoutFile('components.com_actionlogs.layouts.logstable', JPATH_ADMINISTRATOR); + $extension = strtok($context, '.'); + ActionlogsHelper::loadTranslationFiles($extension); + + foreach ($messages as $message) + { + $message->extension = JText::_($extension); + $message->message = ActionlogsHelper::getHumanReadableLogMessage($message); + } + + $displayData = array( + 'messages' => $messages, + 'username' => $username, + 'showIpColumn' => $showIpColumn, + ); + + $body = $layout->render($displayData); + $mailer = JFactory::getMailer(); + $mailer->addRecipient($recipients); + $mailer->setSubject(JText::_('COM_ACTIONLOGS_EMAIL_SUBJECT')); + $mailer->isHTML(true); + $mailer->Encoding = 'base64'; + $mailer->setBody($body); + + if (!$mailer->Send()) + { + JError::raiseWarning(500, JText::_('JERROR_SENDING_EMAIL')); + } + } +} diff --git a/administrator/components/com_actionlogs/models/actionlogs.php b/administrator/components/com_actionlogs/models/actionlogs.php new file mode 100644 index 0000000000000..97d0acf4a5be7 --- /dev/null +++ b/administrator/components/com_actionlogs/models/actionlogs.php @@ -0,0 +1,322 @@ +getUserStateFromRequest($this->context . 'filter.search', 'filter_search', '', 'string'); + $this->setState('filter.search', $search); + + $user = $app->getUserStateFromRequest($this->context . 'filter.user', 'filter_user', '', 'string'); + $this->setState('filter.user', $user); + + $extension = $app->getUserStateFromRequest($this->context . 'filter.extension', 'filter_extension', '', 'string'); + $this->setState('filter.extension', $extension); + + $ip_address = $app->getUserStateFromRequest($this->context . 'filter.ip_address', 'filter_ip_address', '', 'string'); + $this->setState('filter.ip_address', $ip_address); + + $dateRange = $app->getUserStateFromRequest($this->context . 'filter.dateRange', 'filter_dateRange', '', 'string'); + $this->setState('filter.dateRange', $dateRange); + + parent::populateState($ordering, $direction); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + * + * @since __DEPLOY_VERSION__ + */ + protected function getListQuery() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('a.*, u.name') + ->from('#__action_logs AS a') + ->innerJoin('#__users AS u ON a.user_id = u.id'); + + // Get ordering + $fullorderCol = $this->state->get('list.fullordering', 'a.id DESC'); + + // Apply ordering + if (!empty($fullorderCol)) + { + $query->order($db->escape($fullorderCol)); + } + + // Get filter by user + $user = $this->getState('filter.user'); + + // Apply filter by user + if (!empty($user)) + { + $query->where($db->quoteName('a.user_id') . ' = ' . (int) $user); + } + + // Get filter by extension + $extension = $this->getState('filter.extension'); + + // Apply filter by extension + if (!empty($extension)) + { + $query->where($db->quoteName('a.extension') . ' LIKE ' . $db->quote($extension . '%')); + } + + // Get filter by date range + $dateRange = $this->getState('filter.dateRange'); + + // Apply filter by date range + if (!empty($dateRange)) + { + $date = $this->buildDateRange($dateRange); + + // If the chosen range is not more than a year ago + if ($date['dNow'] != false) + { + $query->where( + $db->qn('a.log_date') . ' >= ' . $db->quote($date['dStart']->format('Y-m-d H:i:s')) . + ' AND ' . $db->qn('a.log_date') . ' <= ' . $db->quote($date['dNow']->format('Y-m-d H:i:s')) + ); + } + } + + // Filter the items over the search string if set. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + elseif (stripos($search, 'item_id:') === 0) + { + $query->where($db->quoteName('a.item_id') . ' = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . $db->escape($search, true) . '%'); + $query->where('(' . $db->quoteName('u.username') . ' LIKE ' . $search . ')'); + } + } + + return $query; + } + + /** + * Construct the date range to filter on. + * + * @param string $range The textual range to construct the filter for. + * + * @return array The date range to filter on. + * + * @since __DEPLOY_VERSION__ + */ + private function buildDateRange($range) + { + // Get UTC for now. + $dNow = new JDate; + $dStart = clone $dNow; + + switch ($range) + { + case 'past_week': + $dStart->modify('-7 day'); + break; + + case 'past_1month': + $dStart->modify('-1 month'); + break; + + case 'past_3month': + $dStart->modify('-3 month'); + break; + + case 'past_6month': + $dStart->modify('-6 month'); + break; + + case 'past_year': + $dStart->modify('-1 year'); + break; + + case 'today': + // Ranges that need to align with local 'days' need special treatment. + $offset = JFactory::getApplication()->get('offset'); + + // Reset the start time to be the beginning of today, local time. + $dStart = new JDate('now', $offset); + $dStart->setTime(0, 0, 0); + + // Now change the timezone back to UTC. + $tz = new DateTimeZone('GMT'); + $dStart->setTimezone($tz); + break; + } + + return array('dNow' => $dNow, 'dStart' => $dStart); + } + + /** + * Get all log entries for an item + * + * @param string $extension The extension the item belongs to + * @param integer $itemId The item ID + * + * @return array + * + * @since __DEPLOY_VERSION__ + */ + public function getLogsForItem($extension, $itemId) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('a.*, u.name') + ->from('#__action_logs AS a') + ->innerJoin('#__users AS u ON a.user_id = u.id') + ->where($db->quoteName('a.extension') . ' = ' . $db->quote($extension)) + ->where($db->quoteName('a.item_id') . ' = ' . (int) $itemId); + + // Get ordering + $fullorderCol = $this->getState('list.fullordering', 'a.id DESC'); + + // Apply ordering + if (!empty($fullorderCol)) + { + $query->order($db->escape($fullorderCol)); + } + + $db->setQuery($query); + + return $db->loadObjectList(); + } + + /** + * Get logs data into JTable object + * + * @return array All logs in the table + * + * @since __DEPLOY_VERSION__ + */ + public function getLogsData($pks = null) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('a.*, u.name') + ->from('#__action_logs AS a') + ->innerJoin('#__users AS u ON a.user_id = u.id'); + + if (is_array($pks) && count($pks) > 0) + { + $query->where($db->quoteName('a.id') . ' IN (' . implode(',', ArrayHelper::toInteger($pks)) . ')'); + } + + $db->setQuery($query); + + return $db->loadObjectList(); + } + + /** + * Delete logs + * + * @param array $pks Primary keys of logs + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function delete(&$pks) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->delete($db->quoteName('#__action_logs')) + ->where($db->quoteName('id') . ' IN (' . implode(',', ArrayHelper::toInteger($pks)) . ')'); + $db->setQuery($query); + + try + { + $db->execute(); + + return true; + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + + /** + * Removes all of logs from the table. + * + * @return boolean result of operation + * + * @since __DEPLOY_VERSION__ + */ + public function purge() + { + try + { + $this->getDbo()->truncateTable('#__action_logs'); + + return true; + } + catch (Exception $e) + { + return false; + } + } +} diff --git a/administrator/components/com_actionlogs/models/fields/extension.php b/administrator/components/com_actionlogs/models/fields/extension.php new file mode 100644 index 0000000000000..27699c6e34b0c --- /dev/null +++ b/administrator/components/com_actionlogs/models/fields/extension.php @@ -0,0 +1,65 @@ +getQuery(true) + ->select('DISTINCT ' . $db->quoteName('extension')) + ->from($db->quoteName('#__action_logs')) + ->order($db->quoteName('extension')); + + $db->setQuery($query); + $context = $db->loadColumn(); + + $options = array(); + + foreach ($context as $item) + { + $extensions[] = strtok($item, '.'); + } + + $extensions = array_unique($extensions); + + foreach ($extensions as $extension) + { + ActionlogsHelper::loadTranslationFiles($extension); + $options[] = JHtml::_('select.option', $extension, JText::_($extension)); + } + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/administrator/components/com_actionlogs/models/fields/logcreator.php b/administrator/components/com_actionlogs/models/fields/logcreator.php new file mode 100644 index 0000000000000..9690c00d81f95 --- /dev/null +++ b/administrator/components/com_actionlogs/models/fields/logcreator.php @@ -0,0 +1,79 @@ +element); + + if (!isset(static::$options[$hash])) + { + static::$options[$hash] = parent::getOptions(); + + $options = array(); + + $db = JFactory::getDbo(); + + // Construct the query + $query = $db->getQuery(true) + ->select($db->quoteName('u.id', 'value')) + ->select($db->quoteName('u.name', 'text')) + ->from($db->quoteName('#__users', 'u')) + ->join('INNER', $db->quoteName('#__action_logs', 'c') . ' ON ' . $db->quoteName('c.user_id') . ' = ' . $db->quoteName('u.id')) + ->group($db->quoteName('u.id')) + ->group($db->quoteName('u.name')) + ->order($db->quoteName('u.name')); + + // Setup the query + $db->setQuery($query); + + // Return the result + if ($options = $db->loadObjectList()) + { + static::$options[$hash] = array_merge(static::$options[$hash], $options); + } + } + + return static::$options[$hash]; + } +} diff --git a/administrator/components/com_actionlogs/models/fields/logsdaterange.php b/administrator/components/com_actionlogs/models/fields/logsdaterange.php new file mode 100644 index 0000000000000..0321c6e89615b --- /dev/null +++ b/administrator/components/com_actionlogs/models/fields/logsdaterange.php @@ -0,0 +1,59 @@ + 'COM_ACTIONLOGS_OPTION_RANGE_TODAY', + 'past_week' => 'COM_ACTIONLOGS_OPTION_RANGE_PAST_WEEK', + 'past_1month' => 'COM_ACTIONLOGS_OPTION_RANGE_PAST_1MONTH', + 'past_3month' => 'COM_ACTIONLOGS_OPTION_RANGE_PAST_3MONTH', + 'past_6month' => 'COM_ACTIONLOGS_OPTION_RANGE_PAST_6MONTH', + 'past_year' => 'COM_ACTIONLOGS_OPTION_RANGE_PAST_YEAR', + ); + + /** + * Method to instantiate the form field object. + * + * @param JForm $form The form to attach to the form field object. + * + * @since __DEPLOY_VERSION__ + */ + public function __construct($form = null) + { + parent::__construct($form); + + // Load the required language + $lang = JFactory::getLanguage(); + $lang->load('com_actionlogs', JPATH_ADMINISTRATOR); + } +} diff --git a/administrator/components/com_actionlogs/models/fields/logtype.php b/administrator/components/com_actionlogs/models/fields/logtype.php new file mode 100644 index 0000000000000..638dd7e8792e8 --- /dev/null +++ b/administrator/components/com_actionlogs/models/fields/logtype.php @@ -0,0 +1,66 @@ +getQuery(true) + ->select('a.extension') + ->from($db->quoteName('#__action_logs_extensions', 'a')); + + $db->setQuery($query); + + $extensions = $db->loadObjectList(); + + $options = array(); + $defaults = array(); + + foreach ($extensions as $extension) + { + $tmp = array( + 'checked' => true, + ); + + $defaults[] = $extension; + + ActionlogsHelper::loadTranslationFiles($extension->extension); + $option = JHtml::_('select.option', $extension->extension, JText::_($extension->extension)); + $options[] = (object) array_merge($tmp, (array) $option); + } + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/administrator/components/com_actionlogs/models/forms/filter_actionlogs.xml b/administrator/components/com_actionlogs/models/forms/filter_actionlogs.xml new file mode 100644 index 0000000000000..d7b009b38c930 --- /dev/null +++ b/administrator/components/com_actionlogs/models/forms/filter_actionlogs.xml @@ -0,0 +1,71 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/administrator/components/com_actionlogs/views/actionlogs/tmpl/default.php b/administrator/components/com_actionlogs/views/actionlogs/tmpl/default.php new file mode 100644 index 0000000000000..df9e4b6fa0deb --- /dev/null +++ b/administrator/components/com_actionlogs/views/actionlogs/tmpl/default.php @@ -0,0 +1,103 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+ $this)); ?> + items)) : ?> +
+ +
+ + + + + + + + + showIpColumn) : ?> + + + + + + + + + + + items as $i => $item) : + $extension = strtok($item->extension, '.'); + ActionlogsHelper::loadTranslationFiles($extension); ?> + + + + + + + showIpColumn) : ?> + + + + + + +
+ + + + + + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ id); ?> + + + + escape(JText::_($extension)); ?> + + + log_date); ?> + + + name; ?> + + escape($item->ip_address)); ?> + + id; ?> +
+ + + + +
+
diff --git a/administrator/components/com_actionlogs/views/actionlogs/view.html.php b/administrator/components/com_actionlogs/views/actionlogs/view.html.php new file mode 100644 index 0000000000000..cbfef078d5634 --- /dev/null +++ b/administrator/components/com_actionlogs/views/actionlogs/view.html.php @@ -0,0 +1,109 @@ +items = $this->get('Items'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->pagination = $this->get('Pagination'); + $this->showIpColumn = (bool) $params->get('ip_logging', 0); + + if (count($errors = $this->get('Errors'))) + { + JError::raiseError(500, implode("\n", $errors)); + + return false; + } + + $this->addToolBar(); + + // Load all actionlog plugins language files + ActionlogsHelper::loadActionLogPluginsLanguage(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function addToolbar() + { + JToolbarHelper::title(JText::_('COM_ACTIONLOGS_MANAGER_USERLOGS'), 'list-2'); + + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'actionlogs.delete'); + $bar = JToolbar::getInstance('toolbar'); + $bar->appendButton('Confirm', 'COM_ACTIONLOGS_PURGE_CONFIRM', 'delete', 'COM_ACTIONLOGS_TOOLBAR_PURGE', 'actionlogs.purge', false); + JToolbarHelper::preferences('com_actionlogs'); + JToolbarHelper::help('JHELP_COMPONENTS_ACTIONLOGS'); + JToolBarHelper::custom('actionlogs.exportSelectedLogs', 'download', '', 'COM_ACTIONLOGS_EXPORT_CSV', true); + JToolBarHelper::custom('actionlogs.exportLogs', 'download', '', 'COM_ACTIONLOGS_EXPORT_ALL_CSV', false); + } +} diff --git a/administrator/components/com_admin/script.php b/administrator/components/com_admin/script.php index 6cbf668f4283b..6cd473f2ebee2 100644 --- a/administrator/components/com_admin/script.php +++ b/administrator/components/com_admin/script.php @@ -2309,6 +2309,8 @@ public function updateAssets($installer) 'com_postinstall', 'com_fields', 'com_associations', + 'com_privacy', + 'com_actionlogs', ); foreach ($newComponents as $component) diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-02.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-02.sql new file mode 100644 index 0000000000000..ef74036ca361b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-02.sql @@ -0,0 +1,16 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(35, 0, 'com_privacy', 'component', 'com_privacy', '', 1, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); + +CREATE TABLE IF NOT EXISTS `#__privacy_requests` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `email` varchar(100) NOT NULL DEFAULT '', + `requested_at` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `status` tinyint(4) NOT NULL DEFAULT '0', + `request_type` varchar(25) NOT NULL DEFAULT '', + `confirm_token` varchar(100) NOT NULL DEFAULT '', + `confirm_token_created_at` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `checked_out` int(11) NOT NULL DEFAULT '0', + `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + KEY `idx_checkout` (`checked_out`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-03.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-03.sql new file mode 100644 index 0000000000000..d1f294af6a0ff --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-03.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(482, 0, 'plg_content_confirmconsent', 'plugin', 'confirmconsent', 'content', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-05.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-05.sql new file mode 100644 index 0000000000000..78db9a8d1cc88 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-05.sql @@ -0,0 +1,85 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(36, 0, 'com_actionlogs', 'component', 'com_actionlogs', '', 1, 1, 1, 1, '', '{"ip_logging":0,"csv_delimiter":",","loggable_extensions":["com_banners","com_cache","com_categories","com_config","com_contact","com_content","com_installer","com_media","com_menus","com_messages","com_modules","com_newsfeeds","com_plugins","com_redirect","com_tags","com_templates","com_users"]}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(483, 0, 'plg_system_actionlogs', 'plugin', 'actionlogs', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(484, 0, 'plg_actionlog_joomla', 'plugin', 'joomla', 'actionlog', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); + + +-- +-- Table structure for table `#__action_logs` +-- + +CREATE TABLE IF NOT EXISTS `#__action_logs` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `message_language_key` varchar(255) NOT NULL DEFAULT '', + `message` text NOT NULL, + `log_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `extension` varchar(50) NOT NULL DEFAULT '', + `user_id` int(11) NOT NULL DEFAULT 0, + `item_id` int(11) NOT NULL DEFAULT 0, + `ip_address` VARCHAR(40) NOT NULL DEFAULT '0.0.0.0', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +-- +-- Table structure for table `#__action_logs_extensions` +-- + +CREATE TABLE IF NOT EXISTS `#__action_logs_extensions` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `extension` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +INSERT INTO `#__action_logs_extensions` (`id`, `extension`) VALUES +(1, 'com_banners'), +(2, 'com_cache'), +(3, 'com_categories'), +(4, 'com_config'), +(5, 'com_contact'), +(6, 'com_content'), +(7, 'com_installer'), +(8, 'com_media'), +(9, 'com_menus'), +(10, 'com_messages'), +(11, 'com_modules'), +(12, 'com_newsfeeds'), +(13, 'com_plugins'), +(14, 'com_redirect'), +(15, 'com_tags'), +(16, 'com_templates'), +(17, 'com_users'); + +-- +-- Table structure for table `#__action_log_config` +-- + +CREATE TABLE IF NOT EXISTS `#__action_log_config` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `type_title` varchar(255) NOT NULL DEFAULT '', + `type_alias` varchar(255) NOT NULL DEFAULT '', + `id_holder` varchar(255), + `title_holder` varchar(255), + `table_name` varchar(255), + `text_prefix` varchar(255), + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +INSERT INTO `#__action_log_config` (`id`, `type_title`, `type_alias`, `id_holder`, `title_holder`, `table_name`, `text_prefix`) VALUES +(1, 'article', 'com_content.article', 'id' ,'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA'), +(2, 'article', 'com_content.form', 'id', 'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA'), +(3, 'banner', 'com_banners.banner', 'id' ,'name' , '#__banners', 'PLG_ACTIONLOG_JOOMLA'), +(4, 'user_note', 'com_users.note', 'id', 'subject' ,'#__user_notes', 'PLG_ACTIONLOG_JOOMLA'), +(5, 'media', 'com_media.file', '' , 'name' , '', 'PLG_ACTIONLOG_JOOMLA'), +(6, 'category', 'com_categories.category', 'id' , 'title' , '#__categories', 'PLG_ACTIONLOG_JOOMLA'), +(7, 'menu', 'com_menus.menu', 'id' ,'title' , '#__menu_types', 'PLG_ACTIONLOG_JOOMLA'), +(8, 'menu_item', 'com_menus.item', 'id' , 'title' , '#__menu', 'PLG_ACTIONLOG_JOOMLA'), +(9, 'newsfeed', 'com_newsfeeds.newsfeed', 'id' ,'name' , '#__newsfeeds', 'PLG_ACTIONLOG_JOOMLA'), +(10, 'link', 'com_redirect.link', 'id', 'old_url' , '#__redirect_links', 'PLG_ACTIONLOG_JOOMLA'), +(11, 'tag', 'com_tags.tag', 'id', 'title' , '#__tags', 'PLG_ACTIONLOG_JOOMLA'), +(12, 'style', 'com_templates.style', 'id' , 'title' , '#__template_styles', 'PLG_ACTIONLOG_JOOMLA'), +(13, 'plugin', 'com_plugins.plugin', 'extension_id' , 'name' , '#__extensions', 'PLG_ACTIONLOG_JOOMLA'), +(14, 'component_config', 'com_config.component', 'extension_id' , 'name', '', 'PLG_ACTIONLOG_JOOMLA'), +(15, 'contact', 'com_contact.contact', 'id', 'name', '#__contact_details', 'PLG_ACTIONLOG_JOOMLA'), +(16, 'module', 'com_modules.module', 'id' ,'title', '#__modules', 'PLG_ACTIONLOG_JOOMLA'), +(17, 'access_level', 'com_users.level', 'id' , 'title', '#__viewlevels', 'PLG_ACTIONLOG_JOOMLA'), +(18, 'banner_client', 'com_banners.client', 'id', 'name', '#__banner_clients', 'PLG_ACTIONLOG_JOOMLA'); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-20.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-20.sql new file mode 100644 index 0000000000000..1582f8352f557 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-20.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(319, 0, 'mod_latestactions', 'module', 'mod_latestactions', '', 1, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-24.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-24.sql new file mode 100644 index 0000000000000..af662df1ba84b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-24.sql @@ -0,0 +1,14 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(485, 0, 'plg_system_privacyconsent', 'plugin', 'privacyconsent', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); + +CREATE TABLE IF NOT EXISTS `#__privacy_consents` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `user_id` int(10) unsigned NOT NULL DEFAULT '0', + `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `subject` varchar(25) NOT NULL DEFAULT '', + `body` text NOT NULL, + `remind` tinyint(4) NOT NULL DEFAULT '0', + `token` varchar(100) NOT NULL DEFAULT '', + PRIMARY KEY (`id`), + KEY `idx_user_id` (`user_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-27.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-27.sql new file mode 100644 index 0000000000000..ab0958e02c946 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-27.sql @@ -0,0 +1,3 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(486, 0, 'plg_system_logrotation', 'plugin', 'logrotation', 'system', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(487, 0, 'plg_privacy_user', 'plugin', 'user', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-12.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-12.sql new file mode 100644 index 0000000000000..526c61d53440f --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-12.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(320, 0, 'mod_privacy_dashboard', 'module', 'mod_privacy_dashboard', '', 1, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-13.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-13.sql new file mode 100644 index 0000000000000..edda43880912d --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-13.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(488, 0, 'plg_quickicon_privacycheck', 'plugin', 'privacycheck', 'quickicon', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-14.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-14.sql new file mode 100644 index 0000000000000..cc18b1d191c96 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-14.sql @@ -0,0 +1,3 @@ +INSERT INTO `#__postinstall_messages` (`extension_id`, `title_key`, `description_key`, `action_key`, `language_extension`, `language_client_id`, `type`, `action_file`, `action`, `condition_file`, `condition_method`, `version_introduced`, `enabled`) VALUES +(700, 'COM_ACTIONLOGS_POSTINSTALL_TITLE', 'COM_ACTIONLOGS_POSTINSTALL_BODY', '', 'com_actionlogs', 1, 'message', '', '', '', '', '3.9.0', 1), +(700, 'COM_PRIVACY_POSTINSTALL_TITLE', 'COM_PRIVACY_POSTINSTALL_BODY', '', 'com_privacy', 1, 'message', '', '', '', '', '3.9.0', 1); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-17.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-17.sql new file mode 100644 index 0000000000000..d3d3ee5f930f3 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-17.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(489, 0, 'plg_user_terms', 'plugin', 'terms', 'user', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-09.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-09.sql new file mode 100644 index 0000000000000..7c8215c3f93e6 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-09.sql @@ -0,0 +1,4 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(490, 0, 'plg_privacy_contact', 'plugin', 'contact', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(491, 0, 'plg_privacy_content', 'plugin', 'content', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(492, 0, 'plg_privacy_message', 'plugin', 'message', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-10.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-10.sql new file mode 100644 index 0000000000000..3c8c70a81ade9 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-10.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__action_log_config` (`id`, `type_title`, `type_alias`, `id_holder`, `title_holder`, `table_name`, `text_prefix`) + VALUES (19, 'application_config', 'com_config.application', '', 'name', '', 'PLG_ACTIONLOG_JOOMLA'); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-11.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-11.sql new file mode 100644 index 0000000000000..bc347d66fd884 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-11.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(493, 0, 'plg_privacy_actionlogs', 'plugin', 'actionlogs', 'privacy', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-02.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-02.sql new file mode 100644 index 0000000000000..ae705b2f6e56b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-02.sql @@ -0,0 +1,16 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(35, 0, 'com_privacy', 'component', 'com_privacy', '', 1, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); + +CREATE TABLE "#__privacy_requests" ( + "id" serial NOT NULL, + "email" varchar(100) DEFAULT '' NOT NULL, + "requested_at" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "status" smallint DEFAULT 0 NOT NULL, + "request_type" varchar(25) DEFAULT '' NOT NULL, + "confirm_token" varchar(100) DEFAULT '' NOT NULL, + "confirm_token_created_at" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "checked_out" integer DEFAULT 0 NOT NULL, + "checked_out_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "#__privacy_requests_idx_checked_out" ON "#__privacy_requests" ("checked_out"); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-03.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-03.sql new file mode 100644 index 0000000000000..6ef9999e731f4 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-03.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(482, 0, 'plg_content_confirmconsent', 'plugin', 'confirmconsent', 'content', 0, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-05.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-05.sql new file mode 100644 index 0000000000000..bd5eceb393e32 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-05.sql @@ -0,0 +1,92 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(36, 0, 'com_actionlogs', 'component', 'com_actionlogs', '', 1, 1, 1, 1, '', '{"ip_logging":0,"csv_delimiter":",","loggable_extensions":["com_banners","com_cache","com_categories","com_config","com_contact","com_content","com_installer","com_media","com_menus","com_messages","com_modules","com_newsfeeds","com_plugins","com_redirect","com_tags","com_templates","com_users"]}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(483, 0, 'plg_system_actionlogs', 'plugin', 'actionlogs', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(484, 0, 'plg_actionlog_joomla', 'plugin', 'joomla', 'actionlog', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); + +-- +-- Table: #__action_logs +-- +CREATE TABLE "#__action_logs" ( + "id" serial NOT NULL, + "message_language_key" varchar(255) NOT NULL DEFAULT '', + "message" text NOT NULL DEFAULT '', + "log_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "extension" varchar(50) NOT NULL DEFAULT '', + "user_id" integer DEFAULT 0 NOT NULL, + "item_id" integer DEFAULT 0 NOT NULL, + "ip_address" varchar(40) NOT NULL DEFAULT '0.0.0.0', + PRIMARY KEY ("id") +); + +-- Table: #__action_logs_extensions +-- +CREATE TABLE "#__action_logs_extensions" ( + "id" serial NOT NULL, + "extension" varchar(50) NOT NULL DEFAULT '', + PRIMARY KEY ("id") +); + +-- +-- Dumping data for table '#__action_logs_extensions' +-- +INSERT INTO "#__action_logs_extensions" ("id", "extension") VALUES +(1, 'com_banners'), +(2, 'com_cache'), +(3, 'com_categories'), +(4, 'com_config'), +(5, 'com_contact'), +(6, 'com_content'), +(7, 'com_installer'), +(8, 'com_media'), +(9, 'com_menus'), +(10, 'com_messages'), +(11, 'com_modules'), +(12, 'com_newsfeeds'), +(13, 'com_plugins'), +(14, 'com_redirect'), +(15, 'com_tags'), +(16, 'com_templates'), +(17, 'com_users'); + +SELECT setval('#__action_logs_extensions_id_seq', 18, false); +-- -------------------------------------------------------- + +-- +-- Table: #__action_log_config +-- +CREATE TABLE "#__action_log_config" ( + "id" serial NOT NULL, + "type_title" varchar(255) NOT NULL DEFAULT '', + "type_alias" varchar(255) NOT NULL DEFAULT '', + "id_holder" varchar(255) NULL, + "title_holder" varchar(255) NULL, + "table_name" varchar(255) NULL, + "text_prefix" varchar(255) NULL, + PRIMARY KEY ("id") +); + +-- +-- Dumping data for table #__action_log_config +-- +INSERT INTO "#__action_log_config" ("id", "type_title", "type_alias", "id_holder", "table_name", "text_prefix") VALUES +(1, 'article', 'com_content.article', 'id' ,'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA'), +(2, 'article', 'com_content.form', 'id', 'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA'), +(3, 'banner', 'com_banners.banner', 'id' ,'name' , '#__banners', 'PLG_ACTIONLOG_JOOMLA'), +(4, 'user_note', 'com_users.note', 'id', 'subject' ,'#__user_notes', 'PLG_ACTIONLOG_JOOMLA'), +(5, 'media', 'com_media.file', '' , 'name' , '', 'PLG_ACTIONLOG_JOOMLA'), +(6, 'category', 'com_categories.category', 'id' , 'title' , '#__categories', 'PLG_ACTIONLOG_JOOMLA'), +(7, 'menu', 'com_menus.menu', 'id' ,'title' , '#__menu_types', 'PLG_ACTIONLOG_JOOMLA'), +(8, 'menu_item', 'com_menus.item', 'id' , 'title' , '#__menu', 'PLG_ACTIONLOG_JOOMLA'), +(9, 'newsfeed', 'com_newsfeeds.newsfeed', 'id' ,'name' , '#__newsfeeds', 'PLG_ACTIONLOG_JOOMLA'), +(10, 'link', 'com_redirect.link', 'id', 'old_url' , '#__redirect_links', 'PLG_ACTIONLOG_JOOMLA'), +(11, 'tag', 'com_tags.tag', 'id', 'title' , '#__tags', 'PLG_ACTIONLOG_JOOMLA'), +(12, 'style', 'com_templates.style', 'id' , 'title' , '#__template_styles', 'PLG_ACTIONLOG_JOOMLA'), +(13, 'plugin', 'com_plugins.plugin', 'extension_id' , 'name' , '#__extensions', 'PLG_ACTIONLOG_JOOMLA'), +(14, 'component_config', 'com_config.component', 'extension_id' , 'name', '', 'PLG_ACTIONLOG_JOOMLA'), +(15, 'contact', 'com_contact.contact', 'id', 'name', '#__contact_details', 'PLG_ACTIONLOG_JOOMLA'), +(16, 'module', 'com_modules.module', 'id' ,'title', '#__modules', 'PLG_ACTIONLOG_JOOMLA'), +(17, 'access_level', 'com_users.level', 'id' , 'title', '#__viewlevels', 'PLG_ACTIONLOG_JOOMLA'), +(18, 'banner_client', 'com_banners.client', 'id', 'name', '#__banner_clients', 'PLG_ACTIONLOG_JOOMLA'); + + +SELECT setval('#__action_log_config_id_seq', 18, false); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-20.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-20.sql new file mode 100644 index 0000000000000..3fccb586bf6be --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-20.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(319, 0, 'mod_latestactions', 'module', 'mod_latestactions', '', 1, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-24.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-24.sql new file mode 100644 index 0000000000000..6d1f27acbe6e6 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-24.sql @@ -0,0 +1,18 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(485, 0, 'plg_system_privacyconsent', 'plugin', 'privacyconsent', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); + +-- +-- Table structure for table `#__privacy_consents` +-- + +CREATE TABLE "#__privacy_consents" ( + "id" serial NOT NULL, + "user_id" bigint DEFAULT 0 NOT NULL, + "created" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "subjext" varchar(255) DEFAULT '' NOT NULL, + "body" text NOT NULL, + "remind" smallint DEFAULT 0 NOT NULL, + "token" varchar(100) DEFAULT '' NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "#__privacy_consents_idx_user_id" ON "#__privacy_consents" ("user_id"); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-27.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-27.sql new file mode 100644 index 0000000000000..9d13ef54ad8e7 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-27.sql @@ -0,0 +1,3 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(486, 0, 'plg_system_logrotation', 'plugin', 'logrotation', 'system', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(487, 0, 'plg_privacy_user', 'plugin', 'user', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-12.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-12.sql new file mode 100644 index 0000000000000..24647cf7ccc0d --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-12.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(320, 0, 'mod_privacy_dashboard', 'module', 'mod_privacy_dashboard', '', 1, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-13.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-13.sql new file mode 100644 index 0000000000000..86a8fa6ba7167 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-13.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(488, 0, 'plg_quickicon_privacycheck', 'plugin', 'privacycheck', 'quickicon', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-14.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-14.sql new file mode 100644 index 0000000000000..f2e932fee5a4f --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-14.sql @@ -0,0 +1,3 @@ +INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description_key", "action_key", "language_extension", "language_client_id", "type", "action_file", "action", "condition_file", "condition_method", "version_introduced", "enabled") VALUES +(700, 'COM_ACTIONLOGS_POSTINSTALL_TITLE', 'COM_ACTIONLOGS_POSTINSTALL_BODY', '', 'com_actionlogs', 1, 'message', '', '', '', '', '3.9.0', 1), +(700, 'COM_PRIVACY_POSTINSTALL_TITLE', 'COM_PRIVACY_POSTINSTALL_BODY', '', 'com_privacy', 1, 'message', '', '', '', '', '3.9.0', 1); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-17.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-17.sql new file mode 100644 index 0000000000000..e10fe5087a320 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-17.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(489, 0, 'plg_user_terms', 'plugin', 'terms', 'user', 0, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-09.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-09.sql new file mode 100644 index 0000000000000..513341f9df10d --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-09.sql @@ -0,0 +1,4 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(490, 0, 'plg_privacy_contact', 'plugin', 'contact', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(491, 0, 'plg_privacy_content', 'plugin', 'content', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(492, 0, 'plg_privacy_message', 'plugin', 'message', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-10.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-10.sql new file mode 100644 index 0000000000000..74e65fd4b16be --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-10.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__action_log_config" ("id", "type_title", "type_alias", "id_holder", "title_holder", "table_name", "text_prefix") + VALUES (19, 'application_config', 'com_config.application', '', 'name', '', 'PLG_ACTIONLOG_JOOMLA'); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-11.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-11.sql new file mode 100644 index 0000000000000..afbbed91cd09a --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-11.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(493, 0, 'plg_privacy_actionlogs', 'plugin', 'actionlogs', 'privacy', 0, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-02.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-02.sql new file mode 100644 index 0000000000000..6cbbdd0e8bdc9 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-02.sql @@ -0,0 +1,25 @@ +SET IDENTITY_INSERT #__extensions ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(35, 0, 'com_privacy', 'component', 'com_privacy', '', 1, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT #__extensions OFF; + +CREATE TABLE "#__privacy_requests" ( + "id" int IDENTITY(1,1) NOT NULL, + "email" nvarchar(100) NOT NULL DEFAULT '', + "requested_at" datetime2(0) NOT NULL DEFAULT '1900-01-01 00:00:00', + "status" smallint NOT NULL, + "request_type" nvarchar(25) NOT NULL DEFAULT '', + "confirm_token" nvarchar(100) NOT NULL DEFAULT '', + "confirm_token_created_at" datetime2(0) NOT NULL DEFAULT '1900-01-01 00:00:00', + "checked_out" bigint NOT NULL DEFAULT 0, + "checked_out_time" datetime2(0) NOT NULL DEFAULT '1900-01-01 00:00:00', +CONSTRAINT "PK_#__privacy_requests_id" PRIMARY KEY CLUSTERED( + "id" ASC) +WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON +) ON [PRIMARY]) ON [PRIMARY]; + +CREATE NONCLUSTERED INDEX "idx_checkout" ON "#__privacy_requests" ( + "checked_out" ASC) +WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-03.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-03.sql new file mode 100644 index 0000000000000..b3eeb1f6268b1 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-03.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT #__extensions ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(482, 0, 'plg_content_confirmconsent', 'plugin', 'confirmconsent', 'content', 0, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT #__extensions OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-05.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-05.sql new file mode 100644 index 0000000000000..a93b0fa119981 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-05.sql @@ -0,0 +1,130 @@ +SET IDENTITY_INSERT #__extensions ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(36, 0, 'com_actionlogs', 'component', 'com_actionlogs', '', 1, 1, 1, 1, '', '{"ip_logging":0,"csv_delimiter":",","loggable_extensions":["com_banners","com_cache","com_categories","com_config","com_contact","com_content","com_installer","com_media","com_menus","com_messages","com_modules","com_newsfeeds","com_plugins","com_redirect","com_tags","com_templates","com_users"]}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(483, 0, 'plg_system_actionlogs', 'plugin', 'actionlogs', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(484, 0, 'plg_actionlog_joomla', 'plugin', 'joomla', 'actionlog', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT #__extensions OFF; + +/****** Object: Table [#__action_logs] ******/ +SET QUOTED_IDENTIFIER ON; + +CREATE TABLE [#__action_logs]( + [id] [int] IDENTITY(1,1) NOT NULL, + [message_language_key] [nvarchar](255) NOT NULL DEFAULT '', + [message] [nvarchar](max) NOT NULL DEFAULT '', + [log_date] [datetime] NOT NULL DEFAULT '1900-01-01 00:00:00', + [extension] [nvarchar](255) NOT NULL DEFAULT '', + [user_id] [bigint] NOT NULL DEFAULT 0, + [item_id] [bigint] NOT NULL DEFAULT 0, + [ip_address] [nvarchar](40) NOT NULL DEFAULT '0.0.0.0', + CONSTRAINT [PK_#__action_logs_id] PRIMARY KEY CLUSTERED + ( + [id] ASC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + ) ON [PRIMARY]; + +/****** Object: Table [#__action_logs_extensions] ******/ +SET QUOTED_IDENTIFIER ON; + +CREATE TABLE [#__action_logs_extensions]( + [id] [int] IDENTITY(1,1) NOT NULL, + [extension] [nvarchar](255) NOT NULL DEFAULT '', + CONSTRAINT [PK_#__action_logs_extensions_id] PRIMARY KEY CLUSTERED + ( + [id] ASC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + ) ON [PRIMARY]; +SET IDENTITY_INSERT [#__action_logs_extensions] ON; +INSERT INTO [#__action_logs_extensions] ([id], [extension]) +SELECT 1, 'com_banners' +UNION ALL +SELECT 2, 'com_cache' +UNION ALL +SELECT 3, 'com_categories' +UNION ALL +SELECT 4, 'com_config' +UNION ALL +SELECT 5, 'com_contact' +UNION ALL +SELECT 6, 'com_content' +UNION ALL +SELECT 7, 'com_installer' +UNION ALL +SELECT 8, 'com_media' +UNION ALL +SELECT 9, 'com_menus' +UNION ALL +SELECT 10, 'com_messages' +UNION ALL +SELECT 11, 'com_modules' +UNION ALL +SELECT 12, 'com_newsfeeds' +UNION ALL +SELECT 13, 'com_plugins' +UNION ALL +SELECT 14, 'com_redirect' +UNION ALL +SELECT 15, 'com_tags' +UNION ALL +SELECT 16, 'com_templates' +UNION ALL +SELECT 17, 'com_users'; + +SET IDENTITY_INSERT [#__action_logs_extensions] OFF; +/****** Object: Table [#__action_log_config] ******/ +SET QUOTED_IDENTIFIER ON; + +CREATE TABLE [#__action_log_config]( + [id] [int] IDENTITY(1,1) NOT NULL, + [type_title] [nvarchar](255) NOT NULL DEFAULT '', + [type_alias] [nvarchar](255) NOT NULL DEFAULT '', + [title_holder] [nvarchar](255) NULL, + [table_values] [nvarchar](255) NULL + CONSTRAINT [PK_#__action_log_config_id] PRIMARY KEY CLUSTERED + ( + [id] ASC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + ) ON [PRIMARY]; + +SET IDENTITY_INSERT [#__action_log_config] ON; + +INSERT INTO [#__action_log_config] ([id], [type_title], [type_alias], [id_holder], [title_holder], [table_name], [text_prefix]) +SELECT 1, 'article', 'com_content.article', 'id' ,'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 2, 'article', 'com_content.form', 'id', 'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 3, 'banner', 'com_banners.banner', 'id' ,'name' , '#__banners', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 4, 'user_note', 'com_users.note', 'id', 'subject' ,'#__user_notes', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 5, 'media', 'com_media.file', '' , 'name' , '', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 6, 'category', 'com_categories.category', 'id' , 'title' , '#__categories', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 7, 'menu', 'com_menus.menu', 'id' ,'title' , '#__menu_types', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 8, 'menu_item', 'com_menus.item', 'id' , 'title' , '#__menu', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 9, 'newsfeed', 'com_newsfeeds.newsfeed', 'id' ,'name' , '#__newsfeeds', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 10, 'link', 'com_redirect.link', 'id', 'old_url' , '#__redirect_links', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 11, 'tag', 'com_tags.tag', 'id', 'title' , '#__tags', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 12, 'style', 'com_templates.style', 'id' , 'title' , '#__template_styles', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 13, 'plugin', 'com_plugins.plugin', 'extension_id' , 'name' , '#__extensions', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 14, 'component_config', 'com_config.component', 'extension_id' , 'name', '', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 15, 'contact', 'com_contact.contact', 'id', 'name', '#__contact_details', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 16, 'module', 'com_modules.module', 'id' ,'title', '#__modules', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 17, 'access_level', 'com_users.level', 'id' , 'title', '#__viewlevels', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 18, 'banner_client', 'com_banners.client', 'id', 'name', '#__banner_clients', 'PLG_ACTIONLOG_JOOMLA'; + +SET IDENTITY_INSERT [#__action_log_config] OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-19.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-19.sql index 3536e787202f0..d641491d7532c 100644 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-19.sql +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-19.sql @@ -1,2 +1,6 @@ +SET IDENTITY_INSERT #__extensions ON; + INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES (481, 0, 'plg_fields_repeatable', 'plugin', 'repeatable', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT #__extensions OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-20.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-20.sql new file mode 100644 index 0000000000000..4b399e66fbb67 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-20.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT #__extensions ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(319, 0, 'mod_latestactions', 'module', 'mod_latestactions', '', 1, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT #__extensions OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-24.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-24.sql new file mode 100644 index 0000000000000..0aca510cf5d37 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-24.sql @@ -0,0 +1,27 @@ +SET IDENTITY_INSERT #__extensions ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(485, 0, 'plg_system_privacyconsent', 'plugin', 'privacyconsent', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT #__extensions OFF; + +-- +-- Table structure for table `#__privacy_consents` +-- + +CREATE TABLE "#__privacy_consents" ( + "id" int IDENTITY(1,1) NOT NULL, + "user_id" bigint NOT NULL DEFAULT 0, + "created" datetime2(0) NOT NULL DEFAULT '1900-01-01 00:00:00', + "subject" nvarchar(255) NOT NULL DEFAULT '', + "body" nvarchar(max) NOT NULL, + "remind" smallint NOT NULL, + "token" nvarchar(100) NOT NULL DEFAULT '', +CONSTRAINT "PK_#__privacy_consents_id" PRIMARY KEY CLUSTERED( + "id" ASC) +WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON +) ON [PRIMARY]) ON [PRIMARY]; + +CREATE NONCLUSTERED INDEX "idx_user_id" ON "#__privacy_consents" ( + "user_id" ASC) +WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-27.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-27.sql new file mode 100644 index 0000000000000..a33e33999fc2c --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-27.sql @@ -0,0 +1,7 @@ +SET IDENTITY_INSERT #__extensions ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(486, 0, 'plg_system_logrotation', 'plugin', 'logrotation', 'system', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(487, 0, 'plg_privacy_user', 'plugin', 'user', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT #__extensions OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-12.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-12.sql new file mode 100644 index 0000000000000..bce166e81c09e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-12.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT #__extensions ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(320, 0, 'mod_privacy_dashboard', 'module', 'mod_privacy_dashboard', '', 1, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT #__extensions OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-13.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-13.sql new file mode 100644 index 0000000000000..9b29cbabf9f09 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-13.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT #__extensions ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(488, 0, 'plg_quickicon_privacycheck', 'plugin', 'privacycheck', 'quickicon', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT #__extensions OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-14.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-14.sql new file mode 100644 index 0000000000000..1e13dcea4546a --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-14.sql @@ -0,0 +1,3 @@ +INSERT INTO [#__postinstall_messages] ([extension_id], [title_key], [description_key], [action_key], [language_extension], [language_client_id], [type], [action_file], [action], [condition_file], [condition_method], [version_introduced], [enabled]) +SELECT 700, 'COM_ACTIONLOGS_POSTINSTALL_TITLE', 'COM_ACTIONLOGS_POSTINSTALL_BODY', '', 'com_actionlogs', 1, 'message', '', '', '', '', '3.9.0', 1, +SELECT 700, 'COM_PRIVACY_POSTINSTALL_TITLE', 'COM_PRIVACY_POSTINSTALL_BODY', '', 'com_privacy', 1, 'message', '', '', '', '', '3.9.0', 1 \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-17.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-17.sql new file mode 100644 index 0000000000000..499af063d7ce3 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-17.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT #__extensions ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(489, 0, 'plg_user_terms', 'plugin', 'terms', 'user', 0, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT #__extensions OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-09.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-09.sql new file mode 100644 index 0000000000000..62d5f0ab265ed --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-09.sql @@ -0,0 +1,4 @@ + INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(490, 0, 'plg_privacy_contact', 'plugin', 'user', 'contact', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(491, 0, 'plg_privacy_content', 'plugin', 'user', 'content', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(492, 0, 'plg_privacy_message', 'plugin', 'user', 'message', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-10.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-10.sql new file mode 100644 index 0000000000000..97a62fcb10ce5 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-10.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT #__action_log_config ON; + +INSERT INTO "#__action_log_config" ("id", "type_title", "type_alias", "id_holder", "title_holder", "table_name", "text_prefix") + VALUES (19, 'application_config', 'com_config.application', '', 'name', '', 'PLG_ACTIONLOG_JOOMLA'); + +SET IDENTITY_INSERT #__action_log_config OFF; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-11.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-11.sql new file mode 100644 index 0000000000000..0abfa01a2754c --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-11.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT #__extensions ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(493, 0, 'plg_privacy_actionlogs', 'plugin', 'actionlogs', 'privacy', 0, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT #__extensions OFF; \ No newline at end of file diff --git a/administrator/components/com_config/model/application.php b/administrator/components/com_config/model/application.php index 4abbbfaebc07c..934c33eb441cd 100644 --- a/administrator/components/com_config/model/application.php +++ b/administrator/components/com_config/model/application.php @@ -97,6 +97,7 @@ public function getData() public function save($data) { $app = JFactory::getApplication(); + $dispatcher = JEventDispatcher::getInstance(); // Check that we aren't setting wrong database configuration $options = array( @@ -394,8 +395,21 @@ public function save($data) $this->cleanCache('_system', 0); $this->cleanCache('_system', 1); + $result = $dispatcher->trigger('onApplicationBeforeSave', array($config)); + + // Store the data. + if (in_array(false, $result, true)) + { + throw new RuntimeException(JText::_('COM_CONFIG_ERROR_UNKNOWN_BEFORE_SAVING')); + } + // Write the configuration file. - return $this->writeConfigFile($config); + $result = $this->writeConfigFile($config); + + // Trigger the after save event. + $dispatcher->trigger('onApplicationAfterSave', array($config)); + + return $result; } /** @@ -410,6 +424,8 @@ public function save($data) */ public function removeroot() { + $dispatcher = JEventDispatcher::getInstance(); + // Get the previous configuration. $prev = new JConfig; $prev = ArrayHelper::fromObject($prev); @@ -418,8 +434,21 @@ public function removeroot() unset($prev['root_user']); $config = new Registry($prev); + $result = $dispatcher->trigger('onApplicationBeforeSave', array($config)); + + // Store the data. + if (in_array(false, $result, true)) + { + throw new RuntimeException(JText::_('COM_CONFIG_ERROR_UNKNOWN_BEFORE_SAVING')); + } + // Write the configuration file. - return $this->writeConfigFile($config); + $result = $this->writeConfigFile($config); + + // Trigger the after save event. + $dispatcher->trigger('onApplicationAfterSave', array($config)); + + return $result; } /** diff --git a/administrator/components/com_menus/presets/joomla.xml b/administrator/components/com_menus/presets/joomla.xml index 67917c6f1db32..b775355f19f27 100644 --- a/administrator/components/com_menus/presets/joomla.xml +++ b/administrator/components/com_menus/presets/joomla.xml @@ -161,6 +161,23 @@ + + + + + + getDbo(); + + try + { + /** @var JTableAsset $table */ + $table = $this->getTable('Asset', 'JTable'); + $rootId = $table->getRootId(); + + /** @var JAccessRule[] $rules */ + $rules = JAccess::getAssetRules($rootId)->getData(); + $rawGroups = $rules['core.admin']->getData(); + + if (empty($rawGroups)) + { + $this->setError(JText::_('COM_MESSAGES_ERROR_MISSING_ROOT_ASSET_GROUPS')); + + return false; + } + + $groups = array(); + + foreach ($rawGroups as $g => $enabled) + { + if ($enabled) + { + $groups[] = $db->quote($g); + } + } + + if (empty($groups)) + { + $this->setError(JText::_('COM_MESSAGES_ERROR_NO_GROUPS_SET_AS_SUPER_USER')); + + return false; + } + + $query = $db->getQuery(true) + ->select($db->quoteName('user_id')) + ->from($db->quoteName('#__user_usergroup_map')) + ->where($db->quoteName('group_id') . ' IN(' . implode(',', $groups) . ')'); + + $userIDs = $db->setQuery($query)->loadColumn(0); + + if (empty($userIDs)) + { + $this->setError(JText::_('COM_MESSAGES_ERROR_NO_USERS_SET_AS_SUPER_USER')); + + return false; + } + + foreach ($userIDs as $id) + { + /* + * All messages must have a valid from user, we have use cases where an unauthenticated user may trigger this + * so we will set the from user as the to user + */ + $data = array( + 'user_id_from' => $id, + 'user_id_to' => $id, + 'subject' => $subject, + 'message' => $message, + ); + + if (!$this->save($data)) + { + return false; + } + } + + return true; + } + catch (Exception $exception) + { + $this->setError($exception->getMessage()); + + return false; + } + } } diff --git a/administrator/components/com_privacy/config.xml b/administrator/components/com_privacy/config.xml new file mode 100644 index 0000000000000..833d1a2834a2b --- /dev/null +++ b/administrator/components/com_privacy/config.xml @@ -0,0 +1,22 @@ + + +
+ + + +
+
diff --git a/administrator/components/com_privacy/controller.php b/administrator/components/com_privacy/controller.php new file mode 100644 index 0000000000000..9476d11089276 --- /dev/null +++ b/administrator/components/com_privacy/controller.php @@ -0,0 +1,140 @@ +input->get('view', $this->default_view); + $vFormat = $document->getType(); + $lName = $this->input->get('layout', 'default', 'string'); + + // Get and render the view. + if ($view = $this->getView($vName, $vFormat)) + { + $model = $this->getModel($vName); + $view->setModel($model, true); + + // For the dashboard view, we need to also push the requests model into the view + if ($vName === 'dashboard') + { + $requestsModel = $this->getModel('Requests'); + + $view->setModel($requestsModel, false); + } + + if ($vName === 'request') + { + // For the default layout, we need to also push the action logs model into the view + if ($lName === 'default') + { + JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php'); + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $logsModel = $this->getModel('Actionlogs', 'ActionlogsModel'); + + // Set default ordering for the context + $logsModel->setState('list.fullordering', 'a.log_date DESC'); + + // And push the model into the view + $view->setModel($logsModel, false); + } + + // For the edit layout, if mail sending is disabled then redirect back to the list view as the form is unusable in this state + if ($lName === 'edit' && !JFactory::getConfig()->get('mailonline', 1)) + { + $this->setRedirect( + JRoute::_('index.php?option=com_privacy&view=requests', false), + JText::_('COM_PRIVACY_WARNING_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED'), + 'warning' + ); + + return $this; + } + } + + $view->setLayout($lName); + + // Push document object into the view. + $view->document = $document; + + // Load the submenu. + PrivacyHelper::addSubmenu($this->input->get('view', $this->default_view)); + + $view->display(); + } + + return $this; + } + + /** + * Fetch and report number urgent privacy requests in JSON format, for AJAX requests + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function getNumberUrgentRequests() + { + $app = Factory::getApplication(); + + // Check for a valid token. If invalid, send a 403 with the error message. + if (!Session::checkToken('get')) + { + $app->setHeader('status', 403, true); + $app->sendHeaders(); + echo new JsonResponse(new \Exception(Text::_('JINVALID_TOKEN'), 403)); + $app->close(); + } + + /** @var PrivacyModelRequests $model */ + $model = $this->getModel('requests'); + $numberUrgentRequests = $model->getNumberUrgentRequests(); + + echo new JResponseJson(array('number_urgent_requests' => $numberUrgentRequests)); + + $app->close(); + } +} diff --git a/administrator/components/com_privacy/controllers/request.php b/administrator/components/com_privacy/controllers/request.php new file mode 100644 index 0000000000000..ded79e8b6ca2d --- /dev/null +++ b/administrator/components/com_privacy/controllers/request.php @@ -0,0 +1,395 @@ +getModel(); + + /** @var PrivacyTableRequest $table */ + $table = $model->getTable(); + + // Determine the name of the primary key for the data. + if (empty($key)) + { + $key = $table->getKeyName(); + } + + // To avoid data collisions the urlVar may be different from the primary key. + if (empty($urlVar)) + { + $urlVar = $key; + } + + $recordId = $this->input->getInt($urlVar); + + $item = $model->getItem($recordId); + + // Ensure this record can transition to the requested state + if (!$this->canTransition($item, '2')) + { + $this->setError(\JText::_('COM_PRIVACY_ERROR_COMPLETE_TRANSITION_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Build the data array for the update + $data = array( + $key => $recordId, + 'status' => '2', + ); + + // Access check. + if (!$this->allowSave($data, $key)) + { + $this->setError(\JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Attempt to save the data. + if (!$model->save($data)) + { + // Redirect back to the edit screen. + $this->setError(\JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Log the request completed + $model->logRequestCompleted($recordId); + + $this->setMessage(\JText::_('COM_PRIVACY_REQUEST_COMPLETED')); + + $url = 'index.php?option=com_privacy&view=requests'; + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + + if (!is_null($return) && \JUri::isInternal(base64_decode($return))) + { + $url = base64_decode($return); + } + + // Redirect to the list screen. + $this->setRedirect(\JRoute::_($url, false)); + + return true; + } + + /** + * Method to email the data export for a request. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function emailexport() + { + /** @var PrivacyModelExport $model */ + $model = $this->getModel('Export'); + + $recordId = $this->input->getUint('id'); + + if (!$model->emailDataExport($recordId)) + { + // Redirect back to the edit screen. + $this->setError(\JText::sprintf('COM_PRIVACY_ERROR_EXPORT_EMAIL_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + } + else + { + $this->setMessage(\JText::_('COM_PRIVACY_EXPORT_EMAILED')); + } + + $url = 'index.php?option=com_privacy&view=requests'; + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + + if (!is_null($return) && \JUri::isInternal(base64_decode($return))) + { + $url = base64_decode($return); + } + + // Redirect to the list screen. + $this->setRedirect(\JRoute::_($url, false)); + + return true; + } + + /** + * Method to invalidate a request. + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions). + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function invalidate($key = null, $urlVar = null) + { + // Check for request forgeries. + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + /** @var PrivacyModelRequest $model */ + $model = $this->getModel(); + + /** @var PrivacyTableRequest $table */ + $table = $model->getTable(); + + // Determine the name of the primary key for the data. + if (empty($key)) + { + $key = $table->getKeyName(); + } + + // To avoid data collisions the urlVar may be different from the primary key. + if (empty($urlVar)) + { + $urlVar = $key; + } + + $recordId = $this->input->getInt($urlVar); + + $item = $model->getItem($recordId); + + // Ensure this record can transition to the requested state + if (!$this->canTransition($item, '-1')) + { + $this->setError(\JText::_('COM_PRIVACY_ERROR_INVALID_TRANSITION_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Build the data array for the update + $data = array( + $key => $recordId, + 'status' => '-1', + ); + + // Access check. + if (!$this->allowSave($data, $key)) + { + $this->setError(\JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Attempt to save the data. + if (!$model->save($data)) + { + // Redirect back to the edit screen. + $this->setError(\JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Log the request invalidated + $model->logRequestInvalidated($recordId); + + $this->setMessage(\JText::_('COM_PRIVACY_REQUEST_INVALIDATED')); + + $url = 'index.php?option=com_privacy&view=requests'; + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + + if (!is_null($return) && \JUri::isInternal(base64_decode($return))) + { + $url = base64_decode($return); + } + + // Redirect to the list screen. + $this->setRedirect(\JRoute::_($url, false)); + + return true; + } + + /** + * Method to remove the user data for a privacy remove request. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function remove() + { + /** @var PrivacyModelRemove $model */ + $model = $this->getModel('Remove'); + + $recordId = $this->input->getUint('id'); + + if (!$model->removeDataForRequest($recordId)) + { + // Redirect back to the edit screen. + $this->setError(\JText::sprintf('COM_PRIVACY_ERROR_REMOVE_DATA_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + $this->setMessage(\JText::_('COM_PRIVACY_DATA_REMOVED')); + + $url = 'index.php?option=com_privacy&view=requests'; + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + + if (!is_null($return) && \JUri::isInternal(base64_decode($return))) + { + $url = base64_decode($return); + } + + // Redirect to the list screen. + $this->setRedirect(\JRoute::_($url, false)); + + return true; + } + + /** + * Function that allows child controller access to model data after the data has been saved. + * + * @param \JModelLegacy $model The data model object. + * @param array $validData The validated data. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function postSaveHook(\JModelLegacy $model, $validData = array()) + { + // This hook only processes new items + if (!$model->getState($model->getName() . '.new', false)) + { + return; + } + + if (!$model->logRequestCreated($model->getState($model->getName() . '.id'))) + { + if ($error = $model->getError()) + { + JFactory::getApplication()->enqueueMessage($error, 'warning'); + } + } + + if (!$model->notifyUserAdminCreatedRequest($model->getState($model->getName() . '.id'))) + { + if ($error = $model->getError()) + { + JFactory::getApplication()->enqueueMessage($error, 'warning'); + } + } + else + { + JFactory::getApplication()->enqueueMessage(JText::_('COM_PRIVACY_MSG_CONFIRM_EMAIL_SENT_TO_USER')); + } + } + + /** + * Method to determine if an item can transition to the specified status. + * + * @param object $item The item being updated. + * @param string $newStatus The new status of the item. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + private function canTransition($item, $newStatus) + { + switch ($item->status) + { + case '0': + // A pending item can only move to invalid through this controller due to the requirement for a user to confirm the request + return $newStatus === '-1'; + + case '1': + // A confirmed item can be marked completed or invalid + return in_array($newStatus, array('-1', '2'), true); + + // An item which is already in an invalid or complete state cannot transition, likewise if we don't know the state don't change anything + case '-1': + case '2': + default: + return false; + } + } +} diff --git a/administrator/components/com_privacy/controllers/request.xml.php b/administrator/components/com_privacy/controllers/request.xml.php new file mode 100644 index 0000000000000..3d92a34f892cf --- /dev/null +++ b/administrator/components/com_privacy/controllers/request.xml.php @@ -0,0 +1,32 @@ +input->set('view', 'export'); + + return $this->display(); + } +} diff --git a/administrator/components/com_privacy/controllers/requests.php b/administrator/components/com_privacy/controllers/requests.php new file mode 100644 index 0000000000000..1444a0e36ee79 --- /dev/null +++ b/administrator/components/com_privacy/controllers/requests.php @@ -0,0 +1,34 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/administrator/components/com_privacy/helpers/export/domain.php b/administrator/components/com_privacy/helpers/export/domain.php new file mode 100644 index 0000000000000..0ce1560b13580 --- /dev/null +++ b/administrator/components/com_privacy/helpers/export/domain.php @@ -0,0 +1,72 @@ +items[] = $item; + } + + /** + * Get the domain's items + * + * @return PrivacyExportItem[] + * + * @since __DEPLOY_VERSION__ + */ + public function getItems() + { + return $this->items; + } +} diff --git a/administrator/components/com_privacy/helpers/export/field.php b/administrator/components/com_privacy/helpers/export/field.php new file mode 100644 index 0000000000000..23fe15ba53aa1 --- /dev/null +++ b/administrator/components/com_privacy/helpers/export/field.php @@ -0,0 +1,34 @@ +fields[] = $field; + } + + /** + * Get the item's fields + * + * @return PrivacyExportField[] + * + * @since __DEPLOY_VERSION__ + */ + public function getFields() + { + return $this->fields; + } +} diff --git a/administrator/components/com_privacy/helpers/html/helper.php b/administrator/components/com_privacy/helpers/html/helper.php new file mode 100644 index 0000000000000..27ed235dabcf0 --- /dev/null +++ b/administrator/components/com_privacy/helpers/html/helper.php @@ -0,0 +1,46 @@ +' . JText::_('COM_PRIVACY_STATUS_COMPLETED') . ''; + + case 1: + return '' . JText::_('COM_PRIVACY_STATUS_CONFIRMED') . ''; + + case -1: + return '' . JText::_('COM_PRIVACY_STATUS_INVALID') . ''; + + default: + case 0: + return '' . JText::_('COM_PRIVACY_STATUS_PENDING') . ''; + } + } +} diff --git a/administrator/components/com_privacy/helpers/plugin.php b/administrator/components/com_privacy/helpers/plugin.php new file mode 100644 index 0000000000000..dd75a55cd5e73 --- /dev/null +++ b/administrator/components/com_privacy/helpers/plugin.php @@ -0,0 +1,99 @@ +name = $name; + $domain->description = $description; + + return $domain; + } + + /** + * Create an item object for an array + * + * @param array $data The array data to convert + * @param integer|null $itemId The ID of this item + * + * @return PrivacyExportItem + * + * @since __DEPLOY_VERSION__ + */ + protected function createItemFromArray(array $data, $itemId = null) + { + $item = new PrivacyExportItem; + $item->id = $itemId; + + foreach ($data as $key => $value) + { + if (is_object($value)) + { + $value = (array) $value; + } + + if (is_array($value)) + { + $value = print_r($value, true); + } + + $field = new PrivacyExportField; + $field->name = $key; + $field->value = $value; + + $item->addField($field); + } + + return $item; + } + + /** + * Create an item object for a JTable object + * + * @param JTable $table The JTable object to convert + * + * @return PrivacyExportItem + * + * @since __DEPLOY_VERSION__ + */ + protected function createItemForTable($table) + { + $data = array(); + + foreach (array_keys($table->getFields()) as $fieldName) + { + $data[$fieldName] = $table->$fieldName; + } + + return $this->createItemFromArray($data, $table->{$table->getKeyName(false)}); + } +} diff --git a/administrator/components/com_privacy/helpers/privacy.php b/administrator/components/com_privacy/helpers/privacy.php new file mode 100644 index 0000000000000..92c32547aebeb --- /dev/null +++ b/administrator/components/com_privacy/helpers/privacy.php @@ -0,0 +1,96 @@ +"); + + foreach ($exportData as $domain) + { + $xmlDomain = $export->addChild('domain'); + $xmlDomain->addAttribute('name', $domain->name); + $xmlDomain->addAttribute('description', $domain->description); + + foreach ($domain->getItems() as $item) + { + $xmlItem = $xmlDomain->addChild('item'); + + if ($item->id) + { + $xmlItem->addAttribute('id', $item->id); + } + + foreach ($item->getFields() as $field) + { + $xmlItem->{$field->name} = $field->value; + } + } + } + + $dom = new DOMDocument; + $dom->loadXML($export->asXML()); + $dom->formatOutput = true; + + return $dom->saveXML(); + } +} diff --git a/administrator/components/com_privacy/helpers/removal/status.php b/administrator/components/com_privacy/helpers/removal/status.php new file mode 100644 index 0000000000000..c07ceaa3ab216 --- /dev/null +++ b/administrator/components/com_privacy/helpers/removal/status.php @@ -0,0 +1,36 @@ + array( + JText::_('COM_PRIVACY_CORE_CAPABILITY_SESSION_IP_ADDRESS_AND_COOKIE'), + JText::sprintf('COM_PRIVACY_CORE_CAPABILITY_LOGGING_IP_ADDRESS', $app->get('log_path', JPATH_ADMINISTRATOR . '/logs')), + JText::_('COM_PRIVACY_CORE_CAPABILITY_COMMUNICATION_WITH_JOOMLA_ORG'), + ) + ); + + /* + * We will search for capabilities from the following plugin groups: + * + * - Authentication: These plugins by design process user information and may have capabilities such as creating cookies + * - Captcha: These plugins may communicate information to third party systems + * - Installer: These plugins can add additional install capabilities to the Extension Manager, such as the Install from Web service + * - Privacy: These plugins are the primary integration point into this component + * - User: These plugins are intended to extend the user management system + * + * This is in addition to plugin groups which are imported before this method is triggered, generally this is the system group. + */ + + JPluginHelper::importPlugin('authentication'); + JPluginHelper::importPlugin('captcha'); + JPluginHelper::importPlugin('installer'); + JPluginHelper::importPlugin('privacy'); + JPluginHelper::importPlugin('user'); + + $pluginResults = $app->triggerEvent('onPrivacyCollectAdminCapabilities'); + + // We are going to "cheat" here and include this component's capabilities without using a plugin + $extensionCapabilities = array( + JText::_('COM_PRIVACY') => array( + JText::_('COM_PRIVACY_EXTENSION_CAPABILITY_PERSONAL_INFO'), + ) + ); + + foreach ($pluginResults as $pluginResult) + { + $extensionCapabilities += $pluginResult; + } + + // Sort the extension list alphabetically + ksort($extensionCapabilities); + + // Always prepend the core capabilities to the array + return $coreCapabilities + $extensionCapabilities; + } + + /** + * Method to auto-populate the model state. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function populateState() + { + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + } +} diff --git a/administrator/components/com_privacy/models/consents.php b/administrator/components/com_privacy/models/consents.php new file mode 100644 index 0000000000000..f6c857b82497e --- /dev/null +++ b/administrator/components/com_privacy/models/consents.php @@ -0,0 +1,140 @@ +getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select($this->getState('list.select', 'a.*')); + $query->from($db->quoteName('#__privacy_consents', 'a')); + + // Join over the users for the username. + $query->select($db->quoteName('u.username', 'username')); + $query->join('LEFT', $db->quoteName('#__users', 'u') . ' ON u.id = a.user_id'); + + // Filter by search in email + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + elseif (stripos($search, 'uid:') === 0) + { + $query->where($db->quoteName('a.user_id') . ' = ' . (int) substr($search, 4)); + } + else + { + $search = $db->quote('%' . $db->escape($search, true) . '%'); + $query->where('(' . $db->quoteName('u.username') . ' LIKE ' . $search . ')'); + } + } + + // Handle the list ordering. + $ordering = $this->getState('list.ordering'); + $direction = $this->getState('list.direction'); + + if (!empty($ordering)) + { + $query->order($db->escape($ordering) . ' ' . $db->escape($direction)); + } + + return $query; + } + + /** + * 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 + * + * @since __DEPLOY_VERSION__ + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + + return parent::getStoreId($id); + } + + /** + * 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 __DEPLOY_VERSION__ + */ + protected function populateState($ordering = 'a.id', $direction = 'desc') + { + // Load the filter state. + $this->setState( + 'filter.search', + $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search') + ); + + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + + // List state information. + parent::populateState($ordering, $direction); + } +} diff --git a/administrator/components/com_privacy/models/dashboard.php b/administrator/components/com_privacy/models/dashboard.php new file mode 100644 index 0000000000000..d8aff04dadcce --- /dev/null +++ b/administrator/components/com_privacy/models/dashboard.php @@ -0,0 +1,105 @@ + false, + 'editLink' => '', + ); + + /* + * Prior to __DEPLOY_VERSION__ it was common for a plugin such as the User - Profile plugin to define a privacy policy or + * terms of service article, therefore we will also import the user plugin group to process this event. + */ + JPluginHelper::importPlugin('privacy'); + JPluginHelper::importPlugin('user'); + + JFactory::getApplication()->triggerEvent('onPrivacyCheckPrivacyPolicyPublished', array(&$policy)); + + return $policy; + } + + /** + * Get a count of the active information requests grouped by type and status + * + * @return array Array containing site privacy requests + * + * @since __DEPLOY_VERSION__ + */ + public function getRequestCounts() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select( + array( + 'COUNT(*) AS count', + $db->quoteName('status'), + $db->quoteName('request_type'), + ) + ) + ->from($db->quoteName('#__privacy_requests')) + ->group($db->quoteName('status')) + ->group($db->quoteName('request_type')); + + $db->setQuery($query); + + return $db->loadObjectList(); + } + + /** + * Check whether there is a menu item for the request form + * + * @return array Array containing a status of whether a menu is published for the request form and its current link + * + * @since __DEPLOY_VERSION__ + */ + public function getRequestFormPublished() + { + $app = JFactory::getApplication(); + $menu = $app->getMenu('site'); + + $item = $menu->getItems('link', 'index.php?option=com_privacy&view=request', true); + + $status = array( + 'published' => false, + 'link' => '', + ); + + $linkMode = $app->get('force_ssl', 0) == 2 ? 1 : -1; + + if (!($item instanceof JMenuItem)) + { + $status['link'] = JRoute::link('site', 'index.php?option=com_privacy&view=request', true, $linkMode); + } + else + { + $status['published'] = true; + $status['link'] = JRoute::link('site', 'index.php?Itemid=' . $item->id, true, $linkMode); + } + + return $status; + } +} diff --git a/administrator/components/com_privacy/models/export.php b/administrator/components/com_privacy/models/export.php new file mode 100644 index 0000000000000..baebfc45ec435 --- /dev/null +++ b/administrator/components/com_privacy/models/export.php @@ -0,0 +1,340 @@ +getState($this->getName() . '.request_id'); + + if (!$id) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_ID_REQUIRED_FOR_EXPORT')); + + return false; + } + + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + if ($table->request_type !== 'export') + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_TYPE_NOT_EXPORT')); + + return false; + } + + if ($table->status != 1) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_EXPORT_UNCONFIRMED_REQUEST')); + + return false; + } + + // If there is a user account associated with the email address, load it here for use in the plugins + $db = $this->getDbo(); + + $userId = (int) $db->setQuery( + $db->getQuery(true) + ->select('id') + ->from($db->quoteName('#__users')) + ->where($db->quoteName('email') . ' = ' . $db->quote($table->email)), + 0, + 1 + )->loadResult(); + + $user = $userId ? JUser::getInstance($userId) : null; + + // Log the export + $this->logExport($table); + + JPluginHelper::importPlugin('privacy'); + + $pluginResults = JFactory::getApplication()->triggerEvent('onPrivacyExportRequest', array($table, $user)); + + $domains = array(); + + foreach ($pluginResults as $pluginDomains) + { + $domains = array_merge($domains, $pluginDomains); + } + + return $domains; + } + + /** + * Email the data export to the user. + * + * @param integer $id The request ID to process + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function emailDataExport($id = null) + { + $id = !empty($id) ? $id : (int) $this->getState($this->getName() . '.request_id'); + + if (!$id) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_ID_REQUIRED_FOR_EXPORT')); + + return false; + } + + $exportData = $this->collectDataForExportRequest($id); + + if ($exportData === false) + { + // Error is already set, we just need to bail + return false; + } + + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + if ($table->request_type !== 'export') + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_TYPE_NOT_EXPORT')); + + return false; + } + + if ($table->status != 1) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_EXPORT_UNCONFIRMED_REQUEST')); + + return false; + } + + // Log the email + $this->logExportEmailed($table); + + /* + * If there is an associated user account, we will attempt to send this email in the user's preferred language. + * Because of this, it is expected that Language::_() is directly called and that the Text class is NOT used + * for translating all messages. + * + * Error messages will still be displayed to the administrator, so those messages should continue to use the Text class. + */ + + $lang = JFactory::getLanguage(); + + $db = $this->getDbo(); + + $userId = (int) $db->setQuery( + $db->getQuery(true) + ->select('id') + ->from($db->quoteName('#__users')) + ->where($db->quoteName('email') . ' = ' . $db->quote($table->email)), + 0, + 1 + )->loadResult(); + + if ($userId) + { + $receiver = JUser::getInstance($userId); + + /* + * We don't know if the user has admin access, so we will check if they have an admin language in their parameters, + * falling back to the site language, falling back to the currently active language + */ + + $langCode = $receiver->getParam('admin_language', ''); + + if (!$langCode) + { + $langCode = $receiver->getParam('language', $lang->getTag()); + } + + $lang = JLanguage::getInstance($langCode, $lang->getDebug()); + } + + // Ensure the right language files have been loaded + $lang->load('com_privacy', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('com_privacy', JPATH_ADMINISTRATOR . '/components/com_privacy', null, false, true); + + // The mailer can be set to either throw Exceptions or return boolean false, account for both + try + { + $app = JFactory::getApplication(); + + $substitutions = array( + '[SITENAME]' => $app->get('sitename'), + '[URL]' => JUri::root(), + '\\n' => "\n", + ); + + $emailSubject = $lang->_('COM_PRIVACY_EMAIL_DATA_EXPORT_COMPLETED_SUBJECT'); + $emailBody = $lang->_('COM_PRIVACY_EMAIL_DATA_EXPORT_COMPLETED_BODY'); + + foreach ($substitutions as $k => $v) + { + $emailSubject = str_replace($k, $v, $emailSubject); + $emailBody = str_replace($k, $v, $emailBody); + } + + $mailer = JFactory::getMailer(); + $mailer->setSubject($emailSubject); + $mailer->setBody($emailBody); + $mailer->addRecipient($table->email); + $mailer->addStringAttachment( + PrivacyHelper::renderDataAsXml($exportData), + 'user-data_' . JUri::getInstance()->toString(array('host')) . '.xml' + ); + + $mailResult = $mailer->Send(); + + if ($mailResult instanceof JException) + { + // JError was already called so we just need to return now + return false; + } + elseif ($mailResult === false) + { + $this->setError($mailer->ErrorInfo); + + return false; + } + + return true; + } + catch (phpmailerException $exception) + { + $this->setError($exception->getMessage()); + + return false; + } + + return true; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since __DEPLOY_VERSION__ + * @throws \Exception + */ + public function getTable($name = 'Request', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Log the data export to the action log system. + * + * @param PrivacyTableRequest $request The request record being processed + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function logExport(PrivacyTableRequest $request) + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'export', + 'id' => $request->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $request->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_EXPORT', 'com_privacy.request', $user->id); + } + + /** + * Log the data export email to the action log system. + * + * @param PrivacyTableRequest $request The request record being processed + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function logExportEmailed(PrivacyTableRequest $request) + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'export_emailed', + 'id' => $request->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $request->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_EXPORT_EMAILED', 'com_privacy.request', $user->id); + } + + /** + * Method to auto-populate the model state. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function populateState() + { + // Get the pk of the record from the request. + $this->setState($this->getName() . '.request_id', JFactory::getApplication()->input->getUint('id')); + + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + } +} diff --git a/administrator/components/com_privacy/models/fields/requeststatus.php b/administrator/components/com_privacy/models/fields/requeststatus.php new file mode 100644 index 0000000000000..3a9696719b668 --- /dev/null +++ b/administrator/components/com_privacy/models/fields/requeststatus.php @@ -0,0 +1,41 @@ + 'COM_PRIVACY_STATUS_INVALID', + '0' => 'COM_PRIVACY_STATUS_PENDING', + '1' => 'COM_PRIVACY_STATUS_CONFIRMED', + '2' => 'COM_PRIVACY_STATUS_COMPLETED', + ); +} diff --git a/administrator/components/com_privacy/models/fields/requesttype.php b/administrator/components/com_privacy/models/fields/requesttype.php new file mode 100644 index 0000000000000..4f4e1dc4929cc --- /dev/null +++ b/administrator/components/com_privacy/models/fields/requesttype.php @@ -0,0 +1,39 @@ + 'COM_PRIVACY_HEADING_REQUEST_TYPE_TYPE_EXPORT', + 'remove' => 'COM_PRIVACY_HEADING_REQUEST_TYPE_TYPE_REMOVE', + ); +} diff --git a/administrator/components/com_privacy/models/forms/filter_consents.xml b/administrator/components/com_privacy/models/forms/filter_consents.xml new file mode 100644 index 0000000000000..82e8b4d55ac82 --- /dev/null +++ b/administrator/components/com_privacy/models/forms/filter_consents.xml @@ -0,0 +1,42 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + diff --git a/administrator/components/com_privacy/models/forms/filter_requests.xml b/administrator/components/com_privacy/models/forms/filter_requests.xml new file mode 100644 index 0000000000000..697ba2188baac --- /dev/null +++ b/administrator/components/com_privacy/models/forms/filter_requests.xml @@ -0,0 +1,63 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/administrator/components/com_privacy/models/forms/request.xml b/administrator/components/com_privacy/models/forms/request.xml new file mode 100644 index 0000000000000..edf3efbf83695 --- /dev/null +++ b/administrator/components/com_privacy/models/forms/request.xml @@ -0,0 +1,66 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + +
+
diff --git a/administrator/components/com_privacy/models/remove.php b/administrator/components/com_privacy/models/remove.php new file mode 100644 index 0000000000000..cd0da4f224f9e --- /dev/null +++ b/administrator/components/com_privacy/models/remove.php @@ -0,0 +1,204 @@ +getState($this->getName() . '.request_id'); + + if (!$id) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_ID_REQUIRED_FOR_REMOVE')); + + return false; + } + + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + if ($table->request_type !== 'remove') + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_TYPE_NOT_REMOVE')); + + return false; + } + + if ($table->status != 1) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_REMOVE_UNCONFIRMED_REQUEST')); + + return false; + } + + // If there is a user account associated with the email address, load it here for use in the plugins + $db = $this->getDbo(); + + $userId = (int) $db->setQuery( + $db->getQuery(true) + ->select('id') + ->from($db->quoteName('#__users')) + ->where($db->quoteName('email') . ' = ' . $db->quote($table->email)), + 0, + 1 + )->loadResult(); + + $user = $userId ? JUser::getInstance($userId) : null; + + $canRemove = true; + + JPluginHelper::importPlugin('privacy'); + + /** @var PrivacyRemovalStatus[] $pluginResults */ + $pluginResults = JFactory::getApplication()->triggerEvent('onPrivacyCanRemoveData', array($table, $user)); + + foreach ($pluginResults as $status) + { + if (!$status->canRemove) + { + $this->setError($status->reason ?: JText::_('COM_PRIVACY_ERROR_CANNOT_REMOVE_DATA')); + + $canRemove = false; + } + } + + if (!$canRemove) + { + $this->logRemoveBlocked($table, $this->getErrors()); + + return false; + } + + // Log the removal + $this->logRemove($table); + + JFactory::getApplication()->triggerEvent('onPrivacyRemoveData', array($table, $user)); + + return true; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since __DEPLOY_VERSION__ + * @throws \Exception + */ + public function getTable($name = 'Request', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Log the data removal to the action log system. + * + * @param PrivacyTableRequest $request The request record being processed + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function logRemove(PrivacyTableRequest $request) + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'remove', + 'id' => $request->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $request->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_REMOVE', 'com_privacy.request', $user->id); + } + + /** + * Log the data removal being blocked to the action log system. + * + * @param PrivacyTableRequest $request The request record being processed + * @param string[] $reasons The reasons given why the record could not be removed. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function logRemoveBlocked(PrivacyTableRequest $request, array $reasons) + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'remove-blocked', + 'id' => $request->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $request->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + 'reasons' => implode('; ', $reasons), + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_REMOVE_BLOCKED', 'com_privacy.request', $user->id); + } + + /** + * Method to auto-populate the model state. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function populateState() + { + // Get the pk of the record from the request. + $this->setState($this->getName() . '.request_id', JFactory::getApplication()->input->getUint('id')); + + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + } +} diff --git a/administrator/components/com_privacy/models/request.php b/administrator/components/com_privacy/models/request.php new file mode 100644 index 0000000000000..ec5bb3884886f --- /dev/null +++ b/administrator/components/com_privacy/models/request.php @@ -0,0 +1,457 @@ +loadForm('com_privacy.request', 'request', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since __DEPLOY_VERSION__ + * @throws \Exception + */ + public function getTable($name = 'Request', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Method to get the data that should be injected in the form. + * + * @return array The default data is an empty array. + * + * @since __DEPLOY_VERSION__ + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_privacy.edit.request.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + return $data; + } + + /** + * Log the completion of a request to the action log system. + * + * @param integer $id The ID of the request to process. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function logRequestCompleted($id) + { + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'request-completed', + 'requesttype' => $table->request_type, + 'subjectemail' => $table->email, + 'id' => $table->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $table->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_ADMIN_COMPLETED_REQUEST', 'com_privacy.request', $user->id); + + return true; + } + + /** + * Log the creation of a request to the action log system. + * + * @param integer $id The ID of the request to process. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function logRequestCreated($id) + { + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'request-created', + 'requesttype' => $table->request_type, + 'subjectemail' => $table->email, + 'id' => $table->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $table->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_ADMIN_CREATED_REQUEST', 'com_privacy.request', $user->id); + + return true; + } + + /** + * Log the invalidation of a request to the action log system. + * + * @param integer $id The ID of the request to process. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function logRequestInvalidated($id) + { + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'request-invalidated', + 'requesttype' => $table->request_type, + 'subjectemail' => $table->email, + 'id' => $table->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $table->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_ADMIN_INVALIDATED_REQUEST', 'com_privacy.request', $user->id); + + return true; + } + + /** + * Notifies the user that an information request has been created by a site administrator. + * + * Because confirmation tokens are stored in the database as a hashed value, this method will generate a new confirmation token + * for the request. + * + * @param integer $id The ID of the request to process. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function notifyUserAdminCreatedRequest($id) + { + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + /* + * If there is an associated user account, we will attempt to send this email in the user's preferred language. + * Because of this, it is expected that Language::_() is directly called and that the Text class is NOT used + * for translating all messages. + * + * Error messages will still be displayed to the administrator, so those messages should continue to use the Text class. + */ + + $lang = JFactory::getLanguage(); + + $db = $this->getDbo(); + + $userId = (int) $db->setQuery( + $db->getQuery(true) + ->select('id') + ->from($db->quoteName('#__users')) + ->where($db->quoteName('email') . ' = ' . $db->quote($table->email)), + 0, + 1 + )->loadResult(); + + if ($userId) + { + $receiver = JUser::getInstance($userId); + + /* + * We don't know if the user has admin access, so we will check if they have an admin language in their parameters, + * falling back to the site language, falling back to the currently active language + */ + + $langCode = $receiver->getParam('admin_language', ''); + + if (!$langCode) + { + $langCode = $receiver->getParam('language', $lang->getTag()); + } + + $lang = JLanguage::getInstance($langCode, $lang->getDebug()); + } + + // Ensure the right language files have been loaded + $lang->load('com_privacy', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('com_privacy', JPATH_ADMINISTRATOR . '/components/com_privacy', null, false, true); + + // Regenerate the confirmation token + $token = JApplicationHelper::getHash(JUserHelper::genRandomPassword()); + $hashedToken = JUserHelper::hashPassword($token); + + $table->confirm_token = $hashedToken; + $table->confirm_token_created_at = JFactory::getDate()->toSql(); + + try + { + $table->store(); + } + catch (JDatabaseException $exception) + { + $this->setError($exception->getMessage()); + + return false; + } + + // The mailer can be set to either throw Exceptions or return boolean false, account for both + try + { + $app = JFactory::getApplication(); + + $linkMode = $app->get('force_ssl', 0) == 2 ? 1 : -1; + + $substitutions = array( + '[SITENAME]' => $app->get('sitename'), + '[URL]' => JUri::root(), + '[TOKENURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm&confirm_token=' . $token, false, $linkMode), + '[FORMURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm', false, $linkMode), + '[TOKEN]' => $token, + '\\n' => "\n", + ); + + switch ($table->request_type) + { + case 'export': + $emailSubject = $lang->_('COM_PRIVACY_EMAIL_ADMIN_REQUEST_SUBJECT_EXPORT_REQUEST'); + $emailBody = $lang->_('COM_PRIVACY_EMAIL_ADMIN_REQUEST_BODY_EXPORT_REQUEST'); + + break; + + case 'remove': + $emailSubject = $lang->_('COM_PRIVACY_EMAIL_ADMIN_REQUEST_SUBJECT_REMOVE_REQUEST'); + $emailBody = $lang->_('COM_PRIVACY_EMAIL_ADMIN_REQUEST_BODY_REMOVE_REQUEST'); + + break; + + default: + $this->setError(JText::_('COM_PRIVACY_ERROR_UNKNOWN_REQUEST_TYPE')); + + return false; + } + + foreach ($substitutions as $k => $v) + { + $emailSubject = str_replace($k, $v, $emailSubject); + $emailBody = str_replace($k, $v, $emailBody); + } + + $mailer = JFactory::getMailer(); + $mailer->setSubject($emailSubject); + $mailer->setBody($emailBody); + $mailer->addRecipient($table->email); + + $mailResult = $mailer->Send(); + + if ($mailResult instanceof JException) + { + // JError was already called so we just need to return now + return false; + } + elseif ($mailResult === false) + { + $this->setError($mailer->ErrorInfo); + + return false; + } + + return true; + } + catch (phpmailerException $exception) + { + $this->setError($exception->getMessage()); + + return false; + } + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success, False on error. + * + * @since __DEPLOY_VERSION__ + */ + public function save($data) + { + $table = $this->getTable(); + $key = $table->getKeyName(); + $pk = !empty($data[$key]) ? $data[$key] : (int) $this->getState($this->getName() . '.id'); + + if (!$pk && !JFactory::getConfig()->get('mailonline', 1)) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED')); + + return false; + } + + return parent::save($data); + } + + /** + * Method to validate the form data. + * + * @param JForm $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the field group to validate. + * + * @return array|boolean Array of filtered data if valid, false otherwise. + * + * @see JFormRule + * @see JFilterInput + * @since __DEPLOY_VERSION__ + */ + public function validate($form, $data, $group = null) + { + $validatedData = parent::validate($form, $data, $group); + + // If parent validation failed there's no point in doing our extended validation + if ($validatedData === false) + { + return false; + } + + // The user cannot create a request for their own account + if (strtolower(JFactory::getUser()->email) === strtolower($validatedData['email'])) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_FOR_SELF')); + + return false; + } + + // Check for an active request for this email address + $db = $this->getDbo(); + + $query = $db->getQuery(true) + ->select('COUNT(id)') + ->from('#__privacy_requests') + ->where('email = ' . $db->quote($validatedData['email'])) + ->where('request_type = ' . $db->quote($validatedData['request_type'])) + ->where('status IN (0, 1)'); + + $activeRequestCount = (int) $db->setQuery($query)->loadResult(); + + if ($activeRequestCount > 0) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_ACTIVE_REQUEST_FOR_EMAIL')); + + return false; + } + + return $validatedData; + } +} diff --git a/administrator/components/com_privacy/models/requests.php b/administrator/components/com_privacy/models/requests.php new file mode 100644 index 0000000000000..026d93e72d6ff --- /dev/null +++ b/administrator/components/com_privacy/models/requests.php @@ -0,0 +1,196 @@ +getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select($this->getState('list.select', 'a.*')); + $query->from($db->quoteName('#__privacy_requests', 'a')); + + // Join over the users for the checked out user. + $query->select($db->quoteName('uc.name', 'editor')); + $query->join('LEFT', $db->quoteName('#__users', 'uc') . ' ON uc.id = a.checked_out'); + + // Filter by status + $status = $this->getState('filter.status'); + + if (is_numeric($status)) + { + $query->where('a.status = ' . (int) $status); + } + + // Filter by request type + $requestType = $this->getState('filter.request_type', ''); + + if ($requestType) + { + $query->where('a.request_type = ' . $db->quote($db->escape($requestType, true))); + } + + // Filter by search in email + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . $db->escape($search, true) . '%'); + $query->where('(' . $db->quoteName('a.email') . ' LIKE ' . $search . ')'); + } + } + + // Handle the list ordering. + $ordering = $this->getState('list.ordering'); + $direction = $this->getState('list.direction'); + + if (!empty($ordering)) + { + $query->order($db->escape($ordering) . ' ' . $db->escape($direction)); + } + + return $query; + } + + /** + * 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 + * + * @since __DEPLOY_VERSION__ + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.status'); + $id .= ':' . $this->getState('filter.request_type'); + + return parent::getStoreId($id); + } + + /** + * 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 __DEPLOY_VERSION__ + */ + protected function populateState($ordering = 'a.id', $direction = 'desc') + { + // Load the filter state. + $this->setState( + 'filter.search', + $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search') + ); + + $this->setState( + 'filter.status', + $this->getUserStateFromRequest($this->context . '.filter.status', 'filter_status', '', 'int') + ); + + $this->setState( + 'filter.request_type', + $this->getUserStateFromRequest($this->context . '.filter.request_type', 'filter_request_type', '', 'string') + ); + + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to return number privacy requests older than X days. + * + * @return integer + * + * @since __DEPLOY_VERSION__ + */ + public function getNumberUrgentRequests() + { + // Load the parameters. + $params = ComponentHelper::getComponent('com_privacy')->getParams(); + $notify = (int) $params->get('notify', 14); + $now = JFactory::getDate()->toSql(); + $period = '-' . $notify; + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('COUNT(*)'); + $query->from($db->quoteName('#__privacy_requests')); + $query->where($db->quoteName('status') . ' = 1 '); + $query->where($query->dateAdd($now, $period, 'DAY') . ' > ' . $db->quoteName('requested_at')); + $db->setQuery($query); + + return (int) $db->loadResult(); + } +} diff --git a/administrator/components/com_privacy/privacy.php b/administrator/components/com_privacy/privacy.php new file mode 100644 index 0000000000000..9919fde723be1 --- /dev/null +++ b/administrator/components/com_privacy/privacy.php @@ -0,0 +1,20 @@ +authorise('core.admin')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = JControllerLegacy::getInstance('Privacy'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/administrator/components/com_privacy/privacy.xml b/administrator/components/com_privacy/privacy.xml new file mode 100644 index 0000000000000..2ae488804c791 --- /dev/null +++ b/administrator/components/com_privacy/privacy.xml @@ -0,0 +1,40 @@ + + + com_privacy + Joomla! Project + May 2018 + (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_PRIVACY_XML_DESCRIPTION + + controller.php + privacy.php + router.php + controllers + models + views + + + language/en-GB.com_privacy.ini + + + + config.xml + controller.php + privacy.php + controllers + helpers + models + tables + views + + + language/en-GB.com_privacy.ini + language/en-GB.com_privacy.sys.ini + + + + diff --git a/administrator/components/com_privacy/tables/consent.php b/administrator/components/com_privacy/tables/consent.php new file mode 100644 index 0000000000000..e6f8e6c966fb2 --- /dev/null +++ b/administrator/components/com_privacy/tables/consent.php @@ -0,0 +1,65 @@ +id) + { + if (!$this->remind) + { + $this->remind = '0'; + } + + if (!$this->created) + { + $this->created = $date->toSql(); + } + } + + return parent::store($updateNulls); + } +} diff --git a/administrator/components/com_privacy/tables/request.php b/administrator/components/com_privacy/tables/request.php new file mode 100644 index 0000000000000..76f040f69ed40 --- /dev/null +++ b/administrator/components/com_privacy/tables/request.php @@ -0,0 +1,70 @@ +id) + { + if (!$this->status) + { + $this->status = '0'; + } + + if (!$this->requested_at) + { + $this->requested_at = $date->toSql(); + } + } + + return parent::store($updateNulls); + } +} diff --git a/administrator/components/com_privacy/views/capabilities/tmpl/default.php b/administrator/components/com_privacy/views/capabilities/tmpl/default.php new file mode 100644 index 0000000000000..4f0e03e27e1a9 --- /dev/null +++ b/administrator/components/com_privacy/views/capabilities/tmpl/default.php @@ -0,0 +1,54 @@ + +sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ +
+

+ +
+ capabilities)) : ?> +
+ +
+ + + 'slide-0')); ?> + + capabilities as $extension => $capabilities) : ?> + + +
+ +
+ +
    + +
  • + +
+ + + + + + + +
diff --git a/administrator/components/com_privacy/views/capabilities/view.html.php b/administrator/components/com_privacy/views/capabilities/view.html.php new file mode 100644 index 0000000000000..06a23edf7e0bb --- /dev/null +++ b/administrator/components/com_privacy/views/capabilities/view.html.php @@ -0,0 +1,88 @@ +capabilities = $this->get('Capabilities'); + $this->state = $this->get('State'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function addToolbar() + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_CAPABILITIES'), 'lock'); + + JToolbarHelper::preferences('com_privacy'); + + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_CAPABILITIES'); + } +} diff --git a/administrator/components/com_privacy/views/consents/tmpl/default.php b/administrator/components/com_privacy/views/consents/tmpl/default.php new file mode 100644 index 0000000000000..f54a30ce98ff8 --- /dev/null +++ b/administrator/components/com_privacy/views/consents/tmpl/default.php @@ -0,0 +1,104 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$now = JFactory::getDate(); + +?> +
+ sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + $this)); ?> +
+ items)) : ?> +
+ +
+ + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + + +
+ + + + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ username; ?> + + user_id; ?> + + subject; ?> + + body; ?> + + + created), null, $now); ?> + + + id; ?> +
+ + + + + +
+ diff --git a/administrator/components/com_privacy/views/consents/tmpl/default.xml b/administrator/components/com_privacy/views/consents/tmpl/default.xml new file mode 100644 index 0000000000000..b36c1cde72aea --- /dev/null +++ b/administrator/components/com_privacy/views/consents/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/administrator/components/com_privacy/views/consents/view.html.php b/administrator/components/com_privacy/views/consents/view.html.php new file mode 100644 index 0000000000000..e7741c1dcd78d --- /dev/null +++ b/administrator/components/com_privacy/views/consents/view.html.php @@ -0,0 +1,117 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function addToolbar() + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_CONSENTS'), 'lock'); + + JToolbarHelper::preferences('com_privacy'); + + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_CONSENTS'); + } +} diff --git a/administrator/components/com_privacy/views/dashboard/tmpl/default.php b/administrator/components/com_privacy/views/dashboard/tmpl/default.php new file mode 100644 index 0000000000000..a0c282bf51d74 --- /dev/null +++ b/administrator/components/com_privacy/views/dashboard/tmpl/default.php @@ -0,0 +1,170 @@ + +sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ +
+
+
+ +
+ requestCounts)) : ?> +
+
+
+
+
+ requestCounts as $row) : ?> +
+ +
status); ?>
+
count; ?>
+
+ status, array(0, 1))) : ?> + count; ?> + + count; ?> + +
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+ privacyPolicyInfo['published']) : ?> + + + + + + + + + + +
+
+
+ privacyPolicyInfo['editLink'] !== '') : ?> + + +
+
+
+
+ requestFormPublished['published']) : ?> + + + + + + + + + + +
+
+
+ requestFormPublished['link'] !== '') : ?> + requestFormPublished['link']; ?> + +
+
+
+
+ numberOfUrgentRequests === 0) : ?> + + + + + + + + + + +
+
+
+ urgentRequestDays); ?> + numberOfUrgentRequests > 0) : ?> + + +
+
+
+
+ sendMailEnabled) : ?> + + + + + + + + + + +
+
+ sendMailEnabled) : ?> +
+ + +
+ +
+
+
+
+
+
+
diff --git a/administrator/components/com_privacy/views/dashboard/tmpl/default.xml b/administrator/components/com_privacy/views/dashboard/tmpl/default.xml new file mode 100644 index 0000000000000..f9a24bf36cad4 --- /dev/null +++ b/administrator/components/com_privacy/views/dashboard/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/administrator/components/com_privacy/views/dashboard/view.html.php b/administrator/components/com_privacy/views/dashboard/view.html.php new file mode 100644 index 0000000000000..f86e5ca99c06c --- /dev/null +++ b/administrator/components/com_privacy/views/dashboard/view.html.php @@ -0,0 +1,121 @@ +privacyPolicyInfo = $this->get('PrivacyPolicyInfo'); + $this->requestCounts = $this->get('RequestCounts'); + $this->requestFormPublished = $this->get('RequestFormPublished'); + $this->sendMailEnabled = (bool) JFactory::getConfig()->get('mailonline', 1); + + /** @var PrivacyModelRequests $requestsModel */ + $requestsModel = $this->getModel('requests'); + + $this->numberOfUrgentRequests = $requestsModel->getNumberUrgentRequests(); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->urgentRequestDays = (int) JComponentHelper::getParams('com_privacy')->get('notify', 14); + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function addToolbar() + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_DASHBOARD'), 'lock'); + + JToolbarHelper::preferences('com_privacy'); + + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_DASHBOARD'); + } +} diff --git a/administrator/components/com_privacy/views/export/view.xml.php b/administrator/components/com_privacy/views/export/view.xml.php new file mode 100644 index 0000000000000..d6351ba1fab8e --- /dev/null +++ b/administrator/components/com_privacy/views/export/view.xml.php @@ -0,0 +1,55 @@ +getModel(); + + $exportData = $model->collectDataForExportRequest(); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $requestId = $model->getState($model->getName() . '.request_id'); + + // This document should always be downloaded + $this->document->setDownload(true); + $this->document->setName('export-request-' . $requestId); + + echo PrivacyHelper::renderDataAsXml($exportData); + } +} diff --git a/administrator/components/com_privacy/views/request/tmpl/default.php b/administrator/components/com_privacy/views/request/tmpl/default.php new file mode 100644 index 0000000000000..059982d6331fa --- /dev/null +++ b/administrator/components/com_privacy/views/request/tmpl/default.php @@ -0,0 +1,90 @@ +addScriptDeclaration($js); +?> + +
+
+
+

+
+
:
+
item->email; ?>
+ +
:
+
item->status); ?>
+ +
:
+
item->request_type); ?>
+ +
:
+
item->requested_at, JText::_('DATE_FORMAT_LC6')); ?>
+
+
+
+

+ actionlogs)) : ?> +
+ +
+ + + + + + + + + actionlogs as $i => $item) : ?> + + + + + + + +
+ + + + + +
+ + + escape($item->log_date); ?> + + name; ?> +
+ +
+
+ + + +
diff --git a/administrator/components/com_privacy/views/request/tmpl/edit.php b/administrator/components/com_privacy/views/request/tmpl/edit.php new file mode 100644 index 0000000000000..d679b04a4e384 --- /dev/null +++ b/administrator/components/com_privacy/views/request/tmpl/edit.php @@ -0,0 +1,44 @@ +addScriptDeclaration($js); +?> + +
+
+
+
+
+ form->renderField('email'); ?> + form->renderField('status'); ?> + form->renderField('request_type'); ?> +
+
+
+ + + +
+
diff --git a/administrator/components/com_privacy/views/request/view.html.php b/administrator/components/com_privacy/views/request/view.html.php new file mode 100644 index 0000000000000..36ae3e717e973 --- /dev/null +++ b/administrator/components/com_privacy/views/request/view.html.php @@ -0,0 +1,173 @@ +item = $this->get('Item'); + $this->state = $this->get('State'); + + // Variables only required for the default layout + if ($this->getLayout() === 'default') + { + /** @var ActionlogsModelActionlogs $logsModel */ + $logsModel = $this->getModel('actionlogs'); + + $this->actionlogs = $logsModel->getLogsForItem('com_privacy.request', $this->item->id); + + // Load the com_actionlogs language strings for use in the layout + $lang = JFactory::getLanguage(); + $lang->load('com_actionlogs', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('com_actionlogs', JPATH_ADMINISTRATOR . '/components/com_actionlogs', null, false, true); + } + + // Variables only required for the edit layout + if ($this->getLayout() === 'edit') + { + $this->form = $this->get('Form'); + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function addToolbar() + { + JFactory::getApplication('administrator')->set('hidemainmenu', true); + + // Set the title and toolbar based on the layout + if ($this->getLayout() === 'edit') + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_REQUEST_ADD_REQUEST'), 'lock'); + + JToolbarHelper::apply('request.save'); + JToolbarHelper::cancel('request.cancel'); + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_REQUEST_EDIT'); + } + else + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_REQUEST_SHOW_REQUEST'), 'lock'); + + $bar = JToolbar::getInstance('toolbar'); + + // Add transition and action buttons based on item status + switch ($this->item->status) + { + case '0': + $bar->appendButton('Standard', 'cancel-circle', 'COM_PRIVACY_TOOLBAR_INVALIDATE', 'request.invalidate', false); + + break; + + case '1': + $return = '&return=' . base64_encode('index.php?option=com_privacy&view=request&id=' . (int) $this->item->id); + + $bar->appendButton('Standard', 'apply', 'COM_PRIVACY_TOOLBAR_COMPLETE', 'request.complete', false); + $bar->appendButton('Standard', 'cancel-circle', 'COM_PRIVACY_TOOLBAR_INVALIDATE', 'request.invalidate', false); + + if ($this->item->request_type === 'export') + { + JToolbarHelper::link( + JRoute::_('index.php?option=com_privacy&task=request.export&format=xml&id=' . (int) $this->item->id . $return), + 'COM_PRIVACY_ACTION_EXPORT_DATA', + 'download' + ); + + if (JFactory::getConfig()->get('mailonline', 1)) + { + JToolbarHelper::link( + JRoute::_('index.php?option=com_privacy&task=request.emailexport&id=' . (int) $this->item->id . $return), + 'COM_PRIVACY_ACTION_EMAIL_EXPORT_DATA', + 'mail' + ); + } + } + + if ($this->item->request_type === 'remove') + { + $bar->appendButton('Standard', 'delete', 'COM_PRIVACY_ACTION_DELETE_DATA', 'request.remove', false); + } + + break; + + // Item is in a "locked" state and cannot transition + default: + break; + } + + JToolbarHelper::cancel('request.cancel', 'JTOOLBAR_CLOSE'); + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_REQUEST'); + } + } +} diff --git a/administrator/components/com_privacy/views/requests/tmpl/default.php b/administrator/components/com_privacy/views/requests/tmpl/default.php new file mode 100644 index 0000000000000..5a842cf82a91a --- /dev/null +++ b/administrator/components/com_privacy/views/requests/tmpl/default.php @@ -0,0 +1,127 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$now = JFactory::getDate(); + +$urgentRequestDate= clone $now; +$urgentRequestDate->sub(new DateInterval('P' . $this->urgentRequestAge . 'D')); +?> +
+ sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + $this)); ?> +
+ items)) : ?> +
+ +
+ + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + requested_at); + ?> + + + + + + + + + + +
+ + + + + + + + + + + +
+ pagination->getListFooter(); ?> +
+
+ status == 1 && $item->request_type === 'export') : ?> + + sendMailEnabled) : ?> + + + + status == 1 && $item->request_type === 'remove') : ?> + + +
+
+ status); ?> + + + escape($item->email)); ?> + + status == 1 && $urgentRequestDate >= $itemRequestedAt) : ?> + + + + request_type); ?> + + + + + + id; ?> +
+ + + + + +
+ diff --git a/administrator/components/com_privacy/views/requests/tmpl/default.xml b/administrator/components/com_privacy/views/requests/tmpl/default.xml new file mode 100644 index 0000000000000..4c624d279a747 --- /dev/null +++ b/administrator/components/com_privacy/views/requests/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/administrator/components/com_privacy/views/requests/view.html.php b/administrator/components/com_privacy/views/requests/view.html.php new file mode 100644 index 0000000000000..c5122d3e895d0 --- /dev/null +++ b/administrator/components/com_privacy/views/requests/view.html.php @@ -0,0 +1,141 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->urgentRequestAge = (int) JComponentHelper::getParams('com_privacy')->get('notify', 14); + $this->sendMailEnabled = (bool) JFactory::getConfig()->get('mailonline', 1); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function addToolbar() + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_REQUESTS'), 'lock'); + + // Requests can only be created if mail sending is enabled + if (JFactory::getConfig()->get('mailonline', 1)) + { + JToolbarHelper::addNew('request.add'); + } + + JToolbarHelper::preferences('com_privacy'); + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_REQUESTS'); + + } +} diff --git a/administrator/help/en-GB/toc.json b/administrator/help/en-GB/toc.json index b2cf6954bc995..e48d7359b2a5a 100644 --- a/administrator/help/en-GB/toc.json +++ b/administrator/help/en-GB/toc.json @@ -1 +1 @@ -{ "COMPONENTS_ASSOCIATIONS": "COMPONENTS_ASSOCIATIONS", "COMPONENTS_ASSOCIATIONS_EDIT": "COMPONENTS_ASSOCIATIONS_EDIT", "COMPONENTS_BANNERS_BANNERS": "COMPONENTS_BANNERS_BANNERS", "COMPONENTS_BANNERS_BANNERS_EDIT": "COMPONENTS_BANNERS_BANNERS_EDIT", "COMPONENTS_BANNERS_CATEGORIES": "COMPONENTS_BANNERS_CATEGORIES", "COMPONENTS_BANNERS_CATEGORY_EDIT": "COMPONENTS_BANNERS_CATEGORIES_EDIT", "COMPONENTS_BANNERS_CLIENTS": "COMPONENTS_BANNERS_CLIENTS", "COMPONENTS_BANNERS_CLIENTS_EDIT": "COMPONENTS_BANNERS_CLIENTS_EDIT", "COMPONENTS_BANNERS_TRACKS": "COMPONENTS_BANNERS_TRACKS", "COMPONENTS_CONTACTS_CONTACTS": "COMPONENTS_CONTACTS_CONTACTS", "COMPONENTS_CONTACTS_CONTACTS_EDIT": "COMPONENTS_CONTACTS_CONTACTS_EDIT", "COMPONENTS_CONTACT_CATEGORIES": "COMPONENTS_CONTACT_CATEGORIES", "COMPONENTS_CONTACT_CATEGORY_EDIT": "COMPONENTS_CONTACT_CATEGORIES_EDIT", "COMPONENTS_CONTENT_CATEGORIES": "COMPONENTS_CONTENT_CATEGORIES", "COMPONENTS_CONTENT_CATEGORY_EDIT": "COMPONENTS_CONTENT_CATEGORIES_EDIT", "COMPONENTS_FIELDS_FIELDS": "COMPONENTS_FIELDS_FIELDS", "COMPONENTS_FIELDS_FIELDS_EDIT": "COMPONENTS_FIELDS_FIELDS_EDIT", "COMPONENTS_FIELDS_FIELD_GROUPS": "COMPONENTS_FIELDS_FIELD_GROUPS", "COMPONENTS_FIELDS_FIELD_GROUPS_EDIT": "COMPONENTS_FIELDS_FIELD_GROUPS_EDIT", "COMPONENTS_FINDER_MANAGE_CONTENT_MAPS": "COMPONENTS_FINDER_MANAGE_CONTENT_MAPS", "COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT": "COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT", "COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS": "COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS", "COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT": "COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT", "COMPONENTS_JOOMLA_UPDATE": "COMPONENTS_JOOMLA_UPDATE", "COMPONENTS_MESSAGING_INBOX": "COMPONENTS_MESSAGING_INBOX", "COMPONENTS_MESSAGING_READ": "COMPONENTS_MESSAGING_READ", "COMPONENTS_MESSAGING_WRITE": "COMPONENTS_MESSAGING_WRITE", "COMPONENTS_NEWSFEEDS_CATEGORIES": "COMPONENTS_NEWSFEEDS_CATEGORIES", "COMPONENTS_NEWSFEEDS_CATEGORY_EDIT": "COMPONENTS_NEWSFEEDS_CATEGORIES_EDIT", "COMPONENTS_NEWSFEEDS_FEEDS": "COMPONENTS_NEWSFEEDS_FEEDS", "COMPONENTS_NEWSFEEDS_FEEDS_EDIT": "COMPONENTS_NEWSFEEDS_FEEDS_EDIT", "COMPONENTS_POST_INSTALLATION_MESSAGES": "COMPONENTS_POST_INSTALLATION_MESSAGES", "COMPONENTS_REDIRECT_MANAGER": "COMPONENTS_REDIRECT_MANAGER", "COMPONENTS_REDIRECT_MANAGER_EDIT": "COMPONENTS_REDIRECT_MANAGER_EDIT", "COMPONENTS_SEARCH": "COMPONENTS_SEARCH", "COMPONENTS_TAGS_MANAGER": "COMPONENTS_TAGS_MANAGER", "COMPONENTS_TAGS_MANAGER_EDIT": "COMPONENTS_TAGS_MANAGER_EDIT", "COMPONENTS_WEBLINKS_CATEGORIES": "COMPONENTS_WEBLINKS_CATEGORIES", "COMPONENTS_WEBLINKS_CATEGORY_EDIT": "COMPONENTS_WEBLINKS_CATEGORIES_EDIT", "COMPONENTS_WEBLINKS_LINKS": "COMPONENTS_WEBLINKS_LINKS", "COMPONENTS_WEBLINKS_LINKS_EDIT": "COMPONENTS_WEBLINKS_LINKS_EDIT", "CONTENT_ARTICLE_MANAGER": "CONTENT_ARTICLE_MANAGER", "CONTENT_ARTICLE_MANAGER_EDIT": "CONTENT_ARTICLE_MANAGER_EDIT", "CONTENT_FEATURED_ARTICLES": "CONTENT_FEATURED_ARTICLES", "CONTENT_MEDIA_MANAGER": "CONTENT_MEDIA_MANAGER", "EXTENSIONS_EXTENSION_MANAGER_DATABASE": "EXTENSIONS_EXTENSION_MANAGER_DATABASE", "EXTENSIONS_EXTENSION_MANAGER_DISCOVER": "EXTENSIONS_EXTENSION_MANAGER_DISCOVER", "EXTENSIONS_EXTENSION_MANAGER_INSTALL": "EXTENSIONS_EXTENSION_MANAGER_INSTALL", "EXTENSIONS_EXTENSION_MANAGER_MANAGE": "EXTENSIONS_EXTENSION_MANAGER_MANAGE", "EXTENSIONS_EXTENSION_MANAGER_UPDATE": "EXTENSIONS_EXTENSION_MANAGER_UPDATE", "EXTENSIONS_EXTENSION_MANAGER_WARNINGS": "EXTENSIONS_EXTENSION_MANAGER_WARNINGS", "EXTENSIONS_LANGUAGE_MANAGER_CONTENT": "EXTENSIONS_LANGUAGE_MANAGER_CONTENT", "EXTENSIONS_LANGUAGE_MANAGER_EDIT": "EXTENSIONS_LANGUAGE_MANAGER_EDIT", "EXTENSIONS_LANGUAGE_MANAGER_INSTALLED": "EXTENSIONS_LANGUAGE_MANAGER_INSTALLED", "EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES": "EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES", "EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT": "EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT", "EXTENSIONS_MODULE_MANAGER": "EXTENSIONS_MODULE_MANAGER", "EXTENSIONS_MODULE_MANAGER_EDIT": "EXTENSIONS_MODULE_MANAGER_EDIT", "EXTENSIONS_PLUGIN_MANAGER": "EXTENSIONS_PLUGIN_MANAGER", "EXTENSIONS_PLUGIN_MANAGER_EDIT": "EXTENSIONS_PLUGIN_MANAGER_EDIT", "EXTENSIONS_TEMPLATE_MANAGER_STYLES": "EXTENSIONS_TEMPLATE_MANAGER_STYLES", "EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT": "EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT", "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES": "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES", "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT": "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT", "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT_SOURCE": "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT_SOURCE", "MENUS_MENU_ITEM_MANAGER": "MENUS_MENU_ITEM_MANAGER", "MENUS_MENU_ITEM_MANAGER_EDIT": "MENUS_MENU_ITEM_MANAGER_EDIT", "MENUS_MENU_MANAGER": "MENUS_MENU_MANAGER", "MENUS_MENU_MANAGER_EDIT": "MENUS_MENU_MANAGER_EDIT", "SITE_GLOBAL_CONFIGURATION": "SITE_GLOBAL_CONFIGURATION", "SITE_MAINTENANCE_CLEAR_CACHE": "SITE_MAINTENANCE_CLEAR_CACHE", "SITE_MAINTENANCE_GLOBAL_CHECK-IN": "SITE_MAINTENANCE_GLOBAL_CHECK-IN", "SITE_MAINTENANCE_PURGE_EXPIRED_CACHE": "SITE_MAINTENANCE_PURGE_EXPIRED_CACHE", "SITE_SYSTEM_INFORMATION": "SITE_SYSTEM_INFORMATION", "START_HERE": "START_HERE", "USERS_ACCESS_LEVELS": "USERS_ACCESS_LEVELS", "USERS_ACCESS_LEVELS_EDIT": "USERS_ACCESS_LEVELS_EDIT", "USERS_DEBUG_USERS": "USERS_DEBUG_USER", "USERS_GROUPS": "USERS_GROUPS", "USERS_GROUPS_EDIT": "USERS_GROUPS_EDIT", "USERS_MASS_MAIL_USERS": "USERS_MASS_MAIL_USERS", "USERS_USER_MANAGER": "USERS_USER_MANAGER", "USERS_USER_MANAGER_EDIT": "USERS_USER_MANAGER_EDIT", "USERS_USER_NOTES": "USERS_USER_NOTES", "USERS_USER_NOTES_EDIT": "USERS_USER_NOTES_EDIT" } \ No newline at end of file +{"COMPONENTS_ASSOCIATIONS":"COMPONENTS_ASSOCIATIONS","COMPONENTS_ASSOCIATIONS_EDIT":"COMPONENTS_ASSOCIATIONS_EDIT","COMPONENTS_BANNERS_BANNERS":"COMPONENTS_BANNERS_BANNERS","COMPONENTS_BANNERS_BANNERS_EDIT":"COMPONENTS_BANNERS_BANNERS_EDIT","COMPONENTS_BANNERS_CATEGORIES":"COMPONENTS_BANNERS_CATEGORIES","COMPONENTS_BANNERS_CATEGORY_EDIT":"COMPONENTS_BANNERS_CATEGORIES_EDIT","COMPONENTS_BANNERS_CLIENTS":"COMPONENTS_BANNERS_CLIENTS","COMPONENTS_BANNERS_CLIENTS_EDIT":"COMPONENTS_BANNERS_CLIENTS_EDIT","COMPONENTS_BANNERS_TRACKS":"COMPONENTS_BANNERS_TRACKS","COMPONENTS_CONTACTS_CONTACTS":"COMPONENTS_CONTACTS_CONTACTS","COMPONENTS_CONTACTS_CONTACTS_EDIT":"COMPONENTS_CONTACTS_CONTACTS_EDIT","COMPONENTS_CONTACT_CATEGORIES":"COMPONENTS_CONTACT_CATEGORIES","COMPONENTS_CONTACT_CATEGORY_EDIT":"COMPONENTS_CONTACT_CATEGORIES_EDIT","COMPONENTS_CONTENT_CATEGORIES":"COMPONENTS_CONTENT_CATEGORIES","COMPONENTS_CONTENT_CATEGORY_EDIT":"COMPONENTS_CONTENT_CATEGORIES_EDIT","COMPONENTS_FIELDS_FIELDS":"COMPONENTS_FIELDS_FIELDS","COMPONENTS_FIELDS_FIELDS_EDIT":"COMPONENTS_FIELDS_FIELDS_EDIT","COMPONENTS_FIELDS_FIELD_GROUPS":"COMPONENTS_FIELDS_FIELD_GROUPS","COMPONENTS_FIELDS_FIELD_GROUPS_EDIT":"COMPONENTS_FIELDS_FIELD_GROUPS_EDIT","COMPONENTS_FINDER_MANAGE_CONTENT_MAPS":"COMPONENTS_FINDER_MANAGE_CONTENT_MAPS","COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT":"COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT","COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS":"COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS","COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT":"COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT","COMPONENTS_JOOMLA_UPDATE":"COMPONENTS_JOOMLA_UPDATE","COMPONENTS_MESSAGING_INBOX":"COMPONENTS_MESSAGING_INBOX","COMPONENTS_MESSAGING_READ":"COMPONENTS_MESSAGING_READ","COMPONENTS_MESSAGING_WRITE":"COMPONENTS_MESSAGING_WRITE","COMPONENTS_NEWSFEEDS_CATEGORIES":"COMPONENTS_NEWSFEEDS_CATEGORIES","COMPONENTS_NEWSFEEDS_CATEGORY_EDIT":"COMPONENTS_NEWSFEEDS_CATEGORIES_EDIT","COMPONENTS_NEWSFEEDS_FEEDS":"COMPONENTS_NEWSFEEDS_FEEDS","COMPONENTS_NEWSFEEDS_FEEDS_EDIT":"COMPONENTS_NEWSFEEDS_FEEDS_EDIT","COMPONENTS_REDIRECT_MANAGER":"COMPONENTS_REDIRECT_MANAGER","COMPONENTS_REDIRECT_MANAGER_EDIT":"COMPONENTS_REDIRECT_MANAGER_EDIT","COMPONENTS_SEARCH":"COMPONENTS_SEARCH","COMPONENTS_TAGS_MANAGER":"COMPONENTS_TAGS_MANAGER","COMPONENTS_TAGS_MANAGER_EDIT":"COMPONENTS_TAGS_MANAGER_EDIT","COMPONENTS_WEBLINKS_CATEGORIES":"COMPONENTS_WEBLINKS_CATEGORIES","COMPONENTS_WEBLINKS_CATEGORY_EDIT":"COMPONENTS_WEBLINKS_CATEGORIES_EDIT","COMPONENTS_WEBLINKS_LINKS":"COMPONENTS_WEBLINKS_LINKS","COMPONENTS_WEBLINKS_LINKS_EDIT":"COMPONENTS_WEBLINKS_LINKS_EDIT","CONTENT_ARTICLE_MANAGER":"CONTENT_ARTICLE_MANAGER","CONTENT_ARTICLE_MANAGER_EDIT":"CONTENT_ARTICLE_MANAGER_EDIT","CONTENT_FEATURED_ARTICLES":"CONTENT_FEATURED_ARTICLES","CONTENT_MEDIA_MANAGER":"CONTENT_MEDIA_MANAGER","EXTENSIONS_EXTENSION_MANAGER_DATABASE":"EXTENSIONS_EXTENSION_MANAGER_DATABASE","EXTENSIONS_EXTENSION_MANAGER_DISCOVER":"EXTENSIONS_EXTENSION_MANAGER_DISCOVER","EXTENSIONS_EXTENSION_MANAGER_INSTALL":"EXTENSIONS_EXTENSION_MANAGER_INSTALL","EXTENSIONS_EXTENSION_MANAGER_LANGUAGES":"EXTENSIONS_EXTENSION_MANAGER_LANGUAGES","EXTENSIONS_EXTENSION_MANAGER_MANAGE":"EXTENSIONS_EXTENSION_MANAGER_MANAGE","EXTENSIONS_EXTENSION_MANAGER_UPDATE":"EXTENSIONS_EXTENSION_MANAGER_UPDATE","EXTENSIONS_EXTENSION_MANAGER_WARNINGS":"EXTENSIONS_EXTENSION_MANAGER_WARNINGS","EXTENSIONS_LANGUAGE_MANAGER_CONTENT":"EXTENSIONS_LANGUAGE_MANAGER_CONTENT","EXTENSIONS_LANGUAGE_MANAGER_EDIT":"EXTENSIONS_LANGUAGE_MANAGER_EDIT","EXTENSIONS_LANGUAGE_MANAGER_INSTALLED":"EXTENSIONS_LANGUAGE_MANAGER_INSTALLED","EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES":"EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES","EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT":"EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT","EXTENSIONS_MODULE_MANAGER":"EXTENSIONS_MODULE_MANAGER","EXTENSIONS_MODULE_MANAGER_EDIT":"EXTENSIONS_MODULE_MANAGER_EDIT","EXTENSIONS_PLUGIN_MANAGER":"EXTENSIONS_PLUGIN_MANAGER","EXTENSIONS_PLUGIN_MANAGER_EDIT":"EXTENSIONS_PLUGIN_MANAGER_EDIT","EXTENSIONS_TEMPLATE_MANAGER_STYLES":"EXTENSIONS_TEMPLATE_MANAGER_STYLES","EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT":"EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT","EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES":"EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES","EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT":"EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT","EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT_SOURCE":"EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT_SOURCE","MENUS_MENU_ITEM_MANAGER":"MENUS_MENU_ITEM_MANAGER","MENUS_MENU_ITEM_MANAGER_EDIT":"MENUS_MENU_ITEM_MANAGER_EDIT","MENUS_MENU_MANAGER":"MENUS_MENU_MANAGER","MENUS_MENU_MANAGER_EDIT":"MENUS_MENU_MANAGER_EDIT","SITE_GLOBAL_CONFIGURATION":"SITE_GLOBAL_CONFIGURATION","SITE_MAINTENANCE_CLEAR_CACHE":"SITE_MAINTENANCE_CLEAR_CACHE","SITE_MAINTENANCE_GLOBAL_CHECK-IN":"SITE_MAINTENANCE_GLOBAL_CHECK-IN","SITE_MAINTENANCE_PURGE_EXPIRED_CACHE":"SITE_MAINTENANCE_PURGE_EXPIRED_CACHE","SITE_SYSTEM_INFORMATION":"SITE_SYSTEM_INFORMATION","START_HERE":"START_HERE","USERS_ACCESS_LEVELS":"USERS_ACCESS_LEVELS","USERS_ACCESS_LEVELS_EDIT":"USERS_ACCESS_LEVELS_EDIT","USERS_DEBUG_USERS":"USERS_DEBUG_USER","USERS_GROUPS_EDIT":"USERS_GROUPS_EDIT","USERS_MASS_MAIL_USERS":"USERS_MASS_MAIL_USERS","USERS_USER_MANAGER_EDIT":"USERS_USER_MANAGER_EDIT","USERS_USER_NOTES":"USERS_USER_NOTES","USERS_USER_NOTES_EDIT":"USERS_USER_NOTES_EDIT"} \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.com_actionlogs.ini b/administrator/language/en-GB/en-GB.com_actionlogs.ini new file mode 100644 index 0000000000000..6b6d09dda4b7c --- /dev/null +++ b/administrator/language/en-GB/en-GB.com_actionlogs.ini @@ -0,0 +1,61 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +COM_ACTIONLOGS="User Actions Log" +COM_ACTIONLOGS_ACTION_VIEWLOGS="View logs" +COM_ACTIONLOGS_ACTION_VIEWLOGS_DESC="Allows users in the group to view the logs." +COM_ACTIONLOGS_CONFIGURATION="User Actions Log: Options" +COM_ACTIONLOGS_CSV_DELIMITER="CSV delimiter" +COM_ACTIONLOGS_CSV_DELIMITER_DESC="Set the separator for values in the CSV export." +COM_ACTIONLOGS_COMMA="Comma" +COM_ACTIONLOGS_DATE="Date" +COM_ACTIONLOGS_DISABLED="Disabled" +COM_ACTIONLOGS_EMAIL_DESC="This is the latest action performed by a user on your website." +COM_ACTIONLOGS_EMAIL_SUBJECT="Latest User Actions" +COM_ACTIONLOGS_EXPORT_ALL_CSV="Export All as CSV" +COM_ACTIONLOGS_EXPORT_CSV="Export Selected as CSV" +COM_ACTIONLOGS_EXTENSION="Extension" +COM_ACTIONLOGS_EXTENSION_ASC="Extension ascending" +COM_ACTIONLOGS_EXTENSION_DESC="Extension descending" +COM_ACTIONLOGS_EXTENSION_FILTER_DESC="Search in the User Action logs by extension" +COM_ACTIONLOGS_IP_ADDRESS="IP Address" +COM_ACTIONLOGS_IP_ADDRESS_ASC="IP Address ascending" +COM_ACTIONLOGS_IP_ADDRESS_DESC="IP Address descending" +COM_ACTIONLOGS_IP_INVALID="Invalid IP" +COM_ACTIONLOGS_IP_LOGGING="IP logging" +COM_ACTIONLOGS_IP_LOGGING_DESC="Enable logging the IP address of users." +COM_ACTIONLOGS_LOG_EXTENSIONS="Select events to be logged" +COM_ACTIONLOGS_LOG_EXTENSIONS_DESC="Select events to be logged" +COM_ACTIONLOGS_MANAGER_USERLOGS="User Actions Log" +COM_ACTIONLOGS_ACTION="Action" +COM_ACTIONLOGS_ACTION_ASC="Action ascending" +COM_ACTIONLOGS_ACTION_DESC="Action descending" +COM_ACTIONLOGS_NAME="Name" +COM_ACTIONLOGS_NAME_ASC="Name ascending" +COM_ACTIONLOGS_NAME_DESC="Name descending" +COM_ACTIONLOGS_N_ITEMS_DELETED="%s logs deleted." +COM_ACTIONLOGS_N_ITEMS_DELETED_1="%s log deleted." +COM_ACTIONLOGS_NO_LOGS_TO_EXPORT="There are no User Action logs to export." +COM_ACTIONLOGS_NO_ITEM_SELECTED="Please first make a selection from the list." +COM_ACTIONLOGS_OPTION_FILTER_DATE="- Select Date -" +COM_ACTIONLOGS_OPTION_RANGE_NEVER="Never" +COM_ACTIONLOGS_OPTION_RANGE_PAST_1MONTH="In the last month" +COM_ACTIONLOGS_OPTION_RANGE_PAST_3MONTH="In the last 3 months" +COM_ACTIONLOGS_OPTION_RANGE_PAST_6MONTH="In the last 6 months" +COM_ACTIONLOGS_OPTION_RANGE_PAST_WEEK="In the last week" +COM_ACTIONLOGS_OPTION_RANGE_PAST_YEAR="In the last year" +COM_ACTIONLOGS_OPTION_RANGE_POST_YEAR="More than a year ago" +COM_ACTIONLOGS_OPTION_RANGE_TODAY="Today" +COM_ACTIONLOGS_OPTIONS="Options" +COM_ACTIONLOGS_POSTINSTALL_TITLE="User Actions Can Now Be Logged" +COM_ACTIONLOGS_POSTINSTALL_BODY="

With the release of Joomla 3.9.0 you can now log all administrative actions performed by your users in supported extensions. It is now easy to see who did what and when they did it.

The logs can be reviewed in Joomla or exported for external use.

For further information on this new feature read the User Action Logs documentation.

" +COM_ACTIONLOGS_PURGE_CONFIRM="Are you sure want to delete all User Action logs?" +COM_ACTIONLOGS_PURGE_FAIL="Failed to delete all User Action logs." +COM_ACTIONLOGS_PURGE_SUCCESS="All User Action logs have been deleted." +COM_ACTIONLOGS_SELECT_EXTENSION="- Select Extension -" +COM_ACTIONLOGS_SELECT_USER="- Select User -" +COM_ACTIONLOGS_SEMICOLON="Semicolon" +COM_ACTIONLOGS_TOOLBAR_PURGE="Purge" +COM_ACTIONLOGS_XML_DESCRIPTION="Displays a log of actions performed by users on your website." diff --git a/administrator/language/en-GB/en-GB.com_actionlogs.sys.ini b/administrator/language/en-GB/en-GB.com_actionlogs.sys.ini new file mode 100644 index 0000000000000..db27ad08cf0d0 --- /dev/null +++ b/administrator/language/en-GB/en-GB.com_actionlogs.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +COM_ACTIONLOGS="User Actions Log" +COM_ACTIONLOGS_XML_DESCRIPTION="Displays a log of actions performed by users on your website." diff --git a/administrator/language/en-GB/en-GB.com_admin.ini b/administrator/language/en-GB/en-GB.com_admin.ini index 3ff9f0a5be4ad..2d11e446889a8 100644 --- a/administrator/language/en-GB/en-GB.com_admin.ini +++ b/administrator/language/en-GB/en-GB.com_admin.ini @@ -23,6 +23,7 @@ COM_ADMIN_FILE_UPLOADS="File Uploads" COM_ADMIN_GLOSSARY="Glossary" COM_ADMIN_GO="Go" COM_ADMIN_HELP="Joomla! Help" +COM_ADMIN_HELP_COMPONENTS_ACTIONLOGS="Action Logs" COM_ADMIN_HELP_COMPONENTS_ASSOCIATIONS="Multilingual Associations" COM_ADMIN_HELP_COMPONENTS_ASSOCIATIONS_EDIT="Multilingual Associations: Select" COM_ADMIN_HELP_COMPONENTS_BANNERS_BANNERS="Banners" @@ -55,6 +56,12 @@ COM_ADMIN_HELP_COMPONENTS_NEWSFEEDS_CATEGORIES_EDIT="News Feeds: Categories - Ne COM_ADMIN_HELP_COMPONENTS_NEWSFEEDS_FEEDS="News Feeds" COM_ADMIN_HELP_COMPONENTS_NEWSFEEDS_FEEDS_EDIT="News Feeds: New/Edit" COM_ADMIN_HELP_COMPONENTS_POST_INSTALLATION_MESSAGES="Post-Installation Messages" +COM_ADMIN_HELP_COMPONENTS_PRIVACY_CAPABILITIES="Privacy: Extension Capabilities" +COM_ADMIN_HELP_COMPONENTS_PRIVACY_CONSENTS="Privacy: Consents" +COM_ADMIN_HELP_COMPONENTS_PRIVACY_DASHBOARD="Privacy: Dashboard" +COM_ADMIN_HELP_COMPONENTS_PRIVACY_REQUEST="Privacy: Review Information Request" +COM_ADMIN_HELP_COMPONENTS_PRIVACY_REQUEST_EDIT="Privacy: New Information Request" +COM_ADMIN_HELP_COMPONENTS_PRIVACY_REQUESTS="Privacy: Information Requests" COM_ADMIN_HELP_COMPONENTS_REDIRECT_MANAGER="Redirect: Links" COM_ADMIN_HELP_COMPONENTS_REDIRECT_MANAGER_EDIT="Redirect: Links - New/Edit" COM_ADMIN_HELP_COMPONENTS_SEARCH="Search" diff --git a/administrator/language/en-GB/en-GB.com_config.ini b/administrator/language/en-GB/en-GB.com_config.ini index 1e5ce8a813741..1b576403d9363 100644 --- a/administrator/language/en-GB/en-GB.com_config.ini +++ b/administrator/language/en-GB/en-GB.com_config.ini @@ -37,6 +37,7 @@ COM_CONFIG_ERROR_ROOT_ASSET_NOT_FOUND="The asset for global configuration could COM_CONFIG_ERROR_SSL_NOT_AVAILABLE="HTTPS has not been enabled as it is not available on this server. HTTPS connection test failed with the following error: %s" COM_CONFIG_ERROR_SSL_NOT_AVAILABLE_HTTP_CODE="HTTPS version of the site returned an invalid HTTP status code." COM_CONFIG_ERROR_REMOVING_SUPER_ADMIN="You can't remove your own Super User permissions." +COM_CONFIG_ERROR_UNKNOWN_BEFORE_SAVING="A plugin reported an unknown error before saving the configuration." COM_CONFIG_ERROR_WRITE_FAILED="Could not write to the configuration file" COM_CONFIG_FIELD_CACHE_HANDLER_DESC="Choose the cache handler. Native caching mechanism is file-based. Please make sure the cache folders are writable." COM_CONFIG_FIELD_CACHE_HANDLER_LABEL="Cache Handler" diff --git a/administrator/language/en-GB/en-GB.com_messages.ini b/administrator/language/en-GB/en-GB.com_messages.ini index 210960ed434ab..676051f87e302 100644 --- a/administrator/language/en-GB/en-GB.com_messages.ini +++ b/administrator/language/en-GB/en-GB.com_messages.ini @@ -15,6 +15,9 @@ COM_MESSAGES_ERROR_INVALID_FROM_USER="Invalid sender" COM_MESSAGES_ERROR_INVALID_MESSAGE="Invalid message content" COM_MESSAGES_ERROR_INVALID_SUBJECT="Invalid subject" COM_MESSAGES_ERROR_INVALID_TO_USER="Invalid recipient" +COM_MESSAGES_ERROR_MISSING_ROOT_ASSET_GROUPS="Missing root asset groups to send notification." +COM_MESSAGES_ERROR_NO_GROUPS_SET_AS_SUPER_USER="There are no groups set with super user permissions." +COM_MESSAGES_ERROR_NO_USERS_SET_AS_SUPER_USER="There are no users set with super user permissions." COM_MESSAGES_FIELD_AUTO_PURGE_DESC="Automatically delete private messages after the given number of days." COM_MESSAGES_FIELD_AUTO_PURGE_LABEL="Auto-delete Messages (days)" COM_MESSAGES_FIELD_DATE_TIME_LABEL="Posted" diff --git a/administrator/language/en-GB/en-GB.com_privacy.ini b/administrator/language/en-GB/en-GB.com_privacy.ini new file mode 100644 index 0000000000000..551bf57655c0d --- /dev/null +++ b/administrator/language/en-GB/en-GB.com_privacy.ini @@ -0,0 +1,149 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +COM_PRIVACY="Privacy" +COM_PRIVACY_ACTION_DELETE_DATA="Delete Data" +COM_PRIVACY_ACTION_EMAIL_EXPORT_DATA="Email Data Export" +COM_PRIVACY_ACTION_EXPORT_DATA="Export Data" +COM_PRIVACY_ACTION_LOG_ADMIN_COMPLETED_REQUEST="User {username} completed request #{id} for {subjectemail}" +COM_PRIVACY_ACTION_LOG_ADMIN_CREATED_REQUEST="User {username} created request #{id} for {subjectemail}" +COM_PRIVACY_ACTION_LOG_ADMIN_INVALIDATED_REQUEST="User {username} invalidated request #{id} for {subjectemail}" +COM_PRIVACY_ACTION_LOG_CONFIRMED_REQUEST="{subjectemail} has confirmed request #{id}" +COM_PRIVACY_ACTION_LOG_CREATED_REQUEST="{subjectemail} has submitted request #{id}" +COM_PRIVACY_ACTION_LOG_EXPORT="User {username} exported the data for request #{id}" +COM_PRIVACY_ACTION_LOG_EXPORT_EMAILED="User {username} emailed the data export for request #{id} to the recipient" +COM_PRIVACY_ACTION_LOG_REMOVE="User {username} removed the data for request #{id}" +COM_PRIVACY_ACTION_LOG_REMOVE_BLOCKED="User {username} attempted to remove the data for request #{id} however this action was blocked" +COM_PRIVACY_ACTION_VIEW="View Request" +COM_PRIVACY_BADGE_URGENT_REQUEST="Urgent" +COM_PRIVACY_CONFIGURATION="Privacy: Options" +COM_PRIVACY_CORE_CAPABILITY_COMMUNICATION_WITH_JOOMLA_ORG="When a network connection is available, a Joomla installation will attempt to communicate with the joomla.org servers for various capabilities, to include:
  • Checking for updates for the Joomla application
  • Help screens for core Joomla extensions
  • The Install from Web service (opt-in)
  • The statistics collection server (opt-in)
As with all HTTP requests, the IP address of your server will be transmitted as part of the request. For information on how Joomla processes data on its servers, please review our privacy policy." +; The placeholder for this key is the configured log path for the site. +COM_PRIVACY_CORE_CAPABILITY_LOGGING_IP_ADDRESS="Joomla's logging system records the IP address of the visitor which led to a message being written to its log files. These log files are used to record various activity on a Joomla site, including information related to core updates, invalid login attempts, unhandled errors, and development information such as the use of deprecated APIs. The format of these log files may be customised by any extension which configures a logger, therefore you are encouraged to download and review the log files for your website which may be found at `%s`." +COM_PRIVACY_CORE_CAPABILITY_SESSION_IP_ADDRESS_AND_COOKIE="All requests to a Joomla website start a session which stores the IP address in the session data and creates a session cookie in the user's browser. The IP address is used as a security measure to help protect against potential session hijacking attacks and this information is deleted once the session has expired and its data purged. The session cookie's name is based on a randomly generated hash and therefore does not have a constant identifier. The session cookie is destroyed once the session has expired or the user has exited their browser." +COM_PRIVACY_DASHBOARD_BADGE_ACTIVE_REQUESTS_0="%d Active Requests" +COM_PRIVACY_DASHBOARD_BADGE_ACTIVE_REQUESTS_1="%d Active Request" +COM_PRIVACY_DASHBOARD_BADGE_ACTIVE_REQUESTS_MORE="%d Active Requests" +COM_PRIVACY_DASHBOARD_BADGE_TOTAL_REQUESTS_0="%d Total Requests" +COM_PRIVACY_DASHBOARD_BADGE_TOTAL_REQUESTS_1="%d Total Request" +COM_PRIVACY_DASHBOARD_BADGE_TOTAL_REQUESTS_MORE="%d Total Requests" +COM_PRIVACY_DASHBOARD_HEADING_CHECK="Check" +COM_PRIVACY_DASHBOARD_HEADING_REQUEST_COUNT="# of Requests" +COM_PRIVACY_DASHBOARD_HEADING_REQUEST_STATUS="Status" +COM_PRIVACY_DASHBOARD_HEADING_REQUEST_TYPE="Request Type" +COM_PRIVACY_DASHBOARD_HEADING_STATUS="Status" +COM_PRIVACY_DASHBOARD_HEADING_STATUS_CHECK="Status Check" +COM_PRIVACY_DASHBOARD_HEADING_TOTAL_REQUEST_COUNT="Total Request Count" +COM_PRIVACY_DASHBOARD_NO_REQUESTS="There are no requests." +COM_PRIVACY_DASHBOARD_VIEW_REQUESTS="View Requests" +COM_PRIVACY_DATA_REMOVED="Data removed" +COM_PRIVACY_EDIT_PRIVACY_POLICY="Edit Privacy Policy" +COM_PRIVACY_EXTENSION_CAPABILITY_PERSONAL_INFO="In order to process information requests, information about the user must be collected and logged for the purposes of retaining an audit log. The request system is based on an individual's email address which will be used to link the request to an existing site user if able." +; You can use the following merge codes for all COM_PRIVACY_EMAIL strings: +; [SITENAME] Site name, as set in Global Configuration. +; [URL] URL of the site's frontend page. +; [TOKENURL] URL of the confirm page with the token prefilled. +; [FORMURL] URL of the confirm page where the user can paste their token. +; [TOKEN] The confirmation token. +; \n Newline character. Use it to start a new line in the email. +COM_PRIVACY_EMAIL_ADMIN_REQUEST_BODY_EXPORT_REQUEST="An administrator for [URL] has created a request to export personal information related to this email address. As a security measure, you must confirm that this is a valid request for your personal information from this website.\n\nIn order to confirm this request, you can complete one of the following tasks:\n\n1. Visit the following URL: [TOKENURL]\n\n2. Copy your token from this email, visit the referenced URL, and paste your token into the form.\nURL: [FORMURL]\nToken: [TOKEN]\n\nPlease note that this token is only valid for 24 hours from the time this email was sent." +COM_PRIVACY_EMAIL_ADMIN_REQUEST_BODY_REMOVE_REQUEST="An administrator for [URL] has created a request to remove all personal information related to this email address. As a security measure, you must confirm that this is a valid request for your personal information to be removed from this website.\n\nIn order to confirm this request, you can complete one of the following tasks:\n\n1. Visit the following URL: [TOKENURL]\n\n2. Copy your token from this email, visit the referenced URL, and paste your token into the form.\nURL: [FORMURL]\nToken: [TOKEN]\n\nPlease note that this token is only valid for 24 hours from the time this email was sent." +COM_PRIVACY_EMAIL_ADMIN_REQUEST_SUBJECT_EXPORT_REQUEST="Information Request Created at [SITENAME]" +COM_PRIVACY_EMAIL_ADMIN_REQUEST_SUBJECT_REMOVE_REQUEST="Information Deletion Request Created at [SITENAME]" +COM_PRIVACY_EMAIL_DATA_EXPORT_COMPLETED_BODY="An administrator for [URL] has completed the data export you requested and a copy of the information can be found in the file attached to this message." +COM_PRIVACY_EMAIL_DATA_EXPORT_COMPLETED_SUBJECT="Data Export for [SITENAME]" +COM_PRIVACY_ERROR_ACTIVE_REQUEST_FOR_EMAIL="There is already an active information request for this email address, the active request should be completed before starting a new one." +COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_FOR_SELF="You can't create an information request for yourself." +COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED="Information requests can't be created when sending mail is disabled." +COM_PRIVACY_ERROR_CANNOT_EXPORT_UNCONFIRMED_REQUEST="The data for an unconfirmed request can't be exported." +COM_PRIVACY_ERROR_CANNOT_REMOVE_DATA="The data for this request can't be removed." +COM_PRIVACY_ERROR_CANNOT_REMOVE_UNCONFIRMED_REQUEST="The data for an unconfirmed request can't be removed." +COM_PRIVACY_ERROR_COMPLETE_TRANSITION_NOT_PERMITTED="This record can't be updated to \"Completed\" status." +COM_PRIVACY_ERROR_EXPORT_EMAIL_FAILED="Export failed with the following error: %s" +COM_PRIVACY_ERROR_INVALID_TRANSITION_NOT_PERMITTED="This record can't be updated to \"Invalid\" status." +COM_PRIVACY_ERROR_REMOVE_DATA_FAILED="Removal failed with the following error: %s" +COM_PRIVACY_ERROR_REQUEST_ID_REQUIRED_FOR_EXPORT="A request ID is required to export data." +COM_PRIVACY_ERROR_REQUEST_ID_REQUIRED_FOR_REMOVE="A request ID is required to remove data." +COM_PRIVACY_ERROR_REQUEST_TYPE_NOT_EXPORT="Only export requests may be exported." +COM_PRIVACY_ERROR_REQUEST_TYPE_NOT_REMOVE="Only removal requests may have their data removed." +COM_PRIVACY_ERROR_UNKNOWN_REQUEST_TYPE="Unknown information request type." +COM_PRIVACY_EXPORT_EMAILED="The data export has been emailed." +COM_PRIVACY_FIELD_REQUESTED_AT_LABEL="Date Requested" +COM_PRIVACY_FIELD_REQUEST_TYPE_DESC="The type of information request." +COM_PRIVACY_FIELD_REQUEST_TYPE_LABEL="Request Type" +COM_PRIVACY_FIELD_STATUS_DESC="The status of the information request." +COM_PRIVACY_FILTER_SEARCH_LABEL="Search Requests" +COM_PRIVACY_HEADING_ACTION_LOG="Action Log" +COM_PRIVACY_HEADING_ACTIONS="Actions" +COM_PRIVACY_HEADING_CONSENTS_BODY="Body" +COM_PRIVACY_HEADING_CONSENTS_CREATED="Created" +COM_PRIVACY_HEADING_CONSENTS_SUBJECT="Subject" +COM_PRIVACY_HEADING_CORE_CAPABILITIES="Joomla Core Capabilities" +COM_PRIVACY_HEADING_CREATED_ASC="Created ascending" +COM_PRIVACY_HEADING_CREATED_DESC="Created descending" +COM_PRIVACY_HEADING_EMAIL_ASC="Email ascending" +COM_PRIVACY_HEADING_EMAIL_DESC="Email descending" +COM_PRIVACY_HEADING_REQUEST_INFORMATION="Request Information" +COM_PRIVACY_HEADING_REQUEST_TYPE="Request Type" +COM_PRIVACY_HEADING_REQUEST_TYPE_ASC="Request Type ascending" +COM_PRIVACY_HEADING_REQUEST_TYPE_DESC="Request Type descending" +COM_PRIVACY_HEADING_REQUEST_TYPE_TYPE_EXPORT="Export" +COM_PRIVACY_HEADING_REQUEST_TYPE_TYPE_REMOVE="Remove" +COM_PRIVACY_HEADING_REQUESTED_AT="Requested" +COM_PRIVACY_HEADING_REQUESTED_AT_ASC="Requested ascending" +COM_PRIVACY_HEADING_REQUESTED_AT_DESC="Requested descending" +COM_PRIVACY_HEADING_STATUS_ASC="Status ascending" +COM_PRIVACY_HEADING_STATUS_DESC="Status descending" +COM_PRIVACY_HEADING_USERID="User ID" +COM_PRIVACY_HEADING_USERID_ASC="User ID ascending" +COM_PRIVACY_HEADING_USERID_DESC="User ID descending" +COM_PRIVACY_HEADING_USERNAME_ASC="Username descending" +COM_PRIVACY_HEADING_USERNAME_DESC="Username descending" +COM_PRIVACY_MSG_CAPABILITIES_ABOUT_THIS_INFORMATION="About This Information" +COM_PRIVACY_MSG_CAPABILITIES_INTRODUCTION="The information on this screen is collected from extensions which report their privacy related capabilities to this system. It is intended to help site owners be aware of the capabilities of installed extensions and provide information to help owners create local site policies such as a privacy policy. As this screen requires extensions to support its reporting system, and only displays information from enabled extensions, this should not be considered a complete list and you are encouraged to consult each extension's documentation for more information." +COM_PRIVACY_MSG_CAPABILITIES_NO_CAPABILITIES="There are no reported extension capabilities." +COM_PRIVACY_MSG_CONFIRM_EMAIL_SENT_TO_USER="A confirmation email for this request has been sent to the user." +COM_PRIVACY_MSG_CONSENTS_NO_CONSENTS="There are no stored consents." +COM_PRIVACY_MSG_EXTENSION_NO_CAPABILITIES="This extension does not report any capabilities." +COM_PRIVACY_MSG_REQUESTS_NO_REQUESTS="There are no information requests matching your query." +COM_PRIVACY_NOTIFY_DESC="Show a notification when there are requests older than the specified number of days." +COM_PRIVACY_NOTIFY_LABEL="Days To Consider Request Urgent" +COM_PRIVACY_OPTION_LABEL="Options" +COM_PRIVACY_POSTINSTALL_TITLE="Increased Management Of Users Privacy" +COM_PRIVACY_POSTINSTALL_BODY="

With the introduction of GDPR for EU citizens and similar regulations elsewhere in the world it may be necessary for you to request consent before storing any Personal Information of a user.

Joomla 3.9 introduces new capabilities to assist you in creating site privacy policies and collecting user consent. In addition a workflow is available to help you manage user information requests such as requests for removing their personal data from your site.

For further information on this new feature read the Privacy documentation.

" +COM_PRIVACY_REQUEST_COMPLETED="The request has been completed." +COM_PRIVACY_REQUEST_INVALIDATED="The request has been invalidated." +COM_PRIVACY_SHOW_URGENT_REQUESTS="Show Urgent Requests" +COM_PRIVACY_SELECT_REQUEST_TYPE="- Select Request Type -" +COM_PRIVACY_STATUS_CHECK_OUTSTANDING_URGENT_REQUESTS="Outstanding Urgent Requests" +COM_PRIVACY_STATUS_CHECK_OUTSTANDING_URGENT_REQUESTS_DESCRIPTION="Requests which are older than %d days, as set in the component configuration." +COM_PRIVACY_STATUS_CHECK_REQUEST_FORM_MENU_ITEM_PUBLISHED="Request Form Menu Item Published" +COM_PRIVACY_STATUS_CHECK_PRIVACY_POLICY_PUBLISHED="Privacy Policy Published" +COM_PRIVACY_STATUS_CHECK_SENDMAIL_DISABLED="Mail Sending Disabled" +COM_PRIVACY_STATUS_CHECK_SENDMAIL_DISABLED_DESCRIPTION="Mail Sending must be enabled, it is a requirement to use the request system" +COM_PRIVACY_STATUS_CHECK_SENDMAIL_ENABLED="Mail Sending Enabled" +COM_PRIVACY_STATUS_CHECK_SUCCESSFUL="Check Successful" +COM_PRIVACY_STATUS_CHECK_UNSUCCESSFUL="Check Unsuccessful" +COM_PRIVACY_STATUS_COMPLETED="Completed" +COM_PRIVACY_STATUS_CONFIRMED="Confirmed" +COM_PRIVACY_STATUS_INVALID="Invalid" +COM_PRIVACY_STATUS_PENDING="Pending" +COM_PRIVACY_SEARCH_IN_EMAIL="Search in requestor email address. Prefix with ID: to search for a request ID." +COM_PRIVACY_SEARCH_IN_USERNAME="Search in username. Prefix with ID: to search for a consent ID. Prefix with UID: to search for a User ID." +COM_PRIVACY_SUBMENU_CAPABILITIES="Capabilities" +COM_PRIVACY_SUBMENU_CONSENTS="Consents" +COM_PRIVACY_SUBMENU_DASHBOARD="Dashboard" +COM_PRIVACY_SUBMENU_REQUESTS="Requests" +COM_PRIVACY_TOOLBAR_COMPLETE="Complete" +COM_PRIVACY_TOOLBAR_INVALIDATE="Invalidate" +COM_PRIVACY_USER_FIELD_EMAIL_DESC="The email address of the individual owning the information being requested." +COM_PRIVACY_VIEW_CAPABILITIES="Privacy: Extension Capabilities" +COM_PRIVACY_VIEW_CONSENTS="Privacy: Consents" +COM_PRIVACY_VIEW_DASHBOARD="Privacy: Dashboard" +COM_PRIVACY_VIEW_REQUEST_ADD_REQUEST="Privacy: New Information Request" +COM_PRIVACY_VIEW_REQUEST_SHOW_REQUEST="Privacy: Review Information Request" +COM_PRIVACY_VIEW_REQUESTS="Privacy: Information Requests" +COM_PRIVACY_WARNING_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED="Information requests can't be created when sending mail is disabled." +COM_PRIVACY_XML_DESCRIPTION="Component for managing privacy related actions." diff --git a/administrator/language/en-GB/en-GB.com_privacy.sys.ini b/administrator/language/en-GB/en-GB.com_privacy.sys.ini new file mode 100644 index 0000000000000..a2bf34df661e4 --- /dev/null +++ b/administrator/language/en-GB/en-GB.com_privacy.sys.ini @@ -0,0 +1,21 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +COM_PRIVACY="Privacy" +COM_PRIVACY_CONFIRM_VIEW_DEFAULT_DESC="Displays a form to confirm an information request." +COM_PRIVACY_CONFIRM_VIEW_DEFAULT_OPTION="Default" +COM_PRIVACY_CONFIRM_VIEW_DEFAULT_TITLE="Confirm Request" +COM_PRIVACY_CONSENTS_VIEW_DEFAULT_DESC="Shows a list of user consents" +COM_PRIVACY_CONSENTS_VIEW_DEFAULT_TITLE="Privacy: Consents" +COM_PRIVACY_DASHBOARD_VIEW_DEFAULT_DESC="A dashboard related to the site's privacy settings and information requests." +COM_PRIVACY_DASHBOARD_VIEW_DEFAULT_TITLE="Privacy: Dashboard" +COM_PRIVACY_REMIND_VIEW_DEFAULT_DESC="Displays a form to extend the privacy consent" +COM_PRIVACY_REMIND_VIEW_DEFAULT_TITLE="Extend Consent" +COM_PRIVACY_REQUEST_VIEW_DEFAULT_DESC="Displays a form to submit an information request." +COM_PRIVACY_REQUEST_VIEW_DEFAULT_OPTION="Default" +COM_PRIVACY_REQUEST_VIEW_DEFAULT_TITLE="Create Request" +COM_PRIVACY_REQUESTS_VIEW_DEFAULT_DESC="Shows a list of user information requests" +COM_PRIVACY_REQUESTS_VIEW_DEFAULT_TITLE="Privacy: Information Requests" +COM_PRIVACY_XML_DESCRIPTION="Component for managing privacy related actions." diff --git a/administrator/language/en-GB/en-GB.ini b/administrator/language/en-GB/en-GB.ini index 4a6315d720534..f4a19e2c08e01 100644 --- a/administrator/language/en-GB/en-GB.ini +++ b/administrator/language/en-GB/en-GB.ini @@ -481,6 +481,7 @@ JGLOBAL_NO_ITEM_SELECTED="No items selected" JGLOBAL_NO_ORDER="No Order" JGLOBAL_NOINDEX_FOLLOW="No index, follow" JGLOBAL_NOINDEX_NOFOLLOW="No index, no follow" +JGLOBAL_NONAPPLICABLE="N/A" JGLOBAL_NUM_COLUMNS_DESC="The number of columns in which to show Intro Articles. Normally 1, 2, or 3." JGLOBAL_NUM_COLUMNS_LABEL="# Columns" JGLOBAL_NUM_INTRO_ARTICLES_DESC="Number of articles to show after the leading article. Articles will be shown in columns." @@ -653,6 +654,7 @@ JGRID_HEADING_ORDERING="Ordering" JGRID_HEADING_ORDERING_ASC="Ordering ascending" JGRID_HEADING_ORDERING_DESC="Ordering descending" +JHELP_COMPONENTS_ACTIONLOGS="Components_Actionlogs" JHELP_COMPONENTS_ASSOCIATIONS="Components_Associations" JHELP_COMPONENTS_ASSOCIATIONS_EDIT="Components_Associations_Edit" JHELP_COMPONENTS_BANNERS_BANNERS_EDIT="Components_Banners_Banners_Edit" @@ -665,8 +667,9 @@ JHELP_COMPONENTS_BANNERS_CLIENTS="Components_Banners_Clients" JHELP_COMPONENTS_BANNERS_TRACKS="Components_Banners_Tracks" JHELP_COMPONENTS_CACHE_MANAGER_SETTINGS="Components_Cache_Manager_Settings" JHELP_COMPONENTS_CHECK-IN_CONFIGURATION="Components_Check-in_Configuration" -JHELP_COMPONENTS_COM_BANNERS_OPTIONS="Components_Banner_Manager_Options" +JHELP_COMPONENTS_COM_ACTIONLOGS_OPTIONS="Components_Actionlogs" JHELP_COMPONENTS_COM_ASSOCIATIONS_OPTIONS="Components_Associations_Options" +JHELP_COMPONENTS_COM_BANNERS_OPTIONS="Components_Banner_Manager_Options" JHELP_COMPONENTS_COM_CACHE_OPTIONS="Components_Cache_Manager_Settings" JHELP_COMPONENTS_COM_CHECKIN_OPTIONS="Components_Check_in_Configuration" JHELP_COMPONENTS_COM_CONTACT_OPTIONS="Components_Contact_Manager_Options" @@ -681,6 +684,7 @@ JHELP_COMPONENTS_COM_MESSAGES_OPTIONS="Components_Messages_Configuration" JHELP_COMPONENTS_COM_MODULES_OPTIONS="Components_Module_Manager_Options" JHELP_COMPONENTS_COM_NEWSFEEDS_OPTIONS="Components_News_Feed_Manager_Options" JHELP_COMPONENTS_COM_PLUGINS_OPTIONS="Components_Plugin_Manager_Options" +JHELP_COMPONENTS_COM_PRIVACY_OPTIONS="Components_Privacy_Options" JHELP_COMPONENTS_COM_POSTINSTALL_OPTIONS="Components_Post_installation_Messages_Configuration" JHELP_COMPONENTS_COM_REDIRECT_OPTIONS="Components_Redirect_Manager_Options" JHELP_COMPONENTS_COM_SEARCH_OPTIONS="Components_Search_Manager_Options" @@ -718,6 +722,12 @@ JHELP_COMPONENTS_NEWSFEEDS_CATEGORY_EDIT="Components_Newsfeeds_Categories_Edit" JHELP_COMPONENTS_NEWSFEEDS_FEEDS_EDIT="Components_Newsfeeds_Feeds_Edit" JHELP_COMPONENTS_NEWSFEEDS_FEEDS="Components_Newsfeeds_Feeds" JHELP_COMPONENTS_POST_INSTALLATION_MESSAGES="Components_Post_installation_Messages" +JHELP_COMPONENTS_PRIVACY_CAPABILITIES="Components_Privacy_Capabilities" +JHELP_COMPONENTS_PRIVACY_CONSENTS="Components_Privacy_Consents" +JHELP_COMPONENTS_PRIVACY_DASHBOARD="Components_Privacy_Dashboard" +JHELP_COMPONENTS_PRIVACY_REQUEST="Components_Privacy_Request" +JHELP_COMPONENTS_PRIVACY_REQUEST_EDIT="Components_Privacy_Request_Edit" +JHELP_COMPONENTS_PRIVACY_REQUESTS="Components_Privacy_Requests" JHELP_COMPONENTS_REDIRECT_MANAGER_EDIT="Components_Redirect_Manager_Edit" JHELP_COMPONENTS_REDIRECT_MANAGER="Components_Redirect_Manager" JHELP_COMPONENTS_SEARCH="Components_Search" @@ -753,12 +763,14 @@ JHELP_EXTENSIONS_MODULE_MANAGER="Extensions_Module_Manager" JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_CUSTOM="Extensions_Module_Manager_Admin_Custom" JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_FEED="Extensions_Module_Manager_Admin_Feed" JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_LATEST="Extensions_Module_Manager_Admin_Latest" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_LATESTACTIONS="Extensions_Module_Manager_Admin_Latestactions" JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_LOGGED="Extensions_Module_Manager_Admin_Logged" JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_LOGIN="Extensions_Module_Manager_Admin_Login" JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_MENU="Extensions_Module_Manager_Admin_Menu" JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_MULTILANG="Extensions_Module_Manager_Admin_Multilang" JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_ONLINE="Extensions_Module_Manager_Admin_Online" JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_POPULAR="Extensions_Module_Manager_Admin_Popular" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_PRIVACY_DASHBOARD="Extensions_Module_Manager_Admin_Privacy_Dashboard" JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_QUICKICON="Extensions_Module_Manager_Admin_Quickicon" JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_STATUS="Extensions_Module_Manager_Admin_Status" JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_SUBMENU="Extensions_Module_Manager_Admin_Submenu" @@ -822,6 +834,9 @@ JHELP_MENUS_MENU_ITEM_MENU_ITEM_HEADING="Menus_Menu_Item_Menu_Item_Heading" JHELP_MENUS_MENU_ITEM_NEWSFEED_CATEGORIES="Menus_Menu_Item_Newsfeed_Categories" JHELP_MENUS_MENU_ITEM_NEWSFEED_CATEGORY="Menus_Menu_Item_Newsfeed_Category" JHELP_MENUS_MENU_ITEM_NEWSFEED_SINGLE_NEWSFEED="Menus_Menu_Item_Newsfeed_Single_Newsfeed" +JHELP_MENUS_MENU_ITEM_PRIVACY_CONFIRM_REQUEST="Menus_Menu_Item_Privacy_Confirm_Request" +JHELP_MENUS_MENU_ITEM_PRIVACY_CREATE_REQUEST=" Menus_Menu_Item_Privacy_Create_Request" +JHELP_MENUS_MENU_ITEM_PRIVACY_REMIND_REQUEST="Menus_Menu_Item_Privacy_Remind_Request" JHELP_MENUS_MENU_ITEM_SEARCH_RESULTS="Menus_Menu_Item_Search_Results" JHELP_MENUS_MENU_ITEM_TAGS_ITEMS_COMPACT_LIST="Menus_Menu_Item_Tags_Items_Compact_List" JHELP_MENUS_MENU_ITEM_TAGS_ITEMS_LIST="Menus_Menu_Item_Tags_Items_List" diff --git a/administrator/language/en-GB/en-GB.mod_latestactions.ini b/administrator/language/en-GB/en-GB.mod_latestactions.ini new file mode 100644 index 0000000000000..093c175dca254 --- /dev/null +++ b/administrator/language/en-GB/en-GB.mod_latestactions.ini @@ -0,0 +1,11 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +MOD_LATESTACTIONS="Action Logs - Latest" +MOD_LATESTACTIONS_FIELD_COUNT_LABEL="Count" +MOD_LATESTACTIONS_FIELD_COUNT_DESC="The number of items to display (default 5)." +MOD_LATESTACTIONS_LAYOUT_DEFAULT="Default" +MOD_LATEST_ACTIONS_NO_MATCHING_RESULTS="No Matching Results" +MOD_LATESTACTIONS_XML_DESCRIPTION="This module shows a list of the most recent actions." diff --git a/administrator/language/en-GB/en-GB.mod_latestactions.sys.ini b/administrator/language/en-GB/en-GB.mod_latestactions.sys.ini new file mode 100644 index 0000000000000..2535518ba3835 --- /dev/null +++ b/administrator/language/en-GB/en-GB.mod_latestactions.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + + +MOD_LATESTACTIONS="Action Logs - Latest" +MOD_LATESTACTIONS_XML_DESCRIPTION="This module shows a list of the most recent actions." + diff --git a/administrator/language/en-GB/en-GB.mod_menu.ini b/administrator/language/en-GB/en-GB.mod_menu.ini index df62a5794cc8b..9778511f6d332 100644 --- a/administrator/language/en-GB/en-GB.mod_menu.ini +++ b/administrator/language/en-GB/en-GB.mod_menu.ini @@ -6,6 +6,7 @@ MOD_MENU="Administrator Menu" MOD_MENU_CLEAR_CACHE="Clear Cache" MOD_MENU_COMPONENTS="Components" +MOD_MENU_COM_ACTIONLOGS="User Actions Log" MOD_MENU_COM_CONTENT="Content" MOD_MENU_COM_CONTENT_ARTICLE_MANAGER="Articles" MOD_MENU_COM_CONTENT_CATEGORY_MANAGER="Categories" @@ -15,6 +16,7 @@ MOD_MENU_COM_CONTENT_NEW_CATEGORY="Add New Category" MOD_MENU_COM_LANGUAGES_SUBMENU_CONTENT="Content Languages" MOD_MENU_COM_LANGUAGES_SUBMENU_INSTALLED="Installed" MOD_MENU_COM_LANGUAGES_SUBMENU_OVERRIDES="Overrides" +MOD_MENU_COM_PRIVACY="Privacy" MOD_MENU_COM_TEMPLATES_SUBMENU_STYLES="Styles" MOD_MENU_COM_TEMPLATES_SUBMENU_TEMPLATES="Templates" MOD_MENU_COM_USERS="Users" diff --git a/administrator/language/en-GB/en-GB.mod_privacy_dashboard.ini b/administrator/language/en-GB/en-GB.mod_privacy_dashboard.ini new file mode 100644 index 0000000000000..fde5ee95b941d --- /dev/null +++ b/administrator/language/en-GB/en-GB.mod_privacy_dashboard.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +MOD_PRIVACY_DASHBOARD="Privacy Dashboard" +MOD_PRIVACY_DASHBOARD_XML_DESCRIPTION="The Privacy Dashboard Module shows information about privacy requests." diff --git a/administrator/language/en-GB/en-GB.mod_privacy_dashboard.sys.ini b/administrator/language/en-GB/en-GB.mod_privacy_dashboard.sys.ini new file mode 100644 index 0000000000000..22ea11c29cc1f --- /dev/null +++ b/administrator/language/en-GB/en-GB.mod_privacy_dashboard.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +MOD_PRIVACY_DASHBOARD="Privacy Dashboard" +MOD_PRIVACY_DASHBOARD_XML_DESCRIPTION="The Privacy Dashboard Module shows information about privacy requests." +MOD_PRIVACY_DASHBOARD_LAYOUT_DEFAULT="Default" + diff --git a/administrator/language/en-GB/en-GB.plg_actionlog_joomla.ini b/administrator/language/en-GB/en-GB.plg_actionlog_joomla.ini new file mode 100644 index 0000000000000..cc1943480ab09 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_actionlog_joomla.ini @@ -0,0 +1,49 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_ACTIONLOG_JOOMLA="Action Log - Joomla" +PLG_ACTIONLOG_JOOMLA_XML_DESCRIPTION="Record the actions of users on the site for Joomla core extensions so they can be reviewed if required." +PLG_ACTIONLOG_JOOMLA_APPLICATION_SITE="site" +PLG_ACTIONLOG_JOOMLA_APPLICATION_ADMINISTRATOR="admin" +; Content types title +PLG_ACTIONLOG_JOOMLA_TYPE_ACCESS_LEVEL="access level" +PLG_ACTIONLOG_JOOMLA_TYPE_APPLICATION_CONFIG="Global Configuration" +PLG_ACTIONLOG_JOOMLA_TYPE_ARTICLE="article" +PLG_ACTIONLOG_JOOMLA_TYPE_BANNER="banner" +PLG_ACTIONLOG_JOOMLA_TYPE_BANNER_CLIENT="banner client" +PLG_ACTIONLOG_JOOMLA_TYPE_CATEGORY="category" +PLG_ACTIONLOG_JOOMLA_TYPE_COMPONENT="component" +PLG_ACTIONLOG_JOOMLA_TYPE_COMPONENT_CONFIG="Component Configuration" +PLG_ACTIONLOG_JOOMLA_TYPE_CONTACT="contact" +PLG_ACTIONLOG_JOOMLA_TYPE_FILE="file" +PLG_ACTIONLOG_JOOMLA_TYPE_LANGUAGE="language" +PLG_ACTIONLOG_JOOMLA_TYPE_LIBRARY="library" +PLG_ACTIONLOG_JOOMLA_TYPE_LINK="link redirect" +PLG_ACTIONLOG_JOOMLA_TYPE_LINK_REDIRECT="link redirect" +PLG_ACTIONLOG_JOOMLA_TYPE_MEDIA="media" +PLG_ACTIONLOG_JOOMLA_TYPE_MENU="menu" +PLG_ACTIONLOG_JOOMLA_TYPE_MENU_ITEM="menu item" +PLG_ACTIONLOG_JOOMLA_TYPE_MODULE="module" +PLG_ACTIONLOG_JOOMLA_TYPE_NEWSFEED="newsfeed" +PLG_ACTIONLOG_JOOMLA_TYPE_PACKAGE="package" +PLG_ACTIONLOG_JOOMLA_TYPE_PLUGIN="plugin" +PLG_ACTIONLOG_JOOMLA_TYPE_STYLE="template style" +PLG_ACTIONLOG_JOOMLA_TYPE_TAG="tag" +PLG_ACTIONLOG_JOOMLA_TYPE_TEMPLATE="template" +PLG_ACTIONLOG_JOOMLA_TYPE_USER="user" +PLG_ACTIONLOG_JOOMLA_USER_LOGIN_FAILED="User {username} tried to login to {app}" +PLG_ACTIONLOG_JOOMLA_USER_LOGGED_IN="User {username} logged in to {app}" +PLG_ACTIONLOG_JOOMLA_USER_LOGGED_OUT="User {username} logged out from {app}" +PLG_ACTIONLOG_JOOMLA_USER_REGISTERED="User {username} registered for an account" +PLG_ACTIONLOG_JOOMLA_TYPE_USER_GROUP="user group" +PLG_ACTIONLOG_JOOMLA_TYPE_USER_NOTE="user note" +; Component +PLG_ACTIONLOG_JOOMLA_APPLICATION_CONFIG_UPDATED="User {username} changed settings of the application configuration" +PLG_ACTIONLOG_JOOMLA_COMPONENT_CONFIG_UPDATED="User {username} changed settings of the component {extension_name}" +; Extensions +PLG_ACTIONLOG_JOOMLA_EXTENSION_INSTALLED="User {username} installed the {type} {extension_name}" +PLG_ACTIONLOG_JOOMLA_EXTENSION_UNINSTALLED="User {username} uninstalled the {type} {extension_name}" +PLG_ACTIONLOG_JOOMLA_EXTENSION_UPDATED="User {username} updated the {type} {extension_name}" +PLG_ACTIONLOG_JOOMLA_PLUGIN_INSTALLED="User {username} installed the plugin {extension_name}" diff --git a/administrator/language/en-GB/en-GB.plg_actionlog_joomla.sys.ini b/administrator/language/en-GB/en-GB.plg_actionlog_joomla.sys.ini new file mode 100644 index 0000000000000..df2e8d05681ae --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_actionlog_joomla.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_ACTIONLOG_JOOMLA="Action Log - Joomla" +PLG_ACTIONLOG_JOOMLA_XML_DESCRIPTION="Record the actions of users on the site for Joomla core extensions so they can be reviewed if required." diff --git a/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini b/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini index 8d02e7fe9fbf7..114cea9dd3da1 100644 --- a/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini +++ b/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini @@ -9,5 +9,6 @@ PLG_AUTH_COOKIE_FIELD_COOKIE_LIFETIME_DESC="The number of days until the authent PLG_AUTH_COOKIE_FIELD_COOKIE_LIFETIME_LABEL="Cookie Lifetime" PLG_AUTH_COOKIE_FIELD_KEY_LENGTH_DESC="The length of the key to use to encrypt the cookie. Longer lengths are more secure, but they will slow performance." PLG_AUTH_COOKIE_FIELD_KEY_LENGTH_LABEL="Key Length" +PLG_AUTH_COOKIE_PRIVACY_CAPABILITY_COOKIE="In conjunction with a plugin which supports a \"Remember Me\" feature, such as the \"System - Remember Me\" plugin, this plugin creates a cookie on the user's client if a \"Remember Me\" checkbox is selected when logging into the website. This cookie can be identified with the prefix `joomla_remember_me` and is used to automatically log users into the website when they visit and are not already logged in." PLG_AUTH_COOKIE_XML_DESCRIPTION="Handles Joomla's cookie User authentication.
Warning! You must have at least one other authentication plugin enabled.
You will also need a plugin such as the System - Remember Me plugin to implement cookie login." PLG_AUTHENTICATION_COOKIE="Authentication - Cookie" diff --git a/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.ini b/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.ini index 29821c12ebe7c..8a501818501b4 100644 --- a/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.ini +++ b/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.ini @@ -50,6 +50,8 @@ PLG_RECAPTCHA_ERROR_VERIFY_PARAMS_INCORRECT="The parameters to verify were incor PLG_RECAPTCHA_ERROR_INVALID_REFERRER="reCAPTCHA API keys are tied to a specific domain name for security reasons." PLG_RECAPTCHA_ERROR_RECAPTCHA_NOT_REACHABLE="Unable to contact the reCAPTCHA verify server." +PLG_RECAPTCHA_PRIVACY_CAPABILITY_IP_ADDRESS="The reCAPTCHA plugin integrates with Google's reCAPTCHA system as a spam protection service. As part of this service, the IP of the user who is answering the captcha challenge is transmitted to Google." + ; Uncomment(remove the ";" from the beginning of the line) the following lines if reCAPTCHA is not available in your language ; When uncommenting, do NOT translate PLG_RECAPTCHA_CUSTOM_LANG ; As of 01/01/2012, the following languages do not need translation: en, nl, fr, de, pt, ru, es, tr diff --git a/administrator/language/en-GB/en-GB.plg_content_confirmconsent.ini b/administrator/language/en-GB/en-GB.plg_content_confirmconsent.ini new file mode 100644 index 0000000000000..38c7f59fb893c --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_content_confirmconsent.ini @@ -0,0 +1,11 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_CONFIRMCONSENT_CONSENTBOX_LABEL="Privacy Note" +PLG_CONTENT_CONFIRMCONSENT_FIELD_ARTICLE_DESC="Select the article from the list or create a new one." +PLG_CONTENT_CONFIRMCONSENT_FIELD_ARTICLE_LABEL="Privacy Article" +PLG_CONTENT_CONFIRMCONSENT_FIELD_NOTE_DEFAULT="By submitting this form you agree to the Privacy Policy of this website and the storing of the submitted information." +PLG_CONTENT_CONFIRMCONSENT_FIELD_NOTE_DESC="A summary of the site's privacy policy. If left blank then the default message will be used." +PLG_CONTENT_CONFIRMCONSENT_FIELD_NOTE_LABEL="Short Privacy Policy" diff --git a/administrator/language/en-GB/en-GB.plg_content_confirmconsent.sys.ini b/administrator/language/en-GB/en-GB.plg_content_confirmconsent.sys.ini new file mode 100644 index 0000000000000..ef4ab8ac9e238 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_content_confirmconsent.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_CONFIRMCONSENT="Content - Confirm Consent" +PLG_CONTENT_CONFIRMCONSENT_XML_DESCRIPTION="This plugin adds a required consent checkbox to a form eg the core contact component." diff --git a/administrator/language/en-GB/en-GB.plg_privacy_actionlogs.ini b/administrator/language/en-GB/en-GB.plg_privacy_actionlogs.ini new file mode 100644 index 0000000000000..e6faefd882185 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_privacy_actionlogs.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_ACTIONLOGS="Privacy - Action Logs" +PLG_PRIVACY_ACTIONLOGS_XML_DESCRIPTION="Responsible for exporting the action log data for a user's privacy request. Since the action logs are an audit log, these can not be deleted from the system." diff --git a/administrator/language/en-GB/en-GB.plg_privacy_actionlogs.sys.ini b/administrator/language/en-GB/en-GB.plg_privacy_actionlogs.sys.ini new file mode 100644 index 0000000000000..e6faefd882185 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_privacy_actionlogs.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_ACTIONLOGS="Privacy - Action Logs" +PLG_PRIVACY_ACTIONLOGS_XML_DESCRIPTION="Responsible for exporting the action log data for a user's privacy request. Since the action logs are an audit log, these can not be deleted from the system." diff --git a/administrator/language/en-GB/en-GB.plg_privacy_contact.ini b/administrator/language/en-GB/en-GB.plg_privacy_contact.ini new file mode 100644 index 0000000000000..190cbd446351a --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_privacy_contact.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_CONTACT="Privacy - Contacts" +PLG_PRIVACY_CONTACT_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla contact data." diff --git a/administrator/language/en-GB/en-GB.plg_privacy_contact.sys.ini b/administrator/language/en-GB/en-GB.plg_privacy_contact.sys.ini new file mode 100644 index 0000000000000..190cbd446351a --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_privacy_contact.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_CONTACT="Privacy - Contacts" +PLG_PRIVACY_CONTACT_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla contact data." diff --git a/administrator/language/en-GB/en-GB.plg_privacy_content.ini b/administrator/language/en-GB/en-GB.plg_privacy_content.ini new file mode 100644 index 0000000000000..5d50613c7019e --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_privacy_content.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_CONTENT="Privacy - Content" +PLG_PRIVACY_CONTENT_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla content data." diff --git a/administrator/language/en-GB/en-GB.plg_privacy_content.sys.ini b/administrator/language/en-GB/en-GB.plg_privacy_content.sys.ini new file mode 100644 index 0000000000000..5d50613c7019e --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_privacy_content.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_CONTENT="Privacy - Content" +PLG_PRIVACY_CONTENT_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla content data." diff --git a/administrator/language/en-GB/en-GB.plg_privacy_message.ini b/administrator/language/en-GB/en-GB.plg_privacy_message.ini new file mode 100644 index 0000000000000..c67d1908f89aa --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_privacy_message.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_MESSAGE="Privacy - User Messages" +PLG_PRIVACY_MESSAGE_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla user messages data." diff --git a/administrator/language/en-GB/en-GB.plg_privacy_message.sys.ini b/administrator/language/en-GB/en-GB.plg_privacy_message.sys.ini new file mode 100644 index 0000000000000..c67d1908f89aa --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_privacy_message.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_MESSAGE="Privacy - User Messages" +PLG_PRIVACY_MESSAGE_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla user messages data." diff --git a/administrator/language/en-GB/en-GB.plg_privacy_user.ini b/administrator/language/en-GB/en-GB.plg_privacy_user.ini new file mode 100644 index 0000000000000..d1f733954efba --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_privacy_user.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_USER="Privacy - User Accounts" +PLG_PRIVACY_USER_ERROR_CANNOT_REMOVE_SUPER_USER="Cannot remove a super user account." +PLG_PRIVACY_USER_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla user data." diff --git a/administrator/language/en-GB/en-GB.plg_privacy_user.sys.ini b/administrator/language/en-GB/en-GB.plg_privacy_user.sys.ini new file mode 100644 index 0000000000000..ba043e9af9d9b --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_privacy_user.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_USER="Privacy - User Accounts" +PLG_PRIVACY_USER_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla user data." diff --git a/administrator/language/en-GB/en-GB.plg_quickicon_privacycheck.ini b/administrator/language/en-GB/en-GB.plg_quickicon_privacycheck.ini new file mode 100644 index 0000000000000..4ea2634846cfd --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_quickicon_privacycheck.ini @@ -0,0 +1,15 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_QUICKICON_PRIVACYCHECK="Quick Icon - Joomla! Privacy Requests Notification" +PLG_QUICKICON_PRIVACYCHECK_CHECKING="Checking requests ..." +PLG_QUICKICON_PRIVACYCHECK_ERROR="Unknown requests ..." +PLG_QUICKICON_PRIVACYCHECK_GROUP_DESC="The group of this plugin (this value is compared with the group value used in Quick Icons modules to inject icons)." +PLG_QUICKICON_PRIVACYCHECK_GROUP_LABEL="Group" +PLG_QUICKICON_PRIVACYCHECK_REQUESTFOUND="Urgent Privacy Requests" +PLG_QUICKICON_PRIVACYCHECK_REQUESTFOUND_BUTTON="View Requests" +PLG_QUICKICON_PRIVACYCHECK_REQUESTFOUND_MESSAGE="Urgent Privacy Request(s) to manage." +PLG_QUICKICON_PRIVACYCHECK_NOREQUEST="No Urgent Requests." +PLG_QUICKICON_PRIVACYCHECK_XML_DESCRIPTION="Checks for privacy requests that need to be handled and notifies you when you visit the Control Panel page." diff --git a/administrator/language/en-GB/en-GB.plg_quickicon_privacycheck.sys.ini b/administrator/language/en-GB/en-GB.plg_quickicon_privacycheck.sys.ini new file mode 100644 index 0000000000000..f00ff9298b984 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_quickicon_privacycheck.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_QUICKICON_PRIVACYCHECK="Quick Icon - Joomla! Privacy Requests Notification" +PLG_QUICKICON_PRIVACYCHECK_XML_DESCRIPTION="Checks for privacy requests that need to be handled and notifies you when you visit the Control Panel page." diff --git a/administrator/language/en-GB/en-GB.plg_system_actionlogs.ini b/administrator/language/en-GB/en-GB.plg_system_actionlogs.ini new file mode 100644 index 0000000000000..cd8d760f59c94 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_system_actionlogs.ini @@ -0,0 +1,21 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_ACTIONLOGS="System - User Actions Log" +PLG_SYSTEM_ACTIONLOGS_EXTENSIONS_NOTIFICATIONS="Select events to be notified for" +PLG_SYSTEM_ACTIONLOGS_EXTENSIONS_NOTIFICATIONS_DESC="Select events to be sent to your email as notifications" +PLG_SYSTEM_ACTIONLOGS_LOG_DELETE_PERIOD="Days to delete logs after" +PLG_SYSTEM_ACTIONLOGS_LOG_DELETE_PERIOD_DESC="Enter how many days logs should be kept before they are deleted. Enter 0 if you don't want to delete the logs." +PLG_SYSTEM_ACTIONLOGS_NOTIFICATIONS="Send notifications for User Actions Log" +PLG_SYSTEM_ACTIONLOGS_NOTIFICATIONS_DESC="Send a notifications of users' actions log to your email" +PLG_SYSTEM_ACTIONLOGS_OPTIONS="User Actions Log Options" +PLG_SYSTEM_ACTIONLOGS_XML_DESCRIPTION="Record the actions of users on the site so they can be reviewed if required." +; Common content type log messages +PLG_SYSTEM_ACTIONLOGS_CONTENT_ADDED="User {username} added new {type} {title}" +PLG_SYSTEM_ACTIONLOGS_CONTENT_UPDATED="User {username} updated the {type} {title}" +PLG_SYSTEM_ACTIONLOGS_CONTENT_PUBLISHED="User {username} published the {type} {title}" +PLG_SYSTEM_ACTIONLOGS_CONTENT_UNPUBLISHED="User {username} unpublished the {type} {title}" +PLG_SYSTEM_ACTIONLOGS_CONTENT_TRASHED="User {username} trashed the {type} {title}" +PLG_SYSTEM_ACTIONLOGS_CONTENT_DELETED="User {username} deleted the {type} {title}" diff --git a/administrator/language/en-GB/en-GB.plg_system_actionlogs.sys.ini b/administrator/language/en-GB/en-GB.plg_system_actionlogs.sys.ini new file mode 100644 index 0000000000000..d7a6d3ac86077 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_system_actionlogs.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_ACTIONLOGS="System - Actions Log" +PLG_SYSTEM_ACTIONLOGS_XML_DESCRIPTION="To record actions of users within the CMS, to know who to blame when something wrong happens." diff --git a/administrator/language/en-GB/en-GB.plg_system_languagefilter.ini b/administrator/language/en-GB/en-GB.plg_system_languagefilter.ini index 9d957af004674..bd4c481bad64e 100644 --- a/administrator/language/en-GB/en-GB.plg_system_languagefilter.ini +++ b/administrator/language/en-GB/en-GB.plg_system_languagefilter.ini @@ -24,5 +24,6 @@ PLG_SYSTEM_LANGUAGEFILTER_FIELD_REMOVE_DEFAULT_PREFIX_DESC="Remove the defined U PLG_SYSTEM_LANGUAGEFILTER_FIELD_REMOVE_DEFAULT_PREFIX_LABEL="Remove URL Language Code" PLG_SYSTEM_LANGUAGEFILTER_OPTION_SESSION="Session" PLG_SYSTEM_LANGUAGEFILTER_OPTION_YEAR="Year" +PLG_SYSTEM_LANGUAGEFILTER_PRIVACY_CAPABILITY_LANGUAGE_COOKIE="On a site which supports multiple languages, this plugin can be configured to set a cookie on the user's browser which remembers their language preference. This cookie is used to redirect users to their preferred language when visiting the site and creating a new session. The cookie's name is based on a randomly generated hash and therefore does not have a constant identifier." PLG_SYSTEM_LANGUAGEFILTER_SITE_LANGUAGE="Site Language" PLG_SYSTEM_LANGUAGEFILTER_XML_DESCRIPTION="This plugin filters the displayed content depending on language.
This plugin is to be enabled only when the Language Switcher module is published.
If this plugin is activated, it is recommended to also publish the Administrator multilingual status module." diff --git a/administrator/language/en-GB/en-GB.plg_system_logrotation.ini b/administrator/language/en-GB/en-GB.plg_system_logrotation.ini new file mode 100644 index 0000000000000..d25b74b27274c --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_system_logrotation.ini @@ -0,0 +1,11 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_LOGROTATION="System - Log Rotation" +PLG_SYSTEM_LOGROTATION_XML_DESCRIPTION="This plugin periodically rotates system log files." +PLG_SYSTEM_LOGROTATION_CACHETIMEOUT_LABEL="Log Rotation (in days)" +PLG_SYSTEM_LOGROTATION_CACHETIMEOUT_DESC="How often should the logs be rotated." +PLG_SYSTEM_LOGROTATION_LOGSTOKEEP_DESC="The maximum number of old logs to keep." +PLG_SYSTEM_LOGROTATION_LOGSTOKEEP_LABEL="Maximum Logs" diff --git a/administrator/language/en-GB/en-GB.plg_system_logrotation.sys.ini b/administrator/language/en-GB/en-GB.plg_system_logrotation.sys.ini new file mode 100644 index 0000000000000..c03ea875d9b6d --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_system_logrotation.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_LOGROTATION="System - Log Rotation" +PLG_SYSTEM_LOGROTATION_XML_DESCRIPTION="This plugin periodically rotates system log files." diff --git a/administrator/language/en-GB/en-GB.plg_system_privacyconsent.ini b/administrator/language/en-GB/en-GB.plg_system_privacyconsent.ini new file mode 100644 index 0000000000000..74da392cafd19 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_system_privacyconsent.ini @@ -0,0 +1,42 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_PRIVACYCONSENT="System - Privacy Consent" +PLG_SYSTEM_PRIVACYCONSENT_BODY="

The user consented to storing their user information using the IP address %s

The user agent string of the user's browser was:
%s

This information was automatically recorded when the user submitted their details on the web site and checked the confirm box

" +PLG_SYSTEM_PRIVACYCONSENT_CACHETIMEOUT_DESC="How often the check is performed" +PLG_SYSTEM_PRIVACYCONSENT_CACHETIMEOUT_LABEL="Periodic check (days)" +PLG_SYSTEM_PRIVACYCONSENT_CONSENTEXPIRATION_DESC="Number of days after which the privacy consent shall expire." +PLG_SYSTEM_PRIVACYCONSENT_CONSENTEXPIRATION_LABEL="Expiration" +; You can use the following merge codes for the EMAIL strings: +; [SITENAME] Site name, as set in Global Configuration. +; [URL] URL of the site's frontend page. +; [TOKENURL] URL of the remind page with the token prefilled. +; [FORMURL] URL of the remind page where the user can paste their token. +; [TOKEN] The remind token. +; \n Newline character. Use it to start a new line in the email. +PLG_SYSTEM_PRIVACYCONSENT_EMAIL_REMIND_BODY="Your Privacy Consent given at [URL] will expire in few days, you can renew the privacy consent for this website.\n\nIn order to do this, you can complete one of the following tasks:\n\n1. Visit the following URL: [TOKENURL]\n\n2. Copy your token from this email, visit the referenced URL, and paste your token into the form.\nURL: [FORMURL]\nToken: [TOKEN]\n\nPlease note that this token is only valid for this account." +PLG_SYSTEM_PRIVACYCONSENT_EMAIL_REMIND_SUBJECT="Privacy Consent at [SITENAME]" +PLG_SYSTEM_PRIVACYCONSENT_EXPIRATION_FIELDSET_LABEL="Expiration" +PLG_SYSTEM_PRIVACYCONSENT_FIELD_ARTICLE_DESC="Select the article from the list or create a new one." +PLG_SYSTEM_PRIVACYCONSENT_FIELD_ARTICLE_LABEL="Privacy Article" +PLG_SYSTEM_PRIVACYCONSENT_FIELD_DESC="Read the full privacy policy" +PLG_SYSTEM_PRIVACYCONSENT_FIELD_ENABLED_DESC="When enabled it performs checks for consent expiration" +PLG_SYSTEM_PRIVACYCONSENT_FIELD_ENABLED_LABEL="Enable" +PLG_SYSTEM_PRIVACYCONSENT_FIELD_ERROR="Agreement to the site's Privacy Policy is required." +PLG_SYSTEM_PRIVACYCONSENT_FIELD_LABEL="Privacy Policy" +PLG_SYSTEM_PRIVACYCONSENT_LABEL="Web Site Privacy" +PLG_SYSTEM_PRIVACYCONSENT_NOTE_FIELD_DEFAULT="By signing up to this web site and agreeing to the Privacy Policy you agree to this web site storing your information." +PLG_SYSTEM_PRIVACYCONSENT_NOTE_FIELD_DESC="A summary of the site's privacy policy. If left blank then the default message will be used." +PLG_SYSTEM_PRIVACYCONSENT_NOTE_FIELD_LABEL="Short Privacy Policy" +PLG_SYSTEM_PRIVACYCONSENT_NOTIFICATION_USER_PRIVACY_EXPIRED_SUBJECT="Privacy Consent Expired" +PLG_SYSTEM_PRIVACYCONSENT_NOTIFICATION_USER_PRIVACY_EXPIRED_MESSAGE="Privacy consent has expired for %1$s." +PLG_SYSTEM_PRIVACYCONSENT_OPTION_AGREE="I agree" +PLG_SYSTEM_PRIVACYCONSENT_REDIRECT_MESSAGE_DEFAULT="Please confirm that you consent to this web site storing your information by agreeing to the privacy policy." +PLG_SYSTEM_PRIVACYCONSENT_REDIRECT_MESSAGE_DESC="Custom message to be displayed on redirect. If left blank then the default message will be used." +PLG_SYSTEM_PRIVACYCONSENT_REDIRECT_MESSAGE_LABEL="Redirect Message" +PLG_SYSTEM_PRIVACYCONSENT_REMINDBEFORE_DESC="Number of days to send a reminder before the expiration of the privacy consent." +PLG_SYSTEM_PRIVACYCONSENT_REMINDBEFORE_LABEL="Remind" +PLG_SYSTEM_PRIVACYCONSENT_SUBJECT="Privacy Policy" +PLG_SYSTEM_PRIVACYCONSENT_XML_DESCRIPTION="Basic plugin to request user's consent to the site's privacy policy. Existing users who have not consented yet will be redirected on login to update their profile." diff --git a/administrator/language/en-GB/en-GB.plg_system_privacyconsent.sys.ini b/administrator/language/en-GB/en-GB.plg_system_privacyconsent.sys.ini new file mode 100644 index 0000000000000..9e5e187496742 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_system_privacyconsent.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_PRIVACYCONSENT="System - Privacy Consent" +PLG_SYSTEM_PRIVACYCONSENT_XML_DESCRIPTION="Basic plugin to request user's consent to the site's privacy policy. Existing users who have not consented yet will be redirected on login to update their profile." \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_user_terms.ini b/administrator/language/en-GB/en-GB.plg_user_terms.ini new file mode 100644 index 0000000000000..7ddb767a6fed8 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_user_terms.ini @@ -0,0 +1,19 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_USER_TERMS="User - Terms and Conditions" +PLG_USER_TERMS_FIELD_ARTICLE_DESC="Select the article from the list or create a new one." +PLG_USER_TERMS_FIELD_ARTICLE_LABEL="Terms & Conditions Article" +PLG_USER_TERMS_FIELD_DESC="Read the full terms and conditions." +PLG_USER_TERMS_FIELD_ERROR="Agreement to the site's Terms & Conditions is required." +PLG_USER_TERMS_FIELD_LABEL="Terms & Conditions" +PLG_USER_TERMS_LABEL="Terms & Conditions" +PLG_USER_TERMS_LOGGING_CONSENT_TO_TERMS="User {username} consented to the terms and conditions during registration." +PLG_USER_TERMS_NOTE_FIELD_DEFAULT="By signing up to this web site you accept the Terms & Conditions." +PLG_USER_TERMS_NOTE_FIELD_DESC="A summary of the site's terms & conditions. If left blank then the default message will be used." +PLG_USER_TERMS_NOTE_FIELD_LABEL="Short Terms & Conditions" +PLG_USER_TERMS_OPTION_AGREE="I agree" +PLG_USER_TERMS_SUBJECT="Privacy Policy" +PLG_USER_TERMS_XML_DESCRIPTION="Basic plugin to request user's consent to the site's terms and conditions." diff --git a/administrator/language/en-GB/en-GB.plg_user_terms.sys.ini b/administrator/language/en-GB/en-GB.plg_user_terms.sys.ini new file mode 100644 index 0000000000000..334230cb3885f --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_user_terms.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_USER_TERMS="User - Terms and Conditions" +PLG_USER_TERMS_XML_DESCRIPTION="Basic plugin to request user's consent to the site's terms and conditions." \ No newline at end of file diff --git a/administrator/modules/mod_latestactions/helper.php b/administrator/modules/mod_latestactions/helper.php new file mode 100644 index 0000000000000..8f2fce6a095eb --- /dev/null +++ b/administrator/modules/mod_latestactions/helper.php @@ -0,0 +1,52 @@ + true)); + + // Set the Start and Limit + $model->setState('list.start', 0); + $model->setState('list.limit', $params->get('count', 5)); + $model->setState('list.ordering', 'a.id'); + $model->setState('list.direction', 'DESC'); + + $rows = $model->getItems(); + + // Load all actionlog plugins language files + ActionlogsHelper::loadActionLogPluginsLanguage(); + + foreach ($rows as $row) + { + $row->message = ActionlogsHelper::getHumanReadableLogMessage($row); + } + + return $rows; + } +} diff --git a/administrator/modules/mod_latestactions/mod_latestactions.php b/administrator/modules/mod_latestactions/mod_latestactions.php new file mode 100644 index 0000000000000..b198b637e7820 --- /dev/null +++ b/administrator/modules/mod_latestactions/mod_latestactions.php @@ -0,0 +1,22 @@ +get('automatic_title', 0)) +{ + $module->title = ModLatestHelper::getTitle($params); +} + +require JModuleHelper::getLayoutPath('mod_latestactions', $params->get('layout', 'default')); diff --git a/administrator/modules/mod_latestactions/mod_latestactions.xml b/administrator/modules/mod_latestactions/mod_latestactions.xml new file mode 100644 index 0000000000000..708aee6b32aa5 --- /dev/null +++ b/administrator/modules/mod_latestactions/mod_latestactions.xml @@ -0,0 +1,94 @@ + + + mod_latestactions + Joomla! Project + May 2018 + Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + MOD_LATESTACTIONS_XML_DESCRIPTION + + mod_latestactions.php + helper.php + tmpl + + + en-GB.mod_latestactions.ini + en-GB.mod_latestactions.sys.ini + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + +
+
+
+
diff --git a/administrator/modules/mod_latestactions/tmpl/default.php b/administrator/modules/mod_latestactions/tmpl/default.php new file mode 100644 index 0000000000000..31e684ac936d1 --- /dev/null +++ b/administrator/modules/mod_latestactions/tmpl/default.php @@ -0,0 +1,35 @@ + +
+ + $item) : ?> +
+
+ message; ?> +
+
+
+ log_date, JText::_('DATE_FORMAT_LC5')); ?> +
+
+
+ + +
+
+
+
+
+ +
diff --git a/administrator/modules/mod_menu/menu.php b/administrator/modules/mod_menu/menu.php index 882ee939227e2..108433068fb9e 100644 --- a/administrator/modules/mod_menu/menu.php +++ b/administrator/modules/mod_menu/menu.php @@ -314,7 +314,8 @@ protected function preprocess($items) list($assetName) = isset($query['context']) ? explode('.', $query['context'], 2) : array('com_fields'); } - elseif ($item->element === 'com_config' && !$user->authorise('core.admin')) + // Special case for components which only allow super user access + elseif (in_array($item->element, array('com_config', 'com_privacy', 'com_actionlogs'), true) && !$user->authorise('core.admin')) { continue; } diff --git a/administrator/modules/mod_privacy_dashboard/helper.php b/administrator/modules/mod_privacy_dashboard/helper.php new file mode 100644 index 0000000000000..48d550bf13b8e --- /dev/null +++ b/administrator/modules/mod_privacy_dashboard/helper.php @@ -0,0 +1,42 @@ +getRequestCounts(); + } + catch (JDatabaseException $e) + { + return array(); + } + } +} diff --git a/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.php b/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.php new file mode 100644 index 0000000000000..58b1d8f1057dd --- /dev/null +++ b/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.php @@ -0,0 +1,24 @@ +load('com_privacy', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('com_privacy', JPATH_ADMINISTRATOR . '/components/com_privacy', null, false, true); + +JHtml::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/html'); + +JLoader::register('ModPrivacyDashboardHelper', __DIR__ . '/helper.php'); + +$list = ModPrivacyDashboardHelper::getData(); +$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'), ENT_COMPAT, 'UTF-8'); + +require JModuleHelper::getLayoutPath('mod_privacy_dashboard', $params->get('layout', 'default')); diff --git a/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.xml b/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.xml new file mode 100644 index 0000000000000..0075c4777b9c8 --- /dev/null +++ b/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.xml @@ -0,0 +1,73 @@ + + + mod_privacy_dashboard + Joomla! Project + June 2018 + Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + MOD_PRIVACY_DASHBOARD_XML_DESCRIPTION + + mod_privacy_dashboard.php + tmpl + helper.php + + + en-GB.mod_privacy_dashboard.ini + en-GB.mod_privacy_dashboard.sys.ini + + + + +
+
+
+ + + + + + + + + + + + + + +
+
+
+
diff --git a/administrator/modules/mod_privacy_dashboard/tmpl/default.php b/administrator/modules/mod_privacy_dashboard/tmpl/default.php new file mode 100644 index 0000000000000..b1258b7cb016a --- /dev/null +++ b/administrator/modules/mod_privacy_dashboard/tmpl/default.php @@ -0,0 +1,51 @@ + +
+ +
+
+
+
+
+ +
+ +
status); ?>
+
count; ?>
+
+ status, array(0, 1))) : ?> + count; ?> + + count; ?> + +
+
+
+
+ +
+
+
+
+
+ +
diff --git a/build/helpTOC.php b/build/helpTOC.php index 5ef5744a606a5..725e74b59fe8c 100644 --- a/build/helpTOC.php +++ b/build/helpTOC.php @@ -59,7 +59,7 @@ public function doExecute() { // Get the version data for the script $minorVersion = Version::MAJOR_VERSION . '.' . Version::MINOR_VERSION; - $namespace = 'Help' . $minorVersion . ':'; + $namespace = 'Help' . str_replace('.', '', $minorVersion) . ':'; // Set up options for JMediawiki $options = new Registry; diff --git a/components/com_privacy/controller.php b/components/com_privacy/controller.php new file mode 100644 index 0000000000000..bd5d6bfb55015 --- /dev/null +++ b/components/com_privacy/controller.php @@ -0,0 +1,43 @@ +input->get('view', $this->default_view); + + // Submitting information requests through the frontend is restricted to authenticated users at this time + if ($view === 'request' && JFactory::getUser()->guest) + { + $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false)); + + return $this; + } + + return parent::display($cachable, $urlparams); + } +} diff --git a/components/com_privacy/controllers/request.php b/components/com_privacy/controllers/request.php new file mode 100644 index 0000000000000..9f31e90a24435 --- /dev/null +++ b/components/com_privacy/controllers/request.php @@ -0,0 +1,180 @@ +checkToken('post'); + + /** @var PrivacyModelConfirm $model */ + $model = $this->getModel('Confirm', 'PrivacyModel'); + $data = $this->input->post->get('jform', array(), 'array'); + + $return = $model->confirmRequest($data); + + // Check for a hard error. + if ($return instanceof Exception) + { + // Get the error message to display. + if (JFactory::getApplication()->get('error_reporting')) + { + $message = $return->getMessage(); + } + else + { + $message = JText::_('COM_PRIVACY_ERROR_CONFIRMING_REQUEST'); + } + + // Go back to the confirm form. + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=confirm', false), $message, 'error'); + + return false; + } + elseif ($return === false) + { + // Confirm failed. + // Go back to the confirm form. + $message = JText::sprintf('COM_PRIVACY_ERROR_CONFIRMING_REQUEST_FAILED', $model->getError()); + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=confirm', false), $message, 'notice'); + + return false; + } + else + { + // Confirm succeeded. + $this->setRedirect(JRoute::_(JUri::root()), JText::_('COM_PRIVACY_CONFIRM_REQUEST_SUCCEEDED'), 'info'); + + return true; + } + } + + /** + * Method to submit an information request. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function submit() + { + // Check the request token. + $this->checkToken('post'); + + /** @var PrivacyModelRequest $model */ + $model = $this->getModel('Request', 'PrivacyModel'); + $data = $this->input->post->get('jform', array(), 'array'); + + $return = $model->createRequest($data); + + // Check for a hard error. + if ($return instanceof Exception) + { + // Get the error message to display. + if (JFactory::getApplication()->get('error_reporting')) + { + $message = $return->getMessage(); + } + else + { + $message = JText::_('COM_PRIVACY_ERROR_CREATING_REQUEST'); + } + + // Go back to the confirm form. + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=request', false), $message, 'error'); + + return false; + } + elseif ($return === false) + { + // Confirm failed. + // Go back to the confirm form. + $message = JText::sprintf('COM_PRIVACY_ERROR_CREATING_REQUEST_FAILED', $model->getError()); + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=request', false), $message, 'notice'); + + return false; + } + else + { + // Confirm succeeded. + $this->setRedirect(JRoute::_(JUri::root()), JText::_('COM_PRIVACY_CREATE_REQUEST_SUCCEEDED'), 'info'); + + return true; + } + } + + /** + * Method to extend the privacy consent. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function remind() + { + // Check the request token. + $this->checkToken('post'); + + /** @var PrivacyModelConfirm $model */ + $model = $this->getModel('Remind', 'PrivacyModel'); + $data = $this->input->post->get('jform', array(), 'array'); + + $return = $model->remindRequest($data); + + // Check for a hard error. + if ($return instanceof Exception) + { + // Get the error message to display. + if (JFactory::getApplication()->get('error_reporting')) + { + $message = $return->getMessage(); + } + else + { + $message = JText::_('COM_PRIVACY_ERROR_REMIND_REQUEST'); + } + + // Go back to the confirm form. + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=remind', false), $message, 'error'); + + return false; + } + elseif ($return === false) + { + // Confirm failed. + // Go back to the confirm form. + $message = JText::sprintf('COM_PRIVACY_ERROR_CONFIRMING_REMIND_FAILED', $model->getError()); + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=remind', false), $message, 'notice'); + + return false; + } + else + { + // Confirm succeeded. + $this->setRedirect(JRoute::_(JUri::root()), JText::_('COM_PRIVACY_CONFIRM_REMIND_SUCCEEDED'), 'info'); + + return true; + } + } +} diff --git a/components/com_privacy/models/confirm.php b/components/com_privacy/models/confirm.php new file mode 100644 index 0000000000000..48399cbdea5d4 --- /dev/null +++ b/components/com_privacy/models/confirm.php @@ -0,0 +1,220 @@ +getForm(); + $data['email'] = JStringPunycode::emailToPunycode($data['email']); + + // Check for an error. + if ($form instanceof Exception) + { + return $form; + } + + // Filter and validate the form data. + $data = $form->filter($data); + $return = $form->validate($data); + + // Check for an error. + if ($return instanceof Exception) + { + return $return; + } + + // Check the validation results. + if ($return === false) + { + // Get the validation messages from the form. + foreach ($form->getErrors() as $formError) + { + $this->setError($formError->getMessage()); + } + + return false; + } + + // Search for the information request + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load(array('email' => $data['email'], 'status' => 0))) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_NO_PENDING_REQUESTS')); + + return false; + } + + // A request can only be confirmed if it is in a pending status and has a confirmation token + if ($table->status != '0' || !$table->confirm_token) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_NO_PENDING_REQUESTS')); + + return false; + } + + // A request can only be confirmed if the token is less than 24 hours old + $confirmTokenCreatedAt = new JDate($table->confirm_token_created_at); + $confirmTokenCreatedAt->add(new DateInterval('P1D')); + + $now = new JDate('now'); + + if ($now > $confirmTokenCreatedAt) + { + // Invalidate the request + $table->status = -1; + + try + { + $table->store(); + } + catch (JDatabaseException $exception) + { + // The error will be logged in the database API, we just need to catch it here to not let things fatal out + } + + $this->setError(JText::_('COM_PRIVACY_ERROR_CONFIRM_TOKEN_EXPIRED')); + + return false; + } + + // Verify the token + if (!JUserHelper::verifyPassword($data['confirm_token'], $table->confirm_token)) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_NO_PENDING_REQUESTS')); + + return false; + } + + // Everything is good to go, transition the request to confirmed + $saved = $this->save( + array( + 'id' => $table->id, + 'status' => 1, + ) + ); + + if (!$saved) + { + // Error was set by the save method + return false; + } + + // Push a notification to the site's super users, deliberately ignoring if this process fails so the below message goes out + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_messages/models', 'MessagesModel'); + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_messages/tables'); + + /** @var MessagesModelMessage $messageModel */ + $messageModel = JModelLegacy::getInstance('Message', 'MessagesModel'); + + $messageModel->notifySuperUsers( + JText::_('COM_PRIVACY_ADMIN_NOTIFICATION_USER_CONFIRMED_REQUEST_SUBJECT'), + JText::sprintf('COM_PRIVACY_ADMIN_NOTIFICATION_USER_CONFIRMED_REQUEST_MESSAGE', $table->email) + ); + + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $message = array( + 'action' => 'request-confirmed', + 'subjectemail' => $table->email, + 'id' => $table->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $table->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_CONFIRMED_REQUEST', 'com_privacy.request'); + + return true; + } + + /** + * Method for getting the form from the model. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm|boolean A JForm object on success, false on failure + * + * @since __DEPLOY_VERSION__ + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_privacy.confirm', 'confirm', array('control' => 'jform')); + + if (empty($form)) + { + return false; + } + + $input = JFactory::getApplication()->input; + + if ($input->getMethod() === 'GET') + { + $form->setValue('confirm_token', '', $input->get->getAlnum('confirm_token')); + } + + return $form; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since __DEPLOY_VERSION__ + * @throws \Exception + */ + public function getTable($name = 'Request', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function populateState() + { + // Get the application object. + $params = JFactory::getApplication()->getParams('com_privacy'); + + // Load the parameters. + $this->setState('params', $params); + } +} diff --git a/components/com_privacy/models/forms/confirm.xml b/components/com_privacy/models/forms/confirm.xml new file mode 100644 index 0000000000000..6113c06056b4d --- /dev/null +++ b/components/com_privacy/models/forms/confirm.xml @@ -0,0 +1,24 @@ + +
+
+ + + +
+
diff --git a/components/com_privacy/models/forms/remind.xml b/components/com_privacy/models/forms/remind.xml new file mode 100644 index 0000000000000..f97926394bdfc --- /dev/null +++ b/components/com_privacy/models/forms/remind.xml @@ -0,0 +1,24 @@ + +
+
+ + + +
+
diff --git a/components/com_privacy/models/forms/request.xml b/components/com_privacy/models/forms/request.xml new file mode 100644 index 0000000000000..195e7c79e3c1b --- /dev/null +++ b/components/com_privacy/models/forms/request.xml @@ -0,0 +1,27 @@ + +
+
+ + + + + + +
+
diff --git a/components/com_privacy/models/remind.php b/components/com_privacy/models/remind.php new file mode 100644 index 0000000000000..e7aeb3ee98e3d --- /dev/null +++ b/components/com_privacy/models/remind.php @@ -0,0 +1,183 @@ +getForm(); + $data['email'] = JStringPunycode::emailToPunycode($data['email']); + + // Check for an error. + if ($form instanceof Exception) + { + return $form; + } + + // Filter and validate the form data. + $data = $form->filter($data); + $return = $form->validate($data); + + // Check for an error. + if ($return instanceof Exception) + { + return $return; + } + + // Check the validation results. + if ($return === false) + { + // Get the validation messages from the form. + foreach ($form->getErrors() as $formError) + { + $this->setError($formError->getMessage()); + } + + return false; + } + + /** @var PrivacyTableConsent $table */ + $table = $this->getTable(); + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName(array('r.id', 'r.user_id', 'r.token'))); + $query->from($db->quoteName('#__privacy_consents', 'r')); + $query->join('LEFT', $db->quoteName('#__users', 'u') . ' ON u.id = r.user_id'); + $query->where($db->quoteName('u.email') . ' = ' . $db->quote($data['email'])); + $query->where($db->quoteName('r.remind') . ' = 1'); + $db->setQuery($query); + + try + { + $remind = $db->loadObject(); + } + catch (RuntimeException $e) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_NO_PENDING_REMIND')); + + return false; + } + + if (!$remind) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_NO_PENDING_REMIND')); + + return false; + } + + // Verify the token + if (!JUserHelper::verifyPassword($data['remind_token'], $remind->token)) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_NO_REMIND_REQUESTS')); + + return false; + } + + // Everything is good to go, transition the request to extended + $saved = $this->save( + array( + 'id' => $remind->id, + 'remind' => 0, + 'token' => '', + 'created' => JFactory::getDate()->toSql(), + ) + ); + + if (!$saved) + { + // Error was set by the save method + return false; + } + + return true; + } + + /** + * Method for getting the form from the model. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm|boolean A JForm object on success, false on failure + * + * @since __DEPLOY_VERSION__ + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_privacy.remind', 'remind', array('control' => 'jform')); + + if (empty($form)) + { + return false; + } + + $input = JFactory::getApplication()->input; + + if ($input->getMethod() === 'GET') + { + $form->setValue('remind_token', '', $input->get->getAlnum('remind_token')); + } + + return $form; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since __DEPLOY_VERSION__ + * @throws \Exception + */ + public function getTable($name = 'Consent', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function populateState() + { + // Get the application object. + $params = JFactory::getApplication()->getParams('com_privacy'); + + // Load the parameters. + $this->setState('params', $params); + } +} diff --git a/components/com_privacy/models/request.php b/components/com_privacy/models/request.php new file mode 100644 index 0000000000000..5c40aa4ce5352 --- /dev/null +++ b/components/com_privacy/models/request.php @@ -0,0 +1,269 @@ +get('mailonline', 1)) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED')); + + return false; + } + + // Get the form. + $form = $this->getForm(); + $data['email'] = JStringPunycode::emailToPunycode($data['email']); + + // Check for an error. + if ($form instanceof Exception) + { + return $form; + } + + // Filter and validate the form data. + $data = $form->filter($data); + $return = $form->validate($data); + + // Check for an error. + if ($return instanceof Exception) + { + return $return; + } + + // Check the validation results. + if ($return === false) + { + // Get the validation messages from the form. + foreach ($form->getErrors() as $formError) + { + $this->setError($formError->getMessage()); + } + + return false; + } + + // Search for an open information request matching the email and type + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('COUNT(id)') + ->from('#__privacy_requests') + ->where('email = ' . $db->quote($data['email'])) + ->where('request_type = ' . $db->quote($data['request_type'])) + ->where('status IN (0, 1)'); + + try + { + $result = (int) $db->setQuery($query)->loadResult(); + } + catch (JDatabaseException $exception) + { + // Can't check for existing requests, so don't create a new one + $this->setError(JText::_('COM_PRIVACY_ERROR_CHECKING_FOR_EXISTING_REQUESTS')); + + return false; + } + + if ($result > 0) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_PENDING_REQUEST_OPEN')); + + return false; + } + + // Everything is good to go, create the request + $token = JApplicationHelper::getHash(JUserHelper::genRandomPassword()); + $hashedToken = JUserHelper::hashPassword($token); + + $data['confirm_token'] = $hashedToken; + $data['confirm_token_created_at'] = JFactory::getDate()->toSql(); + + if (!$this->save($data)) + { + // The save function will set the error message, so just return here + return false; + } + + // Push a notification to the site's super users, deliberately ignoring if this process fails so the below message goes out + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_messages/models', 'MessagesModel'); + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_messages/tables'); + + /** @var MessagesModelMessage $messageModel */ + $messageModel = JModelLegacy::getInstance('Message', 'MessagesModel'); + + $messageModel->notifySuperUsers( + JText::_('COM_PRIVACY_ADMIN_NOTIFICATION_USER_CREATED_REQUEST_SUBJECT'), + JText::sprintf('COM_PRIVACY_ADMIN_NOTIFICATION_USER_CREATED_REQUEST_MESSAGE', $data['email']) + ); + + // The mailer can be set to either throw Exceptions or return boolean false, account for both + try + { + $app = JFactory::getApplication(); + + $linkMode = $app->get('force_ssl', 0) == 2 ? 1 : -1; + + $substitutions = array( + '[SITENAME]' => $app->get('sitename'), + '[URL]' => JUri::root(), + '[TOKENURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm&confirm_token=' . $token, false, $linkMode), + '[FORMURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm', false, $linkMode), + '[TOKEN]' => $token, + '\\n' => "\n", + ); + + switch ($data['request_type']) + { + case 'export': + $emailSubject = JText::_('COM_PRIVACY_EMAIL_REQUEST_SUBJECT_EXPORT_REQUEST'); + $emailBody = JText::_('COM_PRIVACY_EMAIL_REQUEST_BODY_EXPORT_REQUEST'); + + break; + + case 'remove': + $emailSubject = JText::_('COM_PRIVACY_EMAIL_REQUEST_SUBJECT_REMOVE_REQUEST'); + $emailBody = JText::_('COM_PRIVACY_EMAIL_REQUEST_BODY_REMOVE_REQUEST'); + + break; + + default: + $this->setError(JText::_('COM_PRIVACY_ERROR_UNKNOWN_REQUEST_TYPE')); + + return false; + } + + foreach ($substitutions as $k => $v) + { + $emailSubject = str_replace($k, $v, $emailSubject); + $emailBody = str_replace($k, $v, $emailBody); + } + + $mailer = JFactory::getMailer(); + $mailer->setSubject($emailSubject); + $mailer->setBody($emailBody); + $mailer->addRecipient($data['email']); + + $mailResult = $mailer->Send(); + + if ($mailResult instanceof JException) + { + // JError was already called so we just need to return now + return false; + } + elseif ($mailResult === false) + { + $this->setError($mailer->ErrorInfo); + + return false; + } + + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($this->getState($this->getName() . '.id'))) + { + $this->setError($table->getError()); + + return false; + } + + // Log the request's creation + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $message = array( + 'action' => 'request-created', + 'requesttype' => $table->request_type, + 'subjectemail' => $table->email, + 'id' => $table->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $table->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_CREATED_REQUEST', 'com_privacy.request'); + + // The email sent and the record is saved, everything is good to go from here + return true; + } + catch (phpmailerException $exception) + { + $this->setError($exception->getMessage()); + + return false; + } + } + + /** + * Method for getting the form from the model. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm|boolean A JForm object on success, false on failure + * + * @since __DEPLOY_VERSION__ + */ + public function getForm($data = array(), $loadData = true) + { + return $this->loadForm('com_privacy.request', 'request', array('control' => 'jform')); + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since __DEPLOY_VERSION__ + * @throws \Exception + */ + public function getTable($name = 'Request', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function populateState() + { + // Get the application object. + $params = JFactory::getApplication()->getParams('com_privacy'); + + // Load the parameters. + $this->setState('params', $params); + } +} diff --git a/components/com_privacy/privacy.php b/components/com_privacy/privacy.php new file mode 100644 index 0000000000000..48eb01941972c --- /dev/null +++ b/components/com_privacy/privacy.php @@ -0,0 +1,14 @@ +execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/components/com_privacy/router.php b/components/com_privacy/router.php new file mode 100644 index 0000000000000..f445ff44ca4f6 --- /dev/null +++ b/components/com_privacy/router.php @@ -0,0 +1,78 @@ +registerView(new JComponentRouterViewconfiguration('confirm')); + $this->registerView(new JComponentRouterViewconfiguration('request')); + $this->registerView(new JComponentRouterViewconfiguration('remind')); + + parent::__construct($app, $menu); + + $this->attachRule(new JComponentRouterRulesMenu($this)); + $this->attachRule(new JComponentRouterRulesStandard($this)); + $this->attachRule(new JComponentRouterRulesNomenu($this)); + } +} + +/** + * Privacy router functions + * + * These functions are proxys for the new router interface + * for old SEF extensions. + * + * @param array &$query REQUEST query + * + * @return array Segments of the SEF url + * + * @since __DEPLOY_VERSION__ + * @deprecated 4.0 Use Class based routers instead + */ +function privacyBuildRoute(&$query) +{ + $app = JFactory::getApplication(); + $router = new PrivacyRouter($app, $app->getMenu()); + + return $router->build($query); +} + +/** + * Convert SEF URL segments into query variables + * + * @param array $segments Segments in the current URL + * + * @return array Query variables + * + * @since __DEPLOY_VERSION__ + * @deprecated 4.0 Use Class based routers instead + */ +function privacyParseRoute($segments) +{ + $app = JFactory::getApplication(); + $router = new PrivacyRouter($app, $app->getMenu()); + + return $router->parse($segments); +} diff --git a/components/com_privacy/views/confirm/tmpl/default.php b/components/com_privacy/views/confirm/tmpl/default.php new file mode 100644 index 0000000000000..8cbf6e703037b --- /dev/null +++ b/components/com_privacy/views/confirm/tmpl/default.php @@ -0,0 +1,44 @@ + +
+ params->get('show_page_heading')) : ?> + + +
+ form->getFieldsets() as $fieldset) : ?> +
+ label)) : ?> + label); ?> + + form->renderFieldset($fieldset->name); ?> +
+ +
+
+ +
+
+ +
+
diff --git a/components/com_privacy/views/confirm/tmpl/default.xml b/components/com_privacy/views/confirm/tmpl/default.xml new file mode 100644 index 0000000000000..e25592846aa3f --- /dev/null +++ b/components/com_privacy/views/confirm/tmpl/default.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/components/com_privacy/views/confirm/view.html.php b/components/com_privacy/views/confirm/view.html.php new file mode 100644 index 0000000000000..3a8a38105fd13 --- /dev/null +++ b/components/com_privacy/views/confirm/view.html.php @@ -0,0 +1,143 @@ +form = $this->get('Form'); + $this->state = $this->get('State'); + $this->params = $this->state->params; + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx'), ENT_COMPAT, 'UTF-8'); + + $this->prepareDocument(); + + return parent::display($tpl); + } + + /** + * Prepares the document. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_PRIVACY_VIEW_CONFIRM_PAGE_TITLE')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/components/com_privacy/views/remind/tmpl/default.php b/components/com_privacy/views/remind/tmpl/default.php new file mode 100644 index 0000000000000..a438c89616713 --- /dev/null +++ b/components/com_privacy/views/remind/tmpl/default.php @@ -0,0 +1,44 @@ + +
+ params->get('show_page_heading')) : ?> + + +
+ form->getFieldsets() as $fieldset) : ?> +
+ label)) : ?> + label); ?> + + form->renderFieldset($fieldset->name); ?> +
+ +
+
+ +
+
+ +
+
diff --git a/components/com_privacy/views/remind/tmpl/default.xml b/components/com_privacy/views/remind/tmpl/default.xml new file mode 100644 index 0000000000000..9b0e5b83a7f67 --- /dev/null +++ b/components/com_privacy/views/remind/tmpl/default.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/components/com_privacy/views/remind/view.html.php b/components/com_privacy/views/remind/view.html.php new file mode 100644 index 0000000000000..2fbd63a0892fa --- /dev/null +++ b/components/com_privacy/views/remind/view.html.php @@ -0,0 +1,143 @@ +form = $this->get('Form'); + $this->state = $this->get('State'); + $this->params = $this->state->params; + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx'), ENT_COMPAT, 'UTF-8'); + + $this->prepareDocument(); + + return parent::display($tpl); + } + + /** + * Prepares the document. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_PRIVACY_VIEW_REMIND_PAGE_TITLE')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/components/com_privacy/views/request/tmpl/default.php b/components/com_privacy/views/request/tmpl/default.php new file mode 100644 index 0000000000000..8eb9a1bbb256f --- /dev/null +++ b/components/com_privacy/views/request/tmpl/default.php @@ -0,0 +1,51 @@ + +
+ params->get('show_page_heading')) : ?> + + + sendMailEnabled) : ?> +
+ form->getFieldsets() as $fieldset) : ?> +
+ label)) : ?> + label); ?> + + form->renderFieldset($fieldset->name); ?> +
+ +
+
+ +
+
+ +
+ +
+

+
+ +
diff --git a/components/com_privacy/views/request/tmpl/default.xml b/components/com_privacy/views/request/tmpl/default.xml new file mode 100644 index 0000000000000..b4d2efda6551d --- /dev/null +++ b/components/com_privacy/views/request/tmpl/default.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/components/com_privacy/views/request/view.html.php b/components/com_privacy/views/request/view.html.php new file mode 100644 index 0000000000000..df35c1341f307 --- /dev/null +++ b/components/com_privacy/views/request/view.html.php @@ -0,0 +1,152 @@ +form = $this->get('Form'); + $this->state = $this->get('State'); + $this->params = $this->state->params; + $this->sendMailEnabled = (bool) JFactory::getConfig()->get('mailonline', 1); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx'), ENT_COMPAT, 'UTF-8'); + + $this->prepareDocument(); + + return parent::display($tpl); + } + + /** + * Prepares the document. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_PRIVACY_VIEW_REQUEST_PAGE_TITLE')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/installation/sql/mysql/joomla.sql b/installation/sql/mysql/joomla.sql index a8ac578924e05..57c8e9227fe9f 100644 --- a/installation/sql/mysql/joomla.sql +++ b/installation/sql/mysql/joomla.sql @@ -31,7 +31,7 @@ CREATE TABLE IF NOT EXISTS `#__assets` ( -- INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `title`, `rules`) VALUES -(1, 0, 0, 105, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 0, 113, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 1, 2, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 3, 6, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 7, 8, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -48,25 +48,25 @@ INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `titl (15, 1, 33, 34, 1, 'com_media', 'com_media', '{"core.admin":{"7":1},"core.manage":{"6":1},"core.create":{"3":1},"core.delete":{"5":1}}'), (16, 1, 35, 38, 1, 'com_menus', 'com_menus', '{"core.admin":{"7":1}}'), (17, 1, 39, 40, 1, 'com_messages', 'com_messages', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), -(18, 1, 41, 74, 1, 'com_modules', 'com_modules', '{"core.admin":{"7":1}}'), -(19, 1, 75, 78, 1, 'com_newsfeeds', 'com_newsfeeds', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), -(20, 1, 79, 80, 1, 'com_plugins', 'com_plugins', '{"core.admin":{"7":1}}'), -(21, 1, 81, 82, 1, 'com_redirect', 'com_redirect', '{"core.admin":{"7":1}}'), -(22, 1, 83, 84, 1, 'com_search', 'com_search', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), -(23, 1, 85, 86, 1, 'com_templates', 'com_templates', '{"core.admin":{"7":1}}'), -(24, 1, 87, 90, 1, 'com_users', 'com_users', '{"core.admin":{"7":1}}'), -(26, 1, 91, 92, 1, 'com_wrapper', 'com_wrapper', '{}'), +(18, 1, 41, 78, 1, 'com_modules', 'com_modules', '{"core.admin":{"7":1}}'), +(19, 1, 79, 82, 1, 'com_newsfeeds', 'com_newsfeeds', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), +(20, 1, 83, 84, 1, 'com_plugins', 'com_plugins', '{"core.admin":{"7":1}}'), +(21, 1, 85, 86, 1, 'com_redirect', 'com_redirect', '{"core.admin":{"7":1}}'), +(22, 1, 87, 88, 1, 'com_search', 'com_search', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), +(23, 1, 89, 90, 1, 'com_templates', 'com_templates', '{"core.admin":{"7":1}}'), +(24, 1, 91, 94, 1, 'com_users', 'com_users', '{"core.admin":{"7":1}}'), +(26, 1, 95, 96, 1, 'com_wrapper', 'com_wrapper', '{}'), (27, 8, 18, 19, 2, 'com_content.category.2', 'Uncategorised', '{}'), (28, 3, 4, 5, 2, 'com_banners.category.3', 'Uncategorised', '{}'), (29, 7, 14, 15, 2, 'com_contact.category.4', 'Uncategorised', '{}'), -(30, 19, 76, 77, 2, 'com_newsfeeds.category.5', 'Uncategorised', '{}'), -(32, 24, 88, 89, 2, 'com_users.category.7', 'Uncategorised', '{}'), -(33, 1, 93, 94, 1, 'com_finder', 'com_finder', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), -(34, 1, 95, 96, 1, 'com_joomlaupdate', 'com_joomlaupdate', '{}'), -(35, 1, 97, 98, 1, 'com_tags', 'com_tags', '{}'), -(36, 1, 99, 100, 1, 'com_contenthistory', 'com_contenthistory', '{}'), -(37, 1, 101, 102, 1, 'com_ajax', 'com_ajax', '{}'), -(38, 1, 103, 104, 1, 'com_postinstall', 'com_postinstall', '{}'), +(30, 19, 80, 81, 2, 'com_newsfeeds.category.5', 'Uncategorised', '{}'), +(32, 24, 92, 93, 2, 'com_users.category.7', 'Uncategorised', '{}'), +(33, 1, 97, 98, 1, 'com_finder', 'com_finder', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), +(34, 1, 99, 100, 1, 'com_joomlaupdate', 'com_joomlaupdate', '{}'), +(35, 1, 101, 102, 1, 'com_tags', 'com_tags', '{}'), +(36, 1, 103, 104, 1, 'com_contenthistory', 'com_contenthistory', '{}'), +(37, 1, 105, 106, 1, 'com_ajax', 'com_ajax', '{}'), +(38, 1, 107, 108, 1, 'com_postinstall', 'com_postinstall', '{}'), (39, 18, 42, 43, 2, 'com_modules.module.1', 'Main Menu', '{}'), (40, 18, 44, 45, 2, 'com_modules.module.2', 'Login', '{}'), (41, 18, 46, 47, 2, 'com_modules.module.3', 'Popular Articles', '{}'), @@ -83,7 +83,12 @@ INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `titl (52, 18, 68, 69, 2, 'com_modules.module.79', 'Multilanguage status', '{}'), (53, 18, 70, 71, 2, 'com_modules.module.86', 'Joomla Version', '{}'), (54, 16, 36, 37, 2, 'com_menus.menu.1', 'Main Menu', '{}'), -(55, 18, 72, 73, 2, 'com_modules.module.87', 'Sample Data', '{}'); +(55, 18, 72, 73, 2, 'com_modules.module.87', 'Sample Data', '{}'), +(56, 1, 109, 110, 1, 'com_privacy', 'com_privacy', '{}'), +(57, 1, 111, 112, 1, 'com_actionlogs', 'com_actionlogs', '{}'), +(58, 18, 74, 75, 2, 'com_modules.module.88', 'Latest Actions', '{}'), +(59, 18, 76, 77, 2, 'com_modules.module.89', 'Privacy Dashboard', '{}'); + -- -------------------------------------------------------- @@ -520,6 +525,8 @@ INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `elem (32, 0, 'com_postinstall', 'component', 'com_postinstall', '', 1, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (33, 0, 'com_fields', 'component', 'com_fields', '', 1, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (34, 0, 'com_associations', 'component', 'com_associations', '', 1, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(35, 0, 'com_privacy', 'component', 'com_privacy', '', 1, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(36, 0, 'com_actionlogs', 'component', 'com_actionlogs', '', 1, 1, 1, 1, '', '{"ip_logging":0,"csv_delimiter":",","loggable_extensions":["com_banners","com_cache","com_categories","com_config","com_contact","com_content","com_installer","com_media","com_menus","com_messages","com_modules","com_newsfeeds","com_plugins","com_redirect","com_tags","com_templates","com_users"]}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (102, 0, 'phputf8', 'library', 'phputf8', '', 0, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (103, 0, 'Joomla! Platform', 'library', 'joomla', '', 0, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (104, 0, 'IDNA Convert', 'library', 'idna_convert', '', 0, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), @@ -566,6 +573,8 @@ INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `elem (316, 0, 'mod_tags_popular', 'module', 'mod_tags_popular', '', 0, 1, 1, 0, '', '{"maximum":"5","timeframe":"alltime","owncache":"1"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (317, 0, 'mod_tags_similar', 'module', 'mod_tags_similar', '', 0, 1, 1, 0, '', '{"maximum":"5","matchtype":"any","owncache":"1"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (318, 0, 'mod_sampledata', 'module', 'mod_sampledata', '', 1, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(319, 0, 'mod_latestactions', 'module', 'mod_latestactions', '', 1, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(320, 0, 'mod_privacy_dashboard', 'module', 'mod_privacy_dashboard', '', 1, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (400, 0, 'plg_authentication_gmail', 'plugin', 'gmail', 'authentication', 0, 0, 1, 0, '', '{"applysuffix":"0","suffix":"","verifypeer":"1","user_blacklist":""}', '', '', 0, '0000-00-00 00:00:00', 1, 0), (401, 0, 'plg_authentication_joomla', 'plugin', 'joomla', 'authentication', 0, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (402, 0, 'plg_authentication_ldap', 'plugin', 'ldap', 'authentication', 0, 0, 1, 0, '', '{"host":"","port":"389","use_ldapV3":"0","negotiate_tls":"0","no_referrals":"0","auth_method":"bind","base_dn":"","search_string":"","users_dn":"","username":"admin","password":"bobby7","ldap_fullname":"fullName","ldap_email":"mail","ldap_uid":"uid"}', '', '', 0, '0000-00-00 00:00:00', 3, 0), @@ -645,6 +654,18 @@ INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `elem (479, 0, 'plg_sampledata_blog', 'plugin', 'blog', 'sampledata', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (480, 0, 'plg_system_sessiongc', 'plugin', 'sessiongc', 'system', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (481, 0, 'plg_fields_repeatable', 'plugin', 'repeatable', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(482, 0, 'plg_content_confirmconsent', 'plugin', 'confirmconsent', 'content', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(483, 0, 'plg_system_actionlogs', 'plugin', 'actionlogs', 'system', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(484, 0, 'plg_actionlog_joomla', 'plugin', 'joomla', 'actionlog', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(485, 0, 'plg_system_privacyconsent', 'plugin', 'privacyconsent', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(486, 0, 'plg_system_logrotation', 'plugin', 'logrotation', 'system', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(487, 0, 'plg_privacy_user', 'plugin', 'user', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(488, 0, 'plg_quickicon_privacycheck', 'plugin', 'privacycheck', 'quickicon', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(489, 0, 'plg_user_terms', 'plugin', 'terms', 'user', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(490, 0, 'plg_privacy_contact', 'plugin', 'contact', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(491, 0, 'plg_privacy_content', 'plugin', 'content', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(492, 0, 'plg_privacy_message', 'plugin', 'message', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(493, 0, 'plg_privacy_actionlogs', 'plugin', 'actionlogs', 'privacy', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (503, 0, 'beez3', 'template', 'beez3', '', 0, 1, 1, 0, '', '{"wrapperSmall":"53","wrapperLarge":"72","sitetitle":"","sitedescription":"","navposition":"center","templatecolor":"nature"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (504, 0, 'hathor', 'template', 'hathor', '', 1, 1, 1, 0, '', '{"showSiteName":"0","colourChoice":"0","boldText":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (506, 0, 'protostar', 'template', 'protostar', '', 0, 1, 1, 0, '', '{"templateColor":"","logoFile":"","googleFont":"1","googleFontName":"Open+Sans","fluidContainer":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), @@ -1512,7 +1533,9 @@ INSERT INTO `#__modules` (`id`, `asset_id`, `title`, `note`, `content`, `orderin (17, 51, 'Breadcrumbs', '', '', 1, 'position-2', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_breadcrumbs', 1, 1, '{"moduleclass_sfx":"","showHome":"1","homeText":"","showComponent":"1","separator":"","cache":"0","cache_time":"0","cachemode":"itemid"}', 0, '*'), (79, 52, 'Multilanguage status', '', '', 1, 'status', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 0, 'mod_multilangstatus', 3, 1, '{"layout":"_:default","moduleclass_sfx":"","cache":"0"}', 1, '*'), (86, 53, 'Joomla Version', '', '', 1, 'footer', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_version', 3, 1, '{"format":"short","product":"1","layout":"_:default","moduleclass_sfx":"","cache":"0"}', 1, '*'), -(87, 55, 'Sample Data', '', '', 0, 'cpanel', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_sampledata', 6, 1, '{}', 1, '*'); +(87, 55, 'Sample Data', '', '', 0, 'cpanel', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_sampledata', 6, 1, '{}', 1, '*'), +(88, 58, 'Latest Actions', '', '', 0, 'cpanel', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'), +(89, 59, 'Privacy Dashboard', '', '', 0, 'cpanel', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_privacy_dashboard', 6, 1, '{}', 1, '*'); -- -------------------------------------------------------- @@ -1548,7 +1571,9 @@ INSERT INTO `#__modules_menu` (`moduleid`, `menuid`) VALUES (17, 0), (79, 0), (86, 0), -(87, 0); +(87, 0), +(88, 0), +(89, 0); -- -------------------------------------------------------- @@ -1646,7 +1671,41 @@ INSERT INTO `#__postinstall_messages` (`extension_id`, `title_key`, `description (700, 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME', 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME_BODY', 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME_ACTION', 'plg_system_updatenotification', 1, 'action', 'site://plugins/system/updatenotification/postinstall/updatecachetime.php', 'updatecachetime_postinstall_action', 'site://plugins/system/updatenotification/postinstall/updatecachetime.php', 'updatecachetime_postinstall_condition', '3.6.3', 1), (700, 'COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_TITLE', 'COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/joomla40checks.php', 'admin_postinstall_joomla40checks_condition', '3.7.0', 1), (700, 'TPL_HATHOR_MESSAGE_POSTINSTALL_TITLE', 'TPL_HATHOR_MESSAGE_POSTINSTALL_BODY', 'TPL_HATHOR_MESSAGE_POSTINSTALL_ACTION', 'tpl_hathor', 1, 'action', 'admin://templates/hathor/postinstall/hathormessage.php', 'hathormessage_postinstall_action', 'admin://templates/hathor/postinstall/hathormessage.php', 'hathormessage_postinstall_condition', '3.7.0', 1), -(700, 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_TITLE', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_BODY', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_ACTION', 'plg_captcha_recaptcha', 1, 'action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_condition', '3.8.6', 1); +(700, 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_TITLE', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_BODY', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_ACTION', 'plg_captcha_recaptcha', 1, 'action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_condition', '3.8.6', 1), +(700, 'COM_ACTIONLOGS_POSTINSTALL_TITLE', 'COM_ACTIONLOGS_POSTINSTALL_BODY', '', 'com_actionlogs', 1, 'message', '', '', '', '', '3.9.0', 1), +(700, 'COM_PRIVACY_POSTINSTALL_TITLE', 'COM_PRIVACY_POSTINSTALL_BODY', '', 'com_privacy', 1, 'message', '', '', '', '', '3.9.0', 1); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__privacy_requests` +-- + +CREATE TABLE IF NOT EXISTS `#__privacy_requests` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `email` varchar(100) NOT NULL DEFAULT '', + `requested_at` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `status` tinyint(4) NOT NULL DEFAULT '0', + `request_type` varchar(25) NOT NULL DEFAULT '', + `confirm_token` varchar(100) NOT NULL DEFAULT '', + `confirm_token_created_at` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `checked_out` int(11) NOT NULL DEFAULT '0', + `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + KEY `idx_checkout` (`checked_out`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `#__privacy_consents` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `user_id` int(10) unsigned NOT NULL DEFAULT '0', + `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `subject` varchar(255) NOT NULL DEFAULT '', + `body` text NOT NULL, + `remind` tinyint(4) NOT NULL DEFAULT '0', + `token` varchar(100) NOT NULL DEFAULT '', + PRIMARY KEY (`id`), + KEY `idx_user_id` (`user_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- @@ -2083,6 +2142,87 @@ CREATE TABLE IF NOT EXISTS `#__user_usergroup_map` ( PRIMARY KEY (`user_id`,`group_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; +-- +-- Table structure for table `#__action_logs` +-- + +CREATE TABLE IF NOT EXISTS `#__action_logs` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `message_language_key` varchar(255) NOT NULL DEFAULT '', + `message` text NOT NULL, + `log_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `extension` varchar(50) NOT NULL DEFAULT '', + `user_id` int(11) NOT NULL DEFAULT 0, + `item_id` int(11) NOT NULL DEFAULT 0, + `ip_address` VARCHAR(40) NOT NULL DEFAULT '0.0.0.0', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +-- +-- Table structure for table `#__action_logs_extensions` +-- + +CREATE TABLE IF NOT EXISTS `#__action_logs_extensions` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `extension` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +INSERT INTO `#__action_logs_extensions` (`id`, `extension`) VALUES +(1, 'com_banners'), +(2, 'com_cache'), +(3, 'com_categories'), +(4, 'com_config'), +(5, 'com_contact'), +(6, 'com_content'), +(7, 'com_installer'), +(8, 'com_media'), +(9, 'com_menus'), +(10, 'com_messages'), +(11, 'com_modules'), +(12, 'com_newsfeeds'), +(13, 'com_plugins'), +(14, 'com_redirect'), +(15, 'com_tags'), +(16, 'com_templates'), +(17, 'com_users'); + +-- +-- Table structure for table `#__action_log_config` +-- + +CREATE TABLE IF NOT EXISTS `#__action_log_config` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `type_title` varchar(255) NOT NULL DEFAULT '', + `type_alias` varchar(255) NOT NULL DEFAULT '', + `id_holder` varchar(255), + `title_holder` varchar(255), + `table_name` varchar(255), + `text_prefix` varchar(255), + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +INSERT INTO `#__action_log_config` (`id`, `type_title`, `type_alias`, `id_holder`, `title_holder`, `table_name`, `text_prefix`) VALUES +(1, 'article', 'com_content.article', 'id' ,'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA'), +(2, 'article', 'com_content.form', 'id', 'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA'), +(3, 'banner', 'com_banners.banner', 'id' ,'name' , '#__banners', 'PLG_ACTIONLOG_JOOMLA'), +(4, 'user_note', 'com_users.note', 'id', 'subject' ,'#__user_notes', 'PLG_ACTIONLOG_JOOMLA'), +(5, 'media', 'com_media.file', '' , 'name' , '', 'PLG_ACTIONLOG_JOOMLA'), +(6, 'category', 'com_categories.category', 'id' , 'title' , '#__categories', 'PLG_ACTIONLOG_JOOMLA'), +(7, 'menu', 'com_menus.menu', 'id' ,'title' , '#__menu_types', 'PLG_ACTIONLOG_JOOMLA'), +(8, 'menu_item', 'com_menus.item', 'id' , 'title' , '#__menu', 'PLG_ACTIONLOG_JOOMLA'), +(9, 'newsfeed', 'com_newsfeeds.newsfeed', 'id' ,'name' , '#__newsfeeds', 'PLG_ACTIONLOG_JOOMLA'), +(10, 'link', 'com_redirect.link', 'id', 'old_url' , '#__redirect_links', 'PLG_ACTIONLOG_JOOMLA'), +(11, 'tag', 'com_tags.tag', 'id', 'title' , '#__tags', 'PLG_ACTIONLOG_JOOMLA'), +(12, 'style', 'com_templates.style', 'id' , 'title' , '#__template_styles', 'PLG_ACTIONLOG_JOOMLA'), +(13, 'plugin', 'com_plugins.plugin', 'extension_id' , 'name' , '#__extensions', 'PLG_ACTIONLOG_JOOMLA'), +(14, 'component_config', 'com_config.component', 'extension_id' , 'name', '', 'PLG_ACTIONLOG_JOOMLA'), +(15, 'contact', 'com_contact.contact', 'id', 'name', '#__contact_details', 'PLG_ACTIONLOG_JOOMLA'), +(16, 'module', 'com_modules.module', 'id' ,'title', '#__modules', 'PLG_ACTIONLOG_JOOMLA'), +(17, 'access_level', 'com_users.level', 'id' , 'title', '#__viewlevels', 'PLG_ACTIONLOG_JOOMLA'), +(18, 'banner_client', 'com_banners.client', 'id', 'name', '#__banner_clients', 'PLG_ACTIONLOG_JOOMLA'), +(19, 'application_config', 'com_config.application', '', 'name', '', 'PLG_ACTIONLOG_JOOMLA'); + -- -- Table structure for table `#__utf8_conversion` -- diff --git a/installation/sql/mysql/sample_blog.sql b/installation/sql/mysql/sample_blog.sql index 2bf75905edc37..19c67b54da37e 100644 --- a/installation/sql/mysql/sample_blog.sql +++ b/installation/sql/mysql/sample_blog.sql @@ -18,7 +18,7 @@ TRUNCATE `#__modules_menu`; -- INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `title`, `rules`) VALUES -(1, 0, 0, 87, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 0, 91, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 1, 2, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 3, 6, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 7, 8, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -61,7 +61,9 @@ INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `titl (44, 1, 79, 80, 1, 'com_tags', 'com_tags', '{"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (45, 1, 81, 82, 1, 'com_contenthistory', 'com_contenthistory', '{}'), (46, 1, 83, 84, 1, 'com_ajax', 'com_ajax', '{}'), -(47, 1, 85, 86, 1, 'com_postinstall', 'com_postinstall', '{}'); +(47, 1, 85, 86, 1, 'com_postinstall', 'com_postinstall', '{}'), +(48, 1, 87, 88, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(49, 1, 89, 90, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); -- -- Dumping data for table `#__categories` @@ -165,7 +167,8 @@ INSERT INTO `#__modules` (`id`, `title`, `note`, `content`, `ordering`, `positio (89, 'Popular Tags', '', '', 1, 'position-7', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_tags_popular', 1, 1, '{"maximum":"8","timeframe":"alltime","order_value":"count","order_direction":"1","display_count":0,"no_results_text":"0","minsize":1,"maxsize":2,"layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (90, 'Similar Items', '', '', 0, '', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_tags_similar', 1, 1, '{"maximum":"5","matchtype":"any","layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (91, 'Site Information', '', '', 4, 'cpanel', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_stats_admin', 6, 1, '{"serverinfo":"1","siteinfo":"1","counter":"0","increase":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"6","header_tag":"h3","header_class":"","style":"0"}', 1, '*'), -(92, 'Release News', '', '', 1, 'postinstall', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_feed', 1, 1, '{"rssurl":"https:\\/\\/www.joomla.org\\/announcements\\/release-news.feed","rssrtl":"0","rsstitle":"1","rssdesc":"1","rssimage":"1","rssitems":"3","rssitemdesc":"1","word_count":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 1, '*'); +(92, 'Release News', '', '', 1, 'postinstall', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_feed', 1, 1, '{"rssurl":"https:\\/\\/www.joomla.org\\/announcements\\/release-news.feed","rssrtl":"0","rsstitle":"1","rssdesc":"1","rssimage":"1","rssitems":"3","rssitemdesc":"1","word_count":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 1, '*'), +(93, 'Latest Actions', '', '', 0, 'cpanel', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); -- -- Dumping data for table `#__modules_menu` @@ -199,6 +202,7 @@ INSERT INTO `#__modules_menu` (`moduleid`, `menuid`) VALUES (89, 0), (90, 0), (91, 0), -(92, 0); +(92, 0), +(93, 0); SET FOREIGN_KEY_CHECKS=1; diff --git a/installation/sql/mysql/sample_brochure.sql b/installation/sql/mysql/sample_brochure.sql index bf4e062101df8..8220fcbcf003e 100644 --- a/installation/sql/mysql/sample_brochure.sql +++ b/installation/sql/mysql/sample_brochure.sql @@ -19,7 +19,7 @@ TRUNCATE `#__template_styles`; -- INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `title`, `rules`) VALUES -(1, 0, 0, 91, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 0, 95, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 1, 2, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 3, 6, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 7, 8, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -64,7 +64,9 @@ INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `titl (50, 18, 52, 53, 2, 'com_modules.module.4', 'Recently Added Articles', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (51, 18, 54, 55, 2, 'com_modules.module.89', 'Site Information', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (52, 18, 56, 57, 2, 'com_modules.module.88', 'Image', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), -(53, 18, 58, 59, 2, 'com_modules.module.90', 'Release News', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'); +(53, 18, 58, 59, 2, 'com_modules.module.90', 'Release News', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), +(54, 1, 91, 92, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(55, 1, 93, 94, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); -- -- Dumping data for table `#__categories` @@ -165,7 +167,8 @@ INSERT INTO `#__modules` (`id`, `asset_id`, `title`, `note`, `content`, `orderin (87, 0, 'Footer', '', '', 1, 'footer', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_footer', 1, 1, '{"layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (88, 52, 'Image', '', '

', 1, 'position-3', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_custom', 1, 0, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (89, 51, 'Site Information', '', '', 4, 'cpanel', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_stats_admin', 6, 1, '{"serverinfo":"1","siteinfo":"1","counter":"1","increase":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"6","header_tag":"h3","header_class":"","style":"0"}', 1, '*'), -(90, 53, 'Release News', '', '', 0, 'postinstall', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_feed', 1, 1, '{"rssurl":"https:\\/\\/www.joomla.org\\/announcements\\/release-news.feed","rssrtl":"0","rsstitle":"1","rssdesc":"1","rssimage":"1","rssitems":"3","rssitemdesc":"1","word_count":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 1, '*'); +(90, 53, 'Release News', '', '', 0, 'postinstall', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_feed', 1, 1, '{"rssurl":"https:\\/\\/www.joomla.org\\/announcements\\/release-news.feed","rssrtl":"0","rsstitle":"1","rssdesc":"1","rssimage":"1","rssitems":"3","rssitemdesc":"1","word_count":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 1, '*'), +(91, 54, 'Latest Actions', '', '', 0, 'cpanel', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); -- -- Dumping data for table `#__modules_menu` @@ -192,7 +195,8 @@ INSERT INTO `#__modules_menu` (`moduleid`, `menuid`) VALUES (83, 0), (85, 0), (86, 0), -(88, 0); +(88, 0), +(91, 0); -- -- Dumping data for table `#__template_styles` diff --git a/installation/sql/mysql/sample_data.sql b/installation/sql/mysql/sample_data.sql index d1da076fdf7a8..1f8d240e9ab1f 100644 --- a/installation/sql/mysql/sample_data.sql +++ b/installation/sql/mysql/sample_data.sql @@ -18,7 +18,7 @@ TRUNCATE `#__tags`; -- INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `title`, `rules`) VALUES -(1, 0, 0, 119, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 0, 123, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 1, 2, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 3, 6, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 7, 8, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -77,7 +77,9 @@ INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `titl (59, 18, 82, 83, 2, 'com_modules.module.92', 'Image Module', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (60, 18, 84, 85, 2, 'com_modules.module.93', 'Search', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (61, 27, 19, 20, 3, 'com_content.article.1', 'Getting Started', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), -(62, 1, 117, 118, 1, '#__ucm_content.1', '#__ucm_content.1', '{}'); +(62, 1, 117, 118, 1, '#__ucm_content.1', '#__ucm_content.1', '{}'), +(63, 1, 119, 120, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(64, 1, 121, 122, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); -- -- Dumping data for table `#__content` @@ -160,7 +162,8 @@ INSERT INTO `#__modules` (`id`, `asset_id`, `title`, `note`, `content`, `orderin (90, 57, 'Latest Articles', '', '', 1, 'position-7', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_articles_latest', 1, 1, '{"catid":[""],"count":"5","show_featured":"","ordering":"c_dsc","user_id":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (91, 58, 'User Menu', '', '', 3, 'position-7', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_menu', 1, 1, '{"menutype":"usermenu","base":"","startLevel":"1","endLevel":"0","showAllChildren":"1","tag_id":"","class_sfx":"","window_open":"","layout":"_:default","moduleclass_sfx":"_menu","cache":"1","cache_time":"900","cachemode":"itemid","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (92, 59, 'Image Module', '', '

Blue Flower

', 0, 'position-3', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_custom', 1, 0, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), -(93, 60, 'Search', '', '', 0, 'position-0', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_search', 1, 1, '{"label":"","width":"20","text":"","button":"0","button_pos":"right","imagebutton":"1","button_text":"","opensearch":"1","opensearch_title":"","set_itemid":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"itemid","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'); +(93, 60, 'Search', '', '', 0, 'position-0', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_search', 1, 1, '{"label":"","width":"20","text":"","button":"0","button_pos":"right","imagebutton":"1","button_text":"","opensearch":"1","opensearch_title":"","set_itemid":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"itemid","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), +(94, 61, 'Latest Actions', '', '', 0, 'cpanel', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); -- -- Dumping data for table `#__modules_menu` @@ -190,7 +193,8 @@ INSERT INTO `#__modules_menu` (`moduleid`, `menuid`) VALUES (90, 0), (91, 0), (92, 0), -(93, 0); +(93, 0), +(94, 0); -- -- Dumping data for table `#__tags` diff --git a/installation/sql/mysql/sample_learn.sql b/installation/sql/mysql/sample_learn.sql index 6d9653261f65b..ecdb6d6d487b9 100644 --- a/installation/sql/mysql/sample_learn.sql +++ b/installation/sql/mysql/sample_learn.sql @@ -21,7 +21,7 @@ TRUNCATE `#__viewlevels`; -- INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `title`, `rules`) VALUES -(1, 0, 1, 430, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 1, 434, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 2, 3, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 4, 11, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 12, 13, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -180,7 +180,9 @@ INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `titl (175, 1, 422, 423, 1, 'com_tags', 'com_tags', '{"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (176, 1, 424, 425, 1, 'com_contenthistory', 'com_contenthistory', '{}'), (177, 1, 426, 427, 1, 'com_ajax', 'com_ajax', '{}'), -(178, 1, 428, 429, 1, 'com_postinstall', 'com_postinstall', '{}'); +(178, 1, 428, 429, 1, 'com_postinstall', 'com_postinstall', '{}'), +(179, 1, 430, 431, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(180, 1, 432, 433, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); -- -- Dumping data for table `#__banners` @@ -577,7 +579,8 @@ INSERT INTO `#__modules` (`id`, `title`, `note`, `content`, `ordering`, `positio (87, 'Fruit Shop', '', '', 1, 'position-7', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_menu', 1, 1, '{"menutype":"fruitshop","startLevel":"1","endLevel":"0","showAllChildren":"1","tag_id":"","class_sfx":"","window_open":"","layout":"_:default","moduleclass_sfx":"","cache":"0","cache_time":"900","cachemode":"itemid","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (88, 'Image Module', '', '

', 1, 'position-3', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_custom', 1, 0, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (89, 'Custom', '', '

In this module you can put whatever text or other content you would like.

', 1, '', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_custom', 1, 1, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), -(90, 'Parks Image Module', '', '

', 1, 'position-3', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_custom', 1, 1, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'); +(90, 'Parks Image Module', '', '

', 1, 'position-3', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_custom', 1, 1, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), +(91, 'Latest Actions', '', '', 0, 'cpanel', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); -- -- Dumping data for table `#__modules_menu` @@ -774,7 +777,8 @@ INSERT INTO `#__modules_menu` (`moduleid`, `menuid`) VALUES (90, 244), (90, 296), (90, 399), -(90, 400); +(90, 400), +(91, 0); -- -- Dumping data for table `#__newsfeeds` diff --git a/installation/sql/mysql/sample_testing.sql b/installation/sql/mysql/sample_testing.sql index 108873dbe436f..46eefb3bab864 100644 --- a/installation/sql/mysql/sample_testing.sql +++ b/installation/sql/mysql/sample_testing.sql @@ -21,7 +21,7 @@ TRUNCATE `#__viewlevels`; -- INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `title`, `rules`) VALUES -(1, 0, 1, 437, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 1, 441, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 2, 3, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 4, 11, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 12, 13, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -184,7 +184,9 @@ INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `titl (177, 1, 433, 434, 1, 'com_postinstall', 'com_postinstall', '{}'), (178, 93, 144, 145, 7, 'com_content.article.71', 'Similar Tags', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (179, 1, 435, 436, 1, '#__ucm_content.3', '#__ucm_content.3', '{}'), -(180, 93, 146, 147, 7, 'com_content.article.72', 'Popular Tags', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'); +(180, 93, 146, 147, 7, 'com_content.article.72', 'Popular Tags', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), +(181, 1, 437, 438, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(182, 1, 439, 440, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); -- -- Dumping data for table `#__banners` @@ -612,7 +614,8 @@ INSERT INTO `#__modules` (`id`, `title`, `note`, `content`, `ordering`, `positio (93, 'Popular Tags', '', '', 1, '', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_tags_popular', 1, 1, '{"maximum":"5","timeframe":"alltime","order_value":"count","order_direction":"1","display_count":0,"no_results_text":"0","minsize":1,"maxsize":2,"layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (94, 'Similar Tags', '', '', 1, '', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_tags_similar', 1, 1, '{"maximum":"5","matchtype":"any","layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (95, 'Syndicate Feeds', '', '', 1, 'position-8', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_syndicate', 1, 1, '{"display_text":1,"text":"Feed Entries","format":"rss","layout":"_:default","moduleclass_sfx":"","cache":"0","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), -(97, 'Similar Tags 2', '', '', 1, 'position-8', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_tags_similar', 1, 1, '{"maximum":"5","matchtype":"any","layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'); +(97, 'Similar Tags 2', '', '', 1, 'position-8', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_tags_similar', 1, 1, '{"maximum":"5","matchtype":"any","layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), +(98, 'Latest Actions', '', '', 0, 'cpanel', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); -- -- Dumping data for table `#__modules_menu` @@ -798,7 +801,8 @@ INSERT INTO `#__modules_menu` (`moduleid`, `menuid`) VALUES (93, 0), (94, 0), (95, 0), -(97, 0); +(97, 0), +(98, 0); -- -- Dumping data for table `#__newsfeeds` diff --git a/installation/sql/postgresql/joomla.sql b/installation/sql/postgresql/joomla.sql index cce24c6630c51..d023601f47b2a 100644 --- a/installation/sql/postgresql/joomla.sql +++ b/installation/sql/postgresql/joomla.sql @@ -35,7 +35,7 @@ COMMENT ON COLUMN "#__assets"."rules" IS 'JSON encoded access control.'; -- INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "title", "rules") VALUES -(1, 0, 0, 105, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 0, 113, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 1, 2, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 3, 6, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 7, 8, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -52,25 +52,25 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (15, 1, 33, 34, 1, 'com_media', 'com_media', '{"core.admin":{"7":1},"core.manage":{"6":1},"core.create":{"3":1},"core.delete":{"5":1}}'), (16, 1, 35, 38, 1, 'com_menus', 'com_menus', '{"core.admin":{"7":1}}'), (17, 1, 39, 40, 1, 'com_messages', 'com_messages', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), -(18, 1, 41, 74, 1, 'com_modules', 'com_modules', '{"core.admin":{"7":1}}'), -(19, 1, 75, 77, 1, 'com_newsfeeds', 'com_newsfeeds', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), -(20, 1, 79, 80, 1, 'com_plugins', 'com_plugins', '{"core.admin":{"7":1}}'), -(21, 1, 81, 82, 1, 'com_redirect', 'com_redirect', '{"core.admin":{"7":1}}'), -(22, 1, 83, 84, 1, 'com_search', 'com_search', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), -(23, 1, 85, 86, 1, 'com_templates', 'com_templates', '{"core.admin":{"7":1}}'), -(24, 1, 87, 90, 1, 'com_users', 'com_users', '{"core.admin":{"7":1}}'), -(26, 1, 91, 92, 1, 'com_wrapper', 'com_wrapper', '{}'), +(18, 1, 41, 78, 1, 'com_modules', 'com_modules', '{"core.admin":{"7":1}}'), +(19, 1, 79, 82, 1, 'com_newsfeeds', 'com_newsfeeds', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), +(20, 1, 83, 84, 1, 'com_plugins', 'com_plugins', '{"core.admin":{"7":1}}'), +(21, 1, 85, 86, 1, 'com_redirect', 'com_redirect', '{"core.admin":{"7":1}}'), +(22, 1, 87, 88, 1, 'com_search', 'com_search', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), +(23, 1, 89, 90, 1, 'com_templates', 'com_templates', '{"core.admin":{"7":1}}'), +(24, 1, 91, 94, 1, 'com_users', 'com_users', '{"core.admin":{"7":1}}'), +(26, 1, 95, 96, 1, 'com_wrapper', 'com_wrapper', '{}'), (27, 8, 18, 19, 2, 'com_content.category.2', 'Uncategorised', '{}'), (28, 3, 4, 5, 2, 'com_banners.category.3', 'Uncategorised', '{}'), (29, 7, 14, 15, 2, 'com_contact.category.4', 'Uncategorised', '{}'), -(30, 19, 76, 77, 2, 'com_newsfeeds.category.5', 'Uncategorised', '{}'), -(32, 24, 88, 89, 2, 'com_users.category.7', 'Uncategorised', '{}'), -(33, 1, 93, 94, 1, 'com_finder', 'com_finder', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), -(34, 1, 95, 96, 1, 'com_joomlaupdate', 'com_joomlaupdate', '{}'), -(35, 1, 97, 98, 1, 'com_tags', 'com_tags', '{}'), -(36, 1, 99, 100, 1, 'com_contenthistory', 'com_contenthistory', '{}'), -(37, 1, 101, 102, 1, 'com_ajax', 'com_ajax', '{}'), -(38, 1, 103, 104, 1, 'com_postinstall', 'com_postinstall', '{}'), +(30, 19, 80, 81, 2, 'com_newsfeeds.category.5', 'Uncategorised', '{}'), +(32, 24, 92, 93, 2, 'com_users.category.7', 'Uncategorised', '{}'), +(33, 1, 97, 98, 1, 'com_finder', 'com_finder', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), +(34, 1, 99, 100, 1, 'com_joomlaupdate', 'com_joomlaupdate', '{}'), +(35, 1, 101, 102, 1, 'com_tags', 'com_tags', '{}'), +(36, 1, 103, 104, 1, 'com_contenthistory', 'com_contenthistory', '{}'), +(37, 1, 105, 106, 1, 'com_ajax', 'com_ajax', '{}'), +(38, 1, 107, 108, 1, 'com_postinstall', 'com_postinstall', '{}'), (39, 18, 42, 43, 2, 'com_modules.module.1', 'Main Menu', '{}'), (40, 18, 44, 45, 2, 'com_modules.module.2', 'Login', '{}'), (41, 18, 46, 47, 2, 'com_modules.module.3', 'Popular Articles', '{}'), @@ -87,9 +87,13 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (52, 18, 68, 69, 2, 'com_modules.module.79', 'Multilanguage status', '{}'), (53, 18, 70, 71, 2, 'com_modules.module.86', 'Joomla Version', '{}'), (54, 16, 36, 37, 2, 'com_menus.menu.1', 'Main Menu', '{}'), -(55, 18, 72, 73, 2, 'com_modules.module.87', 'Sample Data', '{}'); +(55, 18, 72, 73, 2, 'com_modules.module.87', 'Sample Data', '{}'), +(56, 1, 109, 110, 1, 'com_privacy', 'com_privacy', '{}'), +(57, 1, 111, 112, 1, 'com_actionlogs', 'com_actionlogs', '{}'), +(58, 18, 74, 75, 2, 'com_modules.module.88', 'Latest Actions', '{}'), +(59, 18, 76, 77, 2, 'com_modules.module.89', 'Privacy Dashboard', '{}'); -SELECT setval('#__assets_id_seq', 56, false); +SELECT setval('#__assets_id_seq', 60, false); -- -- Table structure for table `#__associations` @@ -534,6 +538,8 @@ INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "elem (32, 0, 'com_postinstall', 'component', 'com_postinstall', '', 1, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), (33, 0, 'com_fields', 'component', 'com_fields', '', 1, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), (34, 0, 'com_associations', 'component', 'com_associations', '', 1, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(35, 0, 'com_privacy', 'component', 'com_privacy', '', 1, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(36, 0, 'com_actionlogs', 'component', 'com_actionlogs', '', 1, 1, 1, 1, '', '{"ip_logging":0,"csv_delimiter":",","loggable_extensions":["com_banners","com_cache","com_categories","com_config","com_contact","com_content","com_installer","com_media","com_menus","com_messages","com_modules","com_newsfeeds","com_plugins","com_redirect","com_tags","com_templates","com_users"]}', '', '', 0, '1970-01-01 00:00:00', 0, 0), (102, 0, 'phputf8', 'library', 'phputf8', '', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), (103, 0, 'Joomla! Platform', 'library', 'joomla', '', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), (104, 0, 'IDNA Convert', 'library', 'idna_convert', '', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), @@ -580,6 +586,8 @@ INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "elem (316, 0, 'mod_tags_popular', 'module', 'mod_tags_popular', '', 0, 1, 1, 0, '', '{"maximum":"5","timeframe":"alltime","owncache":"1"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), (317, 0, 'mod_tags_similar', 'module', 'mod_tags_similar', '', 0, 1, 1, 0, '', '{"maximum":"5","matchtype":"any","owncache":"1"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), (318, 0, 'mod_sampledata', 'module', 'mod_sampledata', '', 1, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(319, 0, 'mod_latestactions', 'module', 'mod_latestactions', '', 1, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(320, 0, 'mod_privacy_dashboard', 'module', 'mod_privacy_dashboard', '', 1, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), (400, 0, 'plg_authentication_gmail', 'plugin', 'gmail', 'authentication', 0, 0, 1, 0, '', '{"applysuffix":"0","suffix":"","verifypeer":"1","user_blacklist":""}', '', '', 0, '1970-01-01 00:00:00', 1, 0), (401, 0, 'plg_authentication_joomla', 'plugin', 'joomla', 'authentication', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), (402, 0, 'plg_authentication_ldap', 'plugin', 'ldap', 'authentication', 0, 0, 1, 0, '', '{"host":"","port":"389","use_ldapV3":"0","negotiate_tls":"0","no_referrals":"0","auth_method":"bind","base_dn":"","search_string":"","users_dn":"","username":"admin","password":"bobby7","ldap_fullname":"fullName","ldap_email":"mail","ldap_uid":"uid"}', '', '', 0, '1970-01-01 00:00:00', 3, 0), @@ -659,6 +667,18 @@ INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "elem (479, 0, 'plg_sampledata_blog', 'plugin', 'blog', 'sampledata', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), (480, 0, 'plg_system_sessiongc', 'plugin', 'sessiongc', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), (481, 0, 'plg_fields_repeatable', 'plugin', 'repeatable', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(482, 0, 'plg_content_confirmconsent', 'plugin', 'confirmconsent', 'content', 0, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(483, 0, 'plg_system_actionlogs', 'plugin', 'actionlogs', 'system', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(484, 0, 'plg_actionlog_joomla', 'plugin', 'joomla', 'actionlog', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(485, 0, 'plg_system_privacyconsent', 'plugin', 'privacyconsent', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(486, 0, 'plg_system_logrotation', 'plugin', 'logrotation', 'system', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(487, 0, 'plg_privacy_user', 'plugin', 'user', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(488, 0, 'plg_quickicon_privacycheck', 'plugin', 'privacycheck', 'quickicon', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(489, 0, 'plg_user_terms', 'plugin', 'terms', 'user', 0, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(490, 0, 'plg_privacy_contact', 'plugin', 'contact', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(491, 0, 'plg_privacy_content', 'plugin', 'content', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(492, 0, 'plg_privacy_message', 'plugin', 'message', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(493, 0, 'plg_privacy_actionlogs', 'plugin', 'actionlogs', 'privacy', 0, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), (503, 0, 'beez3', 'template', 'beez3', '', 0, 1, 1, 0, '', '{"wrapperSmall":"53","wrapperLarge":"72","sitetitle":"","sitedescription":"","navposition":"center","templatecolor":"nature"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), (504, 0, 'hathor', 'template', 'hathor', '', 1, 1, 1, 0, '', '{"showSiteName":"0","colourChoice":"0","boldText":"0"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), (506, 0, 'protostar', 'template', 'protostar', '', 0, 1, 1, 0, '', '{"templateColor":"","logoFile":"","googleFont":"1","googleFontName":"Open+Sans","fluidContainer":"0"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), @@ -1486,9 +1506,11 @@ INSERT INTO "#__modules" ("id", "asset_id", "title", "note", "content", "orderin (17, 51, 'Breadcrumbs', '', '', 1, 'position-2', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_breadcrumbs', 1, 1, '{"moduleclass_sfx":"","showHome":"1","homeText":"","showComponent":"1","separator":"","cache":"0","cache_time":"0","cachemode":"itemid"}', 0, '*'), (79, 52, 'Multilanguage status', '', '', 1, 'status', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 0, 'mod_multilangstatus', 3, 1, '{"layout":"_:default","moduleclass_sfx":"","cache":"0"}', 1, '*'), (86, 53, 'Joomla Version', '', '', 1, 'footer', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_version', 3, 1, '{"format":"short","product":"1","layout":"_:default","moduleclass_sfx":"","cache":"0"}', 1, '*'), -(87, 55, 'Sample Data', '', '', 0, 'cpanel', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_sampledata', 6, 1, '{}', 1, '*'); +(87, 55, 'Sample Data', '', '', 0, 'cpanel', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_sampledata', 6, 1, '{}', 1, '*'), +(88, 58, 'Latest Actions', '', '', 0, 'cpanel', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'), +(89, 59, 'Privacy Dashboard', '', '', 0, 'cpanel', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_privacy_dashboard', 6, 1, '{}', 1, '*'); -SELECT setval('#__modules_id_seq', 88, false); +SELECT setval('#__modules_id_seq', 90, false); -- -- Table structure for table `#__modules_menu` @@ -1522,7 +1544,9 @@ INSERT INTO "#__modules_menu" ("moduleid", "menuid") VALUES (17, 0), (79, 0), (86, 0), -(87, 0); +(87, 0), +(88, 0), +(89, 0); -- -- Table structure for table `#__newsfeeds` @@ -1629,7 +1653,43 @@ INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description (700, 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME', 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME_BODY', 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME_ACTION', 'plg_system_updatenotification', 1, 'action', 'site://plugins/system/updatenotification/postinstall/updatecachetime.php', 'updatecachetime_postinstall_action', 'site://plugins/system/updatenotification/postinstall/updatecachetime.php', 'updatecachetime_postinstall_condition', '3.6.3', 1), (700, 'COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_TITLE', 'COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/joomla40checks.php', 'admin_postinstall_joomla40checks_condition', '3.7.0', 1), (700, 'TPL_HATHOR_MESSAGE_POSTINSTALL_TITLE', 'TPL_HATHOR_MESSAGE_POSTINSTALL_BODY', 'TPL_HATHOR_MESSAGE_POSTINSTALL_ACTION', 'tpl_hathor', 1, 'action', 'admin://templates/hathor/postinstall/hathormessage.php', 'hathormessage_postinstall_action', 'admin://templates/hathor/postinstall/hathormessage.php', 'hathormessage_postinstall_condition', '3.7.0', 1), -(700, 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_TITLE', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_BODY', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_ACTION', 'plg_captcha_recaptcha', 1, 'action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_condition', '3.8.6', 1); +(700, 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_TITLE', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_BODY', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_ACTION', 'plg_captcha_recaptcha', 1, 'action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_condition', '3.8.6', 1), +(700, 'COM_ACTIONLOGS_POSTINSTALL_TITLE', 'COM_ACTIONLOGS_POSTINSTALL_BODY', '', 'com_actionlogs', 1, 'message', '', '', '', '', '3.9.0', 1), +(700, 'COM_PRIVACY_POSTINSTALL_TITLE', 'COM_PRIVACY_POSTINSTALL_BODY', '', 'com_privacy', 1, 'message', '', '', '', '', '3.9.0', 1); + +-- +-- Table structure for table `#__privacy_requests` +-- + +CREATE TABLE "#__privacy_requests" ( + "id" serial NOT NULL, + "email" varchar(100) DEFAULT '' NOT NULL, + "requested_at" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "status" smallint DEFAULT 0 NOT NULL, + "request_type" varchar(25) DEFAULT '' NOT NULL, + "confirm_token" varchar(100) DEFAULT '' NOT NULL, + "confirm_token_created_at" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "checked_out" integer DEFAULT 0 NOT NULL, + "checked_out_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "#__privacy_requests_idx_checked_out" ON "#__privacy_requests" ("checked_out"); + +-- +-- Table structure for table `#__privacy_consents` +-- + +CREATE TABLE "#__privacy_consents" ( + "id" serial NOT NULL, + "user_id" bigint DEFAULT 0 NOT NULL, + "created" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "subjext" varchar(255) DEFAULT '' NOT NULL, + "body" text NOT NULL, + "remind" smallint DEFAULT 0 NOT NULL, + "token" varchar(100) DEFAULT '' NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "#__privacy_consents_idx_user_id" ON "#__privacy_consents" ("user_id"); -- -- Table structure for table `#__redirect_links` @@ -2067,6 +2127,95 @@ CREATE TABLE "#__user_usergroup_map" ( COMMENT ON COLUMN "#__user_usergroup_map"."user_id" IS 'Foreign Key to #__users.id'; COMMENT ON COLUMN "#__user_usergroup_map"."group_id" IS 'Foreign Key to #__usergroups.id'; +-- +-- Table: #__action_logs +-- +CREATE TABLE "#__action_logs" ( + "id" serial NOT NULL, + "message_language_key" varchar(255) NOT NULL DEFAULT '', + "message" text NOT NULL DEFAULT '', + "log_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "extension" varchar(50) NOT NULL DEFAULT '', + "user_id" integer DEFAULT 0 NOT NULL, + "item_id" integer DEFAULT 0 NOT NULL, + "ip_address" varchar(40) NOT NULL DEFAULT '0.0.0.0', + PRIMARY KEY ("id") +); + +-- Table: #__action_logs_extensions +-- +CREATE TABLE "#__action_logs_extensions" ( + "id" serial NOT NULL, + "extension" varchar(50) NOT NULL DEFAULT '', + PRIMARY KEY ("id") +); + +-- +-- Dumping data for table '#__action_logs_extensions' +-- +INSERT INTO "#__action_logs_extensions" ("id", "extension") VALUES +(1, 'com_banners'), +(2, 'com_cache'), +(3, 'com_categories'), +(4, 'com_config'), +(5, 'com_contact'), +(6, 'com_content'), +(7, 'com_installer'), +(8, 'com_media'), +(9, 'com_menus'), +(10, 'com_messages'), +(11, 'com_modules'), +(12, 'com_newsfeeds'), +(13, 'com_plugins'), +(14, 'com_redirect'), +(15, 'com_tags'), +(16, 'com_templates'), +(17, 'com_users'); + +SELECT setval('#__action_logs_extensions_id_seq', 18, false); +-- -------------------------------------------------------- + +-- +-- Table: #__action_log_config +-- +CREATE TABLE "#__action_log_config" ( + "id" serial NOT NULL, + "type_title" varchar(255) NOT NULL DEFAULT '', + "type_alias" varchar(255) NOT NULL DEFAULT '', + "id_holder" varchar(255) NULL, + "title_holder" varchar(255) NULL, + "table_name" varchar(255) NULL, + "text_prefix" varchar(255) NULL, + PRIMARY KEY ("id") +); + +-- +-- Dumping data for table #__action_log_config +-- +INSERT INTO "#__action_log_config" ("id", "type_title", "type_alias", "id_holder", "title_holder", "table_name", "text_prefix") VALUES +(1, 'article', 'com_content.article', 'id' ,'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA'), +(2, 'article', 'com_content.form', 'id', 'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA'), +(3, 'banner', 'com_banners.banner', 'id' ,'name' , '#__banners', 'PLG_ACTIONLOG_JOOMLA'), +(4, 'user_note', 'com_users.note', 'id', 'subject' ,'#__user_notes', 'PLG_ACTIONLOG_JOOMLA'), +(5, 'media', 'com_media.file', '' , 'name' , '', 'PLG_ACTIONLOG_JOOMLA'), +(6, 'category', 'com_categories.category', 'id' , 'title' , '#__categories', 'PLG_ACTIONLOG_JOOMLA'), +(7, 'menu', 'com_menus.menu', 'id' ,'title' , '#__menu_types', 'PLG_ACTIONLOG_JOOMLA'), +(8, 'menu_item', 'com_menus.item', 'id' , 'title' , '#__menu', 'PLG_ACTIONLOG_JOOMLA'), +(9, 'newsfeed', 'com_newsfeeds.newsfeed', 'id' ,'name' , '#__newsfeeds', 'PLG_ACTIONLOG_JOOMLA'), +(10, 'link', 'com_redirect.link', 'id', 'old_url' , '#__redirect_links', 'PLG_ACTIONLOG_JOOMLA'), +(11, 'tag', 'com_tags.tag', 'id', 'title' , '#__tags', 'PLG_ACTIONLOG_JOOMLA'), +(12, 'style', 'com_templates.style', 'id' , 'title' , '#__template_styles', 'PLG_ACTIONLOG_JOOMLA'), +(13, 'plugin', 'com_plugins.plugin', 'extension_id' , 'name' , '#__extensions', 'PLG_ACTIONLOG_JOOMLA'), +(14, 'component_config', 'com_config.component', 'extension_id' , 'name', '', 'PLG_ACTIONLOG_JOOMLA'), +(15, 'contact', 'com_contact.contact', 'id', 'name', '#__contact_details', 'PLG_ACTIONLOG_JOOMLA'), +(16, 'module', 'com_modules.module', 'id' ,'title', '#__modules', 'PLG_ACTIONLOG_JOOMLA'), +(17, 'access_level', 'com_users.level', 'id' , 'title', '#__viewlevels', 'PLG_ACTIONLOG_JOOMLA'), +(18, 'banner_client', 'com_banners.client', 'id', 'name', '#__banner_clients', 'PLG_ACTIONLOG_JOOMLA'), +(19, 'application_config', 'com_config.application', '', 'name', '', 'PLG_ACTIONLOG_JOOMLA'); + + +SELECT setval('#__action_log_config_id_seq', 18, false); + -- -- Table structure for table `#__viewlevels` -- diff --git a/installation/sql/postgresql/sample_blog.sql b/installation/sql/postgresql/sample_blog.sql index c74fd4c27c851..5452f37b43f43 100644 --- a/installation/sql/postgresql/sample_blog.sql +++ b/installation/sql/postgresql/sample_blog.sql @@ -14,7 +14,7 @@ TRUNCATE "#__modules_menu" RESTART IDENTITY; -- INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "title", "rules") VALUES -(1, 0, 0, 87, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 0, 91, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 1, 2, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 3, 6, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 7, 8, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -57,7 +57,9 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (44, 1, 79, 80, 1, 'com_tags', 'com_tags', '{"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (45, 1, 81, 82, 1, 'com_contenthistory', 'com_contenthistory', '{}'), (46, 1, 83, 84, 1, 'com_ajax', 'com_ajax', '{}'), -(47, 1, 85, 86, 1, 'com_postinstall', 'com_postinstall', '{}'); +(47, 1, 85, 86, 1, 'com_postinstall', 'com_postinstall', '{}'), +(48, 1, 87, 88, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(49, 1, 89, 90, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); SELECT setval('#__assets_id_seq', max(id)) FROM "#__assets"; @@ -171,7 +173,8 @@ INSERT INTO "#__modules" ("id", "title", "note", "content", "ordering", "positio (89, 'Popular Tags', '', '', 1, 'position-7', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_tags_popular', 1, 1, '{"maximum":"8","timeframe":"alltime","order_value":"count","order_direction":"1","display_count":0,"no_results_text":"0","minsize":1,"maxsize":2,"layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (90, 'Similar Items', '', '', 0, '', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_tags_similar', 1, 1, '{"maximum":"5","matchtype":"any","layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (91, 'Site Information', '', '', 4, 'cpanel', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_stats_admin', 6, 1, '{"serverinfo":"1","siteinfo":"1","counter":"0","increase":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"6","header_tag":"h3","header_class":"","style":"0"}', 1, '*'), -(92, 'Release News', '', '', 1, 'postinstall', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_feed', 1, 1, '{"rssurl":"https:\\/\\/www.joomla.org\\/announcements\\/release-news.feed","rssrtl":"0","rsstitle":"1","rssdesc":"1","rssimage":"1","rssitems":"3","rssitemdesc":"1","word_count":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 1, '*'); +(92, 'Release News', '', '', 1, 'postinstall', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_feed', 1, 1, '{"rssurl":"https:\\/\\/www.joomla.org\\/announcements\\/release-news.feed","rssrtl":"0","rsstitle":"1","rssdesc":"1","rssimage":"1","rssitems":"3","rssitemdesc":"1","word_count":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 1, '*'), +(93, 'Latest Actions', '', '', 0, 'cpanel', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); SELECT setval('#__modules_id_seq', max(id)) FROM "#__modules"; @@ -207,4 +210,5 @@ INSERT INTO "#__modules_menu" ("moduleid", "menuid") VALUES (89, 0), (90, 0), (91, 0), -(92, 0); +(92, 0), +(93, 0); diff --git a/installation/sql/postgresql/sample_brochure.sql b/installation/sql/postgresql/sample_brochure.sql index bb8058d0b9b51..195b6d629010b 100644 --- a/installation/sql/postgresql/sample_brochure.sql +++ b/installation/sql/postgresql/sample_brochure.sql @@ -15,7 +15,7 @@ TRUNCATE "#__template_styles" RESTART IDENTITY; -- INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "title", "rules") VALUES -(1, 0, 0, 91, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 0, 95, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 1, 2, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 3, 6, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 7, 8, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -60,7 +60,9 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (50, 18, 52, 53, 2, 'com_modules.module.4', 'Recently Added Articles', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (51, 18, 54, 55, 2, 'com_modules.module.89', 'Site Information', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (52, 18, 56, 57, 2, 'com_modules.module.88', 'Image', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), -(53, 18, 58, 59, 2, 'com_modules.module.90', 'Release News', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'); +(53, 18, 58, 59, 2, 'com_modules.module.90', 'Release News', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), +(54, 1, 91, 92, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(55, 1, 93, 94, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); -- -- Dumping data for table `#__categories` @@ -161,7 +163,8 @@ INSERT INTO "#__modules" ("id", "asset_id", "title", "note", "content", "orderin (87, 0, 'Footer', '', '', 1, 'footer', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_footer', 1, 1, '{"layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (88, 52, 'Image', '', '

', 1, 'position-3', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_custom', 1, 0, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (89, 51, 'Site Information', '', '', 4, 'cpanel', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_stats_admin', 6, 1, '{"serverinfo":"1","siteinfo":"1","counter":"1","increase":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"6","header_tag":"h3","header_class":"","style":"0"}', 1, '*'), -(90, 53, 'Release News', '', '', 0, 'postinstall', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_feed', 1, 1, '{"rssurl":"https:\\/\\/www.joomla.org\\/announcements\\/release-news.feed","rssrtl":"0","rsstitle":"1","rssdesc":"1","rssimage":"1","rssitems":"3","rssitemdesc":"1","word_count":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 1, '*'); +(90, 53, 'Release News', '', '', 0, 'postinstall', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_feed', 1, 1, '{"rssurl":"https:\\/\\/www.joomla.org\\/announcements\\/release-news.feed","rssrtl":"0","rsstitle":"1","rssdesc":"1","rssimage":"1","rssitems":"3","rssitemdesc":"1","word_count":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 1, '*'), +(91, 54, 'Latest Actions', '', '', 0, 'cpanel', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); -- -- Dumping data for table `#__modules_menu` @@ -188,7 +191,8 @@ INSERT INTO "#__modules_menu" ("moduleid", "menuid") VALUES (83, 0), (85, 0), (86, 0), -(88, 0); +(88, 0), +(91,54); -- -- Dumping data for table `#__template_styles` diff --git a/installation/sql/postgresql/sample_data.sql b/installation/sql/postgresql/sample_data.sql index 750b2c982e8b5..692d79354e8e3 100644 --- a/installation/sql/postgresql/sample_data.sql +++ b/installation/sql/postgresql/sample_data.sql @@ -14,7 +14,7 @@ TRUNCATE "#__tags" RESTART IDENTITY; -- INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "title", "rules") VALUES -(1, 0, 0, 119, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 0, 123, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 1, 2, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 3, 6, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 7, 8, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -73,7 +73,9 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (59, 18, 82, 83, 2, 'com_modules.module.92', 'Image Module', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (60, 18, 84, 85, 2, 'com_modules.module.93', 'Search', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (61, 27, 19, 20, 3, 'com_content.article.1', 'Getting Started', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), -(62, 1, 117, 118, 1, '#__ucm_content.1', '#__ucm_content.1', '{}'); +(62, 1, 117, 118, 1, '#__ucm_content.1', '#__ucm_content.1', '{}'), +(63, 1, 119, 120, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(64, 1, 121, 122, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); SELECT setval('#__assets_id_seq', max(id)) FROM "#__assets"; @@ -162,7 +164,8 @@ INSERT INTO "#__modules" ("id", "asset_id", "title", "note", "content", "orderin (90, 57, 'Latest Articles', '', '', 1, 'position-7', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_articles_latest', 1, 1, '{"catid":[""],"count":"5","show_featured":"","ordering":"c_dsc","user_id":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (91, 58, 'User Menu', '', '', 3, 'position-7', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_menu', 1, 1, '{"menutype":"usermenu","base":"","startLevel":"1","endLevel":"0","showAllChildren":"1","tag_id":"","class_sfx":"","window_open":"","layout":"_:default","moduleclass_sfx":"_menu","cache":"1","cache_time":"900","cachemode":"itemid","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (92, 59, 'Image Module', '', '

Blue Flower

', 0, 'position-3', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_custom', 1, 0, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), -(93, 60, 'Search', '', '', 0, 'position-0', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_search', 1, 1, '{"label":"","width":"20","text":"","button":"0","button_pos":"right","imagebutton":"1","button_text":"","opensearch":"1","opensearch_title":"","set_itemid":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"itemid","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'); +(93, 60, 'Search', '', '', 0, 'position-0', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_search', 1, 1, '{"label":"","width":"20","text":"","button":"0","button_pos":"right","imagebutton":"1","button_text":"","opensearch":"1","opensearch_title":"","set_itemid":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"itemid","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), +(94, 61, 'Latest Actions', '', '', 0, 'cpanel', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); SELECT setval('#__menu_types_id_seq', max(id)) FROM "#__menu_types"; @@ -194,7 +197,8 @@ INSERT INTO "#__modules_menu" ("moduleid", "menuid") VALUES (90, 0), (91, 0), (92, 0), -(93, 0); +(93, 0), +(94, 0); SELECT setval('#__modules_id_seq', max(id)) FROM "#__modules"; diff --git a/installation/sql/postgresql/sample_learn.sql b/installation/sql/postgresql/sample_learn.sql index 4e600e3afa561..8a8533beb7bdf 100644 --- a/installation/sql/postgresql/sample_learn.sql +++ b/installation/sql/postgresql/sample_learn.sql @@ -17,7 +17,7 @@ TRUNCATE "#__viewlevels" RESTART IDENTITY; -- INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "title", "rules") VALUES -(1, 0, 1, 430, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 1, 434, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 2, 3, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 4, 11, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 12, 13, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -176,7 +176,9 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (175, 1, 422, 423, 1, 'com_tags', 'com_tags', '{"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (176, 1, 424, 425, 1, 'com_contenthistory', 'com_contenthistory', '{}'), (177, 1, 426, 427, 1, 'com_ajax', 'com_ajax', '{}'), -(178, 1, 428, 429, 1, 'com_postinstall', 'com_postinstall', '{}'); +(178, 1, 428, 429, 1, 'com_postinstall', 'com_postinstall', '{}'), +(179, 1, 430, 431, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(180, 1, 432, 433, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); SELECT setval('#__assets_id_seq', max(id)) FROM "#__assets"; @@ -589,7 +591,8 @@ INSERT INTO "#__modules" ("id", "title", "note", "content", "ordering", "positio (87, 'Fruit Shop', '', '', 1, 'position-7', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_menu', 1, 1, '{"menutype":"fruitshop","startLevel":"1","endLevel":"0","showAllChildren":"1","tag_id":"","class_sfx":"","window_open":"","layout":"_:default","moduleclass_sfx":"","cache":"0","cache_time":"900","cachemode":"itemid","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (88, 'Image Module', '', '

', 1, 'position-3', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_custom', 1, 0, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (89, 'Custom', '', '

In this module you can put whatever text or other content you would like.

', 1, '', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_custom', 1, 1, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), -(90, 'Parks Image Module', '', '

', 1, 'position-3', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_custom', 1, 1, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'); +(90, 'Parks Image Module', '', '

', 1, 'position-3', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_custom', 1, 1, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), +(91, 'Latest Actions', '', '', 0, 'cpanel', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); SELECT setval('#__modules_id_seq', max(id)) FROM "#__modules"; @@ -788,7 +791,8 @@ INSERT INTO "#__modules_menu" ("moduleid", "menuid") VALUES (90, 244), (90, 296), (90, 399), -(90, 400); +(90, 400), +(91, 0); -- -- Dumping data for table `#__newsfeeds` diff --git a/installation/sql/postgresql/sample_testing.sql b/installation/sql/postgresql/sample_testing.sql index 9e5f1e03443b4..cbaf424f1c306 100644 --- a/installation/sql/postgresql/sample_testing.sql +++ b/installation/sql/postgresql/sample_testing.sql @@ -17,7 +17,7 @@ TRUNCATE "#__viewlevels" RESTART IDENTITY; -- INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "title", "rules") VALUES -(1, 0, 1, 437, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 1, 441, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 2, 3, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 4, 11, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 12, 13, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -180,7 +180,9 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (177, 1, 433, 434, 1, 'com_postinstall', 'com_postinstall', '{}'), (178, 93, 144, 145, 7, 'com_content.article.71', 'Similar Tags', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (179, 1, 435, 436, 1, '#__ucm_content.3', '#__ucm_content.3', '{}'), -(180, 93, 146, 147, 7, 'com_content.article.72', 'Popular Tags', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'); +(180, 93, 146, 147, 7, 'com_content.article.72', 'Popular Tags', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), +(181, 1, 437, 438, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(182, 1, 439, 440, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); SELECT setval('#__assets_id_seq', max(id)) FROM "#__assets"; @@ -624,7 +626,8 @@ INSERT INTO "#__modules" ("id", "title", "note", "content", "ordering", "positio (93, 'Popular Tags', '', '', 1, '', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_tags_popular', 1, 1, '{"maximum":"5","timeframe":"alltime","order_value":"count","order_direction":"1","display_count":0,"no_results_text":"0","minsize":1,"maxsize":2,"layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (94, 'Similar Tags', '', '', 1, '', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_tags_similar', 1, 1, '{"maximum":"5","matchtype":"any","layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (95, 'Syndicate Feeds', '', '', 1, 'position-8', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_syndicate', 1, 1, '{"display_text":1,"text":"Feed Entries","format":"rss","layout":"_:default","moduleclass_sfx":"","cache":"0","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), -(97, 'Similar Tags 2', '', '', 1, 'position-8', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_tags_similar', 1, 1, '{"maximum":"5","matchtype":"any","layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'); +(97, 'Similar Tags 2', '', '', 1, 'position-8', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_tags_similar', 1, 1, '{"maximum":"5","matchtype":"any","layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), +(98, 'Latest Actions', '', '', 0, 'cpanel', 0, '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); SELECT setval('#__modules_id_seq', max(id)) FROM "#__modules"; @@ -812,7 +815,8 @@ INSERT INTO "#__modules_menu" ("moduleid", "menuid") VALUES (93, 0), (94, 0), (95, 0), -(97, 0); +(97, 0), +(98, 0); -- -- Dumping data for table `#__newsfeeds` diff --git a/installation/sql/sqlazure/joomla.sql b/installation/sql/sqlazure/joomla.sql index 7534256e54889..89ed11b34daa6 100644 --- a/installation/sql/sqlazure/joomla.sql +++ b/installation/sql/sqlazure/joomla.sql @@ -43,7 +43,7 @@ CREATE NONCLUSTERED INDEX "idx_parent_id" ON "#__assets" SET IDENTITY_INSERT "#__assets" ON; INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "title", "rules") VALUES -(1, 0, 0, 105, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 0, 113, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 1, 2, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 3, 6, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 7, 8, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -60,25 +60,25 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (15, 1, 33, 34, 1, 'com_media', 'com_media', '{"core.admin":{"7":1},"core.manage":{"6":1},"core.create":{"3":1},"core.delete":{"5":1}}'), (16, 1, 35, 38, 1, 'com_menus', 'com_menus', '{"core.admin":{"7":1}}'), (17, 1, 39, 40, 1, 'com_messages', 'com_messages', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), -(18, 1, 41, 74, 1, 'com_modules', 'com_modules', '{"core.admin":{"7":1}}'), -(19, 1, 75, 78, 1, 'com_newsfeeds', 'com_newsfeeds', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), -(20, 1, 79, 80, 1, 'com_plugins', 'com_plugins', '{"core.admin":{"7":1}}'), -(21, 1, 81, 82, 1, 'com_redirect', 'com_redirect', '{"core.admin":{"7":1}}'), -(22, 1, 83, 84, 1, 'com_search', 'com_search', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), -(23, 1, 85, 86, 1, 'com_templates', 'com_templates', '{"core.admin":{"7":1}}'), -(24, 1, 87, 90, 1, 'com_users', 'com_users', '{"core.admin":{"7":1}}'), -(26, 1, 91, 92, 1, 'com_wrapper', 'com_wrapper', '{}'), +(18, 1, 41, 78, 1, 'com_modules', 'com_modules', '{"core.admin":{"7":1}}'), +(19, 1, 79, 82, 1, 'com_newsfeeds', 'com_newsfeeds', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), +(20, 1, 83, 84, 1, 'com_plugins', 'com_plugins', '{"core.admin":{"7":1}}'), +(21, 1, 85, 86, 1, 'com_redirect', 'com_redirect', '{"core.admin":{"7":1}}'), +(22, 1, 87, 88, 1, 'com_search', 'com_search', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), +(23, 1, 89, 90, 1, 'com_templates', 'com_templates', '{"core.admin":{"7":1}}'), +(24, 1, 91, 94, 1, 'com_users', 'com_users', '{"core.admin":{"7":1}}'), +(26, 1, 95, 96, 1, 'com_wrapper', 'com_wrapper', '{}'), (27, 8, 18, 19, 2, 'com_content.category.2', 'Uncategorised', '{}'), (28, 3, 4, 5, 2, 'com_banners.category.3', 'Uncategorised', '{}'), (29, 7, 14, 15, 2, 'com_contact.category.4', 'Uncategorised', '{}'), -(30, 19, 76, 77, 2, 'com_newsfeeds.category.5', 'Uncategorised', '{}'), -(32, 24, 88, 89, 2, 'com_users.category.7', 'Uncategorised', '{}'), -(33, 1, 93, 94, 1, 'com_finder', 'com_finder', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), -(34, 1, 95, 96, 1, 'com_joomlaupdate', 'com_joomlaupdate', '{}'), -(35, 1, 97, 98, 1, 'com_tags', 'com_tags', '{}'), -(36, 1, 99, 100, 1, 'com_contenthistory', 'com_contenthistory', '{}'), -(37, 1, 101, 102, 1, 'com_ajax', 'com_ajax', '{}'), -(38, 1, 103, 104, 1, 'com_postinstall', 'com_postinstall', '{}'), +(30, 19, 80, 81, 2, 'com_newsfeeds.category.5', 'Uncategorised', '{}'), +(32, 24, 92, 93, 2, 'com_users.category.7', 'Uncategorised', '{}'), +(33, 1, 97, 98, 1, 'com_finder', 'com_finder', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), +(34, 1, 99, 100, 1, 'com_joomlaupdate', 'com_joomlaupdate', '{}'), +(35, 1, 101, 102, 1, 'com_tags', 'com_tags', '{}'), +(36, 1, 103, 104, 1, 'com_contenthistory', 'com_contenthistory', '{}'), +(37, 1, 105, 106, 1, 'com_ajax', 'com_ajax', '{}'), +(38, 1, 107, 108, 1, 'com_postinstall', 'com_postinstall', '{}'), (39, 18, 42, 43, 2, 'com_modules.module.1', 'Main Menu', '{}'), (40, 18, 44, 45, 2, 'com_modules.module.2', 'Login', '{}'), (41, 18, 46, 47, 2, 'com_modules.module.3', 'Popular Articles', '{}'), @@ -95,7 +95,11 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (52, 18, 68, 69, 2, 'com_modules.module.79', 'Multilanguage status', '{}'), (53, 18, 70, 71, 2, 'com_modules.module.86', 'Joomla Version', '{}'), (54, 16, 36, 37, 2, 'com_menus.menu.1', 'Main Menu', '{}'), -(55, 18, 72, 73, 2, 'com_modules.module.87', 'Sample Data', '{}'); +(55, 18, 72, 73, 2, 'com_modules.module.87', 'Sample Data', '{}'), +(56, 1, 109, 110, 1, 'com_privacy', 'com_privacy', '{}'), +(57, 1, 111, 112, 1, 'com_actionlogs', 'com_actionlogs', '{}'), +(58, 18, 74, 75, 2, 'com_modules.module.88', 'Latest Actions', '{}'); +(59, 18, 76, 77, 2, 'com_modules.module.89', 'Privacy Dashboard', '{}'); SET IDENTITY_INSERT "#__assets" OFF; @@ -749,6 +753,8 @@ INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "elem (32, 0, 'com_postinstall', 'component', 'com_postinstall', '', 1, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), (33, 0, 'com_fields', 'component', 'com_fields', '', 1, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), (34, 0, 'com_associations', 'component', 'com_associations', '', 1, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(35, 0, 'com_privacy', 'component', 'com_privacy', '', 1, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(36, 0, 'com_actionlogs', 'component', 'com_actionlogs', '', 1, 1, 1, 1, '', '{"ip_logging":0,"csv_delimiter":",","loggable_extensions":["com_banners","com_cache","com_categories","com_config","com_contact","com_content","com_installer","com_media","com_menus","com_messages","com_modules","com_newsfeeds","com_plugins","com_redirect","com_tags","com_templates","com_users"]}', '', '', 0, '1900-01-01 00:00:00', 0, 0), (102, 0, 'phputf8', 'library', 'phputf8', '', 0, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), (103, 0, 'Joomla! Platform', 'library', 'joomla', '', 0, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), (104, 0, 'IDNA Convert', 'library', 'idna_convert', '', 0, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), @@ -795,6 +801,8 @@ INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "elem (316, 0, 'mod_tags_popular', 'module', 'mod_tags_popular', '', 0, 1, 1, 0, '', '{"maximum":"5","timeframe":"alltime","owncache":"1"}', '', '', 0, '1900-01-01 00:00:00', 0, 0), (317, 0, 'mod_tags_similar', 'module', 'mod_tags_similar', '', 0, 1, 1, 0, '', '{"maximum":"5","matchtype":"any","owncache":"1"}', '', '', 0, '1900-01-01 00:00:00', 0, 0), (318, 0, 'mod_sampledata', 'module', 'mod_sampledata', '', 1, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(319, 0, 'mod_latestactions', 'module', 'mod_latestactions', '', 1, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(320, 0, 'mod_privacy_dashboard', 'module', 'mod_privacy_dashboard', '', 1, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), (400, 0, 'plg_authentication_gmail', 'plugin', 'gmail', 'authentication', 0, 0, 1, 0, '', '{"applysuffix":"0","suffix":"","verifypeer":"1","user_blacklist":""}', '', '', 0, '1900-01-01 00:00:00', 1, 0), (401, 0, 'plg_authentication_joomla', 'plugin', 'joomla', 'authentication', 0, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), (402, 0, 'plg_authentication_ldap', 'plugin', 'ldap', 'authentication', 0, 0, 1, 0, '', '{"host":"","port":"389","use_ldapV3":"0","negotiate_tls":"0","no_referrals":"0","auth_method":"bind","base_dn":"","search_string":"","users_dn":"","username":"admin","password":"bobby7","ldap_fullname":"fullName","ldap_email":"mail","ldap_uid":"uid"}', '', '', 0, '1900-01-01 00:00:00', 3, 0), @@ -874,6 +882,18 @@ INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "elem (479, 0, 'plg_sampledata_blog', 'plugin', 'blog', 'sampledata', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), (480, 0, 'plg_system_sessiongc', 'plugin', 'sessiongc', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), (481, 0, 'plg_fields_repeatable', 'plugin', 'repeatable', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(482, 0, 'plg_content_confirmconsent', 'plugin', 'confirmconsent', 'content', 0, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(483, 0, 'plg_system_actionlogs', 'plugin', 'actionlogs', 'system', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(484, 0, 'plg_actionlog_joomla', 'plugin', 'joomla', 'actionlog', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(485, 0, 'plg_system_privacyconsent', 'plugin', 'privacyconsent', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(486, 0, 'plg_system_logrotation', 'plugin', 'logrotation', 'system', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(487, 0, 'plg_privacy_user', 'plugin', 'user', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(488, 0, 'plg_quickicon_privacycheck', 'plugin', 'privacycheck', 'quickicon', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(489, 0, 'plg_user_terms', 'plugin', 'terms', 'user', 0, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(490, 0, 'plg_privacy_contact', 'plugin', 'user', 'contact', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(491, 0, 'plg_privacy_content', 'plugin', 'user', 'content', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(492, 0, 'plg_privacy_message', 'plugin', 'user', 'message', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(493, 0, 'plg_privacy_actionlogs', 'plugin', 'actionlogs', 'privacy', 0, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), (503, 0, 'beez3', 'template', 'beez3', '', 0, 1, 1, 0, '', '{"wrapperSmall":"53","wrapperLarge":"72","sitetitle":"","sitedescription":"","navposition":"center","templatecolor":"nature"}', '', '', 0, '1900-01-01 00:00:00', 0, 0), (504, 0, 'hathor', 'template', 'hathor', '', 1, 1, 1, 0, '', '{"showSiteName":"0","colourChoice":"0","boldText":"0"}', '', '', 0, '1900-01-01 00:00:00', 0, 0), (506, 0, 'protostar', 'template', 'protostar', '', 0, 1, 1, 0, '', '{"templateColor":"","logoFile":"","googleFont":"1","googleFontName":"Open+Sans","fluidContainer":"0"}', '', '', 0, '1900-01-01 00:00:00', 0, 0), @@ -2175,7 +2195,9 @@ INSERT INTO "#__modules" ("id", "asset_id", "title", "note", "content", "orderin (17, 51, 'Breadcrumbs', '', '', 1, 'position-2', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_breadcrumbs', 1, 1, '{"moduleclass_sfx":"","showHome":"1","homeText":"","showComponent":"1","separator":"","cache":"0","cache_time":"0","cachemode":"itemid"}', 0, '*'), (79, 52, 'Multilanguage status', '', '', 1, 'status', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 0, 'mod_multilangstatus', 3, 1, '{"layout":"_:default","moduleclass_sfx":"","cache":"0"}', 1, '*'), (86, 53, 'Joomla Version', '', '', 1, 'footer', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_version', 3, 1, '{"format":"short","product":"1","layout":"_:default","moduleclass_sfx":"","cache":"0"}', 1, '*'), -(87, 55, 'Sample Data', '', '', 0, 'cpanel', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_sampledata', 6, 1, '{}', 1, '*'); +(87, 55, 'Sample Data', '', '', 0, 'cpanel', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_sampledata', 6, 1, '{}', 1, '*'), +(88, 58, 'Latest Actions', '', '', 0, 'cpanel', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'), +(89, 59, 'Privacy Dashboard', '', '', 0, 'cpanel', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_privacy_dashboard', 6, 1, '{}', 1, '*'); SET IDENTITY_INSERT "#__modules" OFF; @@ -2215,7 +2237,9 @@ INSERT INTO "#__modules_menu" ("moduleid", "menuid") VALUES (17, 0), (79, 0), (86, 0), -(87, 0); +(87, 0), +(88, 0), +(89, 0); -- -- Table structure for table `#__newsfeeds` @@ -2344,7 +2368,53 @@ INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description (700, 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME', 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME_BODY', 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME_ACTION', 'plg_system_updatenotification', 1, 'action', 'site://plugins/system/updatenotification/postinstall/updatecachetime.php', 'updatecachetime_postinstall_action', 'site://plugins/system/updatenotification/postinstall/updatecachetime.php', 'updatecachetime_postinstall_condition', '3.6.3', 1), (700, 'COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_TITLE', 'COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/joomla40checks.php', 'admin_postinstall_joomla40checks_condition', '3.7.0', 1), (700, 'TPL_HATHOR_MESSAGE_POSTINSTALL_TITLE', 'TPL_HATHOR_MESSAGE_POSTINSTALL_BODY', 'TPL_HATHOR_MESSAGE_POSTINSTALL_ACTION', 'tpl_hathor', 1, 'action', 'admin://templates/hathor/postinstall/hathormessage.php', 'hathormessage_postinstall_action', 'admin://templates/hathor/postinstall/hathormessage.php', 'hathormessage_postinstall_condition', '3.7.0', 1), -(700, 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_TITLE', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_BODY', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_ACTION', 'plg_captcha_recaptcha', 1, 'action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_condition', '3.8.6', 1); +(700, 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_TITLE', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_BODY', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_ACTION', 'plg_captcha_recaptcha', 1, 'action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_condition', '3.8.6', 1), +(700, 'COM_ACTIONLOGS_POSTINSTALL_TITLE', 'COM_ACTIONLOGS_POSTINSTALL_BODY', '', 'com_actionlogs', 1, 'message', '', '', '', '', '3.9.0', 1), +(700, 'COM_PRIVACY_POSTINSTALL_TITLE', 'COM_PRIVACY_POSTINSTALL_BODY', '', 'com_privacy', 1, 'message', '', '', '', '', '3.9.0', 1); + +-- +-- Table structure for table `#__privacy_requests` +-- + +CREATE TABLE "#__privacy_requests" ( + "id" int IDENTITY(1,1) NOT NULL, + "email" nvarchar(100) NOT NULL DEFAULT '', + "requested_at" datetime2(0) NOT NULL DEFAULT '1900-01-01 00:00:00', + "status" smallint NOT NULL, + "request_type" nvarchar(25) NOT NULL DEFAULT '', + "confirm_token" nvarchar(100) NOT NULL DEFAULT '', + "confirm_token_created_at" datetime2(0) NOT NULL DEFAULT '1900-01-01 00:00:00', + "checked_out" bigint NOT NULL DEFAULT 0, + "checked_out_time" datetime2(0) NOT NULL DEFAULT '1900-01-01 00:00:00', +CONSTRAINT "PK_#__privacy_requests_id" PRIMARY KEY CLUSTERED( + "id" ASC) +WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON +) ON [PRIMARY]) ON [PRIMARY]; + +CREATE NONCLUSTERED INDEX "idx_checkout" ON "#__privacy_requests" ( + "checked_out" ASC) +WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); + +-- +-- Table structure for table `#__privacy_consents` +-- + +CREATE TABLE "#__privacy_consents" ( + "id" int IDENTITY(1,1) NOT NULL, + "user_id" bigint NOT NULL DEFAULT 0, + "created" datetime2(0) NOT NULL DEFAULT '1900-01-01 00:00:00', + "subject" nvarchar(255) NOT NULL DEFAULT '', + "body" nvarchar(max) NOT NULL, + "remind" smallint NOT NULL, + "token" nvarchar(100) NOT NULL DEFAULT '', +CONSTRAINT "PK_#__privacy_consents_id" PRIMARY KEY CLUSTERED( + "id" ASC) +WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON +) ON [PRIMARY]) ON [PRIMARY]; + +CREATE NONCLUSTERED INDEX "idx_user_id" ON "#__privacy_consents" ( + "user_id" ASC) +WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); -- -- Table structure for table `#__redirect_links` @@ -2995,6 +3065,132 @@ CREATE TABLE "#__user_usergroup_map" ( )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]; +/****** Object: Table [#__action_logs] ******/ +SET QUOTED_IDENTIFIER ON; + +CREATE TABLE [#__action_logs]( + [id] [int] IDENTITY(1,1) NOT NULL, + [message_language_key] [nvarchar](255) NOT NULL DEFAULT '', + [message] [nvarchar](max) NOT NULL DEFAULT '', + [log_date] [datetime] NOT NULL DEFAULT '1900-01-01 00:00:00', + [extension] [nvarchar](255) NOT NULL DEFAULT '', + [user_id] [bigint] NOT NULL DEFAULT 0, + [item_id] [bigint] NOT NULL DEFAULT 0, + [ip_address] [nvarchar](40) NOT NULL DEFAULT '0.0.0.0', + CONSTRAINT [PK_#__action_logs_id] PRIMARY KEY CLUSTERED + ( + [id] ASC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + ) ON [PRIMARY]; + +/****** Object: Table [#__action_logs_extensions] ******/ +SET QUOTED_IDENTIFIER ON; + +CREATE TABLE [#__action_logs_extensions]( + [id] [int] IDENTITY(1,1) NOT NULL, + [extension] [nvarchar](255) NOT NULL DEFAULT '', + CONSTRAINT [PK_#__action_logs_extensions_id] PRIMARY KEY CLUSTERED + ( + [id] ASC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + ) ON [PRIMARY]; +SET IDENTITY_INSERT [#__action_logs_extensions] ON; +INSERT INTO [#__action_logs_extensions] ([id], [extension]) +SELECT 1, 'com_banners' +UNION ALL +SELECT 2, 'com_cache' +UNION ALL +SELECT 3, 'com_categories' +UNION ALL +SELECT 4, 'com_config' +UNION ALL +SELECT 5, 'com_contact' +UNION ALL +SELECT 6, 'com_content' +UNION ALL +SELECT 7, 'com_installer' +UNION ALL +SELECT 8, 'com_media' +UNION ALL +SELECT 9, 'com_menus' +UNION ALL +SELECT 10, 'com_messages' +UNION ALL +SELECT 11, 'com_modules' +UNION ALL +SELECT 12, 'com_newsfeeds' +UNION ALL +SELECT 13, 'com_plugins' +UNION ALL +SELECT 14, 'com_redirect' +UNION ALL +SELECT 15, 'com_tags' +UNION ALL +SELECT 16, 'com_templates' +UNION ALL +SELECT 17, 'com_users'; + +SET IDENTITY_INSERT [#__action_logs_extensions] OFF; +/****** Object: Table [#__action_log_config] ******/ +SET QUOTED_IDENTIFIER ON; + +CREATE TABLE [#__action_log_config]( + [id] [int] IDENTITY(1,1) NOT NULL, + [type_title] [nvarchar](255) NOT NULL DEFAULT '', + [type_alias] [nvarchar](255) NOT NULL DEFAULT '', + [id_holder] [nvarchar](255) NULL, + [title_holder] [nvarchar](255) NULL, + [table_name] [nvarchar](255) NULL, + [text_prefix] [nvarchar](255) NULL + CONSTRAINT [PK_#__action_log_config_id] PRIMARY KEY CLUSTERED + ( + [id] ASC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + ) ON [PRIMARY]; + +SET IDENTITY_INSERT [#__action_log_config] ON; + +INSERT INTO [#__action_log_config] ([id], [type_title], [type_alias], [id_holder], [title_holder], [table_name], [text_prefix]) +SELECT 1, 'article', 'com_content.article', 'id' ,'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 2, 'article', 'com_content.form', 'id', 'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 3, 'banner', 'com_banners.banner', 'id' ,'name' , '#__banners', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 4, 'user_note', 'com_users.note', 'id', 'subject' ,'#__user_notes', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 5, 'media', 'com_media.file', '' , 'name' , '', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 6, 'category', 'com_categories.category', 'id' , 'title' , '#__categories', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 7, 'menu', 'com_menus.menu', 'id' ,'title' , '#__menu_types', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 8, 'menu_item', 'com_menus.item', 'id' , 'title' , '#__menu', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 9, 'newsfeed', 'com_newsfeeds.newsfeed', 'id' ,'name' , '#__newsfeeds', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 10, 'link', 'com_redirect.link', 'id', 'old_url' , '#__redirect_links', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 11, 'tag', 'com_tags.tag', 'id', 'title' , '#__tags', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 12, 'style', 'com_templates.style', 'id' , 'title' , '#__template_styles', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 13, 'plugin', 'com_plugins.plugin', 'extension_id' , 'name' , '#__extensions', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 14, 'component_config', 'com_config.component', 'extension_id' , 'name', '', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 15, 'contact', 'com_contact.contact', 'id', 'name', '#__contact_details', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 16, 'module', 'com_modules.module', 'id' ,'title', '#__modules', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 17, 'access_level', 'com_users.level', 'id' , 'title', '#__viewlevels', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 18, 'banner_client', 'com_banners.client', 'id', 'name', '#__banner_clients', 'PLG_ACTIONLOG_JOOMLA' +UNION ALL +SELECT 19, 'application_config', 'com_config.application', '', 'name', '', 'PLG_ACTIONLOG_JOOMLA'; + +SET IDENTITY_INSERT [#__action_log_config] OFF; + -- -- Table structure for table `#__viewlevels` -- diff --git a/installation/sql/sqlazure/sample_blog.sql b/installation/sql/sqlazure/sample_blog.sql index 3ac5714abec02..3ca86fbe28875 100644 --- a/installation/sql/sqlazure/sample_blog.sql +++ b/installation/sql/sqlazure/sample_blog.sql @@ -16,7 +16,7 @@ TRUNCATE TABLE "#__modules_menu"; SET IDENTITY_INSERT "#__assets" ON; INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "title", "rules") VALUES -(1, 0, 0, 87, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 0, 91, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 1, 2, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 3, 6, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 7, 8, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -59,7 +59,9 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (44, 1, 79, 80, 1, 'com_tags', 'com_tags', '{"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (45, 1, 81, 82, 1, 'com_contenthistory', 'com_contenthistory', '{}'), (46, 1, 83, 84, 1, 'com_ajax', 'com_ajax', '{}'), -(47, 1, 85, 86, 1, 'com_postinstall', 'com_postinstall', '{}'); +(47, 1, 85, 86, 1, 'com_postinstall', 'com_postinstall', '{}'), +(48, 1, 87, 88, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(49, 1, 89, 90, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); SET IDENTITY_INSERT "#__assets" OFF; @@ -183,7 +185,8 @@ INSERT INTO "#__modules" ("id", "title", "note", "content", "ordering", "positio (89, 'Popular Tags', '', '', 1, 'position-7', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_tags_popular', 1, 1, '{"maximum":"8","timeframe":"alltime","order_value":"count","order_direction":"1","display_count":0,"no_results_text":"0","minsize":1,"maxsize":2,"layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (90, 'Similar Items', '', '', 0, '', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_tags_similar', 1, 1, '{"maximum":"5","matchtype":"any","layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (91, 'Site Information', '', '', 4, 'cpanel', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_stats_admin', 6, 1, '{"serverinfo":"1","siteinfo":"1","counter":"0","increase":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"6","header_tag":"h3","header_class":"","style":"0"}', 1, '*'), -(92, 'Release News', '', '', 1, 'postinstall', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_feed', 1, 1, '{"rssurl":"https:\/\/www.joomla.org\/announcements\/release-news.feed","rssrtl":"0","rsstitle":"1","rssdesc":"1","rssimage":"1","rssitems":"3","rssitemdesc":"1","word_count":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 1, '*'); +(92, 'Release News', '', '', 1, 'postinstall', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_feed', 1, 1, '{"rssurl":"https:\/\/www.joomla.org\/announcements\/release-news.feed","rssrtl":"0","rsstitle":"1","rssdesc":"1","rssimage":"1","rssitems":"3","rssitemdesc":"1","word_count":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 1, '*'), +(93, 'Latest Actions', '', '', 0, 'cpanel', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); SET IDENTITY_INSERT "#__modules" OFF; @@ -219,4 +222,5 @@ INSERT INTO "#__modules_menu" ("moduleid", "menuid") VALUES (89, 0), (90, 0), (91, 0), -(92, 0); +(92, 0), +(93, 0); diff --git a/installation/sql/sqlazure/sample_brochure.sql b/installation/sql/sqlazure/sample_brochure.sql index 1800e89cade07..2c864c3882544 100644 --- a/installation/sql/sqlazure/sample_brochure.sql +++ b/installation/sql/sqlazure/sample_brochure.sql @@ -17,7 +17,7 @@ TRUNCATE TABLE "#__template_styles"; SET IDENTITY_INSERT "#__assets" ON; INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "title", "rules") VALUES -(1, 0, 0, 91, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 0, 95, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 1, 2, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 3, 6, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 7, 8, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -62,7 +62,9 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (50, 18, 52, 53, 2, 'com_modules.module.4', 'Recently Added Articles', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (51, 18, 54, 55, 2, 'com_modules.module.89', 'Site Information', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (52, 18, 56, 57, 2, 'com_modules.module.88', 'Image', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), -(53, 18, 58, 59, 2, 'com_modules.module.90', 'Release News', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'); +(53, 18, 58, 59, 2, 'com_modules.module.90', 'Release News', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), +(54, 1, 91, 92, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(55, 1, 93, 94, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); SET IDENTITY_INSERT "#__assets" OFF; @@ -187,7 +189,8 @@ INSERT INTO "#__modules" ("id", "asset_id", "title", "note", "content", "orderin (87, 0, 'Footer', '', '', 1, 'footer', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_footer', 1, 1, '{"layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (88, 52, 'Image', '', '

', 1, 'position-3', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_custom', 1, 0, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (89, 51, 'Site Information', '', '', 4, 'cpanel', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_stats_admin', 6, 1, '{"serverinfo":"1","siteinfo":"1","counter":"1","increase":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"6","header_tag":"h3","header_class":"","style":"0"}', 1, '*'), -(90, 53, 'Release News', '', '', 0, 'postinstall', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_feed', 1, 1, '{"rssurl":"https:\/\/www.joomla.org\/announcements\/release-news.feed","rssrtl":"0","rsstitle":"1","rssdesc":"1","rssimage":"1","rssitems":"3","rssitemdesc":"1","word_count":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 1, '*'); +(90, 53, 'Release News', '', '', 0, 'postinstall', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_feed', 1, 1, '{"rssurl":"https:\/\/www.joomla.org\/announcements\/release-news.feed","rssrtl":"0","rsstitle":"1","rssdesc":"1","rssimage":"1","rssitems":"3","rssitemdesc":"1","word_count":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 1, '*'), +(91, 54, 'Latest Actions', '', '', 0, 'cpanel', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); SET IDENTITY_INSERT "#__modules" OFF; @@ -216,7 +219,8 @@ INSERT INTO "#__modules_menu" ("moduleid", "menuid") VALUES (83, 0), (85, 0), (86, 0), -(88, 0); +(88, 0), +(91, 54); -- -- Dumping data for table `#__template_styles` diff --git a/installation/sql/sqlazure/sample_data.sql b/installation/sql/sqlazure/sample_data.sql index e9d17a380561f..62f36caeaa1a2 100644 --- a/installation/sql/sqlazure/sample_data.sql +++ b/installation/sql/sqlazure/sample_data.sql @@ -16,7 +16,7 @@ TRUNCATE TABLE "#__tags"; SET IDENTITY_INSERT "#__assets" ON; INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "title", "rules") VALUES -(1, 0, 0, 119, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 0, 123, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 1, 2, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 3, 6, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 7, 8, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -75,7 +75,9 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (59, 18, 82, 83, 2, 'com_modules.module.92', 'Image Module', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (60, 18, 84, 85, 2, 'com_modules.module.93', 'Search', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (61, 27, 19, 20, 3, 'com_content.article.1', 'Getting Started', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), -(62, 1, 117, 118, 1, '#__ucm_content.1', '#__ucm_content.1', '{}'); +(62, 1, 117, 118, 1, '#__ucm_content.1', '#__ucm_content.1', '{}'), +(63, 1, 119, 120, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(64, 1, 121, 122, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); SET IDENTITY_INSERT "#__assets" OFF; @@ -174,7 +176,8 @@ INSERT INTO "#__modules" ("id", "asset_id", "title", "note", "content", "orderin (90, 57, 'Latest Articles', '', '', 1, 'position-7', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_articles_latest', 1, 1, '{"catid":[""],"count":"5","show_featured":"","ordering":"c_dsc","user_id":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (91, 58, 'User Menu', '', '', 3, 'position-7', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_menu', 1, 1, '{"menutype":"usermenu","base":"","startLevel":"1","endLevel":"0","showAllChildren":"1","tag_id":"","class_sfx":"","window_open":"","layout":"_:default","moduleclass_sfx":"_menu","cache":"1","cache_time":"900","cachemode":"itemid","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (92, 59, 'Image Module', '', '

Blue Flower

', 0, 'position-3', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_custom', 1, 0, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), -(93, 60, 'Search', '', '', 0, 'position-0', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_search', 1, 1, '{"label":"","width":"20","text":"","button":"0","button_pos":"right","imagebutton":"1","button_text":"","opensearch":"1","opensearch_title":"","set_itemid":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"itemid","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'); +(93, 60, 'Search', '', '', 0, 'position-0', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_search', 1, 1, '{"label":"","width":"20","text":"","button":"0","button_pos":"right","imagebutton":"1","button_text":"","opensearch":"1","opensearch_title":"","set_itemid":"0","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"itemid","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), +(94, 61, 'Latest Actions', '', '', 0, 'cpanel', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); SET IDENTITY_INSERT "#__modules" OFF; @@ -206,7 +209,8 @@ INSERT INTO "#__modules_menu" ("moduleid", "menuid") VALUES (90, 0), (91, 0), (92, 0), -(93, 0); +(93, 0), +(94, 0); -- -- Dumping data for table `#__tags` diff --git a/installation/sql/sqlazure/sample_learn.sql b/installation/sql/sqlazure/sample_learn.sql index 0cef0e24cbea0..c292dcd1099d7 100644 --- a/installation/sql/sqlazure/sample_learn.sql +++ b/installation/sql/sqlazure/sample_learn.sql @@ -19,7 +19,7 @@ TRUNCATE TABLE "#__viewlevels"; SET IDENTITY_INSERT "#__assets" ON; INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "title", "rules") VALUES -(1, 0, 1, 430, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 1, 434, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 2, 3, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 4, 11, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 12, 13, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -178,7 +178,9 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (175, 1, 422, 423, 1, 'com_tags', 'com_tags', '{"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (176, 1, 424, 425, 1, 'com_contenthistory', 'com_contenthistory', '{}'), (177, 1, 426, 427, 1, 'com_ajax', 'com_ajax', '{}'), -(178, 1, 428, 429, 1, 'com_postinstall', 'com_postinstall', '{}'); +(178, 1, 428, 429, 1, 'com_postinstall', 'com_postinstall', '{}'), +(179, 1, 430, 431, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(180, 1, 432, 433, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); SET IDENTITY_INSERT "#__assets" OFF; @@ -607,7 +609,8 @@ INSERT INTO "#__modules" ("id", "title", "note", "content", "ordering", "positio (87, 'Fruit Shop', '', '', 1, 'position-7', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_menu', 1, 1, '{"menutype":"fruitshop","startLevel":"1","endLevel":"0","showAllChildren":"1","tag_id":"","class_sfx":"","window_open":"","layout":"_:default","moduleclass_sfx":"","cache":"0","cache_time":"900","cachemode":"itemid","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (88, 'Image Module', '', '

', 1, 'position-3', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_custom', 1, 0, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (89, 'Custom', '', '

In this module you can put whatever text or other content you would like.

', 1, '', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_custom', 1, 1, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), -(90, 'Parks Image Module', '', '

', 1, 'position-3', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_custom', 1, 1, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'); +(90, 'Parks Image Module', '', '

', 1, 'position-3', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_custom', 1, 1, '{"prepare_content":"1","backgroundimage":"","layout":"_:default","moduleclass_sfx":"","cache":"1","cache_time":"900","cachemode":"static","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), +(91, 'Latest Actions', '', '', 0, 'cpanel', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); SET IDENTITY_INSERT "#__modules" OFF; @@ -806,7 +809,8 @@ INSERT INTO "#__modules_menu" ("moduleid", "menuid") VALUES (90, 244), (90, 296), (90, 399), -(90, 400); +(90, 400), +(91, 0); -- -- Dumping data for table `#__newsfeeds` diff --git a/installation/sql/sqlazure/sample_testing.sql b/installation/sql/sqlazure/sample_testing.sql index 0c294984a988c..ba7b8a5bf59f6 100644 --- a/installation/sql/sqlazure/sample_testing.sql +++ b/installation/sql/sqlazure/sample_testing.sql @@ -19,7 +19,7 @@ TRUNCATE TABLE [#__viewlevels]; SET IDENTITY_INSERT "#__assets" ON; INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "title", "rules") VALUES -(1, 0, 1, 437, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 1, 441, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 2, 3, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 4, 11, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 12, 13, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -182,7 +182,9 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (177, 1, 433, 434, 1, 'com_postinstall', 'com_postinstall', '{}'), (178, 93, 144, 145, 7, 'com_content.article.71', 'Similar Tags', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), (179, 1, 435, 436, 1, '#__ucm_content.3', '#__ucm_content.3', '{}'), -(180, 93, 146, 147, 7, 'com_content.article.72', 'Popular Tags', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'); +(180, 93, 146, 147, 7, 'com_content.article.72', 'Popular Tags', '{"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1}}'), +(181, 1, 437, 438, 1, 'com_privacy', 'com_privacy', '{"core.admin":{"7":1}}'), +(182, 1, 439, 440, 1, 'com_actionlogs', 'com_actionlogs', '{"core.admin":{"7":1}}'); SET IDENTITY_INSERT "#__assets" OFF; @@ -641,7 +643,8 @@ INSERT INTO "#__modules" ("id", "title", "note", "content", "ordering", "positio (93, 'Popular Tags', '', '', 1, '', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_tags_popular', 1, 1, '{"maximum":"5","timeframe":"alltime","order_value":"count","order_direction":"1","display_count":0,"no_results_text":"0","minsize":1,"maxsize":2,"layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (94, 'Similar Tags', '', '', 1, '', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_tags_similar', 1, 1, '{"maximum":"5","matchtype":"any","layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), (95, 'Syndicate Feeds', '', '', 1, 'position-8', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_syndicate', 1, 1, '{"display_text":1,"text":"Feed Entries","format":"rss","layout":"_:default","moduleclass_sfx":"","cache":"0","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), -(97, 'Similar Tags 2', '', '', 1, 'position-8', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_tags_similar', 1, 1, '{"maximum":"5","matchtype":"any","layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'); +(97, 'Similar Tags 2', '', '', 1, 'position-8', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_tags_similar', 1, 1, '{"maximum":"5","matchtype":"any","layout":"_:default","moduleclass_sfx":"","owncache":"1","module_tag":"div","bootstrap_size":"0","header_tag":"h3","header_class":"","style":"0"}', 0, '*'), +(98, 'Latest Actions', '', '', 0, 'cpanel', 0, '1900-01-01 00:00:00', '1900-01-01 00:00:00', '1900-01-01 00:00:00', 1, 'mod_latestactions', 6, 1, '{}', 1, '*'); SET IDENTITY_INSERT "#__modules" OFF; @@ -829,7 +832,8 @@ INSERT INTO "#__modules_menu" ("moduleid", "menuid") VALUES (93, 0), (94, 0), (95, 0), -(97, 0); +(97, 0), +(98, 0); -- -- Dumping data for table `#__newsfeeds` diff --git a/language/en-GB/en-GB.com_privacy.ini b/language/en-GB/en-GB.com_privacy.ini new file mode 100644 index 0000000000000..4f93e9774eecf --- /dev/null +++ b/language/en-GB/en-GB.com_privacy.ini @@ -0,0 +1,53 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +COM_PRIVACY="Privacy" +COM_PRIVACY_ADMIN_NOTIFICATION_USER_CONFIRMED_REQUEST_MESSAGE="User %1$s has confirmed their information request." +COM_PRIVACY_ADMIN_NOTIFICATION_USER_CONFIRMED_REQUEST_SUBJECT="Information Request Confirmed By User" +COM_PRIVACY_ADMIN_NOTIFICATION_USER_CREATED_REQUEST_MESSAGE="A new information request has been submitted by %1$s." +COM_PRIVACY_ADMIN_NOTIFICATION_USER_CREATED_REQUEST_SUBJECT="Information Request Submitted" +COM_PRIVACY_CONFIRM_REMIND_SUCCEEDED="Your consent to this web site's Privacy Policy has been extended." +COM_PRIVACY_CONFIRM_REQUEST_FIELDSET_LABEL="An email has been sent to your email address. The email has a confirmation token, please confirm your email address again and paste the confirmation token in the field below to prove that you are the owner of the information being requested." +COM_PRIVACY_CONFIRM_REQUEST_SUCCEEDED="Your information request has been confirmed." +COM_PRIVACY_CREATE_REQUEST_SUCCEEDED="Your information request has been created. Before it can be processed, you must verify this request. An email has been sent to your address with additional instructions to complete this verification." +; You can use the following merge codes for all COM_PRIVACY_EMAIL strings: +; [SITENAME] Site name, as set in Global Configuration. +; [URL] URL of the site's frontend page. +; [TOKENURL] URL of the confirm page with the token prefilled. +; [FORMURL] URL of the confirm page where the user can paste their token. +; [TOKEN] The confirmation token. +; \n Newline character. Use it to start a new line in the email. +COM_PRIVACY_EMAIL_REQUEST_BODY_EXPORT_REQUEST="Someone has created a request to export all personal information related to this email address at [URL]. As a security measure, you must confirm that this is a valid request for your personal information from this website.\n\nIn order to confirm this request, you can complete one of the following tasks:\n\n1. Visit the following URL: [TOKENURL]\n\n2. Copy your token from this email, visit the referenced URL, and paste your token into the form.\nURL: [FORMURL]\nToken: [TOKEN]\n\nPlease note that this token is only valid for 24 hours from the time this email was sent." +COM_PRIVACY_EMAIL_REQUEST_BODY_REMOVE_REQUEST="Someone has created a request to remove all personal information related to this email address at [URL]. As a security measure, you must confirm that this is a valid request for your personal information to be removed from this website.\n\nIn order to confirm this request, you can complete one of the following tasks:\n\n1. Visit the following URL: [TOKENURL]\n\n2. Copy your token from this email, visit the referenced URL, and paste your token into the form.\nURL: [FORMURL]\nToken: [TOKEN]\n\nPlease note that this token is only valid for 24 hours from the time this email was sent." +COM_PRIVACY_EMAIL_REQUEST_SUBJECT_EXPORT_REQUEST="Information Request Created at [SITENAME]" +COM_PRIVACY_EMAIL_REQUEST_SUBJECT_REMOVE_REQUEST="Information Deletion Request Created at [SITENAME]" +COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED="An information request can't be created when email support is disabled." +COM_PRIVACY_ERROR_CHECKING_FOR_EXISTING_REQUESTS="There was an error checking for existing information requests, please try submitting this request again." +COM_PRIVACY_ERROR_CONFIRM_TOKEN_EXPIRED="The confirmation token for your information request has expired. You will need to submit a new request." +COM_PRIVACY_ERROR_CONFIRMING_REMIND_FAILED="No expiration reminder was found." +COM_PRIVACY_ERROR_CONFIRMING_REQUEST="Error while confirming the information request." +COM_PRIVACY_ERROR_CONFIRMING_REQUEST_FAILED="Your information request confirmation failed. %s" +COM_PRIVACY_ERROR_CREATING_REQUEST="Error while creating the information request." +COM_PRIVACY_ERROR_CREATING_REQUEST_FAILED="Your information request could not be created. %s" +COM_PRIVACY_ERROR_NO_PENDING_REMIND="No expiration reminder has been sent yet." +COM_PRIVACY_ERROR_NO_PENDING_REQUESTS="There are no information requests for this email address requiring confirmation." +COM_PRIVACY_ERROR_NO_REMIND_REQUESTS="Please re-check the token" +COM_PRIVACY_ERROR_PENDING_REQUEST_OPEN="There is already an active information request for this email address and request type. Please contact the site owner for updates on this request." +COM_PRIVACY_ERROR_REMIND_REQUEST="An error occurred while processing your request." +COM_PRIVACY_ERROR_UNKNOWN_REQUEST_TYPE="Unknown information request type." +COM_PRIVACY_FIELD_CONFIRM_CONFIRM_TOKEN_DESC="Enter the confirmation token you received by email." +COM_PRIVACY_FIELD_CONFIRM_CONFIRM_TOKEN_LABEL="Confirmation Token" +COM_PRIVACY_FIELD_CONFIRM_EMAIL_DESC="Enter your email address." +COM_PRIVACY_FIELD_REMIND_CONFIRM_TOKEN_DESC="Enter the confirmation token you received by email." +COM_PRIVACY_FIELD_REMIND_CONFIRM_TOKEN_LABEL="Confirmation Token" +COM_PRIVACY_FIELD_REQUEST_TYPE_DESC="The type of information request." +COM_PRIVACY_FIELD_REQUEST_TYPE_LABEL="Request Type" +COM_PRIVACY_FIELD_STATUS_DESC="The status of the information request." +COM_PRIVACY_REMIND_REQUEST_FIELDSET_LABEL="Renew Privacy Consent" +COM_PRIVACY_REQUEST_TYPE_EXPORT="Export" +COM_PRIVACY_REQUEST_TYPE_REMOVE="Remove" +COM_PRIVACY_VIEW_CONFIRM_PAGE_TITLE="Confirm Information Request" +COM_PRIVACY_VIEW_REQUEST_PAGE_TITLE="Submit Information Request" +COM_PRIVACY_WARNING_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED="We're sorry, you can't submit an information request at this time." diff --git a/libraries/src/Document/XmlDocument.php b/libraries/src/Document/XmlDocument.php index 1ed2a73f915ed..e7a7b9b428e70 100644 --- a/libraries/src/Document/XmlDocument.php +++ b/libraries/src/Document/XmlDocument.php @@ -25,6 +25,14 @@ class XmlDocument extends Document */ protected $name = 'joomla'; + /** + * Flag indicating the document should be downloaded (Content-Disposition = attachment) versus displayed inline + * + * @var boolean + * @since __DEPLOY_VERSION__ + */ + protected $isDownload = false; + /** * Class constructor * @@ -57,7 +65,9 @@ public function render($cache = false, $params = array()) { parent::render(); - \JFactory::getApplication()->setHeader('Content-disposition', 'inline; filename="' . $this->getName() . '.xml"', true); + $disposition = $this->isDownload ? 'attachment' : 'inline'; + + \JFactory::getApplication()->setHeader('Content-disposition', $disposition . '; filename="' . $this->getName() . '.xml"', true); return $this->getBuffer(); } @@ -89,4 +99,32 @@ public function setName($name = 'joomla') return $this; } + + /** + * Check if this document is intended for download + * + * @return string + * + * @since __DEPLOY_VERSION__ + */ + public function isDownload() + { + return $this->isDownload; + } + + /** + * Sets the document's download state + * + * @param boolean $download If true, this document will be downloaded; if false, this document will be displayed inline + * + * @return XmlDocument instance of $this to allow chaining + * + * @since __DEPLOY_VERSION__ + */ + public function setDownload($download = false) + { + $this->isDownload = $download; + + return $this; + } } diff --git a/libraries/src/Extension/ExtensionHelper.php b/libraries/src/Extension/ExtensionHelper.php index e1e4baf3bba0c..c90592aeba472 100644 --- a/libraries/src/Extension/ExtensionHelper.php +++ b/libraries/src/Extension/ExtensionHelper.php @@ -31,6 +31,7 @@ class ExtensionHelper // Format: `type`, `element`, `folder`, `client_id` // Core component extensions + array('component', 'com_actionlogs', '', 1), array('component', 'com_admin', '', 1), array('component', 'com_ajax', '', 1), array('component', 'com_associations', '', 1), @@ -57,6 +58,7 @@ class ExtensionHelper array('component', 'com_newsfeeds', '', 1), array('component', 'com_plugins', '', 1), array('component', 'com_postinstall', '', 1), + array('component', 'com_privacy', '', 1), array('component', 'com_redirect', '', 1), array('component', 'com_search', '', 1), array('component', 'com_tags', '', 1), @@ -84,11 +86,13 @@ class ExtensionHelper array('module', 'mod_custom', '', 1), array('module', 'mod_feed', '', 1), array('module', 'mod_latest', '', 1), + array('module', 'mod_latestactions', '', 1), array('module', 'mod_logged', '', 1), array('module', 'mod_login', '', 1), array('module', 'mod_menu', '', 1), array('module', 'mod_multilangstatus', '', 1), array('module', 'mod_popular', '', 1), + array('module', 'mod_privacy_dashboard', '', 1), array('module', 'mod_quickicon', '', 1), array('module', 'mod_sampledata', '', 1), array('module', 'mod_stats_admin', '', 1), @@ -128,6 +132,9 @@ class ExtensionHelper // Core package extensions array('package', 'pkg_en-GB', '', 0), + // Core plugin extensions - actionlog + array('plugin', 'joomla', 'actionlog', 0), + // Core plugin extensions - authentication array('plugin', 'cookie', 'authentication', 0), array('plugin', 'gmail', 'authentication', 0), @@ -138,6 +145,7 @@ class ExtensionHelper array('plugin', 'recaptcha', 'captcha', 0), // Core plugin extensions - content + array('plugin', 'confirmconsent', 'content', 0), array('plugin', 'contact', 'content', 0), array('plugin', 'emailcloak', 'content', 0), array('plugin', 'fields', 'content', 0), @@ -196,10 +204,17 @@ class ExtensionHelper array('plugin', 'packageinstaller', 'installer', 0), array('plugin', 'urlinstaller', 'installer', 0), + // Core plugin extensions - privacy + array('plugin', 'contact', 'privacy', 0), + array('plugin', 'content', 'privacy', 0), + array('plugin', 'message', 'privacy', 0), + array('plugin', 'user', 'privacy', 0), + // Core plugin extensions - quick icon array('plugin', 'extensionupdate', 'quickicon', 0), array('plugin', 'joomlaupdate', 'quickicon', 0), array('plugin', 'phpversioncheck', 'quickicon', 0), + array('plugin', 'privacycheck', 'quickicon', 0), // Core plugin extensions - sample data array('plugin', 'blog', 'sampledata', 0), @@ -212,6 +227,7 @@ class ExtensionHelper array('plugin', 'tags', 'search', 0), // Core plugin extensions - system + array('plugin', 'actionlogs', 'system', 0), array('plugin', 'cache', 'system', 0), array('plugin', 'debug', 'system', 0), array('plugin', 'fields', 'system', 0), @@ -220,7 +236,9 @@ class ExtensionHelper array('plugin', 'languagefilter', 'system', 0), array('plugin', 'log', 'system', 0), array('plugin', 'logout', 'system', 0), + array('plugin', 'logrotation', 'system', 0), array('plugin', 'p3p', 'system', 0), + array('plugin', 'privacyconsent', 'system', 0), array('plugin', 'redirect', 'system', 0), array('plugin', 'remember', 'system', 0), array('plugin', 'sef', 'system', 0), @@ -236,6 +254,7 @@ class ExtensionHelper array('plugin', 'contactcreator', 'user', 0), array('plugin', 'joomla', 'user', 0), array('plugin', 'profile', 'user', 0), + array('plugin', 'terms', 'user', 0), // Core template extensions - administrator array('template', 'hathor', '', 1), diff --git a/libraries/src/Form/Form.php b/libraries/src/Form/Form.php index c2af7618cf1d2..b4f81655935d7 100644 --- a/libraries/src/Form/Form.php +++ b/libraries/src/Form/Form.php @@ -322,7 +322,7 @@ public function getFieldAttribute($name, $attribute, $default = null, $group = n * * @param string $set The optional name of the fieldset. * - * @return array The array of JFormField objects in the fieldset. + * @return \JFormField[] The array of JFormField objects in the fieldset. * * @since 11.1 */ @@ -497,7 +497,7 @@ public function getFormControl() * @param boolean $nested True to also include fields in nested groups that are inside of the * group for which to find fields. * - * @return array The array of JFormField objects in the field group. + * @return \JFormField[] The array of JFormField objects in the field group. * * @since 11.1 */ diff --git a/media/plg_quickicon_privacycheck/js/privacycheck.js b/media/plg_quickicon_privacycheck/js/privacycheck.js new file mode 100644 index 0000000000000..221fb20036f96 --- /dev/null +++ b/media/plg_quickicon_privacycheck/js/privacycheck.js @@ -0,0 +1,53 @@ +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +jQuery(document).ready(function() { + var variables = Joomla.getOptions('js-privacy-check'), + plg_quickicon_privacycheck_ajax_url = variables.plg_quickicon_privacycheck_ajax_url, + plg_quickicon_privacycheck_url = variables.plg_quickicon_privacycheck_url, + plg_quickicon_privacycheck_text = variables.plg_quickicon_privacycheck_text; + var ajax_structure = { + success: function(data, textStatus, jqXHR) { + var link = jQuery('#plg_quickicon_privacycheck').find('span.j-links-link'); + + try { + var requestList = jQuery.parseJSON(data); + } catch (e) { + // An error occurred + link.html(plg_quickicon_privacycheck_text.ERROR); + } + + if (requestList.data.number_urgent_requests == 0) { + // No requests + link.html(plg_quickicon_privacycheck_text.NOREQUEST); + } else { + // Requests + var msgString = '' + + requestList.data.number_urgent_requests + ' ' + + plg_quickicon_privacycheck_text.REQUESTFOUND_MESSAGE; + + jQuery('#system-message-container').prepend( + '
' + + msgString + + ' ' + + '
' + ); + + var msgString = plg_quickicon_privacycheck_text.REQUESTFOUND + + ' ' + + requestList.data.number_urgent_requests + '' + + link.html(msgString); + } + }, + error: function(jqXHR, textStatus, errorThrown) { + // An error occurred + jQuery('#plg_quickicon_privacycheck').find('span.j-links-link').html(plg_quickicon_privacycheck_text.ERROR); + }, + url: plg_quickicon_privacycheck_ajax_url + }; + ajax_object = new jQuery.ajax(ajax_structure); +}); diff --git a/plugins/actionlog/joomla/joomla.php b/plugins/actionlog/joomla/joomla.php new file mode 100644 index 0000000000000..c7ae9f661e349 --- /dev/null +++ b/plugins/actionlog/joomla/joomla.php @@ -0,0 +1,934 @@ +getParams(); + + $this->loggableExtensions = $params->get('loggable_extensions', array()); + } + + /** + * After save content logging method + * This method adds a record to #__action_logs contains (message, date, context, user) + * Method is called right after the content is saved + * + * @param string $context The context of the content passed to the plugin + * @param object $article A JTableContent object + * @param boolean $isNew If the content is just about to be created + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onContentAfterSave($context, $article, $isNew) + { + $option = $this->app->input->getCmd('option'); + + if (!$this->checkLoggable($option)) + { + return; + } + + $params = ActionlogsHelper::getLogContentTypeParams($context); + + // Not found a valid content type, don't process further + if ($params === null) + { + return; + } + + $user = JFactory::getUser(); + $contentTypeTitle = strtoupper($params->type_title); + list(, $contentType) = explode('.', $params->type_alias); + + if ($isNew) + { + $messageLanguageKey = strtoupper($params->text_prefix . '_' . $contentTypeTitle . '_ADDED'); + $defaultLanguageKey = strtoupper('PLG_SYSTEM_ACTIONLOGS_CONTENT_ADDED'); + + $action = 'add'; + } + else + { + $messageLanguageKey = strtoupper($params->text_prefix . '_' . $contentTypeTitle . '_UPDATED'); + $defaultLanguageKey = strtoupper('PLG_SYSTEM_ACTIONLOGS_CONTENT_UPDATED'); + + $action = 'update'; + } + + // If the content type doesn't has it own language key, use default language key + if (!JFactory::getLanguage()->hasKey($messageLanguageKey)) + { + $messageLanguageKey = $defaultLanguageKey; + } + + $id = empty($params->id_holder) ? 0 : $article->get($params->id_holder); + + $message = array( + 'action' => $action, + 'type' => strtoupper($params->text_prefix . '_TYPE_' . $contentTypeTitle), + 'id' => $id, + 'title' => $article->get($params->title_holder), + 'itemlink' => ActionlogsHelper::getContentTypeLink($option, $contentType, $id), + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + $this->addLog(array($message), $messageLanguageKey, $context); + } + + /** + * After delete content logging method + * This method adds a record to #__action_logs contains (message, date, context, user) + * Method is called right after the content is deleted + * + * @param string $context The context of the content passed to the plugin + * @param object $article A JTableContent object + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onContentAfterDelete($context, $article) + { + $option = $this->app->input->get('option'); + + if (!$this->checkLoggable($option)) + { + return; + } + + $params = ActionlogsHelper::getLogContentTypeParams($context); + + // Not found a valid content type, don't process further + if ($params === null) + { + return; + } + + $language = JFactory::getLanguage(); + $user = JFactory::getUser(); + $contentTypeTitle = strtoupper($params->type_title); + + // If the content type has it own language key, use it, otherwise, use default language key + if ($language->hasKey(strtoupper($params->text_prefix . '_' . $contentTypeTitle . '_DELETED'))) + { + $messageLanguageKey = strtoupper($params->text_prefix . '_' . $contentTypeTitle . '_DELETED'); + } + else + { + $messageLanguageKey = strtoupper('PLG_SYSTEM_ACTIONLOGS_CONTENT_DELETED'); + } + + $id = empty($params->id_holder) ? 0 : $article->get($params->id_holder); + + $message = array( + 'action' => 'delete', + 'type' => strtoupper($params->text_prefix . '_TYPE_' . $contentTypeTitle), + 'id' => $id, + 'title' => $article->get($params->title_holder), + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + $this->addLog(array($message), $messageLanguageKey, $context); + } + + /** + * On content change status logging method + * This method adds a record to #__action_logs contains (message, date, context, user) + * Method is called when the status of the article is changed + * + * @param string $context The context of the content passed to the plugin + * @param array $pks An array of primary key ids of the content that has changed state. + * @param integer $value The value of the state that the content has been changed to. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onContentChangeState($context, $pks, $value) + { + $option = $this->app->input->getCmd('option'); + + if (!$this->checkLoggable($option)) + { + return; + } + + $params = ActionlogsHelper::getLogContentTypeParams($context); + + // Not found a valid content type, don't process further + if ($params === null) + { + return; + } + + $user = JFactory::getUser(); + $contentTypeTitle = strtoupper($params->type_title); + list(, $contentType) = explode('.', $params->type_alias); + + switch ($value) + { + case 0: + $messageLanguageKey = strtoupper($params->text_prefix . '_' . $contentTypeTitle . '_UNPUBLISHED'); + $defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_UNPUBLISHED'; + $action = 'unpublish'; + break; + case 1: + $messageLanguageKey = strtoupper($params->text_prefix . '_' . $contentTypeTitle . '_PUBLISHED'); + $defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_PUBLISHED'; + $action = 'publish'; + break; + case 2: + $messageLanguageKey = strtoupper($params->text_prefix . '_' . $contentTypeTitle . '_ARCHIVED'); + $defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_ARCHIVED'; + $action = 'archive'; + break; + case -2: + $messageLanguageKey = strtoupper($params->text_prefix . '_' . $contentTypeTitle . '_TRASHED'); + $defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_TRASHED'; + $action = 'trash'; + break; + default: + $messageLanguageKey = ''; + $defaultLanguageKey = ''; + $action = ''; + break; + } + + // If the content type doesn't has it own language key, use default language key + if (!JFactory::getLanguage()->hasKey($messageLanguageKey)) + { + $messageLanguageKey = $defaultLanguageKey; + } + + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName(array($params->title_holder, $params->id_holder))) + ->from($db->quoteName($params->table_name)) + ->where($db->quoteName($params->id_holder) . ' IN (' . implode(',', ArrayHelper::toInteger($pks)) . ')'); + $db->setQuery($query); + + try + { + $items = $db->loadObjectList($params->id_holder); + } + catch (RuntimeException $e) + { + $items = array(); + } + + $messages = array(); + + foreach ($pks as $pk) + { + $message = array( + 'action' => $action, + 'type' => strtoupper($params->text_prefix . '_TYPE_' . $params->type_title), + 'id' => $pk, + 'title' => $items[$pk]->{$params->title_holder}, + 'itemlink' => ActionlogsHelper::getContentTypeLink($option, $contentType, $pk), + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + $messages[] = $message; + } + + $this->addLog($messages, $messageLanguageKey, $context); + } + + /** + * On Saving application configuration logging method + * Method is called when the application config is being saved + * + * @param JRegistry $config JRegistry object with the new config + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onApplicationAfterSave($config) + { + $option = $this->app->input->getCmd('option'); + + if (!$this->checkLoggable($option)) + { + return; + } + + $messageLanguageKey = strtoupper('PLG_ACTIONLOG_JOOMLA_APPLICATION_CONFIG_UPDATED'); + $action = 'update'; + + $user = JFactory::getUser(); + + $message = array( + 'action' => $action, + 'type' => strtoupper('PLG_ACTIONLOG_JOOMLA_TYPE_APPLICATION_CONFIG'), + 'extension_name' => 'com_config.application', + 'itemlink' => 'index.php?option=com_config', + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + $this->addLog(array($message), $messageLanguageKey, 'com_config.application'); + } + + /** + * On installing extensions logging method + * This method adds a record to #__action_logs contains (message, date, context, user) + * Method is called when an extension is installed + * + * @param JInstaller $installer Installer object + * @param integer $eid Extension Identifier + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onExtensionAfterInstall($installer, $eid) + { + $context = $this->app->input->get('option'); + + if (!$this->checkLoggable($context)) + { + return; + } + + $language = JFactory::getLanguage(); + $user = JFactory::getUser(); + $manifest = $installer->get('manifest'); + $extensionType = $manifest->attributes()->type; + + // If the extension type has it own language key, use it, otherwise, use default language key + if ($language->hasKey(strtoupper('PLG_ACTIONLOG_JOOMLA_' . $extensionType . '_INSTALLED'))) + { + $messageLanguageKey = strtoupper('PLG_ACTIONLOG_JOOMLA_' . $extensionType . '_INSTALLED'); + } + else + { + $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_EXTENSION_INSTALLED'; + } + + $message = array( + 'action' => 'install', + 'type' => strtoupper('PLG_ACTIONLOG_JOOMLA_TYPE_' . $extensionType), + 'id' => $eid, + 'name' => (string) $manifest->name, + 'extension_name' => (string) $manifest->name, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + $this->addLog(array($message), $messageLanguageKey, $context); + } + + /** + * On uninstalling extensions logging method + * This method adds a record to #__action_logs contains (message, date, context, user) + * Method is called when an extension is uninstalled + * + * @param JInstaller $installer Installer instance + * @param integer $eid Extension id + * @param integer $result Installation result + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onExtensionAfterUninstall($installer, $eid, $result) + { + $context = $this->app->input->get('option'); + + if (!$this->checkLoggable($context)) + { + return; + } + + // If the process failed, we don't have manifest data, stop process to avoid fatal error + if ($result === false) + { + return; + } + + $language = JFactory::getLanguage(); + $user = JFactory::getUser(); + $manifest = $installer->get('manifest'); + $extensionType = $manifest->attributes()->type; + + // If the extension type has it own language key, use it, otherwise, use default language key + if ($language->hasKey(strtoupper('PLG_ACTIONLOG_JOOMLA_' . $extensionType . '_UNINSTALLED'))) + { + $messageLanguageKey = strtoupper('PLG_ACTIONLOG_JOOMLA_' . $extensionType . '_UNINSTALLED'); + } + else + { + $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_EXTENSION_UNINSTALLED'; + } + + $message = array( + 'action' => 'install', + 'type' => strtoupper('PLG_ACTIONLOG_JOOMLA_TYPE_' . $extensionType), + 'id' => $eid, + 'name' => (string) $manifest->name, + 'extension_name' => (string) $manifest->name, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + $this->addLog(array($message), $messageLanguageKey, $context); + } + + /** + * On updating extensions logging method + * This method adds a record to #__action_logs contains (message, date, context, user) + * Method is called when an extension is updated + * + * @param JInstaller $installer Installer instance + * @param integer $eid Extension id + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onExtensionAfterUpdate($installer, $eid) + { + $context = $this->app->input->get('option'); + + if (!$this->checkLoggable($context)) + { + return; + } + + $language = JFactory::getLanguage(); + $user = JFactory::getUser(); + $manifest = $installer->get('manifest'); + $extensionType = $manifest->attributes()->type; + + // If the extension type has it own language key, use it, otherwise, use default language key + if ($language->hasKey(strtoupper('PLG_ACTIONLOG_JOOMLA_' . $extensionType . '_UPDATED'))) + { + $messageLanguageKey = strtoupper('PLG_ACTIONLOG_JOOMLA_' . $extensionType . '_UPDATED'); + } + else + { + $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_EXTENSION_UPDATED'; + } + + $message = array( + 'action' => 'update', + 'type' => strtoupper('PLG_ACTIONLOG_JOOMLA_TYPE_' . $extensionType), + 'id' => $eid, + 'name' => (string) $manifest->name, + 'extension_name' => (string) $manifest->name, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + $this->addLog(array($message), $messageLanguageKey, $context); + } + + /** + * On Saving extensions logging method + * Method is called when an extension is being saved + * + * @param string $context The extension + * @param JTable $table DataBase Table object + * @param boolean $isNew If the extension is new or not + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onExtensionAfterSave($context, $table, $isNew) + { + $option = $this->app->input->getCmd('option'); + + if (!$this->checkLoggable($option)) + { + return; + } + + $params = ActionlogsHelper::getLogContentTypeParams($context); + + // Not found a valid content type, don't process further + if ($params === null) + { + return; + } + + $extensionType = $params->type_title; + list(, $contentType) = explode('.', $params->type_alias); + + if ($isNew) + { + $messageLanguageKey = strtoupper('PLG_ACTIONLOG_JOOMLA_' . $extensionType . '_ADDED'); + $defaultLanguageKey = strtoupper('PLG_SYSTEM_ACTIONLOGS_CONTENT_ADDED'); + $action = 'add'; + } + else + { + $messageLanguageKey = strtoupper('PLG_ACTIONLOG_JOOMLA_' . $extensionType . '_UPDATED'); + $defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_UPDATED'; + $action = 'update'; + } + + // If the extension type doesn't have it own language key, use default language key + if (!JFactory::getLanguage()->hasKey($messageLanguageKey)) + { + $messageLanguageKey = $defaultLanguageKey; + } + + $user = JFactory::getUser(); + + $message = array( + 'action' => $action, + 'type' => strtoupper('PLG_ACTIONLOG_JOOMLA_TYPE_' . $extensionType), + 'id' => $table->get($params->id_holder), + 'title' => $table->get($params->title_holder), + 'extension_name' => $table->get($params->title_holder), + 'itemlink' => ActionlogsHelper::getContentTypeLink($option, $contentType, $table->get($params->id_holder), $params->id_holder), + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + $this->addLog(array($message), $messageLanguageKey, $context); + } + + /** + * On Deleting extensions logging method + * Method is called when an extension is being deleted + * + * @param string $context The extension + * @param JTable $table DataBase Table object + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onExtensionAfterDelete($context, $table) + { + if (!$this->checkLoggable($this->app->input->get('option'))) + { + return; + } + + $params = ActionlogsHelper::getLogContentTypeParams($context); + + // Not found a valid content type, don't process further + if ($params === null) + { + return; + } + + $messageLanguageKey = strtoupper('PLG_SYSTEM_ACTIONLOGS_CONTENT_DELETED'); + $user = JFactory::getUser(); + + $message = array( + 'action' => 'delete', + 'type' => strtoupper('PLG_ACTIONLOG_JOOMLA_TYPE_' . $params->type_title), + 'title' => $table->get($params->title_holder), + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + $this->addLog(array($message), $messageLanguageKey, $context); + } + + /** + * On saving user data logging method + * + * Method is called after user data is stored in the database. + * This method logs who created/edited any user's data + * + * @param array $user Holds the new user data. + * @param boolean $isnew True if a new user is stored. + * @param boolean $success True if user was succesfully stored in the database. + * @param string $msg Message. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onUserAfterSave($user, $isnew, $success, $msg) + { + $context = $this->app->input->get('option'); + + if (!$this->checkLoggable($context)) + { + return; + } + + $jUser = JFactory::getUser(); + + if (!$jUser->id) + { + $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_USER_REGISTERED'; + $action = 'register'; + } + elseif ($isnew) + { + $messageLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_ADDED'; + $action = 'add'; + } + else + { + $messageLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_UPDATED'; + $action = 'update'; + } + + $userId = $jUser->id ?: $user['id']; + $username = $jUser->username ?: $user['username']; + + $message = array( + 'action' => $action, + 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_USER', + 'id' => $user['id'], + 'title' => $user['name'], + 'itemlink' => 'index.php?option=com_users&task=user.edit&id=' . $user['id'], + 'userid' => $userId, + 'username' => $username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $userId, + ); + + $this->addLog(array($message), $messageLanguageKey, $context, $userId); + } + + /** + * On deleting user data logging method + * + * Method is called after user data is deleted from the database + * + * @param array $user Holds the user data + * @param boolean $success True if user was succesfully stored in the database + * @param string $msg Message + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onUserAfterDelete($user, $success, $msg) + { + $context = $this->app->input->get('option'); + + if (!$this->checkLoggable($context)) + { + return; + } + + $messageLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_DELETED'; + $jUser = JFactory::getUser(); + + $message = array( + 'action' => 'delete', + 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_USER', + 'id' => $user['id'], + 'title' => $user['name'], + 'userid' => $jUser->id, + 'username' => $jUser->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $jUser->id, + ); + + $this->addLog(array($message), $messageLanguageKey, $context); + } + + /** + * On after save user group data logging method + * + * Method is called after user data is deleted from the database + * + * @param string $context The context + * @param JTable $table DataBase Table object + * @param boolean $isNew Is new or not + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onUserAfterSaveGroup($context, $table, $isNew) + { + $context = $this->app->input->get('option'); + + if (!$this->checkLoggable($context)) + { + return; + } + + if ($isNew) + { + $messageLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_ADDED'; + $action = 'add'; + } + else + { + $messageLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_UPDATED'; + $action = 'update'; + } + + $user = JFactory::getUser(); + + $message = array( + 'action' => $action, + 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_USER_GROUP', + 'id' => $table->id, + 'title' => $table->title, + 'itemlink' => 'index.php?option=com_users&task=group.edit&id=' . $table->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + $this->addLog(array($message), $messageLanguageKey, $context); + } + + /** + * On deleting user group data logging method + * + * Method is called after user data is deleted from the database + * + * @param array $group Holds the group data + * @param boolean $success True if user was succesfully stored in the database + * @param string $msg Message + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onUserAfterDeleteGroup($group, $success, $msg) + { + $context = $this->app->input->get('option'); + + if (!$this->checkLoggable($context)) + { + return; + } + + $user = JFactory::getUser(); + + $messageLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_DELETED'; + + $message = array( + 'action' => 'delete', + 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_USER_GROUP', + 'id' => $group['id'], + 'title' => $group['title'], + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + $this->addLog(array($message), $messageLanguageKey, $context); + } + + /** + * Method to log user login success action + * + * @param array $options Array holding options (user, responseType) + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onUserAfterLogin($options) + { + $context = 'com_users'; + + if (!$this->checkLoggable($context)) + { + return; + } + + $loggedInUser = $options['user']; + $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_USER_LOGGED_IN'; + + $message = array( + 'action' => 'login', + 'username' => $loggedInUser->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $loggedInUser->id, + 'app' => strtoupper('PLG_ACTIONLOG_JOOMLA_APPLICATION_' . $this->app->getName()), + ); + + $this->addLog(array($message), $messageLanguageKey, $context, $loggedInUser->id); + } + + /** + * Method to log user login failed action + * + * @param array $response Array of response data. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onUserLoginFailure($response) + { + $context = 'com_users'; + + if (!$this->checkLoggable($context)) + { + return; + } + + $loggedInUser = JUser::getInstance($response['username']); + + // Not a valid user, return + if (!$loggedInUser->id) + { + return; + } + + $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_USER_LOGIN_FAILED'; + + $message = array( + 'action' => 'login', + 'id' => $loggedInUser->id, + 'username' => $loggedInUser->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $loggedInUser->id, + 'app' => strtoupper('PLG_ACTIONLOG_JOOMLA_APPLICATION_' . $this->app->getName()), + ); + + $this->addLog(array($message), $messageLanguageKey, $context, $loggedInUser->id); + } + + /** + * Method to log user's logout action + * + * @param array $user Holds the user data + * @param array $options Array holding options (remember, autoregister, group) + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onUserLogout($user, $options = array()) + { + $context = 'com_users'; + + if (!$this->checkLoggable($context)) + { + return; + } + + $loggedOutUser = JUser::getInstance($user['id']); + $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_USER_LOGGED_OUT'; + + $message = array( + 'action' => 'logout', + 'id' => $loggedOutUser->id, + 'username' => $loggedOutUser->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $loggedOutUser->id, + 'app' => strtoupper('PLG_ACTIONLOG_JOOMLA_APPLICATION_' . $this->app->getName()), + ); + + $this->addLog(array($message), $messageLanguageKey, $context); + } + + /** + * Proxy for ActionlogsModelUserlog addLog method + * + * This method adds a record to #__action_logs contains (message_language_key, message, date, context, user) + * + * @param array $messages The contents of the messages to be logged + * @param string $messageLanguageKey The language key of the message + * @param string $context The context of the content passed to the plugin + * @param int $userId ID of user perform the action, usually ID of current logged in user + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function addLog($messages, $messageLanguageKey, $context, $userId = null) + { + JLoader::register('ActionlogsModelActionlog', JPATH_ADMINISTRATOR . '/components/com_actionlogs/models/actionlog.php'); + + /* @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog($messages, $messageLanguageKey, $context, $userId); + } + + /** + * Function to check if a component is loggable or not + * + * @param string $extension The extension that triggered the event + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + protected function checkLoggable($extension) + { + return in_array($extension, $this->loggableExtensions); + } +} diff --git a/plugins/actionlog/joomla/joomla.xml b/plugins/actionlog/joomla/joomla.xml new file mode 100644 index 0000000000000..e38fa5ea1d973 --- /dev/null +++ b/plugins/actionlog/joomla/joomla.xml @@ -0,0 +1,16 @@ + + + PLG_ACTIONLOG_JOOMLA + Joomla! Project + May 2018 + Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + __DEPLOY_VERSION__ + PLG_ACTIONLOG_JOOMLA_XML_DESCRIPTION + + joomla.php + + + diff --git a/plugins/authentication/cookie/cookie.php b/plugins/authentication/cookie/cookie.php index 9a2effc87ff71..7d86105aa54f7 100644 --- a/plugins/authentication/cookie/cookie.php +++ b/plugins/authentication/cookie/cookie.php @@ -34,6 +34,24 @@ class PlgAuthenticationCookie extends JPlugin */ protected $db; + /** + * Reports the privacy related capabilities for this plugin to site administrators. + * + * @return array + * + * @since __DEPLOY_VERSION__ + */ + public function onPrivacyCollectAdminCapabilities() + { + $this->loadLanguage(); + + return array( + JText::_('PLG_AUTHENTICATION_COOKIE') => array( + JText::_('PLG_AUTH_COOKIE_PRIVACY_CAPABILITY_COOKIE'), + ) + ); + } + /** * This method should handle any authentication and report back to the subject * diff --git a/plugins/captcha/recaptcha/recaptcha.php b/plugins/captcha/recaptcha/recaptcha.php index 6aae275f18ddf..213879d281a07 100644 --- a/plugins/captcha/recaptcha/recaptcha.php +++ b/plugins/captcha/recaptcha/recaptcha.php @@ -25,6 +25,24 @@ class PlgCaptchaRecaptcha extends JPlugin */ protected $autoloadLanguage = true; + /** + * Reports the privacy related capabilities for this plugin to site administrators. + * + * @return array + * + * @since __DEPLOY_VERSION__ + */ + public function onPrivacyCollectAdminCapabilities() + { + $this->loadLanguage(); + + return array( + JText::_('PLG_CAPTCHA_RECAPTCHA') => array( + JText::_('PLG_RECAPTCHA_PRIVACY_CAPABILITY_IP_ADDRESS'), + ) + ); + } + /** * Initialise the captcha * diff --git a/plugins/content/confirmconsent/confirmconsent.php b/plugins/content/confirmconsent/confirmconsent.php new file mode 100644 index 0000000000000..c7e0688130cec --- /dev/null +++ b/plugins/content/confirmconsent/confirmconsent.php @@ -0,0 +1,200 @@ +app->isClient('administrator') || !in_array($form->getName(), $this->supportedContext)) + { + return true; + } + + // Get the consent box Text & the selected privacyarticle + $consentboxLabel = JText::_('PLG_CONTENT_CONFIRMCONSENT_CONSENTBOX_LABEL'); + $consentboxText = (string) $this->params->get('consentbox_text', Text::_('PLG_CONTENT_CONFIRMCONSENT_FIELD_NOTE_DEFAULT')); + $privacyArticle = $this->params->get('privacy_article', false); + + // When we have a article just add it arround to the text + if ($privacyArticle) + { + HTMLHelper::_('behavior.modal'); + + $consentboxLabel = $this->getAssignedArticleUrl($privacyArticle, $consentboxLabel); + } + + $form->load(' +
+
+ + + +
+
' + ); + + return true; + } + + /** + * Return the url of the assigned article based on the current user language + * + * @param integer $articleId The form to be altered. + * @param string $consentboxLabel The consent box label + * + * @return string Returns the a tag containing everything for the modal + * + * @since __DEPLOY_VERSION__ + */ + private function getAssignedArticleUrl($articleId, $consentboxLabel) + { + // Get the info from the article + $query = $this->db->getQuery(true) + ->select($this->db->quoteName(array('id', 'catid', 'language'))) + ->from($this->db->quoteName('#__content')) + ->where($this->db->quoteName('id') . ' = ' . (int) $articleId); + $this->db->setQuery($query); + + $attribs = array(); + $attribs['class'] = 'modal'; + $attribs['rel'] = '{handler: \'iframe\', size: {x:800, y:500}}'; + + try + { + $article = $this->db->loadObject(); + } + catch (JDatabaseExceptionExecuting $e) + { + // Something at the database layer went wrong + return HTMLHelper::_( + 'link', + Route::_( + 'index.php?option=com_content&view=article&id=' + . $articleId . '&tmpl=component' + ), + $consentboxLabel, + $attribs + ); + } + + // Register ContentHelperRoute + JLoader::register('ContentHelperRoute', JPATH_BASE . '/components/com_content/helpers/route.php'); + + if (!Associations::isEnabled()) + { + return HTMLHelper::_('link', + Route::_( + ContentHelperRoute::getArticleRoute( + $article->id, + $article->catid, + $article->language + ) . '&tmpl=component' + ), + $consentboxLabel, + $attribs + ); + } + + $associatedArticles = Associations::getAssociations('com_content', '#__content', 'com_content.item', $article->id); + $currentLang = Factory::getLanguage()->getTag(); + + if (isset($associatedArticles) && $currentLang !== $article->language && array_key_exists($currentLang, $associatedArticles)) + { + return HTMLHelper::_('link', + Route::_( + ContentHelperRoute::getArticleRoute( + $associatedArticles[$currentLang]->id, + $associatedArticles[$currentLang]->catid, + $associatedArticles[$currentLang]->language + ) . '&tmpl=component' + ), + $consentboxLabel, + $attribs + ); + } + + // Association is enabled but this article is not associated + return HTMLHelper::_( + 'link', + Route::_( + 'index.php?option=com_content&view=article&id=' + . $article->id . '&catid=' . $article->catid + . '&tmpl=component&lang=' . $article->language + ), + $consentboxLabel, + $attribs + ); + } +} diff --git a/plugins/content/confirmconsent/confirmconsent.xml b/plugins/content/confirmconsent/confirmconsent.xml new file mode 100644 index 0000000000000..961b08a164db8 --- /dev/null +++ b/plugins/content/confirmconsent/confirmconsent.xml @@ -0,0 +1,44 @@ + + + plg_content_confirmconsent + Joomla! Project + May 2018 + Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + __DEPLOY_VERSION__ + PLG_CONTENT_CONFIRMCONSENT_XML_DESCRIPTION + + confirmconsent.php + + + +
+ + + +
+
+
+
\ No newline at end of file diff --git a/plugins/privacy/actionlogs/actionlogs.php b/plugins/privacy/actionlogs/actionlogs.php new file mode 100644 index 0000000000000..f6db3ceca4743 --- /dev/null +++ b/plugins/privacy/actionlogs/actionlogs.php @@ -0,0 +1,85 @@ +createDomain('actionlog', 'Logged actions of the user'); + + $query = $this->db->getQuery(true) + ->select('a.*, u.name') + ->from('#__action_logs AS a') + ->innerJoin('#__users AS u ON a.user_id = u.id') + ->where($this->db->quoteName('a.user_id') . ' = ' . $user->id); + + $this->db->setQuery($query); + + $data = $this->db->loadObjectList(); + + if (!count($data)) + { + return array(); + } + + $data = ActionlogsHelper::getCsvData($data); + array_shift($data); + + foreach ($data as $item) + { + $domain->addItem($this->createItemFromArray($item)); + } + + return array($domain); + } +} diff --git a/plugins/privacy/actionlogs/actionlogs.xml b/plugins/privacy/actionlogs/actionlogs.xml new file mode 100644 index 0000000000000..f37879f35e81b --- /dev/null +++ b/plugins/privacy/actionlogs/actionlogs.xml @@ -0,0 +1,19 @@ + + + plg_privacy_actionlogs + Joomla! Project + July 2018 + (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + PLG_PRIVACY_ACTIONLOGS_XML_DESCRIPTION + + actionlogs.php + + + en-GB.plg_privacy_actionlogs.ini + en-GB.plg_privacy_actionlogs.sys.ini + + diff --git a/plugins/privacy/contact/contact.php b/plugins/privacy/contact/contact.php new file mode 100644 index 0000000000000..8bf8fd9e1f3cb --- /dev/null +++ b/plugins/privacy/contact/contact.php @@ -0,0 +1,155 @@ +email)) + { + return array(); + } + + $domains = array(); + $domains[] = $this->createContactDomain($request, $user); + + // An user may have more than 1 contact linked to them + foreach ($this->contacts as $contact) + { + $domains[] = $this->createContactCustomFieldsDomain($contact); + } + + return $domains; + } + + /** + * Create the domain for the user contact data + * + * @param PrivacyTableRequest $request The request record being processed + * @param JUser $user The user account associated with this request if available + * + * @return PrivacyExportDomain + * + * @since __DEPLOY_VERSION__ + */ + private function createContactDomain(PrivacyTableRequest $request, JUser $user = null) + { + $domain = $this->createDomain('user contact', 'Joomla! user contact data'); + + if ($user) + { + $query = $this->db->getQuery(true) + ->select('*') + ->from($this->db->quoteName('#__contact_details')) + ->where($this->db->quoteName('user_id') . ' = ' . (int) $user->id) + ->order($this->db->quoteName('ordering') . ' ASC'); + } + else + { + $query = $this->db->getQuery(true) + ->select('*') + ->from($this->db->quoteName('#__contact_details')) + ->where($this->db->quoteName('email_to') . ' = ' . $this->db->quote($request->email)) + ->order($this->db->quoteName('ordering') . ' ASC'); + } + + $items = $this->db->setQuery($query)->loadAssocList(); + + foreach ($items as $item) + { + $domain->addItem($this->createItemFromArray($item)); + $this->contacts[] = (object) $item; + } + + return $domain; + } + + /** + * Create the domain for the contact custom fields + * + * @param Object $contact The contact to process + * + * @return PrivacyExportDomain + * + * @since __DEPLOY_VERSION__ + */ + private function createContactCustomFieldsDomain($contact) + { + $domain = $this->createDomain('contact custom fields', 'Joomla! contact custom fields data'); + + // Get item's fields, also preparing their value property for manual display + $fields = FieldsHelper::getFields('com_contact.contact', $contact); + + foreach ($fields as $field) + { + $fieldValue = is_array($field->value) ? implode(', ', $field->value) : $field->value; + + $data = array( + 'contact_id' => $contact->id, + 'field_name' => $field->name, + 'field_title' => $field->title, + 'field_value' => $fieldValue, + ); + + $domain->addItem($this->createItemFromArray($data)); + } + + return $domain; + } +} diff --git a/plugins/privacy/contact/contact.xml b/plugins/privacy/contact/contact.xml new file mode 100644 index 0000000000000..2de5eed47f655 --- /dev/null +++ b/plugins/privacy/contact/contact.xml @@ -0,0 +1,19 @@ + + + plg_privacy_contact + Joomla! Project + July 2018 + (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + PLG_PRIVACY_CONTACT_XML_DESCRIPTION + + contact.php + + + en-GB.plg_privacy_contact.ini + en-GB.plg_privacy_contact.sys.ini + + diff --git a/plugins/privacy/content/content.php b/plugins/privacy/content/content.php new file mode 100644 index 0000000000000..ddfecde902cb1 --- /dev/null +++ b/plugins/privacy/content/content.php @@ -0,0 +1,142 @@ +createContentDomain($user); + + foreach ($this->contents as $content) + { + $domains[] = $this->createContentCustomFieldsDomain($content); + } + + return $domains; + } + + /** + * Create the domain for the user content data + * + * @param JUser $user The user account associated with this request + * + * @return PrivacyExportDomain + * + * @since __DEPLOY_VERSION__ + */ + private function createContentDomain(JUser $user) + { + $domain = $this->createDomain('user content', 'Joomla! user content data'); + + $query = $this->db->getQuery(true) + ->select('*') + ->from($this->db->quoteName('#__content')) + ->where($this->db->quoteName('created_by') . ' = ' . (int) $user->id) + ->order($this->db->quoteName('ordering') . ' ASC'); + + $items = $this->db->setQuery($query)->loadAssocList(); + + foreach ($items as $item) + { + $domain->addItem($this->createItemFromArray($item)); + $this->contents[] = (object) $item; + } + + return $domain; + } + + /** + * Create the domain for the content custom fields + * + * @param Object $content The content to process + * + * @return PrivacyExportDomain + * + * @since __DEPLOY_VERSION__ + */ + private function createContentCustomFieldsDomain($content) + { + $domain = $this->createDomain('content custom fields', 'Joomla! content custom fields data'); + + // Get item's fields, also preparing their value property for manual display + $fields = FieldsHelper::getFields('com_content.article', $content); + + foreach ($fields as $field) + { + $fieldValue = is_array($field->value) ? implode(', ', $field->value) : $field->value; + + $data = array( + 'content_id' => $content->id, + 'field_name' => $field->name, + 'field_title' => $field->title, + 'field_value' => $fieldValue, + ); + + $domain->addItem($this->createItemFromArray($data)); + } + + return $domain; + } +} diff --git a/plugins/privacy/content/content.xml b/plugins/privacy/content/content.xml new file mode 100644 index 0000000000000..a2114f106c31c --- /dev/null +++ b/plugins/privacy/content/content.xml @@ -0,0 +1,19 @@ + + + plg_privacy_content + Joomla! Project + July 2018 + (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + PLG_PRIVACY_CONTENT_XML_DESCRIPTION + + content.php + + + en-GB.plg_privacy_content.ini + en-GB.plg_privacy_content.sys.ini + + diff --git a/plugins/privacy/message/message.php b/plugins/privacy/message/message.php new file mode 100644 index 0000000000000..023d5e6845567 --- /dev/null +++ b/plugins/privacy/message/message.php @@ -0,0 +1,94 @@ +createMessageDomain($user); + + return $domains; + } + + /** + * Create the domain for the user message data + * + * @param JUser $user The user account associated with this request + * + * @return PrivacyExportDomain + * + * @since __DEPLOY_VERSION__ + */ + private function createMessageDomain(JUser $user) + { + $domain = $this->createDomain('user message', 'Joomla! user message data'); + + $query = $this->db->getQuery(true) + ->select('*') + ->from($this->db->quoteName('#__messages')) + ->where($this->db->quoteName('user_id_from') . ' = ' . (int) $user->id) + ->orWhere($this->db->quoteName('user_id_to') . ' = ' . (int) $user->id) + ->order($this->db->quoteName('date_time') . ' ASC'); + + $items = $this->db->setQuery($query)->loadAssocList(); + + foreach ($items as $item) + { + $domain->addItem($this->createItemFromArray($item)); + } + + return $domain; + } +} diff --git a/plugins/privacy/message/message.xml b/plugins/privacy/message/message.xml new file mode 100644 index 0000000000000..9a7f19f6f1548 --- /dev/null +++ b/plugins/privacy/message/message.xml @@ -0,0 +1,19 @@ + + + plg_privacy_message + Joomla! Project + July 2018 + (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + PLG_PRIVACY_MESSAGE_XML_DESCRIPTION + + message.php + + + en-GB.plg_privacy_message.ini + en-GB.plg_privacy_message.sys.ini + + diff --git a/plugins/privacy/user/user.php b/plugins/privacy/user/user.php new file mode 100644 index 0000000000000..496ff358b0809 --- /dev/null +++ b/plugins/privacy/user/user.php @@ -0,0 +1,308 @@ +authorise('core.admin')) + { + $status->canRemove = false; + $status->reason = JText::_('PLG_PRIVACY_USER_ERROR_CANNOT_REMOVE_SUPER_USER'); + } + + return $status; + } + + /** + * Processes an export request for Joomla core user data + * + * This event will collect data for the following core tables: + * + * - #__users (excluding the password, otpKey, and otep columns) + * - #__user_notes + * - #__user_profiles + * - User custom fields + * + * @param PrivacyTableRequest $request The request record being processed + * @param JUser $user The user account associated with this request if available + * + * @return PrivacyExportDomain[] + * + * @since __DEPLOY_VERSION__ + */ + public function onPrivacyExportRequest(PrivacyTableRequest $request, JUser $user = null) + { + if (!$user) + { + return array(); + } + + /** @var JTableUser $userTable */ + $userTable = JUser::getTable(); + $userTable->load($user->id); + + $domains = array(); + $domains[] = $this->createUserDomain($userTable); + $domains[] = $this->createNotesDomain($userTable); + $domains[] = $this->createProfileDomain($userTable); + $domains[] = $this->createUserCustomFieldsDomain($userTable); + + return $domains; + } + + /** + * Removes the data associated with a remove information request + * + * This event will pseudoanonymise the user account + * + * @param PrivacyTableRequest $request The request record being processed + * @param JUser $user The user account associated with this request if available + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onPrivacyRemoveData(PrivacyTableRequest $request, JUser $user = null) + { + // This plugin only processes data for registered user accounts + if (!$user) + { + return; + } + + $pseudoanonymisedData = array( + 'name' => 'User ID ' . $user->id, + 'username' => bin2hex(random_bytes(12)), + 'email' => 'UserID' . $user->id . 'removed@email.invalid', + 'block' => true, + ); + + $user->bind($pseudoanonymisedData); + + $user->save(); + + // Destroy all sessions for the user account + $sessionIds = $this->db->setQuery( + $this->db->getQuery(true) + ->select($this->db->quoteName('session_id')) + ->from($this->db->quoteName('#__session')) + ->where($this->db->quoteName('userid') . ' = ' . (int) $user->id) + )->loadColumn(); + + // If there aren't any active sessions then there's nothing to do here + if (empty($sessionIds)) + { + return; + } + + $storeName = JFactory::getConfig()->get('session_handler', 'none'); + $store = JSessionStorage::getInstance($storeName); + $quotedIds = array(); + + // Destroy the sessions and quote the IDs to purge the session table + foreach ($sessionIds as $sessionId) + { + $store->destroy($sessionId); + $quotedIds[] = $this->db->quote($sessionId); + } + + $this->db->setQuery( + $this->db->getQuery(true) + ->delete($this->db->quoteName('#__session')) + ->where($this->db->quoteName('session_id') . ' IN (' . implode(', ', $quotedIds) . ')') + )->execute(); + } + + /** + * Create the domain for the user notes data + * + * @param JTableUser $user The JTableUser object to process + * + * @return PrivacyExportDomain + * + * @since __DEPLOY_VERSION__ + */ + private function createNotesDomain(JTableUser $user) + { + $domain = $this->createDomain('user notes', 'Joomla! user notes data'); + + $query = $this->db->getQuery(true) + ->select('*') + ->from($this->db->quoteName('#__user_notes')) + ->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($user->id)); + + $items = $this->db->setQuery($query)->loadAssocList(); + + // Remove user ID columns + foreach (array('user_id', 'created_user_id', 'modified_user_id') as $column) + { + $items = ArrayHelper::dropColumn($items, $column); + } + + foreach ($items as $item) + { + $domain->addItem($this->createItemFromArray($item, $item['id'])); + } + + return $domain; + } + + /** + * Create the domain for the user profile data + * + * @param JTableUser $user The JTableUser object to process + * + * @return PrivacyExportDomain + * + * @since __DEPLOY_VERSION__ + */ + private function createProfileDomain(JTableUser $user) + { + $domain = $this->createDomain('user profile', 'Joomla! user profile data'); + + $query = $this->db->getQuery(true) + ->select('*') + ->from($this->db->quoteName('#__user_profiles')) + ->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($user->id)) + ->order($this->db->quoteName('ordering') . ' ASC'); + + $items = $this->db->setQuery($query)->loadAssocList(); + + foreach ($items as $item) + { + $domain->addItem($this->createItemFromArray($item)); + } + + return $domain; + } + + /** + * Create the domain for the user record + * + * @param JTableUser $user The JTableUser object to process + * + * @return PrivacyExportDomain + * + * @since __DEPLOY_VERSION__ + */ + private function createUserDomain(JTableUser $user) + { + $domain = $this->createDomain('users', 'Joomla! users table data'); + $domain->addItem($this->createItemForUserTable($user)); + + return $domain; + } + + /** + * Create an item object for a JTableUser object + * + * @param JTableUser $user The JTableUser object to convert + * + * @return PrivacyExportItem + * + * @since __DEPLOY_VERSION__ + */ + private function createItemForUserTable(JTableUser $user) + { + $data = array(); + $exclude = array('password', 'otpKey', 'otep'); + + foreach (array_keys($user->getFields()) as $fieldName) + { + if (!in_array($fieldName, $exclude)) + { + $data[$fieldName] = $user->$fieldName; + } + } + + return $this->createItemFromArray($data, $user->id); + } + + /** + * Create the domain for the user custom fields + * + * @param JTableUser $user The JTableUser object to process + * + * @return PrivacyExportDomain + * + * @since __DEPLOY_VERSION__ + */ + private function createUserCustomFieldsDomain(JTableUser $user) + { + $domain = $this->createDomain('user custom fields', 'Joomla! user custom fields data'); + + // Get item's fields, also preparing their value property for manual display + $fields = FieldsHelper::getFields('com_users.user', $user); + + foreach ($fields as $field) + { + $fieldValue = is_array($field->value) ? implode(', ', $field->value) : $field->value; + + $data = array( + 'user_id' => $user->id, + 'field_name' => $field->name, + 'field_title' => $field->title, + 'field_value' => $fieldValue, + ); + + $domain->addItem($this->createItemFromArray($data)); + } + + return $domain; + } +} diff --git a/plugins/privacy/user/user.xml b/plugins/privacy/user/user.xml new file mode 100644 index 0000000000000..06277aad43f93 --- /dev/null +++ b/plugins/privacy/user/user.xml @@ -0,0 +1,19 @@ + + + plg_privacy_user + Joomla! Project + May 2018 + (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + PLG_PRIVACY_USER_XML_DESCRIPTION + + user.php + + + en-GB.plg_privacy_user.ini + en-GB.plg_privacy_user.sys.ini + + diff --git a/plugins/quickicon/privacycheck/privacycheck.php b/plugins/quickicon/privacycheck/privacycheck.php new file mode 100644 index 0000000000000..f78fabd4286de --- /dev/null +++ b/plugins/quickicon/privacycheck/privacycheck.php @@ -0,0 +1,80 @@ +params->get('context', 'mod_quickicon') || !Factory::getUser()->authorise('core.admin', 'com_privacy')) + { + return; + } + + JHtml::_('jquery.framework'); + + $token = Session::getFormToken() . '=' . 1; + $privacy = 'index.php?option=com_privacy'; + + $options = array( + 'plg_quickicon_privacycheck_url' => Uri::base() . $privacy . '&view=requests&filter[status]=1&list[fullordering]=a.requested_at ASC', + 'plg_quickicon_privacycheck_ajax_url' => Uri::base() . $privacy . '&task=getNumberUrgentRequests&' . $token, + 'plg_quickicon_privacycheck_text' => array( + "NOREQUEST" => Text::_('PLG_QUICKICON_PRIVACYCHECK_NOREQUEST', true), + "REQUESTFOUND" => Text::_('PLG_QUICKICON_PRIVACYCHECK_REQUESTFOUND', true), + "REQUESTFOUND_MESSAGE" => Text::_('PLG_QUICKICON_PRIVACYCHECK_REQUESTFOUND_MESSAGE', true), + "REQUESTFOUND_BUTTON" => Text::_('PLG_QUICKICON_PRIVACYCHECK_REQUESTFOUND_BUTTON', true), + "ERROR" => Text::_('PLG_QUICKICON_PRIVACYCHECK_ERROR', true), + ) + ); + + Factory::getDocument()->addScriptOptions('js-privacy-check', $options); + + JHtml::_('script', 'plg_quickicon_privacycheck/privacycheck.js', array('version' => 'auto', 'relative' => true)); + + return array( + array( + 'link' => $privacy . '&view=requests&filter[status]=1&list[fullordering]=a.requested_at ASC', + 'image' => 'users', + 'icon' => 'header/icon-48-user.png', + 'text' => Text::_('PLG_QUICKICON_PRIVACYCHECK_CHECKING'), + 'id' => 'plg_quickicon_privacycheck', + 'group' => 'MOD_QUICKICON_USERS' + ) + ); + } +} diff --git a/plugins/quickicon/privacycheck/privacycheck.xml b/plugins/quickicon/privacycheck/privacycheck.xml new file mode 100644 index 0000000000000..4825bf588eaa5 --- /dev/null +++ b/plugins/quickicon/privacycheck/privacycheck.xml @@ -0,0 +1,19 @@ + + + plg_quickicon_privacycheck + Joomla! Project + June 2018 + Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + PLG_QUICKICON_PRIVACYCHECK_XML_DESCRIPTION + + privacycheck.php + + + en-GB.plg_quickicon_privacycheck.ini + en-GB.plg_quickicon_privacycheck.sys.ini + + diff --git a/plugins/system/actionlogs/actionlogs.php b/plugins/system/actionlogs/actionlogs.php new file mode 100644 index 0000000000000..00b5e6ced8f56 --- /dev/null +++ b/plugins/system/actionlogs/actionlogs.php @@ -0,0 +1,265 @@ +subject->setError('JERROR_NOT_A_FORM'); + + return false; + } + + $formName = $form->getName(); + + $allowedFormNames = array( + 'com_users.profile', + 'com_admin.profile', + 'com_users.user', + ); + + if (!in_array($formName, $allowedFormNames)) + { + return true; + } + + /** + * We only allow users who has Super User permission change this setting for himself or for other users + * who has same Super User permission + */ + + $user = JFactory::getUser(); + + if (!$user->authorise('core.admin')) + { + return true; + } + + // If we are on the save command, no data is passed to $data variable, we need to get it directly from request + $jformData = $this->app->input->get('jform', array(), 'array'); + + if ($jformData && !$data) + { + $data = $jformData; + } + + if (is_array($data)) + { + $data = (object) $data; + } + + if (!empty($data->id) && !JUser::getInstance($data->id)->authorise('core.admin')) + { + return true; + } + + JForm::addFormPath(dirname(__FILE__) . '/forms'); + $form->loadFile('actionlogs', false); + } + + /** + * Runs after the HTTP response has been sent to the client and delete log records older than certain days + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onAfterRespond() + { + $daysToDeleteAfter = (int) $this->params->get('logDeletePeriod', 0); + + if ($daysToDeleteAfter <= 0) + { + return; + } + + // The delete frequency will be once per day + $deleteFrequency = 3600 * 24; + + // Do we need to run? Compare the last run timestamp stored in the plugin's options with the current + // timestamp. If the difference is greater than the cache timeout we shall not execute again. + $now = time(); + $last = (int) $this->params->get('lastrun', 0); + + if (abs($now - $last) < $deleteFrequency) + { + return; + } + + // Update last run status + $this->params->set('lastrun', $now); + + $db = $this->db; + $query = $db->getQuery(true) + ->update($db->qn('#__extensions')) + ->set($db->qn('params') . ' = ' . $db->q($this->params->toString('JSON'))) + ->where($db->qn('type') . ' = ' . $db->q('plugin')) + ->where($db->qn('folder') . ' = ' . $db->q('system')) + ->where($db->qn('element') . ' = ' . $db->q('actionlogs')); + + try + { + // Lock the tables to prevent multiple plugin executions causing a race condition + $db->lockTable('#__extensions'); + } + catch (Exception $e) + { + // If we can't lock the tables it's too risky to continue execution + return; + } + + try + { + // Update the plugin parameters + $result = $db->setQuery($query)->execute(); + + $this->clearCacheGroups(array('com_plugins'), array(0, 1)); + } + catch (Exception $exc) + { + // If we failed to execite + $db->unlockTables(); + $result = false; + } + + try + { + // Unlock the tables after writing + $db->unlockTables(); + } + catch (Exception $e) + { + // If we can't lock the tables assume we have somehow failed + $result = false; + } + + // Abort on failure + if (!$result) + { + return; + } + + $daysToDeleteAfter = (int) $this->params->get('logDeletePeriod', 0); + + if ($daysToDeleteAfter > 0) + { + $conditions = array($db->quoteName('log_date') . ' < DATE_SUB(NOW(), INTERVAL ' . $daysToDeleteAfter . ' DAY)'); + + $query->clear() + ->delete($db->quoteName('#__action_logs'))->where($conditions); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + // Ignore it + return; + } + } + } + + /** + * Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp. + * + * @param array $clearGroups The cache groups to clean + * @param array $cacheClients The cache clients (site, admin) to clean + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function clearCacheGroups(array $clearGroups, array $cacheClients = array(0, 1)) + { + $conf = JFactory::getConfig(); + + foreach ($clearGroups as $group) + { + foreach ($cacheClients as $client_id) + { + try + { + $options = array( + 'defaultgroup' => $group, + 'cachebase' => $client_id ? JPATH_ADMINISTRATOR . '/cache' : + $conf->get('cache_path', JPATH_SITE . '/cache') + ); + + $cache = JCache::getInstance('callback', $options); + $cache->clean(); + } + catch (Exception $e) + { + // Ignore it + } + } + } + } +} diff --git a/plugins/system/actionlogs/actionlogs.xml b/plugins/system/actionlogs/actionlogs.xml new file mode 100644 index 0000000000000..d40bf67394489 --- /dev/null +++ b/plugins/system/actionlogs/actionlogs.xml @@ -0,0 +1,40 @@ + + + PLG_SYSTEM_ACTIONLOGS + Joomla! Project + May 2018 + Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + __DEPLOY_VERSION__ + PLG_SYSTEM_ACTIONLOGS_XML_DESCRIPTION + + actionlogs.php + forms + + + +
+ + +
+
+
+
diff --git a/plugins/system/actionlogs/forms/actionlogs.xml b/plugins/system/actionlogs/forms/actionlogs.xml new file mode 100644 index 0000000000000..1aef8b6157a56 --- /dev/null +++ b/plugins/system/actionlogs/forms/actionlogs.xml @@ -0,0 +1,27 @@ + +
+ +
+ + + + + +
+
+
diff --git a/plugins/system/languagefilter/languagefilter.php b/plugins/system/languagefilter/languagefilter.php index a04d7c4791a69..57b854e444fa5 100644 --- a/plugins/system/languagefilter/languagefilter.php +++ b/plugins/system/languagefilter/languagefilter.php @@ -518,6 +518,24 @@ public function parseRule(&$router, &$uri) return $array; } + /** + * Reports the privacy related capabilities for this plugin to site administrators. + * + * @return array + * + * @since __DEPLOY_VERSION__ + */ + public function onPrivacyCollectAdminCapabilities() + { + $this->loadLanguage(); + + return array( + JText::_('PLG_SYSTEM_LANGUAGEFILTER') => array( + JText::_('PLG_SYSTEM_LANGUAGEFILTER_PRIVACY_CAPABILITY_LANGUAGE_COOKIE'), + ) + ); + } + /** * Before store user method. * diff --git a/plugins/system/logrotation/logrotation.php b/plugins/system/logrotation/logrotation.php new file mode 100644 index 0000000000000..542f13e17e23c --- /dev/null +++ b/plugins/system/logrotation/logrotation.php @@ -0,0 +1,274 @@ +params->get('cachetimeout', 30); + $cache_timeout = 24 * 3600 * $cache_timeout; + $logsToKeep = (int) $this->params->get('logstokeep', 1); + + // Do we need to run? Compare the last run timestamp stored in the plugin's options with the current + // timestamp. If the difference is greater than the cache timeout we shall not execute again. + $now = time(); + $last = (int) $this->params->get('lastrun', 0); + + if ((abs($now - $last) < $cache_timeout)) + { + return; + } + + // Update last run status + $this->params->set('lastrun', $now); + + $db = $this->db; + $query = $db->getQuery(true) + ->update($db->qn('#__extensions')) + ->set($db->qn('params') . ' = ' . $db->q($this->params->toString('JSON'))) + ->where($db->qn('type') . ' = ' . $db->q('plugin')) + ->where($db->qn('folder') . ' = ' . $db->q('system')) + ->where($db->qn('element') . ' = ' . $db->q('logrotation')); + + try + { + // Lock the tables to prevent multiple plugin executions causing a race condition + $db->lockTable('#__extensions'); + } + catch (Exception $e) + { + // If we can't lock the tables it's too risky to continue execution + return; + } + + try + { + // Update the plugin parameters + $result = $db->setQuery($query)->execute(); + + $this->clearCacheGroups(array('com_plugins'), array(0, 1)); + } + catch (Exception $exc) + { + // If we failed to execite + $db->unlockTables(); + $result = false; + } + + try + { + // Unlock the tables after writing + $db->unlockTables(); + } + catch (Exception $e) + { + // If we can't lock the tables assume we have somehow failed + $result = false; + } + + // Abort on failure + if (!$result) + { + return; + } + + // Get the log path + $logPath = Path::clean($this->app->get('log_path')); + + // Invalid path, stop processing further + if (!is_dir($logPath)) + { + return; + } + + $logFiles = $this->getLogFiles($logPath); + + // Sort log files by version number in reserve order + krsort($logFiles, SORT_NUMERIC); + + foreach ($logFiles as $version => $files) + { + if ($version >= $logsToKeep) + { + // Delete files which has version greater than or equals $logsToKeep + foreach ($files as $file) + { + File::delete($logPath . '/' . $file); + } + } + else + { + // For files which has version smaller than $logsToKeep, rotate (increase version number) + foreach ($files as $file) + { + $this->rotate($logPath, $file, $version); + } + } + } + } + + /** + * Get log files from log folder + * + * @param string $path The folder to get log files + * + * @return array The log files in the given path grouped by version number (not rotated files has number 0) + * + * @since __DEPLOY_VERSION__ + */ + private function getLogFiles($path) + { + $logFiles = array(); + $files = Folder::files($path, '\.php$'); + + foreach ($files as $file) + { + $parts = explode('.', $file); + + /* + * Rotated log file has this filename format [VERSION].[FILENAME].php. So if $parts has at least 3 elements + * and the first element is a number, we know that it's a rotated file and can get it's current version + */ + if (count($parts) >= 3 && is_numeric($parts[0])) + { + $version = (int) $parts[0]; + } + else + { + $version = 0; + } + + if (!isset($logFiles[$version])) + { + $logFiles[$version] = array(); + } + + $logFiles[$version][] = $file; + } + + return $logFiles; + } + + /** + * Method to rotate (increase version) of a log file + * + * @param string $path Path to file to rotate + * @param string $filename Name of file to rotate + * @param int $currentVersion The current version number + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function rotate($path, $filename, $currentVersion) + { + if ($currentVersion === 0) + { + $rotatedFile = $path . '/1.' . $filename; + } + else + { + /* + * Rotated log file has this filename format [VERSION].[FILENAME].php. To rotate it, we just need to explode + * the filename into an array, increase value of first element (keep version) and implode it back to get the + * rotated file name + */ + $parts = explode('.', $filename); + $parts[0] = $currentVersion + 1; + + $rotatedFile = $path . '/' . implode('.', $parts); + } + + File::move($path . '/' . $filename, $rotatedFile); + } + + /** + * Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp. + * + * @param array $clearGroups The cache groups to clean + * @param array $cacheClients The cache clients (site, admin) to clean + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function clearCacheGroups(array $clearGroups, array $cacheClients = array(0, 1)) + { + $conf = JFactory::getConfig(); + + foreach ($clearGroups as $group) + { + foreach ($cacheClients as $client_id) + { + try + { + $options = array( + 'defaultgroup' => $group, + 'cachebase' => $client_id ? JPATH_ADMINISTRATOR . '/cache' : + $conf->get('cache_path', JPATH_SITE . '/cache') + ); + + $cache = JCache::getInstance('callback', $options); + $cache->clean(); + } + catch (Exception $e) + { + // Ignore it + } + } + } + } +} diff --git a/plugins/system/logrotation/logrotation.xml b/plugins/system/logrotation/logrotation.xml new file mode 100644 index 0000000000000..6b826a8d800f7 --- /dev/null +++ b/plugins/system/logrotation/logrotation.xml @@ -0,0 +1,57 @@ + + + plg_system_logrotation + Joomla! Project + May 2018 + Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + PLG_SYSTEM_LOGROTATION_XML_DESCRIPTION + + logrotation.php + + + en-GB.plg_system_logrotation.ini + en-GB.plg_system_logrotation.sys.ini + + + +
+ + + + + +
+
+
+
diff --git a/plugins/system/privacyconsent/field/privacy.php b/plugins/system/privacyconsent/field/privacy.php new file mode 100644 index 0000000000000..6a86c260a956a --- /dev/null +++ b/plugins/system/privacyconsent/field/privacy.php @@ -0,0 +1,127 @@ +element['note']) ? $this->element['note'] : Text::_('PLG_SYSTEM_PRIVACYCONSENT_NOTE_FIELD_DEFAULT'); + + echo '
' . $privacynote . '
'; + + return parent::getInput(); + } + + /** + * Method to get the field label markup. + * + * @return string The field label markup. + * + * @since __DEPLOY_VERSION__ + */ + protected function getLabel() + { + if ($this->hidden) + { + return ''; + } + + // Get the label text from the XML element, defaulting to the element name. + $text = $this->element['label'] ? (string) $this->element['label'] : (string) $this->element['name']; + $text = $this->translateLabel ? Text::_($text) : $text; + + // Set required to true as this field is not displayed at all if not required. + $this->required = true; + + JHtml::_('behavior.modal'); + + // Build the class for the label. + $class = !empty($this->description) ? 'hasPopover' : ''; + $class = $class . ' required'; + $class = !empty($this->labelClass) ? $class . ' ' . $this->labelClass : $class; + + // Add the opening label tag and main attributes. + $label = ''; + + return $label; + } +} diff --git a/plugins/system/privacyconsent/privacyconsent.php b/plugins/system/privacyconsent/privacyconsent.php new file mode 100644 index 0000000000000..8172594f03ad6 --- /dev/null +++ b/plugins/system/privacyconsent/privacyconsent.php @@ -0,0 +1,701 @@ +_subject->setError('JERROR_NOT_A_FORM'); + + return false; + } + + // Check we are manipulating a valid form - we only display this on user registration form and user profile form. + $name = $form->getName(); + + if (!in_array($name, array('com_users.profile', 'com_users.registration'))) + { + return true; + } + + // We only display this if user has not consented before + if (is_object($data)) + { + $userId = isset($data->id) ? $data->id : 0; + + if ($userId > 0 && $this->isUserConsented($userId)) + { + return true; + } + } + + // Add the privacy policy fields to the form. + JForm::addFormPath(__DIR__ . '/privacyconsent'); + $form->loadFile('privacyconsent'); + + $privacyArticleId = $this->getPrivacyArticleId(); + $privacynote = $this->params->get('privacy_note'); + + // Push the privacy article ID into the privacy field. + $form->setFieldAttribute('privacy', 'article', $privacyArticleId, 'privacyconsent'); + $form->setFieldAttribute('privacy', 'note', $privacynote, 'privacyconsent'); + } + + /** + * Method is called before user data is stored in the database + * + * @param array $user Holds the old user data. + * @param boolean $isNew True if a new user is stored. + * @param array $data Holds the new user data. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + * @throws InvalidArgumentException on missing required data. + */ + public function onUserBeforeSave($user, $isNew, $data) + { + // // Only check for front-end user creation/update profile + if ($this->app->isClient('administrator')) + { + return true; + } + + $userId = ArrayHelper::getValue($user, 'id', 0, 'int'); + + // User already consented before, no need to check it further + if ($userId > 0 && $this->isUserConsented($userId)) + { + return true; + } + + // Check that the privacy is checked if required ie only in registration from frontend. + $option = $this->app->input->getCmd('option'); + $task = $this->app->input->get->getCmd('task'); + $form = $this->app->input->post->get('jform', array(), 'array'); + + if ($option == 'com_users' && in_array($task, array('registration.register', 'profile.save')) + && empty($form['privacyconsent']['privacy'])) + { + throw new InvalidArgumentException(Text::_('PLG_SYSTEM_PRIVACYCONSENT_FIELD_ERROR')); + } + + return true; + } + + /** + * Saves user privacy confirmation + * + * @param array $data entered user data + * @param boolean $isNew true if this is a new user + * @param boolean $result true if saving the user worked + * @param string $error error message + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function onUserAfterSave($data, $isNew, $result, $error) + { + // Only create an entry on front-end user creation/update profile + if ($this->app->isClient('administrator')) + { + return true; + } + + // Get the user's ID + $userId = ArrayHelper::getValue($data, 'id', 0, 'int'); + + // If user already consented before, no need to check it further + if ($userId > 0 && $this->isUserConsented($userId)) + { + return true; + } + + $option = $this->app->input->getCmd('option'); + $task = $this->app->input->get->getCmd('task'); + $form = $this->app->input->post->get('jform', array(), 'array'); + + if ($option == 'com_users' + &&in_array($task, array('registration.register', 'profile.save')) + && !empty($form['privacyconsent']['privacy'])) + { + $userId = ArrayHelper::getValue($data, 'id', 0, 'int'); + + // Get the user's IP address + $ip = $this->app->input->server->get('REMOTE_ADDR', '', 'string'); + + // Get the user agent string + $userAgent = $this->app->input->server->get('HTTP_USER_AGENT', '', 'string'); + + // Create the user note + $userNote = (object) array( + 'user_id' => $userId, + 'subject' => Text::_('PLG_SYSTEM_PRIVACYCONSENT_SUBJECT'), + 'body' => Text::sprintf('PLG_SYSTEM_PRIVACYCONSENT_BODY', $ip, $userAgent), + 'created' => Factory::getDate()->toSql(), + ); + + try + { + $this->db->insertObject('#__privacy_consents', $userNote); + } + catch (Exception $e) + { + // Do nothing if the save fails + } + } + + return true; + } + + /** + * Remove all user privacy consent information for the given user ID + * + * Method is called after user data is deleted from the database + * + * @param array $user Holds the user data + * @param boolean $success True if user was succesfully stored in the database + * @param string $msg Message + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function onUserAfterDelete($user, $success, $msg) + { + if (!$success) + { + return false; + } + + $userId = ArrayHelper::getValue($user, 'id', 0, 'int'); + + if ($userId) + { + // Remove user's consent + try + { + $query = $this->db->getQuery(true) + ->delete($this->db->quoteName('#__privacy_consents')) + ->where($this->db->quoteName('user_id') . ' = ' . (int) $userId); + $this->db->setQuery($query); + $this->db->execute(); + } + catch (Exception $e) + { + $this->_subject->setError($e->getMessage()); + + return false; + } + } + + return true; + } + + /** + * If logged in users haven't agreed to privacy consent, redirect them to profile edit page, ask them to agree to + * privacy consent before allowing access to any other pages + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onAfterRoute() + { + // Run this in frontend only + if ($this->app->isClient('administrator')) + { + return; + } + + $userId = Factory::getUser()->id; + + // Check to see whether user already consented, if not, redirect to user profile page + if ($userId > 0) + { + // If user consented before, no need to check it further + if ($this->isUserConsented($userId)) + { + return; + } + + $option = $this->app->input->getCmd('option'); + $task = $this->app->input->get('task'); + $view = $this->app->input->getString('view', ''); + $layout = $this->app->input->getString('layout', ''); + $id = $this->app->input->getInt('id'); + + $privacyArticleId = $this->getPrivacyArticleId(); + + /* + * If user is already on edit profile screen or view privacy article + * or press update/apply button, or logout, do nothing to avoid infinite redirect + */ + if ($option == 'com_users' && in_array($task, array('profile.save', 'profile.apply', 'user.logout')) + || ($option == 'com_content' && $view == 'article' && $id == $privacyArticleId) + || ($option == 'com_users' && $view == 'profile' && $layout == 'edit')) + { + return; + } + + // Redirect to com_users profile edit + $this->app->enqueueMessage($this->getRedirectMessage(), 'notice'); + $link = 'index.php?option=com_users&view=profile&layout=edit'; + $this->app->redirect(\JRoute::_($link, false)); + } + } + + /** + * Event to specify whether a privacy policy has been published. + * + * @param array &$policy The privacy policy status data, passed by reference, with keys "published" and "editLink" + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onPrivacyCheckPrivacyPolicyPublished(&$policy) + { + // If another plugin has already indicated a policy is published, we won't change anything here + if ($policy['published']) + { + return; + } + + $articleId = $this->params->get('privacy_article'); + + if (!$articleId) + { + return; + } + + $policy['published'] = true; + $policy['editLink'] = JRoute::_('index.php?option=com_content&task=article.edit&id=' . $articleId); + } + + /** + * Returns the configured redirect message and falls back to the default version. + * + * @return string redirect message + * + * @since __DEPLOY_VERSION__ + */ + private function getRedirectMessage() + { + $messageOnRedirect = trim($this->params->get('messageOnRedirect', '')); + + if (empty($messageOnRedirect)) + { + return Text::_('PLG_SYSTEM_PRIVACYCONSENT_REDIRECT_MESSAGE_DEFAULT'); + } + + return $messageOnRedirect; + } + + /** + * Method to check if the given user has consented yet + * + * @param integer $userId ID of uer to check + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + private function isUserConsented($userId) + { + $query = $this->db->getQuery(true); + $query->select('COUNT(*)') + ->from('#__privacy_consents') + ->where('user_id = ' . (int) $userId); + $this->db->setQuery($query); + + return (int) $this->db->loadResult() > 0; + } + + /** + * Get privacy article ID. If the site is a multilingual website and there is associated article for the + * current language, ID of the associlated article will be returned + * + * @return integer + * + * @since __DEPLOY_VERSION__ + */ + private function getPrivacyArticleId() + { + $privacyArticleId = $this->params->get('privacy_article'); + + if ($privacyArticleId > 0 && JLanguageAssociations::isEnabled()) + { + $privacyAssociated = JLanguageAssociations::getAssociations('com_content', '#__content', 'com_content.item', $privacyArticleId); + $currentLang = JFactory::getLanguage()->getTag(); + + if (isset($privacyAssociated[$currentLang])) + { + $privacyArticleId = $privacyAssociated[$currentLang]->id; + } + } + + return $privacyArticleId; + } + + /** + * The privacy consent expiration check code is triggered after the page has fully rendered. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onAfterRender() + { + if (!$this->params->get('enabled', 0)) + { + return; + } + + $cacheTimeout = (int) $this->params->get('cachetimeout', 30); + $cacheTimeout = 24 * 3600 * $cacheTimeout; + + // Do we need to run? Compare the last run timestamp stored in the plugin's options with the current + // timestamp. If the difference is greater than the cache timeout we shall not execute again. + $now = time(); + $last = (int) $this->params->get('lastrun', 0); + + if ((abs($now - $last) < $cacheTimeout)) + { + return; + } + + // Update last run status + $this->params->set('lastrun', $now); + $db = $this->db; + $query = $db->getQuery(true) + ->update($db->quoteName('#__extensions')) + ->set($db->quoteName('params') . ' = ' . $db->quote($this->params->toString('JSON'))) + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) + ->where($db->quoteName('element') . ' = ' . $db->quote('privacyconsent')); + + try + { + // Lock the tables to prevent multiple plugin executions causing a race condition + $db->lockTable('#__extensions'); + } + catch (Exception $e) + { + // If we can't lock the tables it's too risky to continue execution + return; + } + + try + { + // Update the plugin parameters + $result = $db->setQuery($query)->execute(); + $this->clearCacheGroups(array('com_plugins'), array(0, 1)); + } + catch (Exception $exc) + { + // If we failed to execute + $db->unlockTables(); + $result = false; + } + + try + { + // Unlock the tables after writing + $db->unlockTables(); + } + catch (Exception $e) + { + // If we can't lock the tables assume we have somehow failed + $result = false; + } + + // Abort on failure + if (!$result) + { + return; + } + + // Delete the expired privacy consents + $this->deleteExpiredConsents(); + + // Remind for privacy consents near to expire + $this->remindExpiringConsents(); + + } + + /** + * Method to send the remind for privacy consents renew + * + * @return integer + * + * @since __DEPLOY_VERSION__ + */ + private function remindExpiringConsents() + { + // Load the parameters. + $expire = (int) $this->params->get('consentexpiration', 365); + $remind = (int) $this->params->get('remind', 30); + $now = JFactory::getDate()->toSql(); + $period = '-' . ($expire - $remind); + + $db = $this->db; + $query = $db->getQuery(true) + ->select($db->quoteName(array('r.id', 'r.user_id', 'u.email'))) + ->from($db->quoteName('#__privacy_consents', 'r')) + ->leftJoin($db->quoteName('#__users', 'u') . ' ON u.id = r.user_id') + ->where($db->quoteName('remind') . ' = 0'); + $query->where($query->dateAdd($now, $period, 'DAY') . ' > ' . $db->quoteName('created')); + + try + { + $users = $db->setQuery($query)->loadObjectList(); + } + catch (JDatabaseException $exception) + { + return false; + } + + $app = JFactory::getApplication(); + $linkMode = $app->get('force_ssl', 0) == 2 ? 1 : -1; + + foreach ($users as $user) + { + $token = JApplicationHelper::getHash(JUserHelper::genRandomPassword()); + $hashedToken = JUserHelper::hashPassword($token); + + // The mail + try + { + $substitutions = array( + '[SITENAME]' => $app->get('sitename'), + '[URL]' => JUri::root(), + '[TOKENURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=remind&remind_token=' . $token, false, $linkMode), + '[FORMURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=remind', false, $linkMode), + '[TOKEN]' => $token, + '\\n' => "\n", + ); + + $emailSubject = JText::_('PLG_SYSTEM_PRIVACYCONSENT_EMAIL_REMIND_SUBJECT'); + $emailBody = JText::_('PLG_SYSTEM_PRIVACYCONSENT_EMAIL_REMIND_BODY'); + + foreach ($substitutions as $k => $v) + { + $emailSubject = str_replace($k, $v, $emailSubject); + $emailBody = str_replace($k, $v, $emailBody); + } + + $mailer = JFactory::getMailer(); + $mailer->setSubject($emailSubject); + $mailer->setBody($emailBody); + $mailer->addRecipient($user->email); + + $mailResult = $mailer->Send(); + + if ($mailResult instanceof JException) + { + return false; + } + elseif ($mailResult === false) + { + return false; + } + + // Update the privacy_consents item to not send the reminder again + $query->clear() + ->update($db->quoteName('#__privacy_consents')) + ->set($db->quoteName('remind') . ' = 1 ') + ->set($db->quoteName('token') . ' = ' . $db->quote($hashedToken)) + ->where($db->quoteName('id') . ' = ' . $db->quote($user->id)); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + return false; + } + + return true; + } + catch (phpmailerException $exception) + { + return false; + } + } + } + + /** + * Method to delete the expired privacy consents + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + private function deleteExpiredConsents() + { + // Load the parameters. + $expire = (int) $this->params->get('consentexpiration', 365); + $now = JFactory::getDate()->toSql(); + $period = '-' . $expire; + + $db = $this->db; + $query = $db->getQuery(true) + ->select($db->quoteName(array('id', 'user_id'))) + ->from($db->quoteName('#__privacy_consents')); + $query->where($query->dateAdd($now, $period, 'DAY') . ' > ' . $db->quoteName('created')); + $db->setQuery($query); + + try + { + $users = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + return false; + } + + // Do not process further if no expired consents found + if (empty($users)) + { + return true; + } + + // Push a notification to the site's super users + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_messages/models', 'MessagesModel'); + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_messages/tables'); + /** @var MessagesModelMessage $messageModel */ + $messageModel = JModelLegacy::getInstance('Message', 'MessagesModel'); + + foreach ($users as $user) + { + $query = $db->getQuery(true) + ->delete($db->quoteName('#__privacy_consents')); + $query->where($db->quoteName('id') . ' = ' . $user->id); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + return false; + } + + $messageModel->notifySuperUsers( + JText::_('PLG_SYSTEM_PRIVACYCONSENT_NOTIFICATION_USER_PRIVACY_EXPIRED_SUBJECT'), + JText::sprintf('PLG_SYSTEM_PRIVACYCONSENT_NOTIFICATION_USER_PRIVACY_EXPIRED_MESSAGE', $user->user_id) + ); + } + + return true; + } + /** + * Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp. + * + * @param array $clearGroups The cache groups to clean + * @param array $cacheClients The cache clients (site, admin) to clean + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function clearCacheGroups(array $clearGroups, array $cacheClients = array(0, 1)) + { + $conf = JFactory::getConfig(); + + foreach ($clearGroups as $group) + { + foreach ($cacheClients as $client_id) + { + try + { + $options = array( + 'defaultgroup' => $group, + 'cachebase' => $client_id ? JPATH_ADMINISTRATOR . '/cache' : + $conf->get('cache_path', JPATH_SITE . '/cache') + ); + + $cache = JCache::getInstance('callback', $options); + $cache->clean(); + } + catch (Exception $e) + { + // Ignore it + } + } + } + } +} diff --git a/plugins/system/privacyconsent/privacyconsent.xml b/plugins/system/privacyconsent/privacyconsent.xml new file mode 100644 index 0000000000000..f995ddc8686b2 --- /dev/null +++ b/plugins/system/privacyconsent/privacyconsent.xml @@ -0,0 +1,119 @@ + + + plg_system_privacyconsent + Joomla! Project + April 2018 + (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + PLG_SYSTEM_PRIVACYCONSENT_XML_DESCRIPTION + + privacyconsent.php + privacyconsent + field + + + en-GB.plg_system_privacyconsent.ini + en-GB.plg_system_privacyconsent.sys.ini + + + +
+ + + +
+
+ + + + + + + + +
+
+
+
diff --git a/plugins/system/privacyconsent/privacyconsent/privacyconsent.xml b/plugins/system/privacyconsent/privacyconsent/privacyconsent.xml new file mode 100644 index 0000000000000..f86b54faaf58c --- /dev/null +++ b/plugins/system/privacyconsent/privacyconsent/privacyconsent.xml @@ -0,0 +1,21 @@ + +
+ +
+ + + + +
+
+
diff --git a/plugins/user/terms/field/terms.php b/plugins/user/terms/field/terms.php new file mode 100644 index 0000000000000..e82996b800703 --- /dev/null +++ b/plugins/user/terms/field/terms.php @@ -0,0 +1,146 @@ +element['note']) ? $this->element['note'] : Text::_('PLG_USER_TERMS_NOTE_FIELD_DEFAULT'); + + echo '
' . $termsnote . '
'; + + return parent::getInput(); + } + + /** + * Method to get the field label markup. + * + * @return string The field label markup. + * + * @since __DEPLOY_VERSION__ + */ + protected function getLabel() + { + if ($this->hidden) + { + return ''; + } + + // Get the label text from the XML element, defaulting to the element name. + $text = $this->element['label'] ? (string) $this->element['label'] : (string) $this->element['name']; + $text = $this->translateLabel ? Text::_($text) : $text; + + // Set required to true + $this->required = true; + + JHtml::_('behavior.modal'); + + // Build the class for the label. + $class = !empty($this->description) ? 'hasPopover' : ''; + $class = $class . ' required'; + $class = !empty($this->labelClass) ? $class . ' ' . $this->labelClass : $class; + + // Add the opening label tag and main attributes. + $label = ''; + + return $label; + } +} diff --git a/plugins/user/terms/terms.php b/plugins/user/terms/terms.php new file mode 100644 index 0000000000000..a5e4e3b7e5d82 --- /dev/null +++ b/plugins/user/terms/terms.php @@ -0,0 +1,178 @@ +_subject->setError('JERROR_NOT_A_FORM'); + + return false; + } + + // Check we are manipulating a valid form - we only display this on user registration form. + $name = $form->getName(); + + if (!in_array($name, array('com_users.registration'))) + { + return true; + } + + // Add the terms and conditions fields to the form. + JForm::addFormPath(__DIR__ . '/terms'); + $form->loadFile('terms'); + + $termsarticle = $this->params->get('terms_article'); + $termsnote = $this->params->get('terms_note'); + + // Push the terms and conditions article ID into the terms field. + $form->setFieldAttribute('terms', 'article', $termsarticle, 'terms'); + $form->setFieldAttribute('terms', 'note', $termsnote, 'terms'); + } + + /** + * Method is called before user data is stored in the database + * + * @param array $user Holds the old user data. + * @param boolean $isNew True if a new user is stored. + * @param array $data Holds the new user data. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + * @throws InvalidArgumentException on missing required data. + */ + public function onUserBeforeSave($user, $isNew, $data) + { + // // Only check for front-end user registration + if ($this->app->isClient('administrator')) + { + return true; + } + + $userId = ArrayHelper::getValue($user, 'id', 0, 'int'); + + // User already registered, no need to check it further + if ($userId > 0) + { + return true; + } + + // Check that the terms is checked if required ie only in registration from frontend. + $option = $this->app->input->getCmd('option'); + $task = $this->app->input->get->getCmd('task'); + $form = $this->app->input->post->get('jform', array(), 'array'); + + if ($option == 'com_users' && in_array($task, array('registration.register')) && empty($form['terms']['terms'])) + { + throw new InvalidArgumentException(Text::_('PLG_USER_TERMS_FIELD_ERROR')); + } + + return true; + } + + /** + * Saves user profile data + * + * @param array $data entered user data + * @param boolean $isNew true if this is a new user + * @param boolean $result true if saving the user worked + * @param string $error error message + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function onUserAfterSave($data, $isNew, $result, $error) + { + if (!$isNew || !$result) + { + return true; + } + + JLoader::register('ActionlogsModelActionlog', JPATH_ADMINISTRATOR . '/components/com_actionlogs/models/actionlog.php'); + $userId = ArrayHelper::getValue($data, 'id', 0, 'int'); + + $message = array( + 'action' => 'consent', + 'id' => $userId, + 'title' => $data['name'], + 'itemlink' => 'index.php?option=com_users&task=user.edit&id=' . $userId, + 'userid' => $userId, + 'username' => $data['username'], + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $userId, + ); + + /* @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'PLG_USER_TERMS_LOGGING_CONSENT_TO_TERMS', 'plg_user_terms', $userId); + } +} diff --git a/plugins/user/terms/terms.xml b/plugins/user/terms/terms.xml new file mode 100644 index 0000000000000..f3c8a9286bd03 --- /dev/null +++ b/plugins/user/terms/terms.xml @@ -0,0 +1,49 @@ + + + plg_user_terms + Joomla! Project + June 2018 + (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + PLG_USER_TERMS_XML_DESCRIPTION + + terms.php + terms + field + + + en-GB.plg_user_terms.ini + en-GB.plg_user_terms.sys.ini + + + +
+ + +
+
+
+
diff --git a/plugins/user/terms/terms/terms.xml b/plugins/user/terms/terms/terms.xml new file mode 100644 index 0000000000000..c654e3cc3e44a --- /dev/null +++ b/plugins/user/terms/terms/terms.xml @@ -0,0 +1,21 @@ + +
+ +
+ + + + +
+
+