Update on v1.0.5 (beta for next version)
Here's an update on the current version, which includes changes towards the next release still in beta.
This commit is contained in:
parent
32498659b4
commit
908fd6a45a
@ -8,13 +8,13 @@ A component to keep track of release checking.
|
|||||||
+ *Author*: [Joomla! Project](mailto:admin@joomla.org)
|
+ *Author*: [Joomla! Project](mailto:admin@joomla.org)
|
||||||
+ *Name*: [Track Release Checking](http://www.joomla.org)
|
+ *Name*: [Track Release Checking](http://www.joomla.org)
|
||||||
+ *First Build*: 29th July, 2020
|
+ *First Build*: 29th July, 2020
|
||||||
+ *Last Build*: 21st September, 2022
|
+ *Last Build*: 10th August, 2023
|
||||||
+ *Version*: 1.0.x
|
+ *Version*: 1.0.x
|
||||||
+ *Copyright*: (C) 2020 Open Source Matters, Inc.
|
+ *Copyright*: (C) 2020 Open Source Matters, Inc.
|
||||||
+ *License*: GNU General Public License version 2 or later; see LICENSE.txt
|
+ *License*: GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
|
||||||
## Some Fun Numbers
|
## Some Fun Numbers
|
||||||
|
|
||||||
+ *Line count*: **22248**
|
+ *Line count*: **23163**
|
||||||
+ *File count*: **213**
|
+ *File count*: **226**
|
||||||
+ *Folder count*: **62**
|
+ *Folder count*: **64**
|
@ -8,13 +8,13 @@ A component to keep track of release checking.
|
|||||||
+ *Author*: [Joomla! Project](mailto:admin@joomla.org)
|
+ *Author*: [Joomla! Project](mailto:admin@joomla.org)
|
||||||
+ *Name*: [Track Release Checking](http://www.joomla.org)
|
+ *Name*: [Track Release Checking](http://www.joomla.org)
|
||||||
+ *First Build*: 29th July, 2020
|
+ *First Build*: 29th July, 2020
|
||||||
+ *Last Build*: 21st September, 2022
|
+ *Last Build*: 10th August, 2023
|
||||||
+ *Version*: 1.0.x
|
+ *Version*: 1.0.x
|
||||||
+ *Copyright*: (C) 2020 Open Source Matters, Inc.
|
+ *Copyright*: (C) 2020 Open Source Matters, Inc.
|
||||||
+ *License*: GNU General Public License version 2 or later; see LICENSE.txt
|
+ *License*: GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
|
||||||
## Some Fun Numbers
|
## Some Fun Numbers
|
||||||
|
|
||||||
+ *Line count*: **22248**
|
+ *Line count*: **23163**
|
||||||
+ *File count*: **213**
|
+ *File count*: **226**
|
||||||
+ *Folder count*: **62**
|
+ *Folder count*: **64**
|
@ -11,6 +11,49 @@
|
|||||||
// No direct access to this file
|
// No direct access to this file
|
||||||
defined('_JEXEC') or die('Restricted access');
|
defined('_JEXEC') or die('Restricted access');
|
||||||
|
|
||||||
|
// register this component namespace
|
||||||
|
spl_autoload_register(function ($class) {
|
||||||
|
// project-specific base directories and namespace prefix
|
||||||
|
$search = [
|
||||||
|
'libraries/jcb_powers/VDM.Joomla' => 'VDM\\Joomla'
|
||||||
|
];
|
||||||
|
// Start the search and load if found
|
||||||
|
$found = false;
|
||||||
|
$found_base_dir = "";
|
||||||
|
$found_len = 0;
|
||||||
|
foreach ($search as $base_dir => $prefix)
|
||||||
|
{
|
||||||
|
// does the class use the namespace prefix?
|
||||||
|
$len = strlen($prefix);
|
||||||
|
if (strncmp($prefix, $class, $len) === 0)
|
||||||
|
{
|
||||||
|
// we have a match so load the values
|
||||||
|
$found = true;
|
||||||
|
$found_base_dir = $base_dir;
|
||||||
|
$found_len = $len;
|
||||||
|
// done here
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check if we found a match
|
||||||
|
if (!$found)
|
||||||
|
{
|
||||||
|
// not found so move to the next registered autoloader
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// get the relative class name
|
||||||
|
$relative_class = substr($class, $found_len);
|
||||||
|
// replace the namespace prefix with the base directory, replace namespace
|
||||||
|
// separators with directory separators in the relative class name, append
|
||||||
|
// with .php
|
||||||
|
$file = JPATH_ROOT . '/' . $found_base_dir . '/src' . str_replace('\\', '/', $relative_class) . '.php';
|
||||||
|
// if the file exists, require it
|
||||||
|
if (file_exists($file))
|
||||||
|
{
|
||||||
|
require $file;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
use Joomla\CMS\Filesystem\File;
|
use Joomla\CMS\Filesystem\File;
|
||||||
use Joomla\CMS\Language\Language;
|
use Joomla\CMS\Language\Language;
|
||||||
use Joomla\Registry\Registry;
|
use Joomla\Registry\Registry;
|
||||||
|
@ -13,6 +13,7 @@ defined('_JEXEC') or die('Restricted access');
|
|||||||
|
|
||||||
use Joomla\CMS\MVC\Model\ListModel;
|
use Joomla\CMS\MVC\Model\ListModel;
|
||||||
use Joomla\Utilities\ArrayHelper;
|
use Joomla\Utilities\ArrayHelper;
|
||||||
|
use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Release_checking Ajax List Model
|
* Release_checking Ajax List Model
|
||||||
@ -61,7 +62,7 @@ class Release_checkingModelAjax extends ListModel
|
|||||||
$query->select($db->quoteName( array('a.id') ));
|
$query->select($db->quoteName( array('a.id') ));
|
||||||
$query->from($db->quoteName('#__release_checking_action', 'a'));
|
$query->from($db->quoteName('#__release_checking_action', 'a'));
|
||||||
// we also filter out the actions this user already did on this context
|
// we also filter out the actions this user already did on this context
|
||||||
if (Release_checkingHelper::checkArray($result['removed_ids']))
|
if (UtilitiesArrayHelper::check($result['removed_ids']))
|
||||||
{
|
{
|
||||||
$query->where($db->quoteName('a.id') . ' NOT IN (' . implode(', ', $result['removed_ids']) . ')');
|
$query->where($db->quoteName('a.id') . ' NOT IN (' . implode(', ', $result['removed_ids']) . ')');
|
||||||
}
|
}
|
||||||
|
@ -48,14 +48,14 @@ class JFormFieldActionsfiltername extends JFormFieldList
|
|||||||
// Reset the query using our newly populated query object.
|
// Reset the query using our newly populated query object.
|
||||||
$db->setQuery($query);
|
$db->setQuery($query);
|
||||||
|
|
||||||
$results = $db->loadColumn();
|
$_results = $db->loadColumn();
|
||||||
$_filter = array();
|
$_filter = array();
|
||||||
$_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_RELEASE_CHECKING_FILTER_SELECT_NAME') . ' -');
|
$_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_RELEASE_CHECKING_FILTER_SELECT_NAME') . ' -');
|
||||||
|
|
||||||
if ($results)
|
if ($_results)
|
||||||
{
|
{
|
||||||
$results = array_unique($results);
|
$_results = array_unique($_results);
|
||||||
foreach ($results as $name)
|
foreach ($_results as $name)
|
||||||
{
|
{
|
||||||
// Now add the name and its text to the options array
|
// Now add the name and its text to the options array
|
||||||
$_filter[] = JHtml::_('select.option', $name, $name);
|
$_filter[] = JHtml::_('select.option', $name, $name);
|
||||||
|
@ -48,14 +48,14 @@ class JFormFieldContextsfiltername extends JFormFieldList
|
|||||||
// Reset the query using our newly populated query object.
|
// Reset the query using our newly populated query object.
|
||||||
$db->setQuery($query);
|
$db->setQuery($query);
|
||||||
|
|
||||||
$results = $db->loadColumn();
|
$_results = $db->loadColumn();
|
||||||
$_filter = array();
|
$_filter = array();
|
||||||
$_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_RELEASE_CHECKING_FILTER_SELECT_NAME') . ' -');
|
$_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_RELEASE_CHECKING_FILTER_SELECT_NAME') . ' -');
|
||||||
|
|
||||||
if ($results)
|
if ($_results)
|
||||||
{
|
{
|
||||||
$results = array_unique($results);
|
$_results = array_unique($_results);
|
||||||
foreach ($results as $name)
|
foreach ($_results as $name)
|
||||||
{
|
{
|
||||||
// Now add the name and its text to the options array
|
// Now add the name and its text to the options array
|
||||||
$_filter[] = JHtml::_('select.option', $name, $name);
|
$_filter[] = JHtml::_('select.option', $name, $name);
|
||||||
|
@ -48,13 +48,13 @@ class JFormFieldReleasechecksfiltercreatedby extends JFormFieldList
|
|||||||
// Reset the query using our newly populated query object.
|
// Reset the query using our newly populated query object.
|
||||||
$db->setQuery($query);
|
$db->setQuery($query);
|
||||||
|
|
||||||
$results = $db->loadColumn();
|
$_results = $db->loadColumn();
|
||||||
$_filter = array();
|
$_filter = array();
|
||||||
|
|
||||||
if ($results)
|
if ($_results)
|
||||||
{
|
{
|
||||||
$results = array_unique($results);
|
$_results = array_unique($_results);
|
||||||
foreach ($results as $created_by)
|
foreach ($_results as $created_by)
|
||||||
{
|
{
|
||||||
// Now add the created_by and its text to the options array
|
// Now add the created_by and its text to the options array
|
||||||
$_filter[] = JHtml::_('select.option', $created_by, JFactory::getUser($created_by)->name);
|
$_filter[] = JHtml::_('select.option', $created_by, JFactory::getUser($created_by)->name);
|
||||||
|
@ -48,20 +48,20 @@ class JFormFieldReleasechecksfilteroutcome extends JFormFieldList
|
|||||||
// Reset the query using our newly populated query object.
|
// Reset the query using our newly populated query object.
|
||||||
$db->setQuery($query);
|
$db->setQuery($query);
|
||||||
|
|
||||||
$results = $db->loadColumn();
|
$_results = $db->loadColumn();
|
||||||
$_filter = array();
|
$_filter = array();
|
||||||
|
|
||||||
if ($results)
|
if ($_results)
|
||||||
{
|
{
|
||||||
// get release_checksmodel
|
// get release_checksmodel
|
||||||
$model = Release_checkingHelper::getModel('release_checks');
|
$_model = Release_checkingHelper::getModel('release_checks');
|
||||||
$results = array_unique($results);
|
$_results = array_unique($_results);
|
||||||
foreach ($results as $outcome)
|
foreach ($_results as $outcome)
|
||||||
{
|
{
|
||||||
// Translate the outcome selection
|
// Translate the outcome selection
|
||||||
$text = $model->selectionTranslation($outcome,'outcome');
|
$_text = $_model->selectionTranslation($outcome,'outcome');
|
||||||
// Now add the outcome and its text to the options array
|
// Now add the outcome and its text to the options array
|
||||||
$_filter[] = JHtml::_('select.option', $outcome, JText::_($text));
|
$_filter[] = JHtml::_('select.option', $outcome, JText::_($_text));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $_filter;
|
return $_filter;
|
||||||
|
@ -17,7 +17,7 @@ use Joomla\CMS\Filesystem\Folder;
|
|||||||
use Joomla\Utilities\ArrayHelper;
|
use Joomla\Utilities\ArrayHelper;
|
||||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||||
|
|
||||||
/**
|
/***
|
||||||
* Release_checking Import Base Database Model
|
* Release_checking Import Base Database Model
|
||||||
*/
|
*/
|
||||||
class Release_checkingModelImport extends BaseDatabaseModel
|
class Release_checkingModelImport extends BaseDatabaseModel
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Joomla.CMS
|
|
||||||
* @maintainer Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
|
||||||
*
|
|
||||||
* @created 29th July, 2020
|
|
||||||
* @copyright (C) 2020 Open Source Matters, Inc. <http://www.joomla.org>
|
|
||||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
|
||||||
*/
|
|
||||||
|
|
||||||
// No direct access to this file
|
|
||||||
defined('JPATH_PLATFORM') or die;
|
|
||||||
|
|
||||||
use Joomla\CMS\Form\Form;
|
|
||||||
use Joomla\CMS\Form\FormRule;
|
|
||||||
use Joomla\Registry\Registry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Form Rule (Int) class for the Joomla Platform.
|
|
||||||
*/
|
|
||||||
class JFormRuleInt extends FormRule
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Method to test that an integer value was added.
|
|
||||||
*
|
|
||||||
* @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object.
|
|
||||||
* @param mixed $value The form field value to validate.
|
|
||||||
* @param string $group The field name group control value. This acts as an array container for the field.
|
|
||||||
* For example if the field has name="foo" and the group value is set to "bar" then the
|
|
||||||
* full field name would end up being "bar[foo]".
|
|
||||||
* @param Registry $input An optional Registry object with the entire data set to validate against the entire form.
|
|
||||||
* @param Form $form The form object for which the field is being tested.
|
|
||||||
*
|
|
||||||
* @return boolean True if the value is valid integer, false otherwise.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null)
|
|
||||||
{
|
|
||||||
// Check if the field is required.
|
|
||||||
$required = ((string) $element['required'] == 'true' || (string) $element['required'] == 'required');
|
|
||||||
|
|
||||||
// If the value is empty and the field is not required return True.
|
|
||||||
if (($value === '' || $value === null) && ! $required)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now validate the value to be an integer
|
|
||||||
// we need to validate a string with the integer in it
|
|
||||||
// since this is how Joomla passes the value to the test method
|
|
||||||
// so we use type coercion along with is_numeric
|
|
||||||
return is_numeric($value) && is_int(+$value);
|
|
||||||
// if you have a better idea... lets hear it.
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,6 +11,49 @@
|
|||||||
// No direct access to this file
|
// No direct access to this file
|
||||||
defined('_JEXEC') or die('Restricted access');
|
defined('_JEXEC') or die('Restricted access');
|
||||||
|
|
||||||
|
// register this component namespace
|
||||||
|
spl_autoload_register(function ($class) {
|
||||||
|
// project-specific base directories and namespace prefix
|
||||||
|
$search = [
|
||||||
|
'libraries/jcb_powers/VDM.Joomla' => 'VDM\\Joomla'
|
||||||
|
];
|
||||||
|
// Start the search and load if found
|
||||||
|
$found = false;
|
||||||
|
$found_base_dir = "";
|
||||||
|
$found_len = 0;
|
||||||
|
foreach ($search as $base_dir => $prefix)
|
||||||
|
{
|
||||||
|
// does the class use the namespace prefix?
|
||||||
|
$len = strlen($prefix);
|
||||||
|
if (strncmp($prefix, $class, $len) === 0)
|
||||||
|
{
|
||||||
|
// we have a match so load the values
|
||||||
|
$found = true;
|
||||||
|
$found_base_dir = $base_dir;
|
||||||
|
$found_len = $len;
|
||||||
|
// done here
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check if we found a match
|
||||||
|
if (!$found)
|
||||||
|
{
|
||||||
|
// not found so move to the next registered autoloader
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// get the relative class name
|
||||||
|
$relative_class = substr($class, $found_len);
|
||||||
|
// replace the namespace prefix with the base directory, replace namespace
|
||||||
|
// separators with directory separators in the relative class name, append
|
||||||
|
// with .php
|
||||||
|
$file = JPATH_ROOT . '/' . $found_base_dir . '/src' . str_replace('\\', '/', $relative_class) . '.php';
|
||||||
|
// if the file exists, require it
|
||||||
|
if (file_exists($file))
|
||||||
|
{
|
||||||
|
require $file;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Access check.
|
// Access check.
|
||||||
|
9
libraries/jcb_powers/.htaccess
Normal file
9
libraries/jcb_powers/.htaccess
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Apache 2.4+
|
||||||
|
<IfModule mod_authz_core.c>
|
||||||
|
Require all denied
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# Apache 2.0-2.2
|
||||||
|
<IfModule !mod_authz_core.c>
|
||||||
|
Deny from all
|
||||||
|
</IfModule>
|
107
libraries/jcb_powers/VDM.Joomla/src/Utilities/ArrayHelper.php
Normal file
107
libraries/jcb_powers/VDM.Joomla/src/Utilities/ArrayHelper.php
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package Joomla.Component.Builder
|
||||||
|
*
|
||||||
|
* @created 3rd September, 2020
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VDM\Joomla\Utilities;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some array tricks helper
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
abstract class ArrayHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check if have an array with a length
|
||||||
|
*
|
||||||
|
* @input array The array to check
|
||||||
|
*
|
||||||
|
* @returns int|false number of items in array on success
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public static function check($array, $removeEmptyString = false)
|
||||||
|
{
|
||||||
|
if (is_array($array) && ($nr = count((array) $array)) > 0)
|
||||||
|
{
|
||||||
|
// also make sure the empty strings are removed
|
||||||
|
if ($removeEmptyString)
|
||||||
|
{
|
||||||
|
$array = array_filter($array);
|
||||||
|
|
||||||
|
if ($array === [])
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count($array);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $nr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge an array of array's
|
||||||
|
*
|
||||||
|
* @input array The arrays you would like to merge
|
||||||
|
*
|
||||||
|
* @returns array|null merged array on success
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
public static function merge($arrays): ?array
|
||||||
|
{
|
||||||
|
if(self::check($arrays))
|
||||||
|
{
|
||||||
|
$merged = [];
|
||||||
|
foreach ($arrays as $array)
|
||||||
|
{
|
||||||
|
if (self::check($array))
|
||||||
|
{
|
||||||
|
$merged = array_merge($merged, $array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $merged;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if arrays intersect
|
||||||
|
*
|
||||||
|
* @input array The first array
|
||||||
|
* @input array The second array
|
||||||
|
*
|
||||||
|
* @returns bool true if intersect else false
|
||||||
|
*
|
||||||
|
* @since 3.1.1
|
||||||
|
*/
|
||||||
|
public static function intersect($a_array, $b_array): bool
|
||||||
|
{
|
||||||
|
// flip the second array
|
||||||
|
$b_array = array_flip($b_array);
|
||||||
|
|
||||||
|
// loop the first array
|
||||||
|
foreach ($a_array as $v)
|
||||||
|
{
|
||||||
|
if (isset($b_array[$v]))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
1
libraries/jcb_powers/VDM.Joomla/src/Utilities/index.html
Normal file
1
libraries/jcb_powers/VDM.Joomla/src/Utilities/index.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<html><body bgcolor="#FFFFFF"></body></html>
|
9
libraries/jcb_powers/htaccess.txt
Normal file
9
libraries/jcb_powers/htaccess.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Apache 2.4+
|
||||||
|
<IfModule mod_authz_core.c>
|
||||||
|
Require all denied
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# Apache 2.0-2.2
|
||||||
|
<IfModule !mod_authz_core.c>
|
||||||
|
Deny from all
|
||||||
|
</IfModule>
|
1
libraries/jcb_powers/index.html
Normal file
1
libraries/jcb_powers/index.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<html><body bgcolor="#FFFFFF"></body></html>
|
7
libraries/jcb_powers/web.config
Normal file
7
libraries/jcb_powers/web.config
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<system.web>
|
||||||
|
<authorization>
|
||||||
|
<deny users="*" />
|
||||||
|
</authorization>
|
||||||
|
</system.web>
|
||||||
|
</configuration>
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<extension type="component" version="4" method="upgrade">
|
<extension type="component" version="4" method="upgrade">
|
||||||
<name>COM_RELEASE_CHECKING</name>
|
<name>COM_RELEASE_CHECKING</name>
|
||||||
<creationDate>21st September, 2022</creationDate>
|
<creationDate>10th August, 2023</creationDate>
|
||||||
<author>Joomla! Project</author>
|
<author>Joomla! Project</author>
|
||||||
<authorEmail>admin@joomla.org</authorEmail>
|
<authorEmail>admin@joomla.org</authorEmail>
|
||||||
<authorUrl>http://www.joomla.org</authorUrl>
|
<authorUrl>http://www.joomla.org</authorUrl>
|
||||||
|
Loading…
Reference in New Issue
Block a user