Spade

Mini Shell

Directory:~$ /home/lmsyaran/public_html/css/
Upload File

[Home] [System Details] [Kill Me]
Current File:~$ /home/lmsyaran/public_html/css/com_privacy.tar

config.xml000064400000000547151165412120006537 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<config>
	<fieldset
		name="privacy"
		label="COM_PRIVACY_OPTION_LABEL"
	>

		<field
			name="notify"
			type="integer"
			label="COM_PRIVACY_NOTIFY_LABEL"
			description="COM_PRIVACY_NOTIFY_DESC"
			first="1"
			last="29"
			step="1"
			default="14"
			filter="int"
			validate="number"
		/>

    </fieldset>
</config>
controller.php000064400000002646151165412120007446 0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Privacy Controller
 *
 * @since  3.9.0
 */
class PrivacyController extends JControllerLegacy
{
	/**
	 * Method to display a view.
	 *
	 * @param   boolean  $cachable   If true, the view output will be cached
	 * @param   array    $urlparams  An array of safe URL parameters and their
variable types, for valid values see {@link JFilterInput::clean()}.
	 *
	 * @return  $this
	 *
	 * @since   3.9.0
	 */
	public function display($cachable = false, $urlparams = array())
	{
		$view = $this->input->get('view',
$this->default_view);

		// Submitting information requests and confirmation through the frontend
is restricted to authenticated users at this time
		if (in_array($view, array('confirm', 'request'))
&& JFactory::getUser()->guest)
		{
			$this->setRedirect(
				JRoute::_('index.php?option=com_users&view=login&return='
. base64_encode('index.php?option=com_privacy&view=' .
$view), false)
			);

			return $this;
		}

		// Set a Referrer-Policy header for views which require it
		if (in_array($view, array('confirm', 'remind')))
		{
			JFactory::getApplication()->setHeader('Referrer-Policy',
'no-referrer', true);
		}

		return parent::display($cachable, $urlparams);
	}
}
controllers/consents.php000064400000004031151165412120011453
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Consents management controller class.
 *
 * @since  3.9.0
 */
class PrivacyControllerConsents extends JControllerForm
{
	/**
	 * Method to invalidate specific consents.
	 *
	 * @return  boolean
	 *
	 * @since   3.9.0
	 */
	public function invalidate($key = null, $urlVar = null)
	{
		// Check for request forgeries
		JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		$ids    = $this->input->get('cid', array(),
'array');

		if (empty($ids))
		{
			$this->setError(JText::_('JERROR_NO_ITEMS_SELECTED'));
		}
		else
		{
			// Get the model.
			/** @var PrivacyModelConsents $model */
			$model = $this->getModel();

			// Publish the items.
			if (!$model->invalidate($ids))
			{
				$this->setError($model->getError());
			}

			$message = JText::plural('COM_PRIVACY_N_CONSENTS_INVALIDATED',
count($ids));
		}

		$this->setRedirect(JRoute::_('index.php?option=com_privacy&view=consents',
false), $message);
	}

	/**
	 * Method to invalidate all consents of a specific subject.
	 *
	 * @return  boolean
	 *
	 * @since   3.9.0
	 */
	public function invalidateAll()
	{
		// Check for request forgeries
		JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		$filters = $this->input->get('filter', array(),
'array');

		if (isset($filters['subject']) &&
$filters['subject'] != '')
		{
			$subject = $filters['subject'];
		}
		else
		{
			$this->setError(JText::_('JERROR_NO_ITEMS_SELECTED'));
		}

		// Get the model.
		/** @var PrivacyModelConsents $model */
		$model = $this->getModel();

		// Publish the items.
		if (!$model->invalidateAll($subject))
		{
			$this->setError($model->getError());
		}

		$message = JText::_('COM_PRIVACY_CONSENTS_INVALIDATED_ALL');

		$this->setRedirect(JRoute::_('index.php?option=com_privacy&view=consents',
false), $message);
	}
}
controllers/request.php000064400000010443151165412120011313
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Request action controller class.
 *
 * @since  3.9.0
 */
class PrivacyControllerRequest extends JControllerLegacy
{
	/**
	 * Method to confirm the information request.
	 *
	 * @return  boolean
	 *
	 * @since   3.9.0
	 */
	public function confirm()
	{
		// Check the request token.
		$this->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   3.9.0
	 */
	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   3.9.0
	 */
	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;
		}
	}
}
controllers/request.xml.php000064400000001137151165412120012112
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Request management controller class.
 *
 * @since  3.9.0
 */
class PrivacyControllerRequest extends JControllerLegacy
{
	/**
	 * Method to export the data for a request.
	 *
	 * @return  $this
	 *
	 * @since   3.9.0
	 */
	public function export()
	{
		$this->input->set('view', 'export');

		return $this->display();
	}
}
controllers/requests.php000064400000001670151165412120011500
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Requests management controller class.
 *
 * @since  3.9.0
 */
class PrivacyControllerRequests extends JControllerAdmin
{
	/**
	 * 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  JModelLegacy|boolean  Model object on success; otherwise false
on failure.
	 *
	 * @since   3.9.0
	 */
	public function getModel($name = 'Request', $prefix =
'PrivacyModel', $config = array('ignore_request' =>
true))
	{
		return parent::getModel($name, $prefix, $config);
	}
}
helpers/export/domain.php000064400000002436151165412120011512
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('PrivacyExportItem', __DIR__ .
'/item.php');

/**
 * Data object representing all data contained in a domain.
 *
 * A domain is typically a single database table and the items within the
domain are separate rows from the table.
 *
 * @since  3.9.0
 */
class PrivacyExportDomain
{
	/**
	 * The name of this domain
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	public $name;

	/**
	 * A short description of the data in this domain
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	public $description;

	/**
	 * The items belonging to this domain
	 *
	 * @var    PrivacyExportItem[]
	 * @since  3.9.0
	 */
	protected $items = array();

	/**
	 * Add an item to the domain
	 *
	 * @param   PrivacyExportItem  $item  The item to add
	 *
	 * @return  void
	 *
	 * @since  3.9.0
	 */
	public function addItem(PrivacyExportItem $item)
	{
		$this->items[] = $item;
	}

	/**
	 * Get the domain's items
	 *
	 * @return  PrivacyExportItem[]
	 *
	 * @since  3.9.0
	 */
	public function getItems()
	{
		return $this->items;
	}
}
helpers/export/field.php000064400000001071151165412120011320
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Data object representing a field within an item.
 *
 * @since  3.9.0
 */
class PrivacyExportField
{
	/**
	 * The name of this field
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	public $name;

	/**
	 * The field's value
	 *
	 * @var    mixed
	 * @since  3.9.0
	 */
	public $value;
}
helpers/export/item.php000064400000002254151165412120011177
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('PrivacyExportField', __DIR__ .
'/field.php');

/**
 * Data object representing a single item within a domain.
 *
 * An item is typically a single row from a database table.
 *
 * @since  3.9.0
 */
class PrivacyExportItem
{
	/**
	 * The primary identifier of this item, typically the primary key for a
database row.
	 *
	 * @var    integer
	 * @since  3.9.0
	 */
	public $id;

	/**
	 * The fields belonging to this item
	 *
	 * @var    PrivacyExportField[]
	 * @since  3.9.0
	 */
	protected $fields = array();

	/**
	 * Add a field to the item
	 *
	 * @param   PrivacyExportField  $field  The field to add
	 *
	 * @return  void
	 *
	 * @since  3.9.0
	 */
	public function addField(PrivacyExportField $field)
	{
		$this->fields[] = $field;
	}

	/**
	 * Get the item's fields
	 *
	 * @return  PrivacyExportField[]
	 *
	 * @since  3.9.0
	 */
	public function getFields()
	{
		return $this->fields;
	}
}
helpers/html/helper.php000064400000002033151165412120011136
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Privacy component HTML helper.
 *
 * @since  3.9.0
 */
class PrivacyHtmlHelper
{
	/**
	 * Render a status label
	 *
	 * @param   integer  $status  The item status
	 *
	 * @return  string
	 *
	 * @since   3.9.0
	 */
	public static function statusLabel($status)
	{
		switch ($status)
		{
			case 2:
				return '<span class="label label-success">' .
JText::_('COM_PRIVACY_STATUS_COMPLETED') .
'</span>';

			case 1:
				return '<span class="label label-info">' .
JText::_('COM_PRIVACY_STATUS_CONFIRMED') .
'</span>';

			case -1:
				return '<span class="label label-important">'
. JText::_('COM_PRIVACY_STATUS_INVALID') .
'</span>';

			default:
			case 0:
				return '<span class="label label-warning">' .
JText::_('COM_PRIVACY_STATUS_PENDING') .
'</span>';
		}
	}
}
helpers/plugin.php000064400000007237151165412120010224 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('PrivacyExportDomain', __DIR__ .
'/export/domain.php');
JLoader::register('PrivacyExportField', __DIR__ .
'/export/field.php');
JLoader::register('PrivacyExportItem', __DIR__ .
'/export/item.php');
JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR .
'/components/com_fields/helpers/fields.php');

/**
 * Base class for privacy plugins
 *
 * @since  3.9.0
 */
abstract class PrivacyPlugin extends JPlugin
{
	/**
	 * Database object
	 *
	 * @var    JDatabaseDriver
	 * @since  3.9.0
	 */
	protected $db;

	/**
	 * Affects constructor behaviour. If true, language files will be loaded
automatically.
	 *
	 * @var    boolean
	 * @since  3.9.0
	 */
	protected $autoloadLanguage = true;

	/**
	 * Create a new domain object
	 *
	 * @param   string  $name         The domain's name
	 * @param   string  $description  The domain's description
	 *
	 * @return  PrivacyExportDomain
	 *
	 * @since   3.9.0
	 */
	protected function createDomain($name, $description = '')
	{
		$domain              = new PrivacyExportDomain;
		$domain->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   3.9.0
	 */
	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   3.9.0
	 */
	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)});
	}

	/**
	 * Helper function to create the domain for the items custom fields.
	 *
	 * @param   string  $context  The context
	 * @param   array   $items    The items
	 *
	 * @return  PrivacyExportDomain
	 *
	 * @since   3.9.0
	 */
	protected function createCustomFieldsDomain($context, $items = array())
	{
		if (!is_array($items))
		{
			$items = array($items);
		}

		$parts = FieldsHelper::extract($context);

		if (!$parts)
		{
			return array();
		}

		$type = str_replace('com_', '', $parts[0]);

		$domain = $this->createDomain($type . '_' . $parts[1] .
'_custom_fields', 'joomla_' . $type . '_' .
$parts[1] . '_custom_fields_data');

		foreach ($items as $item)
		{
			// Get item's fields, also preparing their value property for
manual display
			$fields = FieldsHelper::getFields($parts[0] . '.' . $parts[1],
$item);

			foreach ($fields as $field)
			{
				$fieldValue = is_array($field->value) ? implode(', ',
$field->value) : $field->value;

				$data = array(
					$type . '_id' => $item->id,
					'field_name'  => $field->name,
					'field_title' => $field->title,
					'field_value' => $fieldValue,
				);

				$domain->addItem($this->createItemFromArray($data));
			}
		}

		return $domain;
	}
}
helpers/privacy.php000064400000005454151165412120010402 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Factory;

/**
 * Privacy component helper.
 *
 * @since  3.9.0
 */
class PrivacyHelper extends JHelperContent
{
	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 *
	 * @since   3.9.0
	 */
	public static function addSubmenu($vName)
	{
		JHtmlSidebar::addEntry(
			JText::_('COM_PRIVACY_SUBMENU_DASHBOARD'),
			'index.php?option=com_privacy&view=dashboard',
			$vName === 'dashboard'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_PRIVACY_SUBMENU_REQUESTS'),
			'index.php?option=com_privacy&view=requests',
			$vName === 'requests'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_PRIVACY_SUBMENU_CAPABILITIES'),
			'index.php?option=com_privacy&view=capabilities',
			$vName === 'capabilities'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_PRIVACY_SUBMENU_CONSENTS'),
			'index.php?option=com_privacy&view=consents',
			$vName === 'consents'
		);
	}

	/**
	 * Render the data request as a XML document.
	 *
	 * @param   PrivacyExportDomain[]  $exportData  The data to be exported.
	 *
	 * @return  string
	 *
	 * @since   3.9.0
	 */
	public static function renderDataAsXml(array $exportData)
	{
		$export = new SimpleXMLElement('<?xml version="1.0"
encoding="utf-8"?><data-export />');

		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();
	}

	/**
	 * Gets the privacyconsent system plugin extension id.
	 *
	 * @return  integer  The privacyconsent system plugin extension id.
	 *
	 * @since   3.9.2
	 */
	public static function getPrivacyConsentPluginId()
	{
		$db    = Factory::getDbo();
		$query = $db->getQuery(true)
			->select($db->quoteName('extension_id'))
			->from($db->quoteName('#__extensions'))
			->where($db->quoteName('folder') . ' = ' .
$db->quote('system'))
			->where($db->quoteName('element') . ' = ' .
$db->quote('privacyconsent'));

		$db->setQuery($query);

		try
		{
			$result = (int) $db->loadResult();
		}
		catch (RuntimeException $e)
		{
			JError::raiseWarning(500, $e->getMessage());
		}

		return $result;
	}
}
helpers/removal/status.php000064400000001511151165412120011703
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Data object communicating the status of whether the data for an
information request can be removed.
 *
 * Typically, this object will only be used to communicate data will be
removed.
 *
 * @since  3.9.0
 */
class PrivacyRemovalStatus
{
	/**
	 * Flag indicating the status reported by the plugin on whether the
information can be removed
	 *
	 * @var    boolean
	 * @since  3.9.0
	 */
	public $canRemove = true;

	/**
	 * A status message indicating the reason data can or cannot be removed
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	public $reason;
}
models/capabilities.php000064400000006535151165412120011200
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Capabilities model class.
 *
 * @since  3.9.0
 */
class PrivacyModelCapabilities extends JModelLegacy
{
	/**
	 * Retrieve the extension capabilities.
	 *
	 * @return  array
	 *
	 * @since   3.9.0
	 */
	public function getCapabilities()
	{
		$app = JFactory::getApplication();

		/*
		 * Capabilities will be collected in two parts:
		 *
		 * 1) Core capabilities - This will cover the core API, i.e. all library
level classes
		 * 2) Extension capabilities - This will be collected by a plugin hook to
select plugin groups
		 *
		 * Plugins which report capabilities should return an associative array
with a single root level key which is used as the title
		 * for the reporting section and an array with each value being a
separate capability. All capability messages should be translated
		 * by the extension when building the array. An example of the structure
expected to be returned from plugins can be found in the
		 * $coreCapabilities array below.
		 */

		$coreCapabilities = array(
			JText::_('COM_PRIVACY_HEADING_CORE_CAPABILITIES') => 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   3.9.0
	 */
	protected function populateState()
	{
		// Load the parameters.
		$this->setState('params',
JComponentHelper::getParams('com_privacy'));
	}
}
models/consents.php000064400000012432151165412120010374 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

/**
 * Consents management model class.
 *
 * @since  3.9.0
 */
class PrivacyModelConsents extends JModelList
{
	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 *
	 * @since   3.9.0
	 */
	public function __construct($config = array())
	{
		if (empty($config['filter_fields']))
		{
			$config['filter_fields'] = array(
				'id', 'a.id', 
				'user_id', 'a.user_id',
				'subject', 'a.subject',
				'created', 'a.created',
				'username', 'u.username',
				'state', 'a.state'
			);
		}

		parent::__construct($config);
	}

	/**
	 * Method to get a JDatabaseQuery object for retrieving the data set from
a database.
	 *
	 * @return  JDatabaseQuery
	 *
	 * @since   3.9.0
	 */
	protected function getListQuery()
	{
		// Create a new query object.
		$db    = $this->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 .
')');
			}
		}

		$state = $this->getState('filter.state');

		if ($state != '')
		{
			$query->where($db->quoteName('a.state') . ' =
' . (int) $state);
		}

		// 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   3.9.0
	 */
	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   3.9.0
	 */
	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.subject',
			$this->getUserStateFromRequest($this->context .
'.filter.subject', 'filter_subject')
		);

		$this->setState(
			'filter.state',
			$this->getUserStateFromRequest($this->context .
'.filter.state', 'filter_state')
		);

		// Load the parameters.
		$this->setState('params',
JComponentHelper::getParams('com_privacy'));

		// List state information.
		parent::populateState($ordering, $direction);
	}

	/**
	 * Method to invalidate specific consents.
	 *
	 * @param   array  $pks  The ids of the consents to invalidate.
	 *
	 * @return  boolean  True on success.
	 */
	public function invalidate($pks)
	{
		// Sanitize the ids.
		$pks = (array) $pks;
		$pks = ArrayHelper::toInteger($pks);

		try
		{
			$db = $this->getDbo();
			$query = $db->getQuery(true)
				->update($db->quoteName('#__privacy_consents'))
				->set($db->quoteName('state') . ' = -1')
				->where($db->quoteName('id') . ' IN (' .
implode(',', $pks) . ')')
				->where($db->quoteName('state') . ' = 1');
			$db->setQuery($query);
			$db->execute();
		}
		catch (JDatabaseExceptionExecuting $e)
		{
			$this->setError($e->getMessage());

			return false;
		}

		return true;
	}

	/**
	 * Method to invalidate a group of specific consents.
	 *
	 * @param   array  $subject  The subject of the consents to invalidate.
	 *
	 * @return  boolean  True on success.
	 */
	public function invalidateAll($subject)
	{
		try
		{
			$db = $this->getDbo();
			$query = $db->getQuery(true)
				->update($db->quoteName('#__privacy_consents'))
				->set($db->quoteName('state') . ' = -1')
				->where($db->quoteName('subject') . ' = ' .
$db->quote($subject))
				->where($db->quoteName('state') . ' = 1');
			$db->setQuery($query);
			$db->execute();
		}
		catch (JDatabaseExceptionExecuting $e)
		{
			$this->setError($e->getMessage());

			return false;
		}

		return true;
	}
}
models/dashboard.php000064400000010115151165412120010463 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Router\Route;

/**
 * Dashboard model class.
 *
 * @since  3.9.0
 */
class PrivacyModelDashboard extends JModelLegacy
{
	/**
	 * Get the information about the published privacy policy
	 *
	 * @return  array  Array containing a status of whether a privacy policy
is set and a link to the policy document for editing
	 *
	 * @since   3.9.0
	 */
	public function getPrivacyPolicyInfo()
	{
		$policy = array(
			'published'         => false,
			'articlePublished'  => false,
			'editLink'          => '',
		);

		/*
		 * Prior to 3.9.0 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   3.9.0
	 */
	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   3.9.0
	 */
	public function getRequestFormPublished()
	{
		$status = array(
			'exists'    => false,
			'published' => false,
			'link'      => '',
		);

		$db    = $this->getDbo();
		$query = $db->getQuery(true)
			->select($db->quoteName('id') . ', ' .
$db->quoteName('published') . ', ' .
$db->quoteName('language'))
			->from($db->quoteName('#__menu'))
			->where($db->quoteName('client_id') . ' = 0')
			->where($db->quoteName('link') . ' = ' .
$db->quote('index.php?option=com_privacy&view=request'));
		$db->setQuery($query);

		$menuItem = $db->loadObject();

		// Check if the menu item exists in database
		if ($menuItem)
		{
			$status['exists'] = true;

			// Check if the menu item is published
			if ($menuItem->published == 1)
			{
				$status['published'] = true;
			}

			// Add language to the url if the site is multilingual
			if (JLanguageMultilang::isEnabled() && $menuItem->language
&& $menuItem->language !== '*')
			{
				$lang = '&lang=' . $menuItem->language;
			}
			else
			{
				$lang = '';
			}
		}

		$linkMode = JFactory::getApplication()->get('force_ssl', 0)
== 2 ? Route::TLS_FORCE : Route::TLS_IGNORE;

		if (!$menuItem)
		{
			if (JLanguageMultilang::isEnabled())
			{
				// Find the Itemid of the home menu item tagged to the site default
language
				$params = JComponentHelper::getParams('com_languages');
				$defaultSiteLanguage = $params->get('site');

				$db    = $this->getDbo();
				$query = $db->getQuery(true)
					->select($db->quoteName('id'))
					->from($db->quoteName('#__menu'))
					->where($db->quoteName('client_id') . ' =
0')
					->where($db->quoteName('home') . ' = 1')
					->where($db->quoteName('language') . ' = ' .
$db->quote($defaultSiteLanguage));
				$db->setQuery($query);

				$homeId = (int) $db->loadResult();
				$itemId = $homeId ? '&Itemid=' . $homeId : '';
			}
			else
			{
				$itemId = '';
			}

			$status['link'] = JRoute::link('site',
'index.php?option=com_privacy&view=request' . $itemId, true,
$linkMode);
		}
		else
		{
			$status['link'] = JRoute::link('site',
'index.php?Itemid=' . $menuItem->id . $lang, true, $linkMode);
		}

		return $status;
	}
}
models/export.php000064400000021303151165412120010056 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('PrivacyHelper', JPATH_ADMINISTRATOR .
'/components/com_privacy/helpers/privacy.php');

/**
 * Export model class.
 *
 * @since  3.9.0
 */
class PrivacyModelExport extends JModelLegacy
{
	/**
	 * Create the export document for an information request.
	 *
	 * @param   integer  $id  The request ID to process
	 *
	 * @return  PrivacyExportDomain[]|boolean  A SimpleXMLElement object for a
successful export or boolean false on an error
	 *
	 * @since   3.9.0
	 */
	public function collectDataForExportRequest($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;
		}

		/** @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('LOWER(' . $db->quoteName('email') .
') = LOWER(' . $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   3.9.0
	 */
	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('LOWER(' . $db->quoteName('email') .
') = LOWER(' . $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   3.9.0
	 * @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   3.9.0
	 */
	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   3.9.0
	 */
	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   3.9.0
	 */
	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'));
	}
}
models/fields/requeststatus.php000064400000001542151165412120012742
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JFormHelper::loadFieldClass('predefinedlist');

/**
 * Form Field to load a list of request statuses
 *
 * @since  3.9.0
 */
class PrivacyFormFieldRequeststatus extends JFormFieldPredefinedList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	public $type = 'RequestStatus';

	/**
	 * Available statuses
	 *
	 * @var    array
	 * @since  3.9.0
	 */
	protected $predefinedOptions = array(
		'-1' => 'COM_PRIVACY_STATUS_INVALID',
		'0'  => 'COM_PRIVACY_STATUS_PENDING',
		'1'  => 'COM_PRIVACY_STATUS_CONFIRMED',
		'2'  => 'COM_PRIVACY_STATUS_COMPLETED',
	);
}
models/fields/requesttype.php000064400000001460151165412120012377
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JFormHelper::loadFieldClass('predefinedlist');

/**
 * Form Field to load a list of request types
 *
 * @since  3.9.0
 */
class PrivacyFormFieldRequesttype extends JFormFieldPredefinedList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	public $type = 'RequestType';

	/**
	 * Available types
	 *
	 * @var    array
	 * @since  3.9.0
	 */
	protected $predefinedOptions = array(
		'export' =>
'COM_PRIVACY_HEADING_REQUEST_TYPE_TYPE_EXPORT',
		'remove' =>
'COM_PRIVACY_HEADING_REQUEST_TYPE_TYPE_REMOVE',
	);
}
models/forms/filter_consents.xml000064400000004423151165412120013101
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset
addfieldpath="/administrator/components/com_privacy/models/fields"
/>

	<fields name="filter">
		<field
			name="search"
			type="text"
			inputmode="search"
			label="COM_PRIVACY_FILTER_SEARCH_LABEL"
			description="COM_PRIVACY_SEARCH_IN_USERNAME"
			hint="JSEARCH_FILTER"
		/>

		<field
			name="state"
			type="list"
			label="COM_PRIVACY_CONSENTS_FILTER_STATE"
			onchange="this.form.submit();"
			>
			<option value="">JOPTION_SELECT_PUBLISHED</option>
			<option
value="1">COM_PRIVACY_CONSENTS_STATE_VALID</option>
			<option
value="0">COM_PRIVACY_CONSENTS_STATE_OBSOLETE</option>
			<option
value="-1">COM_PRIVACY_CONSENTS_STATE_INVALIDATED</option>
		</field>

		<field
			name="subject"
			type="sql"
			label="COM_PRIVACY_CONSENTS_FILTER_SUBJECT"
			sql_select="subject"
			sql_from="#__privacy_consents"
			sql_group="subject"
			sql_order="subject ASC"
			key_field="subject"
			translate="true"
			onchange="this.form.submit();"
			>
			<option
value="">COM_PRIVACY_CONSENTS_SUBJECT_DEFAULT</option>
		</field>
	</fields>

	<fields name="list">
		<field
			name="fullordering"
			type="list"
			label="JGLOBAL_SORT_BY"
			description="JGLOBAL_SORT_BY"
			onchange="this.form.submit();"
			default="a.id DESC"
			validate="options"
			>
			<option value="a.state
ASC">COM_PRIVACY_HEADING_STATUS_ASC</option>
			<option value="a.state
DESC">COM_PRIVACY_HEADING_STATUS_DESC</option>
			<option value="u.username
ASC">COM_PRIVACY_HEADING_USERNAME_ASC</option>
			<option value="u.username
DESC">COM_PRIVACY_HEADING_USERNAME_DESC</option>
			<option value="a.user_id
ASC">COM_PRIVACY_HEADING_USERID_ASC</option>
			<option value="a.user_id
DESC">COM_PRIVACY_HEADING_USERID_DESC</option>
			<option value="a.subject
ASC">COM_PRIVACY_HEADING_SUBJECT_ASC</option>
			<option value="a.subject
DESC">COM_PRIVACY_HEADING_SUBJECT_DESC</option>	
			<option value="a.created
ASC">COM_PRIVACY_HEADING_CREATED_ASC</option>
			<option value="a.created
DESC">COM_PRIVACY_HEADING_CREATED_DESC</option>
			<option value="a.id
ASC">JGRID_HEADING_ID_ASC</option>
			<option value="a.id
DESC">JGRID_HEADING_ID_DESC</option>
		</field>

		<field
			name="limit"
			type="limitbox"
			class="input-mini"
			default="25"
			onchange="this.form.submit();"
		/>
	</fields>
</form>
models/forms/filter_requests.xml000064400000003522151165412120013117
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset
addfieldpath="/administrator/components/com_privacy/models/fields"
/>

	<fields name="filter">
		<field
			name="search"
			type="text"
			inputmode="search"
			label="COM_PRIVACY_FILTER_SEARCH_LABEL"
			description="COM_PRIVACY_SEARCH_IN_EMAIL"
			hint="JSEARCH_FILTER"
		/>

		<field
			name="status"
			type="privacy.requeststatus"
			label="COM_PRIVACY_FILTER_STATUS"
			description="COM_PRIVACY_FILTER_STATUS_DESC"
			onchange="this.form.submit();"
			>
			<option value="">JOPTION_SELECT_PUBLISHED</option>
		</field>

		<field
			name="request_type"
			type="privacy.requesttype"
			label="COM_PRIVACY_FILTER_REQUEST_TYPE"
			description="COM_PRIVACY_FILTER_REQUEST_TYPE_DESC"
			onchange="this.form.submit();"
			>
			<option
value="">COM_PRIVACY_SELECT_REQUEST_TYPE</option>
		</field>
	</fields>

	<fields name="list">
		<field
			name="fullordering"
			type="list"
			label="JGLOBAL_SORT_BY"
			description="JGLOBAL_SORT_BY"
			onchange="this.form.submit();"
			default="a.id DESC"
			validate="options"
			>
			<option value="">JGLOBAL_SORT_BY</option>
			<option value="a.email
ASC">COM_PRIVACY_HEADING_EMAIL_ASC</option>
			<option value="a.email
DESC">COM_PRIVACY_HEADING_EMAIL_DESC</option>
			<option value="a.request_type
ASC">COM_PRIVACY_HEADING_REQUEST_TYPE_ASC</option>
			<option value="a.request_type
DESC">COM_PRIVACY_HEADING_REQUEST_TYPE_DESC</option>
			<option value="a.requested_at
ASC">COM_PRIVACY_HEADING_REQUESTED_AT_ASC</option>
			<option value="a.requested_at
DESC">COM_PRIVACY_HEADING_REQUESTED_AT_DESC</option>
			<option value="a.id
ASC">JGRID_HEADING_ID_ASC</option>
			<option value="a.id
DESC">JGRID_HEADING_ID_DESC</option>
		</field>

		<field
			name="limit"
			type="limitbox"
			class="input-mini"
			default="25"
			onchange="this.form.submit();"
		/>
	</fields>
</form>
models/forms/request.xml000064400000000705151165412120011367
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset name="default">
		<field
			name="request_type"
			type="list"
			label="COM_PRIVACY_FIELD_REQUEST_TYPE_LABEL"
			description="COM_PRIVACY_FIELD_REQUEST_TYPE_DESC"
			filter="string"
			default="export"
			validate="options"
			>
			<option
value="export">COM_PRIVACY_REQUEST_TYPE_EXPORT</option>
			<option
value="remove">COM_PRIVACY_REQUEST_TYPE_REMOVE</option>
		</field>
	</fieldset>
</form>
models/remove.php000064400000012632151165412120010037 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('PrivacyHelper', JPATH_ADMINISTRATOR .
'/components/com_privacy/helpers/privacy.php');
JLoader::register('PrivacyRemovalStatus', JPATH_ADMINISTRATOR .
'/components/com_privacy/helpers/removal/status.php');

/**
 * Remove model class.
 *
 * @since  3.9.0
 */
class PrivacyModelRemove extends JModelLegacy
{
	/**
	 * Remove the user data.
	 *
	 * @param   integer  $id  The request ID to process
	 *
	 * @return  boolean
	 *
	 * @since   3.9.0
	 */
	public function removeDataForRequest($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_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('LOWER(' . $db->quoteName('email') .
') = LOWER(' . $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   3.9.0
	 * @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   3.9.0
	 */
	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   3.9.0
	 */
	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   3.9.0
	 */
	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'));
	}
}
models/request.php000064400000016533151165412120010236 0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Router\Route;

/**
 * Request model class.
 *
 * @since  3.9.0
 */
class PrivacyModelRequest extends JModelAdmin
{
	/**
	 * Creates an information request.
	 *
	 * @param   array  $data  The data expected for the form.
	 *
	 * @return  mixed  Exception | JException | boolean
	 *
	 * @since   3.9.0
	 */
	public function createRequest($data)
	{
		// Creating requests requires the site's email sending be enabled
		if (!JFactory::getConfig()->get('mailonline', 1))
		{
			$this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED'));

			return false;
		}

		// Get the form.
		$form = $this->getForm();		

		// 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;
		}

		// Get the user email address
		$data['email'] = JFactory::getUser()->email;

		// 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 ?
Route::TLS_FORCE : Route::TLS_IGNORE;

			$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, true),
				'[FORMURL]'  => JRoute::link('site',
'index.php?option=com_privacy&view=confirm', false,
$linkMode, true),
				'[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   3.9.0
	 */
	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   3.9.0
	 * @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   3.9.0
	 */
	protected function populateState()
	{
		// Get the application object.
		$params =
JFactory::getApplication()->getParams('com_privacy');

		// Load the parameters.
		$this->setState('params', $params);
	}
}
models/requests.php000064400000011217151165412120010413 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Component\ComponentHelper;

/**
 * Requests management model class.
 *
 * @since  3.9.0
 */
class PrivacyModelRequests extends JModelList
{
	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 *
	 * @since   3.9.0
	 */
	public function __construct($config = array())
	{
		if (empty($config['filter_fields']))
		{
			$config['filter_fields'] = array(
				'id', 'a.id',
				'email', 'a.email',
				'requested_at', 'a.requested_at',
				'request_type', 'a.request_type',
				'status', 'a.status',
			);
		}

		parent::__construct($config);
	}

	/**
	 * Method to get a JDatabaseQuery object for retrieving the data set from
a database.
	 *
	 * @return  JDatabaseQuery
	 *
	 * @since   3.9.0
	 */
	protected function getListQuery()
	{
		// Create a new query object.
		$db    = $this->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'));

		// 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   3.9.0
	 */
	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   3.9.0
	 */
	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   3.9.0
	 */
	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($db->quote($now), $period,
'DAY') . ' > ' .
$db->quoteName('requested_at'));
		$db->setQuery($query);

		return (int) $db->loadResult();
	}
}
privacy.php000064400000000630151165412120006727 0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

$controller = JControllerLegacy::getInstance('Privacy');
$controller->execute(JFactory::getApplication()->input->get('task'));
$controller->redirect();
privacy.xml000064400000002541151165412120006743 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<extension type="component" version="3.9"
method="upgrade">
	<name>com_privacy</name>
	<author>Joomla! Project</author>
	<creationDate>May 2018</creationDate>
	<copyright>(C) 2005 - 2020 Open Source Matters. All rights
reserved.</copyright>
	<license>GNU General Public License version 2 or later; see
LICENSE.txt</license>
	<authorEmail>admin@joomla.org</authorEmail>
	<authorUrl>www.joomla.org</authorUrl>
	<version>3.9.0</version>
	<description>COM_PRIVACY_XML_DESCRIPTION</description>
	<files folder="site">
		<filename>controller.php</filename>
		<filename>privacy.php</filename>
		<filename>router.php</filename>
		<folder>controllers</folder>
		<folder>models</folder>
		<folder>views</folder>
	</files>
	<languages folder="site">
		<language
tag="en-GB">language/en-GB.com_privacy.ini</language>
	</languages>
	<administration>
		<files folder="admin">
			<filename>config.xml</filename>
			<filename>controller.php</filename>
			<filename>privacy.php</filename>
			<folder>controllers</folder>
			<folder>helpers</folder>
			<folder>models</folder>
			<folder>tables</folder>
			<folder>views</folder>
		</files>
		<languages folder="admin">
			<language
tag="en-GB">language/en-GB.com_privacy.ini</language>
			<language
tag="en-GB">language/en-GB.com_privacy.sys.ini</language>
		</languages>
	</administration>
</extension>

tables/consent.php000064400000003012151165412120010172 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Table interface class for the #__privacy_consents table
 *
 * @property   integer  $id       Item ID (primary key)
 * @property   integer  $remind   The status of the reminder request
 * @property   string   $token    Hashed token for the reminder request
 * @property   integer  $user_id  User ID (pseudo foreign key to the
#__users table) if the request is associated to a user account
 *
 * @since  3.9.0
 */
class PrivacyTableConsent extends JTable
{
	/**
	 * The class constructor.
	 *
	 * @param   JDatabaseDriver  $db  JDatabaseDriver connector object.
	 *
	 * @since   3.9.0
	 */
	public function __construct(JDatabaseDriver $db)
	{
		parent::__construct('#__privacy_consents', 'id',
$db);
	}

	/**
	 * Method to store a row in the database from the Table instance
properties.
	 *
	 * @param   boolean  $updateNulls  True to update fields even if they are
null.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   3.9.0
	 */
	public function store($updateNulls = false)
	{
		$date = JFactory::getDate();

		// Set default values for new records
		if (!$this->id)
		{
			if (!$this->remind)
			{
				$this->remind = '0';
			}

			if (!$this->created)
			{
				$this->created = $date->toSql();
			}
		}

		return parent::store($updateNulls);
	}
}
tables/request.php000064400000003512151165412120010216 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Table interface class for the #__privacy_requests table
 *
 * @property   integer  $id                        Item ID (primary key)
 * @property   string   $email                     The email address of the
individual requesting the data
 * @property   string   $requested_at              The time the request was
created at
 * @property   integer  $status                    The status of the
information request
 * @property   string   $request_type              The type of information
request
 * @property   string   $confirm_token             Hashed token for
confirming the information request
 * @property   string   $confirm_token_created_at  The time the
confirmation token was generated
 *
 * @since  3.9.0
 */
class PrivacyTableRequest extends JTable
{
	/**
	 * The class constructor.
	 *
	 * @param   JDatabaseDriver  $db  JDatabaseDriver connector object.
	 *
	 * @since   3.9.0
	 */
	public function __construct(JDatabaseDriver $db)
	{
		parent::__construct('#__privacy_requests', 'id',
$db);
	}

	/**
	 * Method to store a row in the database from the Table instance
properties.
	 *
	 * @param   boolean  $updateNulls  True to update fields even if they are
null.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   3.9.0
	 */
	public function store($updateNulls = false)
	{
		$date = JFactory::getDate();

		// Set default values for new records
		if (!$this->id)
		{
			if (!$this->status)
			{
				$this->status = '0';
			}

			if (!$this->requested_at)
			{
				$this->requested_at = $date->toSql();
			}
		}

		return parent::store($updateNulls);
	}
}
views/capabilities/tmpl/default.php000064400000003363151165412120013446
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/** @var PrivacyViewCapabilities $this */

?>
<?php if (!empty($this->sidebar)) : ?>
	<div id="j-sidebar-container" class="span2">
		<?php echo $this->sidebar; ?>
	</div>
	<div id="j-main-container" class="span10">
<?php else : ?>
	<div id="j-main-container">
<?php endif; ?>
	<div class="alert alert-info">
		<h4 class="alert-heading"><?php echo
JText::_('COM_PRIVACY_MSG_CAPABILITIES_ABOUT_THIS_INFORMATION');
?></h4>
		<?php echo
JText::_('COM_PRIVACY_MSG_CAPABILITIES_INTRODUCTION'); ?>
	</div>
	<?php if (empty($this->capabilities)) : ?>
		<div class="alert alert-no-items">
			<?php echo
JText::_('COM_PRIVACY_MSG_CAPABILITIES_NO_CAPABILITIES'); ?>
		</div>
	<?php else : ?>
		<?php $i = 0; ?>
		<?php echo JHtml::_('bootstrap.startAccordion',
'slide-capabilities', array('active' =>
'slide-0')); ?>

		<?php foreach ($this->capabilities as $extension =>
$capabilities) : ?>
			<?php echo JHtml::_('bootstrap.addSlide',
'slide-capabilities', $extension, 'slide-' . $i); ?>
				<?php if (empty($capabilities)) : ?>
					<div class="alert alert-no-items">
						<?php echo
JText::_('COM_PRIVACY_MSG_EXTENSION_NO_CAPABILITIES'); ?>
					</div>
				<?php else : ?>
					<ul>
						<?php foreach ($capabilities as $capability) : ?>
							<li><?php echo $capability; ?></li>
						<?php endforeach; ?>
					</ul>
				<?php endif; ?>
			<?php echo JHtml::_('bootstrap.endSlide'); ?>
			<?php $i++; ?>
		<?php endforeach; ?>

		<?php echo JHtml::_('bootstrap.endAccordion'); ?>
	<?php endif; ?>
</div>
views/capabilities/view.html.php000064400000003346151165412120012764
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Capabilities view class
 *
 * @since  3.9.0
 */
class PrivacyViewCapabilities extends JViewLegacy
{
	/**
	 * The reported extension capabilities
	 *
	 * @var    array
	 * @since  3.9.0
	 */
	protected $capabilities;

	/**
	 * The HTML markup for the sidebar
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	protected $sidebar;

	/**
	 * The state information
	 *
	 * @var    JObject
	 * @since  3.9.0
	 */
	protected $state;

	/**
	 * Execute and display a template script.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise an Error object.
	 *
	 * @see     JViewLegacy::loadTemplate()
	 * @since   3.9.0
	 * @throws  Exception
	 */
	public function display($tpl = null)
	{
		// Initialise variables
		$this->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   3.9.0
	 */
	protected function addToolbar()
	{
		JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_CAPABILITIES'),
'lock');

		JToolbarHelper::preferences('com_privacy');

		JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_CAPABILITIES');
	}
}
views/consents/tmpl/default.php000064400000010207151165412120012644
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/** @var PrivacyViewConsent $this */

// Load the tooltip behavior.
JHtml::_('bootstrap.tooltip');
JHtml::_('behavior.multiselect');
JHtml::_('formbehavior.chosen', 'select');

$user       = JFactory::getUser();
$listOrder  =
$this->escape($this->state->get('list.ordering'));
$listDirn   =
$this->escape($this->state->get('list.direction'));
$now        = JFactory::getDate();
$stateIcons = array(-1 => 'trash', 0 =>
'archive', 1 => 'publish');
$stateMsgs  = array(-1 =>
JText::_('COM_PRIVACY_CONSENTS_STATE_INVALIDATED'), 0 =>
JText::_('COM_PRIVACY_CONSENTS_STATE_OBSOLETE'), 1 =>
JText::_('COM_PRIVACY_CONSENTS_STATE_VALID'));

?>
<form action="<?php echo
JRoute::_('index.php?option=com_privacy&view=consents');
?>" method="post" name="adminForm"
id="adminForm">
	<?php if (!empty($this->sidebar)) : ?>
		<div id="j-sidebar-container" class="span2">
			<?php echo $this->sidebar; ?>
		</div>
		<div id="j-main-container" class="span10">
	<?php else : ?>
		<div id="j-main-container">
	<?php endif; ?>
		<?php echo
JLayoutHelper::render('joomla.searchtools.default',
array('view' => $this)); ?>
		<div class="clearfix"> </div>
		<?php if (empty($this->items)) : ?>
			<div class="alert alert-no-items">
				<?php echo
JText::_('COM_PRIVACY_MSG_CONSENTS_NO_CONSENTS'); ?>
			</div>
		<?php else : ?>
			<table class="table table-striped"
id="consentList">
				<thead>
					<tr>
						<th width="1%" class="center">
							<?php echo JHtml::_('grid.checkall'); ?>
						</th>
						<th width="1%" class="nowrap center">
							<?php echo JHtml::_('searchtools.sort',
'JSTATUS', 'a.state', $listDirn, $listOrder); ?>
						</th>
						<th width="10%" class="nowrap">
							<?php echo JHtml::_('searchtools.sort',
'JGLOBAL_USERNAME', 'u.username', $listDirn,
$listOrder); ?>
						</th>
						<th width="1%" class="nowrap">
							<?php echo JHtml::_('searchtools.sort',
'COM_PRIVACY_HEADING_USERID', 'a.user_id', $listDirn,
$listOrder); ?>
						</th>
						<th width="10%" class="nowrap">
							<?php echo JHtml::_('searchtools.sort',
'COM_PRIVACY_HEADING_CONSENTS_SUBJECT', 'a.subject',
$listDirn, $listOrder); ?>
						</th>
						<th class="nowrap">
							<?php echo
JText::_('COM_PRIVACY_HEADING_CONSENTS_BODY'); ?>
						</th>
						<th width="15%" class="nowrap">
							<?php echo JHtml::_('searchtools.sort',
'COM_PRIVACY_HEADING_CONSENTS_CREATED', 'a.created',
$listDirn, $listOrder); ?>
						</th>
						<th width="1%" class="nowrap hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder);
?>
						</th>
					</tr>
				</thead>
				<tfoot>
					<tr>
						<td colspan="9">
							<?php echo $this->pagination->getListFooter(); ?>
						</td>
					</tr>
				</tfoot>
				<tbody>
					<?php foreach ($this->items as $i => $item) : ?>
						<tr class="row<?php echo $i % 2; ?>">
							<td class="center">
								<?php echo JHtml::_('grid.id', $i, $item->id);
?>
							</td>
							<td>
								<span class="icon icon-<?php echo
$stateIcons[$item->state]; ?>" title="<?php echo
$stateMsgs[$item->state]; ?>"></span>
							</td>
							<td>
								<?php echo $item->username; ?>
							</td>
							<td>
								<?php echo $item->user_id; ?>
							</td>
							<td>
								<?php echo JText::_($item->subject); ?>
							</td>
							<td>
								<?php echo $item->body; ?>
							</td>
							<td class="break-word">
								<span class="hasTooltip" title="<?php echo
JHtml::_('date', $item->created,
JText::_('DATE_FORMAT_LC6')); ?>">
									<?php echo JHtml::_('date.relative', new
JDate($item->created), null, $now); ?>
								</span>
							</td>
							<td class="hidden-phone">
								<?php echo (int) $item->id; ?>
							</td>
						</tr>
					<?php endforeach; ?>
				</tbody>
			</table>
		<?php endif; ?>

		<input type="hidden" name="task"
value="" />
		<input type="hidden" name="boxchecked"
value="0" />
		<?php echo JHtml::_('form.token'); ?>
	</div>
</form>
views/consents/tmpl/default.xml000064400000000322151165412120012652
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_PRIVACY_CONSENTS_VIEW_DEFAULT_TITLE">
		<message>
			<![CDATA[COM_PRIVACY_CONSENTS_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/consents/view.html.php000064400000005676151165412120012177
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Consents view class
 *
 * @since  3.9.0
 */
class PrivacyViewConsents extends JViewLegacy
{
	/**
	 * The active search tools filters
	 *
	 * @var    array
	 * @since  3.9.0
	 * @note   Must be public to be accessed from the search tools layout
	 */
	public $activeFilters;

	/**
	 * Form instance containing the search tools filter form
	 *
	 * @var    JForm
	 * @since  3.9.0
	 * @note   Must be public to be accessed from the search tools layout
	 */
	public $filterForm;

	/**
	 * The items to display
	 *
	 * @var    array
	 * @since  3.9.0
	 */
	protected $items;

	/**
	 * The pagination object
	 *
	 * @var    JPagination
	 * @since  3.9.0
	 */
	protected $pagination;

	/**
	 * The HTML markup for the sidebar
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	protected $sidebar;

	/**
	 * The state information
	 *
	 * @var    JObject
	 * @since  3.9.0
	 */
	protected $state;

	/**
	 * Execute and display a template script.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise an Error object.
	 *
	 * @see     JViewLegacy::loadTemplate()
	 * @since   3.9.0
	 * @throws  Exception
	 */
	public function display($tpl = null)
	{
		// Initialise variables
		$this->items         = $this->get('Items');
		$this->pagination    = $this->get('Pagination');
		$this->state         = $this->get('State');
		$this->filterForm    = $this->get('FilterForm');
		$this->activeFilters = $this->get('ActiveFilters');

		// 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   3.9.0
	 */
	protected function addToolbar()
	{
		JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_CONSENTS'),
'lock');

		$bar = JToolbar::getInstance('toolbar');

		// Add a button to invalidate a consent
		$bar->appendButton(
			'Confirm',
			'COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE_CONFIRM_MSG',
			'trash',
			'COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE',
			'consents.invalidate',
			true
		);

		// If the filter is restricted to a specific subject, show the
"Invalidate all" button
		if ($this->state->get('filter.subject') != '')
		{
			$bar->appendButton(
				'Confirm',
				'COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE_ALL_CONFIRM_MSG',
				'cancel',
				'COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE_ALL',
				'consents.invalidateAll',
				false
			);
		}

		JToolbarHelper::preferences('com_privacy');

		JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_CONSENTS');
	}
}
views/dashboard/tmpl/default.php000064400000020132151165412120012735
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;

/** @var PrivacyViewDashboard $this */

// Include the component HTML helpers.
JHtml::addIncludePath(JPATH_ADMINISTRATOR .
'/components/com_privacy/helpers/html');

JHtml::_('bootstrap.tooltip');

$totalRequests  = 0;
$activeRequests = 0;

?>
<?php if (!empty($this->sidebar)) : ?>
	<div id="j-sidebar-container" class="span2">
		<?php echo $this->sidebar; ?>
	</div>
	<div id="j-main-container" class="span10">
<?php else : ?>
	<div id="j-main-container">
<?php endif; ?>
	<div class="row-fluid">
		<div class="span6">
			<div class="well well-small">
				<h3 class="module-title nav-header"><?php echo
Text::_('COM_PRIVACY_DASHBOARD_HEADING_TOTAL_REQUEST_COUNT');
?></h3>
				<div class="row-striped">
					<?php if (count($this->requestCounts)) : ?>
						<div class="row-fluid">
							<div class="span5"><strong><?php echo
Text::_('COM_PRIVACY_DASHBOARD_HEADING_REQUEST_TYPE');
?></strong></div>
							<div class="span5"><strong><?php echo
Text::_('COM_PRIVACY_DASHBOARD_HEADING_REQUEST_STATUS');
?></strong></div>
							<div class="span2"><strong><?php echo
Text::_('COM_PRIVACY_DASHBOARD_HEADING_REQUEST_COUNT');
?></strong></div>
						</div>
						<?php foreach ($this->requestCounts as $row) : ?>
							<div class="row-fluid">
								<div class="span5">
									<a class="hasTooltip" href="<?php echo
JRoute::_('index.php?option=com_privacy&view=requests&filter[request_type]='
. $row->request_type . '&filter[status]=' .
$row->status); ?>" data-original-title="<?php echo
JText::_('COM_PRIVACY_DASHBOARD_VIEW_REQUESTS'); ?>">
										<strong><?php echo
Text::_('COM_PRIVACY_HEADING_REQUEST_TYPE_TYPE_' .
$row->request_type); ?></strong>
									</a>
								</div>
								<div class="span5"><?php echo
JHtml::_('PrivacyHtml.helper.statusLabel', $row->status);
?></div>
								<div class="span2"><span class="badge
badge-info"><?php echo $row->count;
?></span></div>
							</div>
							<?php if (in_array($row->status, array(0, 1))) : ?>
								<?php $activeRequests += $row->count; ?>
							<?php endif; ?>
							<?php $totalRequests += $row->count; ?>
						<?php endforeach; ?>
						<div class="row-fluid">
							<div class="span5"><?php echo
Text::plural('COM_PRIVACY_DASHBOARD_BADGE_TOTAL_REQUESTS',
$totalRequests); ?></div>
							<div class="span7"><?php echo
Text::plural('COM_PRIVACY_DASHBOARD_BADGE_ACTIVE_REQUESTS',
$activeRequests); ?></div>
						</div>
					<?php else : ?>
						<div class="row-fluid">
							<div class="span12">
								<div class="alert"><?php echo
Text::_('COM_PRIVACY_DASHBOARD_NO_REQUESTS'); ?></div>
							</div>
						</div>
					<?php endif; ?>
				</div>
			</div>
		</div>
		<div class="span6">
			<div class="well well-small">
				<h3 class="module-title nav-header"><?php echo
Text::_('COM_PRIVACY_DASHBOARD_HEADING_STATUS_CHECK');
?></h3>
				<div class="row-striped">
					<div class="row-fluid">
						<div class="span3"><strong><?php echo
Text::_('COM_PRIVACY_DASHBOARD_HEADING_STATUS');
?></strong></div>
						<div class="span9"><strong><?php echo
Text::_('COM_PRIVACY_DASHBOARD_HEADING_CHECK');
?></strong></div>
					</div>
					<div class="row-fluid">
						<div class="span3">
							<?php if ($this->privacyPolicyInfo['published']
&& $this->privacyPolicyInfo['articlePublished']) :
?>
								<span class="label label-success">
									<span class="icon-checkbox"
aria-hidden="true"></span>
									<?php echo Text::_('JPUBLISHED'); ?>
								</span>
							<?php elseif ($this->privacyPolicyInfo['published']
&& !$this->privacyPolicyInfo['articlePublished']) :
?>
								<span class="label label-warning">
									<span class="icon-warning"
aria-hidden="true"></span>
									<?php echo Text::_('JUNPUBLISHED'); ?>
								</span>
							<?php else : ?>
								<span class="label label-warning">
									<span class="icon-warning"
aria-hidden="true"></span>
									<?php echo
Text::_('COM_PRIVACY_STATUS_CHECK_NOT_AVAILABLE'); ?>
								</span>
							<?php endif; ?>
						</div>
						<div class="span9">
							<div><?php echo
Text::_('COM_PRIVACY_STATUS_CHECK_PRIVACY_POLICY_PUBLISHED');
?></div>
							<?php if ($this->privacyPolicyInfo['editLink'] !==
'') : ?>
								<small><a href="<?php echo
$this->privacyPolicyInfo['editLink']; ?>"><?php
echo Text::_('COM_PRIVACY_EDIT_PRIVACY_POLICY');
?></a></small>
							<?php else : ?>
								<?php $link =
Route::_('index.php?option=com_plugins&task=plugin.edit&extension_id='
. $this->privacyConsentPluginId); ?>
								<small><a href="<?php echo $link;
?>"><?php echo
Text::_('COM_PRIVACY_EDIT_PRIVACY_CONSENT_PLUGIN');
?></a></small>
							<?php endif; ?>
						</div>
					</div>
					<div class="row-fluid">
						<div class="span3">
							<?php if ($this->requestFormPublished['published']
&& $this->requestFormPublished['exists']) : ?>
								<span class="label label-success">
									<span class="icon-checkbox"
aria-hidden="true"></span>
									<?php echo Text::_('JPUBLISHED'); ?>
								</span>
							<?php elseif
(!$this->requestFormPublished['published'] &&
$this->requestFormPublished['exists']) : ?>
								<span class="label label-warning">
									<span class="icon-warning"
aria-hidden="true"></span>
									<?php echo Text::_('JUNPUBLISHED'); ?>
								</span>
							<?php else : ?>
								<span class="label label-warning">
									<span class="icon-warning"
aria-hidden="true"></span>
									<?php echo
Text::_('COM_PRIVACY_STATUS_CHECK_NOT_AVAILABLE'); ?>
								</span>
							<?php endif; ?>
						</div>
						<div class="span9">
							<div><?php echo
Text::_('COM_PRIVACY_STATUS_CHECK_REQUEST_FORM_MENU_ITEM_PUBLISHED');
?></div>
							<?php if ($this->requestFormPublished['link'] !==
'') : ?>
								<small><a href="<?php echo
$this->requestFormPublished['link']; ?>"><?php
echo $this->requestFormPublished['link'];
?></a></small>
							<?php endif; ?>
						</div>
					</div>
					<div class="row-fluid">
						<div class="span3">
							<?php if ($this->numberOfUrgentRequests === 0) : ?>
								<span class="label label-success">
									<span class="icon-checkbox"
aria-hidden="true"></span>
									<?php echo Text::_('JNONE'); ?>
								</span>
							<?php else : ?>
								<span class="label label-important">
									<span class="icon-warning"
aria-hidden="true"></span>
									<?php echo Text::_('WARNING'); ?>
								</span>
							<?php endif; ?>
						</div>
						<div class="span9">
							<div><?php echo
Text::_('COM_PRIVACY_STATUS_CHECK_OUTSTANDING_URGENT_REQUESTS');
?></div>
							<small><?php echo
Text::plural('COM_PRIVACY_STATUS_CHECK_OUTSTANDING_URGENT_REQUESTS_DESCRIPTION',
$this->urgentRequestDays); ?></small>
							<?php if ($this->numberOfUrgentRequests > 0) : ?>
								<small><a href="<?php echo
Route::_('index.php?option=com_privacy&view=requests&filter[status]=1&list[fullordering]=a.requested_at
ASC'); ?>"><?php echo
JText::_('COM_PRIVACY_SHOW_URGENT_REQUESTS');
?></a></small>
							<?php endif; ?>
						</div>
					</div>
					<div class="row-fluid">
						<div class="span3">
							<?php if ($this->sendMailEnabled) : ?>
								<span class="label label-success">
									<span class="icon-checkbox"
aria-hidden="true"></span>
									<?php echo Text::_('JENABLED'); ?>
								</span>
							<?php else : ?>
								<span class="label label-important">
									<span class="icon-warning"
aria-hidden="true"></span>
									<?php echo Text::_('JDISABLED'); ?>
								</span>
							<?php endif; ?>
						</div>
						<div class="span9">
							<?php if (!$this->sendMailEnabled) : ?>
								<div><?php echo
Text::_('COM_PRIVACY_STATUS_CHECK_SENDMAIL_DISABLED');
?></div>
								<small><?php echo
Text::_('COM_PRIVACY_STATUS_CHECK_SENDMAIL_DISABLED_DESCRIPTION');
?></small>
							<?php else : ?>
								<div><?php echo
Text::_('COM_PRIVACY_STATUS_CHECK_SENDMAIL_ENABLED');
?></div>
							<?php endif; ?>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>
views/dashboard/tmpl/default.xml000064400000000324151165412120012747
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_PRIVACY_DASHBOARD_VIEW_DEFAULT_TITLE">
		<message>
			<![CDATA[COM_PRIVACY_DASHBOARD_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/dashboard/view.html.php000064400000005673151165412120012267
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;

/**
 * Dashboard view class
 *
 * @since  3.9.0
 */
class PrivacyViewDashboard extends JViewLegacy
{
	/**
	 * Number of urgent requests based on the component configuration
	 *
	 * @var    integer
	 * @since  3.9.0
	 */
	protected $numberOfUrgentRequests;

	/**
	 * Information about whether a privacy policy is published
	 *
	 * @var    array
	 * @since  3.9.0
	 */
	protected $privacyPolicyInfo;

	/**
	 * The request counts
	 *
	 * @var    array
	 * @since  3.9.0
	 */
	protected $requestCounts;

	/**
	 * Information about whether a menu item for the request form is published
	 *
	 * @var    array
	 * @since  3.9.0
	 */
	protected $requestFormPublished;

	/**
	 * Flag indicating the site supports sending email
	 *
	 * @var    boolean
	 * @since  3.9.0
	 */
	protected $sendMailEnabled;

	/**
	 * The HTML markup for the sidebar
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	protected $sidebar;

	/**
	 * Id of the system privacy consent plugin
	 *
	 * @var    integer
	 * @since  3.9.2
	 */
	protected $privacyConsentPluginId;

	/**
	 * Execute and display a template script.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise an Error object.
	 *
	 * @see     JViewLegacy::loadTemplate()
	 * @since   3.9.0
	 * @throws  Exception
	 */
	public function display($tpl = null)
	{
		// Initialise variables
		$this->privacyConsentPluginId =
PrivacyHelper::getPrivacyConsentPluginId();
		$this->privacyPolicyInfo      =
$this->get('PrivacyPolicyInfo');
		$this->requestCounts          =
$this->get('RequestCounts');
		$this->requestFormPublished   =
$this->get('RequestFormPublished');
		$this->sendMailEnabled        = (bool)
Factory::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)
ComponentHelper::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   3.9.0
	 */
	protected function addToolbar()
	{
		JToolbarHelper::title(Text::_('COM_PRIVACY_VIEW_DASHBOARD'),
'lock');

		JToolbarHelper::preferences('com_privacy');

		JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_DASHBOARD');
	}
}
views/export/view.xml.php000064400000002655151165412120011512
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('PrivacyHelper', JPATH_ADMINISTRATOR .
'/components/com_privacy/helpers/privacy.php');

/**
 * Export view class
 *
 * @since  3.9.0
 *
 * @property-read   \Joomla\CMS\Document\XmlDocument  $document
 */
class PrivacyViewExport extends JViewLegacy
{
	/**
	 * Execute and display a template script.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise an Error object.
	 *
	 * @see     JViewLegacy::loadTemplate()
	 * @since   3.9.0
	 * @throws  Exception
	 */
	public function display($tpl = null)
	{
		/** @var PrivacyModelExport $model */
		$model = $this->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);
	}
}
views/request/tmpl/default.php000064400000003114151165412120012477
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/** @var PrivacyViewRequest $this */

JHtml::_('behavior.keepalive');
JHtml::_('behavior.formvalidator');
JHtml::_('formbehavior.chosen', 'select');

?>
<div class="request-form<?php echo $this->pageclass_sfx;
?>">
	<?php if ($this->params->get('show_page_heading')) :
?>
		<div class="page-header">
			<h1>
				<?php echo
$this->escape($this->params->get('page_heading')); ?>
			</h1>
		</div>
	<?php endif; ?>
	<?php if ($this->sendMailEnabled) : ?>
		<form action="<?php echo
JRoute::_('index.php?option=com_privacy&task=request.submit');
?>" method="post" class="form-validate
form-horizontal well">
			<?php foreach ($this->form->getFieldsets() as $fieldset) :
?>
				<fieldset>
					<?php if (!empty($fieldset->label)) : ?>
						<legend><?php echo JText::_($fieldset->label);
?></legend>
					<?php endif; ?>
					<?php echo $this->form->renderFieldset($fieldset->name);
?>
				</fieldset>
			<?php endforeach; ?>
			<div class="control-group">
				<div class="controls">
					<button type="submit" class="btn btn-primary
validate">
						<?php echo JText::_('JSUBMIT'); ?>
					</button>
				</div>
			</div>
			<?php echo JHtml::_('form.token'); ?>
		</form>
	<?php else : ?>
		<div class="alert alert-warning">
			<p><?php echo
JText::_('COM_PRIVACY_WARNING_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED');
?></p>
		</div>
	<?php endif; ?>
</div>
views/request/tmpl/edit.php000064400000002466151165412120012011
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/** @var PrivacyViewRequest $this */

JHtml::_('behavior.formvalidator');
JHtml::_('behavior.keepalive');
JHtml::_('formbehavior.chosen', 'select');

$js = <<< JS
Joomla.submitbutton = function(task) {
	if (task === 'request.cancel' ||
document.formvalidator.isValid(document.getElementById('item-form')))
{
		Joomla.submitform(task, document.getElementById('item-form'));
	}
};
JS;

JFactory::getDocument()->addScriptDeclaration($js);
?>

<form action="<?php echo
JRoute::_('index.php?option=com_privacy&view=request&layout=edit&id='
. (int) $this->item->id); ?>" method="post"
name="adminForm" id="item-form"
class="form-validate">
	<div class="form-horizontal">
		<div class="row-fluid">
			<div class="span9">
				<fieldset class="adminform">
					<?php echo $this->form->renderField('email'); ?>
					<?php echo $this->form->renderField('status');
?>
					<?php echo
$this->form->renderField('request_type'); ?>
				</fieldset>
			</div>
		</div>

		<input type="hidden" name="task"
value="" />
		<?php echo JHtml::_('form.token'); ?>
	</div>
</form>
views/request/view.html.php000064400000006330151165412120012017
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Registry\Registry;

/**
 * Request view class
 *
 * @since  3.9.0
 */
class PrivacyViewRequest extends JViewLegacy
{
	/**
	 * The form object
	 *
	 * @var    JForm
	 * @since  3.9.0
	 */
	protected $form;

	/**
	 * The CSS class suffix to append to the view container
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	protected $pageclass_sfx;

	/**
	 * The view parameters
	 *
	 * @var    Registry
	 * @since  3.9.0
	 */
	protected $params;

	/**
	 * Flag indicating the site supports sending email
	 *
	 * @var    boolean
	 * @since  3.9.0
	 */
	protected $sendMailEnabled;

	/**
	 * The state information
	 *
	 * @var    JObject
	 * @since  3.9.0
	 */
	protected $state;

	/**
	 * Execute and display a template script.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise an Error object.
	 *
	 * @see     JViewLegacy::loadTemplate()
	 * @since   3.9.0
	 * @throws  Exception
	 */
	public function display($tpl = null)
	{
		// Initialise variables.
		$this->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   3.9.0
	 */
	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'));
		}
	}
}
views/requests/tmpl/default.php000064400000013366151165412120012674
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/** @var PrivacyViewRequests $this */

// Include the component HTML helpers.
JHtml::addIncludePath(JPATH_ADMINISTRATOR .
'/components/com_privacy/helpers/html');

// Load the tooltip behavior.
JHtml::_('bootstrap.tooltip');
JHtml::_('behavior.multiselect');
JHtml::_('formbehavior.chosen', 'select');

$user      = JFactory::getUser();
$listOrder =
$this->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'));
?>
<form action="<?php echo
JRoute::_('index.php?option=com_privacy&view=requests');
?>" method="post" name="adminForm"
id="adminForm">
	<?php if (!empty($this->sidebar)) : ?>
		<div id="j-sidebar-container" class="span2">
			<?php echo $this->sidebar; ?>
		</div>
		<div id="j-main-container" class="span10">
	<?php else : ?>
		<div id="j-main-container">
	<?php endif; ?>
		<?php echo
JLayoutHelper::render('joomla.searchtools.default',
array('view' => $this)); ?>
		<div class="clearfix"> </div>
		<?php if (empty($this->items)) : ?>
			<div class="alert alert-no-items">
				<?php echo
JText::_('COM_PRIVACY_MSG_REQUESTS_NO_REQUESTS'); ?>
			</div>
		<?php else : ?>
			<table class="table table-striped"
id="requestList">
				<thead>
					<tr>
						<th width="5%" class="nowrap center">
							<?php echo JText::_('COM_PRIVACY_HEADING_ACTIONS');
?>
						</th>
						<th width="5%" class="nowrap center">
							<?php echo JText::_('JSTATUS'); ?>
						</th>
						<th class="nowrap">
							<?php echo JHtml::_('searchtools.sort',
'JGLOBAL_EMAIL', 'a.email', $listDirn, $listOrder);
?>
						</th>
						<th width="10%" class="nowrap">
							<?php echo JHtml::_('searchtools.sort',
'COM_PRIVACY_HEADING_REQUEST_TYPE', 'a.request_type',
$listDirn, $listOrder); ?>
						</th>
						<th width="20%" class="nowrap">
							<?php echo JHtml::_('searchtools.sort',
'COM_PRIVACY_HEADING_REQUESTED_AT', 'a.requested_at',
$listDirn, $listOrder); ?>
						</th>
						<th width="1%" class="nowrap hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder);
?>
						</th>
					</tr>
				</thead>
				<tfoot>
					<tr>
						<td colspan="7">
							<?php echo $this->pagination->getListFooter(); ?>
						</td>
					</tr>
				</tfoot>
				<tbody>
					<?php foreach ($this->items as $i => $item) : ?>
						<?php
						$itemRequestedAt = new JDate($item->requested_at);
						?>
						<tr class="row<?php echo $i % 2; ?>">
							<td class="center">
								<div class="btn-group">
									<?php if ($item->status == 1 &&
$item->request_type === 'export') : ?>
										<a class="btn btn-micro hasTooltip"
href="<?php echo
JRoute::_('index.php?option=com_privacy&task=request.export&format=xml&id='
. (int) $item->id); ?>" title="<?php echo
JText::_('COM_PRIVACY_ACTION_EXPORT_DATA');
?>"><span class="icon-download"
aria-hidden="true"></span><span
class="element-invisible"><?php echo
JText::_('COM_PRIVACY_ACTION_EXPORT_DATA');
?></span></a>
										<?php if ($this->sendMailEnabled) : ?>
											<a class="btn btn-micro hasTooltip"
href="<?php echo
JRoute::_('index.php?option=com_privacy&task=request.emailexport&id='
. (int) $item->id . '&' .
JFactory::getSession()->getFormToken() . '=1'); ?>"
title="<?php echo
JText::_('COM_PRIVACY_ACTION_EMAIL_EXPORT_DATA');
?>"><span class="icon-mail"
aria-hidden="true"></span><span
class="element-invisible"><?php echo
JText::_('COM_PRIVACY_ACTION_EMAIL_EXPORT_DATA');
?></span></a>
										<?php endif; ?>
									<?php endif; ?>
									<?php if ($item->status == 1 &&
$item->request_type === 'remove') : ?>
										<a class="btn btn-micro hasTooltip"
href="<?php echo
JRoute::_('index.php?option=com_privacy&task=request.remove&id='
. (int) $item->id . '&' .
JFactory::getSession()->getFormToken() . '=1'); ?>"
title="<?php echo
JText::_('COM_PRIVACY_ACTION_DELETE_DATA');
?>"><span class="icon-delete"
aria-hidden="true"></span><span
class="element-invisible"><?php echo
JText::_('COM_PRIVACY_ACTION_DELETE_DATA');
?></span></a>
									<?php endif; ?>
								</div>
							</td>
							<td class="center">
								<?php echo JHtml::_('PrivacyHtml.helper.statusLabel',
$item->status); ?>
							</td>
							<td>
								<?php if ($item->status == 1 && $urgentRequestDate
>= $itemRequestedAt) : ?>
									<span class="pull-right label
label-important"><?php echo
JText::_('COM_PRIVACY_BADGE_URGENT_REQUEST'); ?></span>
								<?php endif; ?>
								<a class="hasTooltip" href="<?php echo
JRoute::_('index.php?option=com_privacy&view=request&id='
. (int) $item->id); ?>" title="<?php echo
JText::_('COM_PRIVACY_ACTION_VIEW'); ?>">
									<?php echo
JStringPunycode::emailToUTF8($this->escape($item->email)); ?>
								</a>
							</td>
							<td class="break-word">
								<?php echo
JText::_('COM_PRIVACY_HEADING_REQUEST_TYPE_TYPE_' .
$item->request_type); ?>
							</td>
							<td class="break-word">
								<span class="hasTooltip" title="<?php echo
JHtml::_('date', $item->requested_at,
JText::_('DATE_FORMAT_LC6')); ?>">
									<?php echo JHtml::_('date.relative',
$itemRequestedAt, null, $now); ?>
								</span>
							</td>
							<td class="hidden-phone">
								<?php echo (int) $item->id; ?>
							</td>
						</tr>
					<?php endforeach; ?>
				</tbody>
			</table>
		<?php endif; ?>

		<input type="hidden" name="task"
value="" />
		<input type="hidden" name="boxchecked"
value="0" />
		<?php echo JHtml::_('form.token'); ?>
	</div>
</form>
views/requests/tmpl/default.xml000064400000000322151165412120012671
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_PRIVACY_REQUESTS_VIEW_DEFAULT_TITLE">
		<message>
			<![CDATA[COM_PRIVACY_REQUESTS_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/requests/view.html.php000064400000005634151165412120012210
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Requests view class
 *
 * @since  3.9.0
 */
class PrivacyViewRequests extends JViewLegacy
{
	/**
	 * The active search tools filters
	 *
	 * @var    array
	 * @since  3.9.0
	 * @note   Must be public to be accessed from the search tools layout
	 */
	public $activeFilters;

	/**
	 * Form instance containing the search tools filter form
	 *
	 * @var    JForm
	 * @since  3.9.0
	 * @note   Must be public to be accessed from the search tools layout
	 */
	public $filterForm;

	/**
	 * The items to display
	 *
	 * @var    array
	 * @since  3.9.0
	 */
	protected $items;

	/**
	 * The pagination object
	 *
	 * @var    JPagination
	 * @since  3.9.0
	 */
	protected $pagination;

	/**
	 * Flag indicating the site supports sending email
	 *
	 * @var    boolean
	 * @since  3.9.0
	 */
	protected $sendMailEnabled;

	/**
	 * The HTML markup for the sidebar
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	protected $sidebar;

	/**
	 * The state information
	 *
	 * @var    JObject
	 * @since  3.9.0
	 */
	protected $state;

	/**
	 * The age of urgent requests
	 *
	 * @var    integer
	 * @since  3.9.0
	 */
	protected $urgentRequestAge;

	/**
	 * Execute and display a template script.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise an Error object.
	 *
	 * @see     JViewLegacy::loadTemplate()
	 * @since   3.9.0
	 * @throws  Exception
	 */
	public function display($tpl = null)
	{
		// Initialise variables
		$this->items            = $this->get('Items');
		$this->pagination       = $this->get('Pagination');
		$this->state            = $this->get('State');
		$this->filterForm       = $this->get('FilterForm');
		$this->activeFilters    = $this->get('ActiveFilters');
		$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   3.9.0
	 */
	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');

	}
}
models/confirm.php000064400000013151151165776720010217 0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Request confirmation model class.
 *
 * @since  3.9.0
 */
class PrivacyModelConfirm extends JModelAdmin
{
	/**
	 * Confirms the information request.
	 *
	 * @param   array  $data  The data expected for the form.
	 *
	 * @return  mixed  Exception | JException | boolean
	 *
	 * @since   3.9.0
	 */
	public function confirmRequest($data)
	{
		// Get the form.
		$form = $this->getForm();

		// 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;
		}

		// Get the user email address
		$data['email'] = JFactory::getUser()->email;

		// 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;
			$table->confirm_token = '';

			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,
				'confirm_token' => '',
			)
		);

		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   3.9.0
	 */
	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   3.9.0
	 * @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   3.9.0
	 */
	protected function populateState()
	{
		// Get the application object.
		$params =
JFactory::getApplication()->getParams('com_privacy');

		// Load the parameters.
		$this->setState('params', $params);
	}
}
models/forms/confirm.xml000064400000000557151165776720011364
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset name="default"
label="COM_PRIVACY_CONFIRM_REQUEST_FIELDSET_LABEL">
		<field
			name="confirm_token"
			type="text"
			label="COM_PRIVACY_FIELD_CONFIRM_CONFIRM_TOKEN_LABEL"
			description="COM_PRIVACY_FIELD_CONFIRM_CONFIRM_TOKEN_DESC"
			filter="alnum"
			required="true"
			size="32"
		/>
	</fieldset>
</form>
models/forms/remind.xml000064400000001034151165776720011174
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset name="default"
label="COM_PRIVACY_REMIND_REQUEST_FIELDSET_LABEL">
		<field
			name="email"
			type="text"
			label="JGLOBAL_EMAIL"
			description="COM_PRIVACY_FIELD_CONFIRM_EMAIL_DESC"
			validate="email"
			required="true"
			size="30"
		/>

		<field
			name="remind_token"
			type="text"
			label="COM_PRIVACY_FIELD_REMIND_CONFIRM_TOKEN_LABEL"
			description="COM_PRIVACY_FIELD_REMIND_CONFIRM_TOKEN_DESC"
			filter="alnum"
			required="true"
			size="32"
		/>
	</fieldset>
</form>
models/remind.php000064400000010055151165776720010040 0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Remind confirmation model class.
 *
 * @since  3.9.0
 */
class PrivacyModelRemind extends JModelAdmin
{
	/**
	 * Confirms the remind request.
	 *
	 * @param   array  $data  The data expected for the form.
	 *
	 * @return  mixed  Exception | JException | boolean
	 *
	 * @since   3.9.0
	 */
	public function remindRequest($data)
	{
		// 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;
		}

		/** @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   3.9.0
	 */
	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   3.9.0
	 * @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   3.9.0
	 */
	protected function populateState()
	{
		// Get the application object.
		$params =
JFactory::getApplication()->getParams('com_privacy');

		// Load the parameters.
		$this->setState('params', $params);
	}
}
router.php000064400000003610151165776720006616 0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Routing class from com_privacy
 *
 * @since  3.9.0
 */
class PrivacyRouter extends JComponentRouterView
{
	/**
	 * Privacy Component router constructor
	 *
	 * @param   JApplicationCms  $app   The application object
	 * @param   JMenu            $menu  The menu object to work with
	 *
	 * @since   3.9.0
	 */
	public function __construct($app = null, $menu = null)
	{
		$this->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 proxies for the new router interface
 * for old SEF extensions.
 *
 * @param   array  &$query  REQUEST query
 *
 * @return  array  Segments of the SEF url
 *
 * @since   3.9.0
 * @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   3.9.0
 * @deprecated  4.0  Use Class based routers instead
 */
function privacyParseRoute($segments)
{
	$app = JFactory::getApplication();
	$router = new PrivacyRouter($app, $app->getMenu());

	return $router->parse($segments);
}
views/confirm/tmpl/default.php000064400000002466151165776720012500
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/** @var PrivacyViewConfirm $this */

JHtml::_('behavior.keepalive');
JHtml::_('behavior.formvalidator');

?>
<div class="request-confirm<?php echo $this->pageclass_sfx;
?>">
	<?php if ($this->params->get('show_page_heading')) :
?>
		<div class="page-header">
			<h1>
				<?php echo
$this->escape($this->params->get('page_heading')); ?>
			</h1>
		</div>
	<?php endif; ?>
	<form action="<?php echo
JRoute::_('index.php?option=com_privacy&task=request.confirm');
?>" method="post" class="form-validate
form-horizontal well">
		<?php foreach ($this->form->getFieldsets() as $fieldset) : ?>
			<fieldset>
				<?php if (!empty($fieldset->label)) : ?>
					<legend><?php echo JText::_($fieldset->label);
?></legend>
				<?php endif; ?>
				<?php echo $this->form->renderFieldset($fieldset->name);
?>
			</fieldset>
		<?php endforeach; ?>
		<div class="control-group">
			<div class="controls">
				<button type="submit" class="btn btn-primary
validate">
					<?php echo JText::_('JSUBMIT'); ?>
				</button>
			</div>
		</div>
		<?php echo JHtml::_('form.token'); ?>
	</form>
</div>
views/confirm/tmpl/default.xml000064400000000505151165776720012501
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_PRIVACY_CONFIRM_VIEW_DEFAULT_TITLE"
option="COM_PRIVACY_CONFIRM_VIEW_DEFAULT_OPTION">
		<help
			key="JHELP_MENUS_MENU_ITEM_PRIVACY_CONFIRM_REQUEST"
		/>
		<message>
			<![CDATA[COM_PRIVACY_CONFIRM_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/confirm/view.html.php000064400000005765151165776720012022
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Registry\Registry;

/**
 * Request confirmation view class
 *
 * @since  3.9.0
 */
class PrivacyViewConfirm extends JViewLegacy
{
	/**
	 * The form object
	 *
	 * @var    JForm
	 * @since  3.9.0
	 */
	protected $form;

	/**
	 * The CSS class suffix to append to the view container
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	protected $pageclass_sfx;

	/**
	 * The view parameters
	 *
	 * @var    Registry
	 * @since  3.9.0
	 */
	protected $params;

	/**
	 * The state information
	 *
	 * @var    JObject
	 * @since  3.9.0
	 */
	protected $state;

	/**
	 * Execute and display a template script.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise an Error object.
	 *
	 * @see     JViewLegacy::loadTemplate()
	 * @since   3.9.0
	 * @throws  Exception
	 */
	public function display($tpl = null)
	{
		// Initialise variables.
		$this->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   3.9.0
	 */
	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'));
		}
	}
}
views/remind/tmpl/default.php000064400000002464151165776720012317
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/** @var PrivacyViewConfirm $this */

JHtml::_('behavior.keepalive');
JHtml::_('behavior.formvalidator');

?>
<div class="remind-confirm<?php echo $this->pageclass_sfx;
?>">
	<?php if ($this->params->get('show_page_heading')) :
?>
		<div class="page-header">
			<h1>
				<?php echo
$this->escape($this->params->get('page_heading')); ?>
			</h1>
		</div>
	<?php endif; ?>
	<form action="<?php echo
JRoute::_('index.php?option=com_privacy&task=request.remind');
?>" method="post" class="form-validate
form-horizontal well">
		<?php foreach ($this->form->getFieldsets() as $fieldset) : ?>
			<fieldset>
				<?php if (!empty($fieldset->label)) : ?>
					<legend><?php echo JText::_($fieldset->label);
?></legend>
				<?php endif; ?>
				<?php echo $this->form->renderFieldset($fieldset->name);
?>
			</fieldset>
		<?php endforeach; ?>
		<div class="control-group">
			<div class="controls">
				<button type="submit" class="btn btn-primary
validate">
					<?php echo JText::_('JSUBMIT'); ?>
				</button>
			</div>
		</div>
		<?php echo JHtml::_('form.token'); ?>
	</form>
</div>
views/remind/tmpl/default.xml000064400000000501151165776720012316
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_PRIVACY_REMIND_VIEW_DEFAULT_TITLE"
option="COM_PRIVACY_REMIND_VIEW_DEFAULT_OPTION">
		<help
			key="JHELP_MENUS_MENU_ITEM_PRIVACY_REMIND_REQUEST"
		/>
		<message>
			<![CDATA[COM_PRIVACY_REMIND_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/remind/view.html.php000064400000005762151165776720011640
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Registry\Registry;

/**
 * Remind confirmation view class
 *
 * @since  3.9.0
 */
class PrivacyViewRemind extends JViewLegacy
{
	/**
	 * The form object
	 *
	 * @var    JForm
	 * @since  3.9.0
	 */
	protected $form;

	/**
	 * The CSS class suffix to append to the view container
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	protected $pageclass_sfx;

	/**
	 * The view parameters
	 *
	 * @var    Registry
	 * @since  3.9.0
	 */
	protected $params;

	/**
	 * The state information
	 *
	 * @var    JObject
	 * @since  3.9.0
	 */
	protected $state;

	/**
	 * Execute and display a template script.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise an Error object.
	 *
	 * @see     JViewLegacy::loadTemplate()
	 * @since   3.9.0
	 * @throws  Exception
	 */
	public function display($tpl = null)
	{
		// Initialise variables.
		$this->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   3.9.0
	 */
	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'));
		}
	}
}
views/request/tmpl/default.xml000064400000000504151165776720012533
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_PRIVACY_REQUEST_VIEW_DEFAULT_TITLE"
option="COM_PRIVACY_REQUEST_VIEW_DEFAULT_OPTION">
		<help
			key="JHELP_MENUS_MENU_ITEM_PRIVACY_CREATE_REQUEST"
		/>
		<message>
			<![CDATA[COM_PRIVACY_REQUEST_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>