52
0
plg_extension_componentbuil.../componentbuilderprivacycompiler.php

882 lines
40 KiB
PHP

<?php
/**
* @package Joomla.Component.Builder
*
* @created 30th April, 2015
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Registry\Registry;
JLoader::register('ComponentbuilderHelper', JPATH_ADMINISTRATOR . '/components/com_componentbuilder/helpers/componentbuilder.php');
use VDM\Joomla\Componentbuilder\Compiler\Factory as CFactory;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line;
/**
* Extension - Componentbuilder Privacy Compiler plugin.
*
* @package ComponentbuilderPrivacyCompiler
* @since 1.1.3
*/
class PlgExtensionComponentbuilderPrivacyCompiler extends CMSPlugin
{
/**
* Affects constructor behavior. If true, language files will be loaded automatically.
*
* @var boolean
* @since 1.0.0
*/
protected $autoloadLanguage = true;
/**
* The language string builder
*
* @var array
*/
protected $languageArray = array();
/**
* Global switch to see if component have need of privacy plugin to be loaded.
*
* @var boolean
* @since 1.0.0
*/
protected $loadPrivacy = false;
/**
* The Views Linked to Joomla Users
*
* @var array
* @since 1.0.0
*/
protected $activeViews = array();
/**
* The Views permission fields
*
* @var array
* @since 1.0.0
*/
protected $permissionFields = array();
/**
* The permissions core
*
* @var array
*/
protected $permissionCore = array();
/**
* The permissions Builder
*
* @var array
*/
protected $permissionBuilder = array();
/**
* Event Triggered in the compiler [on Before Model View Data]
*
* @return void
*
* @since 1.0
*/
public function jcb_ce_onBeforeModelViewData(&$context, &$view, &$placeholders)
{
// add the privacy
$view->params = (isset($view->params) && ComponentbuilderHelper::checkJson($view->params)) ? json_decode($view->params, true) : $view->params;
if (ComponentbuilderHelper::checkArray($view->params) && isset($view->params['privacy']) && ComponentbuilderHelper::checkArray($view->params['privacy']) &&
isset($view->params['privacy']['activate']) && $view->params['privacy']['activate'] == 1)
{
// activate the load of the privacy plugin
$this->loadPrivacy = true;
// load the admin view details
$this->activeViews[$view->id] = $view;
// add permissions
$view->addpermissions = (isset($view->addpermissions) && ComponentbuilderHelper::checkJson($view->addpermissions)) ? json_decode($view->addpermissions, true) : null;
if (ComponentbuilderHelper::checkArray($view->addpermissions))
{
$view->addpermissions = array_values($view->addpermissions);
// add the new permissions
$view->addpermissions[] = array('action' => 'view.privacy.delete', 'implementation' => 3, 'title' => $view->name_list . ' Privacy Delete', 'description' => ' Allows the users in this group to remove their personal data in ' . $view->name_list . ' via the Joomla privacy suite.');
$view->addpermissions[] = array('action' => 'view.privacy.access', 'implementation' => 3, 'title' => $view->name_list . ' Privacy Access', 'description' => ' Allows the users in this group to access their personal data in ' . $view->name_list . ' via the Joomla privacy suite.');
// convert back to json
$view->addpermissions = json_encode($view->addpermissions, JSON_FORCE_OBJECT);
}
// add placeholders to view if not already set
if (!isset($this->activeViews[$view->id]->placeholders))
{
$this->activeViews[$view->id]->placeholders = CFactory::_('Placeholder')->active;
}
}
}
/**
* Event Triggered in the compiler [on After Build Access Sections]
*
* @return void
*
* @since 1.0
*/
public function jcb_ce_onAfterBuildAccessSections(&$context, $compiler)
{
// check if this component needs a privacy plugin loaded
if ($this->loadPrivacy)
{
// get the permission builder array
$this->permissionBuilder = $compiler->permissionBuilder;
// get the permission core array
$this->permissionCore = $compiler->permissionCore;
}
}
/**
* Event Triggered in the compiler [on After Get]
*
* @return void
*
* @since 1.0
*/
public function jcb_ce_onAfterGet(&$context, $compiler)
{
// check if this component needs a privacy plugin loaded
if ($this->loadPrivacy)
{
$plugin = JPluginHelper::getPlugin('content', 'componentbuilderprivacytabs');
// check if this is json
if (isset($plugin->params) && ComponentbuilderHelper::checkJson($plugin->params))
{
// Convert the params field to an array.
$registry = new Registry;
$registry->loadString($plugin->params);
$plugin->params = $registry->toArray();
}
// now get the plugin ID if set
if (isset($plugin->params['plugin']) && $plugin->params['plugin'] > 0)
{
// if linked it will only load it once
CFactory::_('Joomlaplugin.Data')->set($plugin->params['plugin']);
}
else
{
JFactory::getApplication()->enqueueMessage(JText::_('PLG_EXTENSION_COMPONENTBUILDERPRIVACYCOMPILER_YOU_DO_NOT_HAVE_A_GLOBAL_PRIVACY_PLUGIN_SETUP_SO_THE_INTEGRATION_WITH_JOOMLA_PRIVACY_SUITE_COULD_NOT_BE_BUILD'), 'Error');
$this->loadPrivacy= false;
}
}
}
/**
* Event Triggered in the compiler [on Before Update Files]
*
* @return void
*
* @since 1.0
*/
public function jcb_ce_onBeforeUpdateFiles(&$context, $compiler)
{
// check if privacy is to be loaded
if ($this->loadPrivacy && ComponentbuilderHelper::checkArray($this->activeViews))
{
// get compiler defaults
$strictFieldExportPermissions = $compiler->strictFieldExportPermissions;
$exportTextOnly = $compiler->exportTextOnly;
// load the getPrivacyExport functions
foreach ($this->activeViews as $id => &$view)
{
// set permissions based on view
if (isset($view->params['privacy']['permissions']))
{
$compiler->strictFieldExportPermissions = (int) $view->params['privacy']['permissions'];
}
// allow text only export
$compiler->exportTextOnly = 1;
// set view list name
$viewName_list = ComponentbuilderHelper::safeString($view->name_list);
// set view single name
$viewName_single = ComponentbuilderHelper::safeString($view->name_single);
// load the function
CFactory::_('Content')->add_($viewName_list, 'MODELEXPORTMETHOD',
$compiler->setGetItemsModelMethod(
$viewName_single,
$viewName_list,
[
'functionName' => 'getPrivacyExport',
'docDesc' => 'Method to get data during an export request.',
'type' => 'privacy'
]
)
);
// get the permissions building values for later if needed
if ($compiler->strictFieldExportPermissions &&
isset($compiler->permissionFields[$viewName_single]) &&
ComponentbuilderHelper::checkArray($compiler->permissionFields[$viewName_single]))
{
$this->permissionFields[$viewName_single] = $compiler->permissionFields[$viewName_single];
}
}
// set compiler defaults
$compiler->strictFieldExportPermissions = $strictFieldExportPermissions;
$compiler->exportTextOnly = $exportTextOnly;
// add helper classes
$helper_strings = ['CUSTOM_HELPER_SCRIPT', 'SITE_CUSTOM_HELPER_SCRIPT', 'BOTH_CUSTOM_HELPER_SCRIPT'];
$privacy_events = [
'PrivacyCanRemoveData' => true,
'PrivacyExportRequest' => true,
'PrivacyRemoveData' => true
];
foreach ($helper_strings as $helper)
{
if (($helper_content = CFactory::_('Content')->get($helper)) !== null &&
ComponentbuilderHelper::checkString($helper_content))
{
foreach ($privacy_events as $privacy_event => &$add)
{
// check if the even is overwriten
if (strpos($helper_content,
'public static function on' . $privacy_event . '(') !== false)
{
$add = false;
}
}
}
}
// add the events still needed
CFactory::_('Content')->add('BOTH_CUSTOM_HELPER_SCRIPT',
CFactory::_('Placeholder')->update_($this->getHelperMethod($privacy_events))
);
}
}
/**
* Event Triggered in the compiler [on Before Set Lang File Data]
*
* @return void
*
* @since 1.0
*/
public function jcb_ce_onBeforeSetLangFileData(&$context, $compiler)
{
if (ComponentbuilderHelper::checkArray($this->languageArray))
{
foreach($this->languageArray as $key => $string)
{
$compiler->setLangContent('site', $key, $string);
}
}
}
/**
* get the Helper methods needed to integrate with Joomla Privacy Suite
*
* @param string $helperMethods The helper methods string
*
* @return void
*
* @since 1.0
*/
protected function getHelperMethod(&$events)
{
$methods = '';
foreach ($events as $event => $add)
{
// check if the even should be added
if ($add)
{
// add the event
$this->{'set'.$event}($methods);
}
}
// only add header if there was events added
if (ComponentbuilderHelper::checkString($methods))
{
$methods = PHP_EOL . PHP_EOL . Indent::_(1) . "//" . Line::_(__Line__, __Class__) . " <<<=== Privacy integration with Joomla Privacy suite ===>>>" . PHP_EOL . $methods;
}
return $methods;
}
/**
* Set Privacy Can Remove Data
*
* @param string $methods The methods string
*
* @return void
*
*/
protected function setPrivacyCanRemoveData(&$methods)
{
$methods .= PHP_EOL . Indent::_(1) . "/**";
$methods .= PHP_EOL . Indent::_(1) . " * Performs validation to determine if the data associated with a remove information request can be processed";
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @param PrivacyPlugin \$plugin The plugin being processed";
$methods .= PHP_EOL . Indent::_(1) . " * @param PrivacyRemovalStatus \$status The status being set";
$methods .= PHP_EOL . Indent::_(1) . " * @param PrivacyTableRequest \$request The request record being processed";
$methods .= PHP_EOL . Indent::_(1) . " * @param JUser \$user The user account associated with this request if available";
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @return PrivacyRemovalStatus";
$methods .= PHP_EOL . Indent::_(1) . " */";
$methods .= PHP_EOL . Indent::_(1) . "public static function onPrivacyCanRemoveData(&\$plugin, &\$status, &\$request, &\$user)";
$methods .= PHP_EOL . Indent::_(1) . "{";
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Bucket to get all reasons why removal not allowed";
$methods .= PHP_EOL . Indent::_(2) . "\$reasons = array();";
foreach ($this->activeViews as $view)
{
// set view single name
$viewName_single = ComponentbuilderHelper::safeString($view->name_single);
// setup correct core target
$coreLoad = false;
if (isset($this->permissionCore[$viewName_single]))
{
$core = $this->permissionCore[$viewName_single];
$coreLoad = true;
}
// load the canDo from getActions helper method
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Check if user has permission to delete " . $view->name_list;
// set the if statement based on the permission builder
if ($coreLoad && isset($this->permissionBuilder[$core['core.delete']]) && ComponentbuilderHelper::checkArray($this->permissionBuilder[$core['core.delete']]) && in_array($viewName_single, $this->permissionBuilder[$core['core.delete']]))
{
$methods .= PHP_EOL . Indent::_(2) . "if (!\$user->authorise('" . $core['core.delete'] . "', 'com_" . Placefix::_("component") . "') && !\$user->authorise('" . $core['core.privacy.delete'] . "', 'com_" . Placefix::_("component") . "'))";
}
else
{
$methods .= PHP_EOL . Indent::_(2) . "if (!\$user->authorise('core.delete', 'com_" . Placefix::_("component") . "') && !\$user->authorise('" . $core['core.privacy.delete'] . "', 'com_" . Placefix::_("component") . "'))";
}
$methods .= PHP_EOL . Indent::_(2) . "{";
// set language key
$lang_key = $view->placeholders[Placefix::_("LANG_PREFIX")] . '_PRIVACY_CANT_REMOVE_' . $view->placeholders[Placefix::_("VIEWS")];
// set language string
$this->languageArray[$lang_key] = "You do not have permission to remove/delete ". $view->name_list . ".";
$methods .= PHP_EOL . Indent::_(3) . "\$reasons[] = JTe" . "xt::_('" . $lang_key . "');";
$methods .= PHP_EOL . Indent::_(2) . "}";
// set language key
$lang_key = $view->placeholders[Placefix::_("LANG_PREFIX")] . '_PRIVACY_CANT_REMOVE_CONTACT_SUPPORT';
}
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Check if any reasons were found not to allow removal";
$methods .= PHP_EOL . Indent::_(2) . "if (self::checkArray(\$reasons))";
$methods .= PHP_EOL . Indent::_(2) . "{";
$methods .= PHP_EOL . Indent::_(3) . "\$status->canRemove = false;";
// set language string
$this->languageArray[$lang_key] = 'Please contact support for more details.';
$methods .= PHP_EOL . Indent::_(3) . "\$status->reason = implode(' ' . PHP_EOL, \$reasons) . ' ' . PHP_EOL . JTe" . "xt::_('" . $lang_key . "');";
$methods .= PHP_EOL . Indent::_(2) . "}";
$methods .= PHP_EOL . Indent::_(2) . "return \$status;";
$methods .= PHP_EOL . Indent::_(1) . "}" . PHP_EOL;
}
/**
* Set Privacy Export Request
*
* @param string $methods The methods string
*
* @return void
*
*/
protected function setPrivacyExportRequest(&$methods)
{
$methods .= PHP_EOL . Indent::_(1) . "/**";
$methods .= PHP_EOL . Indent::_(1) . " * Processes an export request for Joomla core user data";
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @param PrivacyPlugin \$plugin The plugin being processed";
$methods .= PHP_EOL . Indent::_(1) . " * @param DomainArray \$domains The array of domains";
$methods .= PHP_EOL . Indent::_(1) . " * @param PrivacyTableRequest \$request The request record being processed";
$methods .= PHP_EOL . Indent::_(1) . " * @param JUser \$user The user account associated with this request if available";
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @return PrivacyExportDomain[]";
$methods .= PHP_EOL . Indent::_(1) . " */";
$methods .= PHP_EOL . Indent::_(1) . "public static function onPrivacyExportRequest(&\$plugin, &\$domains, &\$request, &\$user)";
$methods .= PHP_EOL . Indent::_(1) . "{";
foreach ($this->activeViews as $view)
{
// set view list name
$viewName_list = ComponentbuilderHelper::safeString($view->name_list);
// set view single name
$viewName_single = ComponentbuilderHelper::safeString($view->name_single);
// setup correct core target
$coreLoad = false;
if (isset($this->permissionCore[$viewName_single]))
{
$core = $this->permissionCore[$viewName_single];
$coreLoad = true;
}
// load the canDo from getActions helper method
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Check if user has permission to access " . $view->name_list;
// set the if statement based on the permission builder
if ($coreLoad && isset($core['core.access']) && isset($this->permissionBuilder['global'][$core['core.access']]) && ComponentbuilderHelper::checkArray($this->permissionBuilder['global'][$core['core.access']]) && in_array($viewName_single, $this->permissionBuilder['global'][$core['core.access']]))
{
$methods .= PHP_EOL . Indent::_(2) . "if (\$user->authorise('" . $core['core.access'] . "', 'com_" . Placefix::_("component") . "') || \$user->authorise('" . $core['core.privacy.access'] . "', 'com_" . Placefix::_("component") . "'))";
}
else
{
$methods .= PHP_EOL . Indent::_(2) . "if (\$user->authorise('" . $core['core.privacy.access'] . "', 'com_" . Placefix::_("component") . "'))";
}
$methods .= PHP_EOL . Indent::_(2) . "{";
$methods .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Get " . $view->name_single . " domain";
$methods .= PHP_EOL . Indent::_(3) . "\$domains[] = self::create" . ucfirst($viewName_list) . "Domain(\$plugin, \$user);";
$methods .= PHP_EOL . Indent::_(2) . "}";
}
$methods .= PHP_EOL . Indent::_(2) . "return \$domains;";
$methods .= PHP_EOL . Indent::_(1) . "}" . PHP_EOL;
foreach ($this->activeViews as $view)
{
// set view list name
$viewName_list = ComponentbuilderHelper::safeString($view->name_list);
// set view single name
$viewName_single = ComponentbuilderHelper::safeString($view->name_single);
$methods .= PHP_EOL . Indent::_(1) . "/**";
$methods .= PHP_EOL . Indent::_(1) . " * Create the domain for the " . $view->name_single;
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @param JTableUser \$user The JTableUser object to process";
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @return PrivacyExportDomain";
$methods .= PHP_EOL . Indent::_(1) . " */";
$methods .= PHP_EOL . Indent::_(1) . "protected static function create" . ucfirst($viewName_list) . "Domain(&\$plugin, &\$user)";
$methods .= PHP_EOL . Indent::_(1) . "{";
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " create " . $view->name_list . " domain";
$methods .= PHP_EOL . Indent::_(2) . "\$domain = self::createDomain('" . $viewName_single . "', '" . Placefix::_("component") . "_" . $viewName_single . "_data');";
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " get database object";
$methods .= PHP_EOL . Indent::_(2) . "\$db = JFactory::getDbo();";
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " get all item ids of " . $view->name_list . " that belong to this user";
$methods .= PHP_EOL . Indent::_(2) . "\$query = \$db->getQuery(true)";
$methods .= PHP_EOL . Indent::_(3) . "->select('id')";
$methods .= PHP_EOL . Indent::_(3) . "->from(\$db->quoteName('#__" . Placefix::_('component') . '_' . $viewName_single . "'));";
// get via custom script
if (isset($view->params['privacy']['user_link']) && $view->params['privacy']['user_link'] == 3)
{
$methods .= PHP_EOL . str_replace(array_keys($view->placeholders), array_values($view->placeholders), $view->params['privacy']['custom_link']);
}
// just another field
elseif (isset($view->params['privacy']['user_link']) && $view->params['privacy']['user_link'] == 2 && isset($view->params['privacy']['other_user_field']))
{
// get the field name
if (($field_name = $this->getFieldName($view->fields, $view->params['privacy']['other_user_field'])) !== false)
{
$methods .= PHP_EOL . Indent::_(2) . "\$query->where(\$db->quoteName('" . $field_name . "') . ' = ' . \$db->quote(\$user->id));";
}
else
{
// give a warning message (TODO)
// stop any from loading
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " ==== ERROR ===== ERROR ====== (field name not found)";
$methods .= PHP_EOL . Indent::_(2) . "\$query->where(\$db->quoteName('id') . ' = -2'; //" . Line::_(__Line__, __Class__) . " <-- this will never return any value. Check your [other user field] selected in the admin view privacy tab.";
}
}
// get based on created by
else
{
$methods .= PHP_EOL . Indent::_(2) . "\$query->where(\$db->quoteName('created_by') . ' = ' . \$db->quote(\$user->id));";
}
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " get all items for the " . $view->name_list . " domain";
$methods .= PHP_EOL . Indent::_(2) . "\$pks = \$db->setQuery(\$query)->loadColumn();";
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " get the " . $view->name_list . " model";
$methods .= PHP_EOL . Indent::_(2) . "\$model = self::getModel('" . $viewName_list . "', JPATH_ADMINISTRATOR . '/components/com_" . Placefix::_("component") . "');";
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Get all item details of " . $view->name_list . " that belong to this user";
$methods .= PHP_EOL . Indent::_(2) . "\$items = \$model->getPrivacyExport(\$pks, \$user);";
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " check if we have items since permissions could block the request";
$methods .= PHP_EOL . Indent::_(2) . "if (self::checkArray(\$items))";
$methods .= PHP_EOL . Indent::_(2) . "{";
$methods .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Remove " . $view->name_single . " default columns";
$methods .= PHP_EOL . Indent::_(3) . "foreach (array('params', 'asset_id', 'checked_out', 'checked_out_time', 'created', 'created_by', 'modified', 'modified_by', 'published', 'ordering', 'access', 'version', 'hits') as \$column)";
$methods .= PHP_EOL . Indent::_(3) . "{";
$methods .= PHP_EOL . Indent::_(4) . "\$items = ArrayHelper::dropColumn(\$items, \$column);";
$methods .= PHP_EOL . Indent::_(3) . "}";
$methods .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " load the items into the domain object";
$methods .= PHP_EOL . Indent::_(3) . "foreach (\$items as \$item)";
$methods .= PHP_EOL . Indent::_(3) . "{";
$methods .= PHP_EOL . Indent::_(4) . "\$domain->addItem(self::createItemFromArray(\$item, \$item['id']));";
$methods .= PHP_EOL . Indent::_(3) . "}";
$methods .= PHP_EOL . Indent::_(2) . "}";
$methods .= PHP_EOL . Indent::_(2) . "return \$domain;";
$methods .= PHP_EOL . Indent::_(1) . "}" . PHP_EOL;
}
// we must add these helper methods
$methods .= PHP_EOL . Indent::_(1) . "/**";
$methods .= PHP_EOL . Indent::_(1) . " * Create a new domain object";
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @param string \$name The domain's name";
$methods .= PHP_EOL . Indent::_(1) . " * @param string \$description The domain's description";
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @return PrivacyExportDomain";
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @since 3.9.0";
$methods .= PHP_EOL . Indent::_(1) . " */";
$methods .= PHP_EOL . Indent::_(1) . "protected static function createDomain(\$name, \$description = '')";
$methods .= PHP_EOL . Indent::_(1) . "{";
$methods .= PHP_EOL . Indent::_(2) . "\$domain = new PrivacyExportDomain;";
$methods .= PHP_EOL . Indent::_(2) . "\$domain->name = \$name;";
$methods .= PHP_EOL . Indent::_(2) . "\$domain->description = \$description;";
$methods .= PHP_EOL . PHP_EOL . Indent::_(2) . "return \$domain;";
$methods .= PHP_EOL . Indent::_(1) . "}";
$methods .= PHP_EOL . PHP_EOL . Indent::_(1) . "/**";
$methods .= PHP_EOL . Indent::_(1) . " * Create an item object for an array";
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @param array \$data The array data to convert";
$methods .= PHP_EOL . Indent::_(1) . " * @param integer|null \$itemId The ID of this item";
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @return PrivacyExportItem";
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @since 3.9.0";
$methods .= PHP_EOL . Indent::_(1) . " */";
$methods .= PHP_EOL . Indent::_(1) . "protected static function createItemFromArray(array \$data, \$itemId = null)";
$methods .= PHP_EOL . Indent::_(1) . "{";
$methods .= PHP_EOL . Indent::_(2) . "\$item = new PrivacyExportItem;";
$methods .= PHP_EOL . Indent::_(2) . "\$item->id = \$itemId;";
$methods .= PHP_EOL . PHP_EOL . Indent::_(2) . "foreach (\$data as \$key => \$value)";
$methods .= PHP_EOL . Indent::_(2) . "{";
$methods .= PHP_EOL . Indent::_(3) . "if (is_object(\$value))";
$methods .= PHP_EOL . Indent::_(3) . "{";
$methods .= PHP_EOL . Indent::_(4) . "\$value = (array) \$value;";
$methods .= PHP_EOL . Indent::_(3) . "}";
$methods .= PHP_EOL . PHP_EOL . Indent::_(3) . "if (is_array(\$value))";
$methods .= PHP_EOL . Indent::_(3) . "{";
$methods .= PHP_EOL . Indent::_(4) . "\$value = print_r(\$value, true);";
$methods .= PHP_EOL . Indent::_(3) . "}";
$methods .= PHP_EOL . PHP_EOL . Indent::_(3) . "\$field = new PrivacyExportField;";
$methods .= PHP_EOL . Indent::_(3) . "\$field->name = \$key;";
$methods .= PHP_EOL . Indent::_(3) . "\$field->value = \$value;";
$methods .= PHP_EOL . PHP_EOL . Indent::_(3) . "\$item->addField(\$field);";
$methods .= PHP_EOL . Indent::_(2) . "}";
$methods .= PHP_EOL . PHP_EOL . Indent::_(2) . "return \$item;";
$methods .= PHP_EOL . Indent::_(1) . "}" . PHP_EOL;
}
/**
* get the field name
*
* @param array $fields The fields array
* @param int $id The field id
*
* @return string The field name
*
*/
protected function getFieldName(&$fields, $id)
{
foreach ($fields as $field)
{
if ($field['field'] == $id)
{
return $field['base_name'];
}
}
return false;
}
/**
* Set Privacy Remove Data
*
* @param string $methods The methods string
*
* @return void
*
*/
protected function setPrivacyRemoveData(&$methods)
{
$methods .= PHP_EOL . Indent::_(1) . "/**";
$methods .= PHP_EOL . Indent::_(1) . " * Removes the data associated with a remove information request";
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @param PrivacyTableRequest \$request The request record being processed";
$methods .= PHP_EOL . Indent::_(1) . " * @param JUser \$user The user account associated with this request if available";
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @return void";
$methods .= PHP_EOL . Indent::_(1) . " */";
$methods .= PHP_EOL . Indent::_(1) . "public static function onPrivacyRemoveData(&\$plugin, &\$request, &\$user)";
$methods .= PHP_EOL . Indent::_(1) . "{";
foreach ($this->activeViews as $view)
{
// set the anonymize switch
$anonymize = false;
if (isset($view->params['privacy']['anonymize']) && $view->params['privacy']['anonymize'] == 1 && isset($view->params['privacy']['anonymize_fields']) && ComponentbuilderHelper::checkArray($view->params['privacy']['anonymize_fields'], true))
{
// Anonymize the data
$anonymize = true;
}
// set view list name
$viewName_list = ComponentbuilderHelper::safeString($view->name_list);
// set view single name
$viewName_single = ComponentbuilderHelper::safeString($view->name_single);
// setup correct core target
$coreLoad = false;
if (isset($this->permissionCore[$viewName_single]))
{
$core = $this->permissionCore[$viewName_single];
$coreLoad = true;
}
// load the canDo from getActions helper method
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Check if user has permission to delet " . $view->name_list;
// set the if statement based on the permission builder
if ($coreLoad && isset($this->permissionBuilder[$core['core.delete']]) && ComponentbuilderHelper::checkArray($this->permissionBuilder[$core['core.delete']]) && in_array($viewName_single, $this->permissionBuilder[$core['core.delete']]))
{
$methods .= PHP_EOL . Indent::_(2) . "if (\$user->authorise('" . $core['core.delete'] . "', 'com_" . Placefix::_("component") . "') || \$user->authorise('" . $core['core.privacy.delete'] . "', 'com_" . Placefix::_("component") . "'))";
}
else
{
$methods .= PHP_EOL . Indent::_(2) . "if (\$user->authorise('core.delete', 'com_" . Placefix::_("component") . "') || \$user->authorise('" . $core['core.privacy.delete'] . "', 'com_" . Placefix::_("component") . "'))";
}
$methods .= PHP_EOL . Indent::_(2) . "{";
// check if this is a plain delete, or it is a Anonymize
if ($anonymize)
{
// anonymize the data
$methods .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Anonymize " . $view->name_single . " data";
$methods .= PHP_EOL . Indent::_(3) . "self::anonymize" . ucfirst($viewName_list) . "Data(\$plugin, \$user);";
}
else
{
// just dump, delete the rows
$methods .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Remove " . $view->name_single . " data";
$methods .= PHP_EOL . Indent::_(3) . "self::remove" . ucfirst($viewName_list) . "Data(\$plugin, \$user);";
}
$methods .= PHP_EOL . Indent::_(2) . "}";
}
$methods .= PHP_EOL . Indent::_(1) . "}" . PHP_EOL;
foreach ($this->activeViews as $view)
{
// set the anonymize switch
$anonymize = false;
if (isset($view->params['privacy']['anonymize']) && $view->params['privacy']['anonymize'] == 1 && isset($view->params['privacy']['anonymize_fields']) && ComponentbuilderHelper::checkArray($view->params['privacy']['anonymize_fields'], true))
{
// Anonymize the data
$anonymize = true;
}
// set view list name
$viewName_list = ComponentbuilderHelper::safeString($view->name_list);
// set view single name
$viewName_single = ComponentbuilderHelper::safeString($view->name_single);
$methods .= PHP_EOL . Indent::_(1) . "/**";
// check if this is a plain delete, or it is a Anonymize
if ($anonymize)
{
// Anonymize the data
$methods .= PHP_EOL . Indent::_(1) . " * Anonymize the " . $view->name_single . " data";
}
else
{
// Delete the rows
$methods .= PHP_EOL . Indent::_(1) . " * Remove the " . $view->name_single . " data";
}
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @param JTableUser \$user The JTableUser object to process";
$methods .= PHP_EOL . Indent::_(1) . " *";
$methods .= PHP_EOL . Indent::_(1) . " * @return void";
$methods .= PHP_EOL . Indent::_(1) . " */";
// check if this is a plain delete, or it is a Anonymize
if ($anonymize)
{
// Anonymize the data
$methods .= PHP_EOL . Indent::_(1) . "protected static function anonymize" . ucfirst($viewName_list) . "Data(&\$plugin, &\$user)";
}
else
{
// Delete the rows
$methods .= PHP_EOL . Indent::_(1) . "protected static function remove" . ucfirst($viewName_list) . "Data(&\$plugin, &\$user)";
}
$methods .= PHP_EOL . Indent::_(1) . "{";
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " get database object";
$methods .= PHP_EOL . Indent::_(2) . "\$db = JFactory::getDbo();";
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " get all item ids of " . $view->name_list . " that belong to this user";
$methods .= PHP_EOL . Indent::_(2) . "\$query = \$db->getQuery(true)";
$methods .= PHP_EOL . Indent::_(3) . "->select('id')";
$methods .= PHP_EOL . Indent::_(3) . "->from(\$db->quoteName('#__" . Placefix::_('component') . '_' . $viewName_single . "'));";
// get via custom script
if (isset($view->params['privacy']['user_link']) && $view->params['privacy']['user_link'] == 3)
{
$methods .= PHP_EOL . str_replace(array_keys($view->placeholders), array_values($view->placeholders), $view->params['privacy']['custom_link']);
}
// just another field
elseif (isset($view->params['privacy']['user_link']) && $view->params['privacy']['user_link'] == 2 && isset($view->params['privacy']['other_user_field']))
{
// get the field name
if (($field_name = $this->getFieldName($view->fields, $view->params['privacy']['other_user_field'])) !== false)
{
$methods .= PHP_EOL . Indent::_(2) . "\$query->where(\$db->quoteName('" . $field_name . "') . ' = ' . \$db->quote(\$user->id));";
}
else
{
// give a warning message (TODO)
// stop any from loading
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " ==== ERROR ===== ERROR ====== (field name not found)";
$methods .= PHP_EOL . Indent::_(2) . "\$query->where(\$db->quoteName('id') . ' = -2'; //" . Line::_(__Line__, __Class__) . " <-- this will never return any value. Check your [other user field] selected in the admin view privacy tab.";
}
}
// get based on created by
else
{
$methods .= PHP_EOL . Indent::_(2) . "\$query->where(\$db->quoteName('created_by') . ' = ' . \$db->quote(\$user->id));";
}
$methods .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " get all items for the " . $view->name_list . " table that belong to this user";
$methods .= PHP_EOL . Indent::_(2) . "\$pks = \$db->setQuery(\$query)->loadColumn();";
$methods .= PHP_EOL .PHP_EOL . Indent::_(2) . "if (self::checkArray(\$pks))";
$methods .= PHP_EOL . Indent::_(2) . "{";
$methods .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " get the " . $viewName_single . " model";
$methods .= PHP_EOL . Indent::_(3) . "\$model = self::getModel('" . $viewName_single . "', JPATH_ADMINISTRATOR . '/components/com_" . Placefix::_("component") . "');";
// check if this is a plain delete, or it is a Anonymize
if ($anonymize)
{
// build the pseudoanonymised data array
$_data_bucket = array();
$_random_bucket = array();
$_permission_bucket = array();
foreach ($view->params['privacy']['anonymize_fields'] as $row)
{
if (($field_name = $this->getFieldName($view->fields, $row['field'])) !== false)
{
if ('RANDOM' === $row['value'])
{
$_random_bucket[$field_name] = 8; // (TODO) make the size dynamic
}
$_data_bucket[] = PHP_EOL . Indent::_(4) . "'" . $field_name . "' => '" . $row['value'] ."'";
$_permission_bucket[$field_name] = $field_name;
}
}
// Anonymize the data
$methods .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " this is the pseudoanonymised data array for " . $view->name_list;
$methods .= PHP_EOL . Indent::_(3) . "\$pseudoanonymisedData = array(";
$methods .= implode(',', $_data_bucket);
$methods .= PHP_EOL . Indent::_(3) . ");";
// add the permissional removal of values the user has not right to view or access
$hasPermissional = false;
if (isset($this->permissionFields[$viewName_single]) && ComponentbuilderHelper::checkArray($this->permissionFields[$viewName_single]))
{
foreach ($this->permissionFields[$viewName_single] as $fieldName => $permission_options)
{
if (!$hasPermissional && isset($_permission_bucket[$fieldName]))
{
foreach($permission_options as $permission_option => $fieldType)
{
if (!$hasPermissional)
{
switch ($permission_option)
{
case 'access':
case 'view':
case 'edit':
$hasPermissional = true;
break;
}
}
}
}
}
// add the notes and get the global switch
if ($hasPermissional)
{
$methods .= PHP_EOL . PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Get global permissional control activation. (default is inactive)";
$methods .= PHP_EOL . Indent::_(3) . "\$strict_permission_per_field = JComponentHelper::getParams('com_" . Placefix::_("component") . "')->get('strict_permission_per_field', 0);";
$methods .= PHP_EOL . Indent::_(3) . "if(\$strict_permission_per_field)";
$methods .= PHP_EOL . Indent::_(3) . "{";
$methods .= PHP_EOL . Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " remove all fields that is not permitted to be changed";
foreach ($this->permissionFields[$viewName_single] as $fieldName => $permission_options)
{
if (isset($_permission_bucket[$fieldName]))
{
$methods .= PHP_EOL . Indent::_(4) . "if (";
$_permission_if = array();
foreach ($permission_options as $perm_key => $field_typrew)
{
$_permission_if[] = "!\$user->authorise('" . $viewName_single . "." . $perm_key . "." . $fieldName . "', 'com_" . Placefix::_("component") . "')";
}
$methods .= implode(' || ', $_permission_if);
$methods .= ")";
$methods .= PHP_EOL . Indent::_(4) . "{";
$methods .= PHP_EOL . Indent::_(5) . "unset(\$pseudoanonymisedData['". $fieldName . "']);";
$methods .= PHP_EOL . Indent::_(4) . "}";
}
}
$methods .= PHP_EOL . Indent::_(3) . "}";
}
}
$methods .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " get the " . $view->name_list . " table";
$methods .= PHP_EOL . Indent::_(3) . "\$table = \$model->getTable();";
$methods .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " check that we still have pseudoanonymised data for " . $view->name_list . " set";
$methods .= PHP_EOL . Indent::_(3) . "if (!self::checkArray(\$pseudoanonymisedData))";
$methods .= PHP_EOL . Indent::_(3) . "{";
$methods .= PHP_EOL . Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " still archive all items";
$methods .= PHP_EOL . Indent::_(4) . "\$table->publish(\$pks, 2);";
$methods .= PHP_EOL . Indent::_(4) . "return false;";
$methods .= PHP_EOL . Indent::_(3) . "}";
$methods .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Iterate the items to anonimize each one.";
$methods .= PHP_EOL . Indent::_(3) . "foreach (\$pks as \$i => \$pk)";
$methods .= PHP_EOL . Indent::_(3) . "{";
$methods .= PHP_EOL . Indent::_(4) . "\$table->reset();";
$methods .= PHP_EOL . Indent::_(4) . "\$pseudoanonymisedData['id'] = \$pk;";
if (ComponentbuilderHelper::checkArray($_random_bucket))
{
foreach ($_random_bucket as $fieldName => $size)
{
$methods .= PHP_EOL . Indent::_(4) . "if (isset(\$pseudoanonymisedData['" . $fieldName . "']))";
$methods .= PHP_EOL . Indent::_(4) . "{";
$methods .= PHP_EOL . Indent::_(5) . "\$pseudoanonymisedData['" . $fieldName . "'] = self::randomkey(" . (int) $size . ");";
$methods .= PHP_EOL . Indent::_(4) . "}";
}
}
$methods .= PHP_EOL . PHP_EOL . Indent::_(4) . "if (\$table->bind(\$pseudoanonymisedData))";
$methods .= PHP_EOL . Indent::_(4) . "{";
$methods .= PHP_EOL . Indent::_(5) . "\$table->store();";
$methods .= PHP_EOL . Indent::_(4) . "}";
$methods .= PHP_EOL . Indent::_(3) . "}";
$methods .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " archive all items";
$methods .= PHP_EOL . Indent::_(3) . "\$table->publish(\$pks, 2);";
}
else
{
// Delete the rows
$methods .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " get the " . $view->name_list . " table";
$methods .= PHP_EOL . Indent::_(3) . "\$table = \$model->getTable();";
$methods .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Iterate the items to delete each one.";
$methods .= PHP_EOL . Indent::_(3) . "foreach (\$pks as \$i => \$pk)";
$methods .= PHP_EOL . Indent::_(3) . "{";
$methods .= PHP_EOL . Indent::_(4) . "if (\$table->load(\$pk))";
$methods .= PHP_EOL . Indent::_(4) . "{";
$methods .= PHP_EOL . Indent::_(5) . "\$table->delete(\$pk);";
$methods .= PHP_EOL . Indent::_(4) . "}";
$methods .= PHP_EOL . Indent::_(3) . "}";
$methods .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Clear the component's cache";
$methods .= PHP_EOL . Indent::_(3) . "\$model->cleanCache();";
}
$methods .= PHP_EOL . Indent::_(2) . "}";
$methods .= PHP_EOL . Indent::_(1) . "}" . PHP_EOL;
}
}
}