| Current Path : /var/www/html/administrator/manifests/packages/kunena/ |
| Current File : /var/www/html/administrator/manifests/packages/kunena/script.php |
<?php
/**
* Kunena Package
*
* @package Kunena.Package
*
* @copyright Copyright (C) 2008 - 2026 Kunena Team. All rights reserved.
* @license https://www.gnu.org/copyleft/gpl.html GNU/GPL
* @link https://www.kunena.org
**/
use Joomla\CMS\Factory;
use Joomla\CMS\Application\AdministratorApplication;
use Joomla\CMS\Date\Date;
use Joomla\Filesystem\Folder;
use Joomla\CMS\Installer\InstallerAdapter;
use Joomla\CMS\Installer\InstallerScriptInterface;
use Joomla\CMS\Language\Text;
use Joomla\Database\DatabaseInterface;
use Joomla\Database\ParameterType;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Filesystem\File;
use Kunena\Forum\Libraries\Forum\KunenaForum;
use Kunena\Forum\Libraries\Install\KunenaModelInstall;
use Kunena\Forum\Libraries\Menu\KunenaMenuFix;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
return new class() implements ServiceProviderInterface {
public function register(Container $container)
{
$container->set(
InstallerScriptInterface::class,
new class(
$container->get(AdministratorApplication::class),
$container->get(DatabaseInterface::class)
) implements InstallerScriptInterface {
private AdministratorApplication $app;
private DatabaseInterface $db;
/**
* Minimum Joomla! version required to install the extension
*
* @var string
* @since 6.0.0
*/
protected $minimumJoomla = '5.3.4';
/**
* List of supported versions. Newest version first!
*
* @var array
* @since Kunena 2.0
*/
protected $versions = [
'PHP' => [
'8.5' => '8.5.0',
'8.4' => '8.4.1',
'8.3' => '8.3.0',
'8.2' => '8.2.0',
'0' => '8.5.0', // Preferred version
],
'MySQL' => [
'9.6' => '9.6.0',
'9.5' => '9.5.0',
'9.4' => '9.4.0',
'9.3' => '9.3.0',
'9.2' => '9.2.0',
'9.1' => '9.1.0',
'9.0' => '9.0.0',
'8.4' => '8.4.2',
'8.3' => '8.3.0',
'8.2' => '8.2.0',
'8.1' => '8.1.0',
'8.0' => '8.0.16',
'0' => '9.6.0', // Preferred version
],
'mariaDB' => [
'12.2' => '12.2.2',
'12.1' => '12.1.2',
'12.0' => '12.0.2',
'11.8' => '11.8.2',
'11.7' => '11.7.2',
'11.6' => '11.6.2',
'11.5' => '11.5.2',
'11.4' => '11.4.2',
'11.3' => '11.3',
'11.2' => '11.2',
'11.1' => '11.1',
'11.0' => '11.0',
'10.11' => '10.11',
'10.10' => '10.10',
'10.9' => '10.9',
'10.8' => '10.8',
'10.7' => '10.7',
'10.6' => '10.6',
'10.5' => '10.5',
'10.4' => '10.4',
'0' => '12.2.2', // Preferred version
],
'Joomla!' => [
'6.1' => '6.1.1',
'6.0' => '6.0.4',
'5.4' => '5.4.6',
'5.3' => '5.3.4',
'0' => '6.1.0', // Preferred version
],
];
/**
* List of required PHP extensions.
*
* @var array
* @since Kunena 2.0
*/
protected $extensions = ['dom', 'gd', 'json', 'pcre', 'SimpleXML', 'fileinfo', 'mbstring'];
/**
* Version of the currently installed Kunena component
*
* @var string
* @since Kunena 7.0.0
*/
protected string $installedVersion;
/**
*
* @since Kunena 7.0.0
*/
public function __construct(AdministratorApplication $app, DatabaseInterface $db)
{
$this->app = $app;
$this->db = $db;
$this->installedVersion = $this->getInstalledVersion();
}
/**
*
* @since Kunena 7.0.0
*/
public function install(InstallerAdapter $parent): bool
{
$this->app->enqueueMessage('Successful installed.');
return true;
}
/**
*
* @since Kunena 7.0.0
*/
public function update(InstallerAdapter $parent): bool
{
$this->app->enqueueMessage('Successful updated.');
return true;
}
/**
*
* @since Kunena 7.0.0
*/
public function uninstall(InstallerAdapter $parent): bool
{
$this->app->enqueueMessage('Successful uninstalled.');
return true;
}
/**
*
* @since Kunena 7.0.0
*/
public function preflight(string $type, InstallerAdapter $parent): bool
{
if ($type === 'uninstall') {
$items = KunenaMenuFix::getAll();
foreach ($items as $item) {
KunenaMenuFix::delete($item->id);
}
$installer = new KunenaModelInstall();
$installer->deleteMenu();
return true;
}
$manifest = $parent->manifest;
// Prevent installation if requirements are not met.
if (!$this->checkRequirements($manifest->version)) {
return false;
}
if (file_exists(JPATH_SITE . '/components/com_kunena/template/aurelia/assets/scss/custom.scss')) {
File::copy(JPATH_SITE . '/components/com_kunena/template/aurelia/assets/scss/custom.scss', JPATH_SITE . '/tmp/custom.scss');
}
$this->deleteRemovedFolder($this->installedVersion);
return true;
}
/**
*
* @since Kunena 7.0.0
*/
public function postflight(string $type, InstallerAdapter $parent): bool
{
if ($type === 'uninstall') {
return true;
}
if (function_exists('apcu_clear_cache')) {
apcu_clear_cache();
}
$db = Factory::getContainer()->get(DatabaseInterface::class);
$table = $db->getPrefix() . 'kunena_version';
$db->setQuery("SHOW TABLES LIKE {$db->quote($table)}");
$upgrade = 0;
$installed = 'NONE';
if ($db->loadResult() == $table) {
$db->setQuery("SELECT version FROM #__kunena_version ORDER BY `id` DESC", 0, 1);
$installed = $db->loadResult();
if (!empty($installed)) {
if (version_compare($installed, '5.2.99', '<')) {
$query = "ALTER TABLE `#__kunena_version` ADD `sampleData` boolean NOT NULL default '0' AFTER `versionname`;";
$db->setQuery($query);
$db->execute();
}
$upgrade = 1;
}
}
$file = JPATH_MANIFESTS . '/packages/pkg_kunena.xml';
$manifest = simplexml_load_file($file);
$version = (string) $manifest->version;
$build = (string) $manifest->version;
$date = (string) $manifest->creationDate;
$versionname = (string) $manifest->versionname;
$installdate = Factory::getDate('now');
$state = '';
$sampleData = 0;
if ($upgrade == 1) {
$sampleData = 1;
} else {
// In case of a clean install the ranks and smileys needs to be inserted in the table to avoid else emoticons/ranks not appears
$queries = [];
$query = "INSERT INTO `#__kunena_ranks`
(`rankId`, `rankTitle`, `rankMin`, `rankSpecial`, `rankImage`) VALUES
(1, {$db->quote('COM_KUNENA_SAMPLEDATA_RANK1')}, 0, 0, 'rank1.gif'),
(2, {$db->quote('COM_KUNENA_SAMPLEDATA_RANK2')}, 20, 0, 'rank2.gif'),
(3, {$db->quote('COM_KUNENA_SAMPLEDATA_RANK3')}, 40, 0, 'rank3.gif'),
(4, {$db->quote('COM_KUNENA_SAMPLEDATA_RANK4')}, 80, 0, 'rank4.gif'),
(5, {$db->quote('COM_KUNENA_SAMPLEDATA_RANK5')}, 160, 0, 'rank5.gif'),
(6, {$db->quote('COM_KUNENA_SAMPLEDATA_RANK6')}, 320, 0, 'rank6.gif'),
(7, {$db->quote('COM_KUNENA_SAMPLEDATA_RANK_ADMIN')}, 0, 1, 'rankadmin.gif'),
(8, {$db->quote('COM_KUNENA_SAMPLEDATA_RANK_MODERATOR')}, 0, 1, 'rankmod.gif'),
(9, {$db->quote('COM_KUNENA_SAMPLEDATA_RANK_SPAMMER')}, 0, 1, 'rankspammer.gif'),
(10, {$db->quote('COM_KUNENA_SAMPLEDATA_RANK_BANNED')}, 0, 1, 'rankbanned.gif');";
$queries[] = ['kunena_ranks', $query];
$query = "INSERT INTO `#__kunena_smileys`
(`id`,`code`,`location`,`emoticonbar`) VALUES
(1, 'B)', '1.png', 1),
(2, '8)', '2.png', 1),
(3, '8-)', '3.png', 1),
(4, ':-(', '4.png', 1),
(5, ':(', '5.png', 1),
(6, ':sad:', '6.png', 1),
(7, ':cry:', '7.png', 1),
(8, ':)', '8.png', 1),
(9, ':-)', '9.png', 1),
(10, ':cheer:', '10.png', 1),
(11, ';)', '11.png', 1),
(12, ';-)', '12.png', 1),
(13, ':wink:', '13.png', 1),
(14, ';-)', '14.png', 1),
(15, ':P', '15.png', 1),
(16, ':p', '16.png', 1),
(17, ':-p', '17.png', 1),
(18, ':-P', '18.png', 1),
(19, ':razz:', '19.png', 1),
(20, ':angry:', '20.png', 1),
(21, ':mad:', '21.png', 1),
(22, ':unsure:', '22.png', 1),
(23, ':o', '23.png', 1);";
$queries[] = ['kunena_smileys', $query];
foreach ($queries as $query) {
// Only insert sample/default data if table is empty
$db->setQuery("SELECT * FROM " . $db->quoteName($db->getPrefix() . $query[0]), 0, 1);
$filled = $db->loadObject();
if (!$filled) {
$db->setQuery($query[1]);
$db->execute();
}
}
}
$query = $db->createQuery();
$values = [
$db->quote($version),
$db->quote($build),
$db->quote($date),
$db->quote($versionname),
$db->quote($sampleData),
$db->quote($installdate),
$db->quote($state),
];
$query->insert($db->quoteName('#__kunena_version'))
->columns(
[
$db->quoteName('version'),
$db->quoteName('build'),
$db->quoteName('versiondate'),
$db->quoteName('versionname'),
$db->quoteName('sampleData'),
$db->quoteName('installdate'),
$db->quoteName('state'),
]
)
->values(implode(', ', $values));
$db->setQuery($query);
$db->execute();
$version = '';
$date = '';
$file = JPATH_MANIFESTS . '/packages/pkg_kunena.xml';
if (file_exists($file)) {
$manifest = simplexml_load_file($file);
$version = (string) $manifest->version;
$date = (string) $manifest->creationDate;
} else {
$db = Factory::getContainer()->get(DatabaseInterface::class);
$query = $db->createQuery();
$query->select('version')->from('#__kunena_version')->order('id');
$query->setLimit(1);
$db->setQuery($query);
$version = $db->loadResult();
if (!empty($version->versiondate)) {
$date = (string) $version->versiondate;
} else {
$date = new Date('now');
}
}
if (file_exists(JPATH_SITE . '/tmp/custom.scss')) {
File::copy(JPATH_SITE . '/tmp/custom.scss', JPATH_SITE . '/components/com_kunena/template/aurelia/assets/scss/custom.scss');
}
return true;
}
/**
* Delete the folders from Kunena directories which has been removed in the install package
*
* @param string $version version
*
* @since 7.0.0
*/
protected function deleteRemovedFolder(string $installedVersion)
{
if (version_compare($installedVersion, '6.3.0', '<') && version_compare($installedVersion, '6.0.0', '>=')) {
// Set and delete the following folders
$deleteFolders = [];
// Administrator folders
$deleteFolders[] = '/administrator/components/com_kunena/api';
$deleteFolders[] = '/administrator/components/com_kunena/forms';
$deleteFolders[] = '/administrator/components/com_kunena/install';
$deleteFolders[] = '/administrator/components/com_kunena/language';
$deleteFolders[] = '/administrator/components/com_kunena/media';
$deleteFolders[] = '/administrator/components/com_kunena/services';
$deleteFolders[] = '/administrator/components/com_kunena/sql';
$deleteFolders[] = '/administrator/components/com_kunena/src';
$deleteFolders[] = '/administrator/components/com_kunena/tmpl';
// Site folders
$deleteFolders[] = '/components/com_kunena/language';
$deleteFolders[] = '/components/com_kunena/src';
$deleteFolders[] = '/components/com_kunena/template/system';
$deleteFolders[] = '/components/com_kunena/tmpl';
// Library folders
$deleteFolders[] = '/libraries/kunena/Src';
foreach ($deleteFolders as $folder) {
if (is_dir(JPATH_ROOT . $folder) && !Folder::delete(JPATH_ROOT . $folder)) {
echo Text::sprintf('JLIB_INSTALLER_ERROR_FILE_FOLDER', $folder) . '<br>';
}
}
}
}
/**
* Get the version of the current installed Kunena from Joomla! extensions table
*
* @return string Installed version number or 0 when not installed
* @since 7.0.0
*/
private function getInstalledVersion(): string
{
$type = 'package';
$element = 'pkg_kunena';
$db = Factory::getContainer()->get(DatabaseInterface::class);
$query = $db->createQuery();
$query->select($db->quoteName('manifest_cache'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('type') . ' = :type')
->where($db->quoteName('element') . ' = :element')
->bind(':type', $type, ParameterType::STRING)
->bind(':element', $element, ParameterType::STRING);
// if (!is_null($this->folder)) {
// $query->where($db->quoteName('folder') . ' = :folder')
// ->bind(':folder', $this->folder, ParameterType::STRING);
// }
$db->setQuery($query);
$result = $db->loadResult();
if ($result) {
$return = \json_decode($result);
if ($return) {
return $return->version;
} else {
return '0';
}
} else {
return '0';
}
}
/**
* Check all the requirements mandatory to allow to install Kunena
*
* @param string $version version
*
* @return boolean|integer
*
* @since version
*/
public function checkRequirements($version)
{
$db = Factory::getContainer()->get(DatabaseInterface::class);
$pass = $this->checkVersion('PHP', $this->getCleanPhpVersion());
$pass &= $this->checkVersion('Joomla!', JVERSION);
$pass &= $this->checkDbVersion($db->getVersion());
$pass &= $this->checkDbo($db->name, ['mysql', 'mysqli', 'pdomysql']);
$pass &= $this->checkPhpExtensions($this->extensions);
$pass &= $this->checkKunena($version);
return $pass;
}
/**
* @param string $name name
* @param string $version version
*
* @return boolean
*
* @throws Exception
* @since version
*/
protected function checkVersion($name, $version)
{
$app = Factory::getApplication();
$major = $minor = 0;
foreach ($this->versions[$name] as $major => $minor) {
if (!$major || version_compare($version, $major, '<')) {
continue;
}
if (version_compare($version, $minor, '>=')) {
return true;
}
break;
}
if (!$major) {
$minor = reset($this->versions[$name]);
}
$recommended = end($this->versions[$name]);
reset($this->versions[$name]);
if (version_compare($version, next($this->versions[$name]), '<=')) {
$app->enqueueMessage(
sprintf(
"%s %s is not supported. Minimum required version is %s %s, but it is highly recommended to use %s %s or later.",
$name,
$version,
$name,
$minor,
$name,
$recommended
),
'notice'
);
} else {
$app->enqueueMessage(
sprintf(
"%s %s is not supported. Minimum required version is %s %s.",
$name,
$version,
$name,
$minor
),
'notice'
);
}
return false;
}
/**
* Check MariaDB and MySQL versions
*
* @since Kunena 6.2
*/
protected function checkDbVersion($version)
{
if (preg_match('/(?:.*-)?(\d+\.\d+\.\d+)-MariaDB.*/', $version, $matches)) {
return $this->checkVersion('mariaDB', $matches[1]);
}
return $this->checkVersion('MySQL', $version);
}
/**
* On some hosting the PHP version given with the version of the packet in the distribution
*
* @return string
*
* @since Kunena
*/
protected function getCleanPhpVersion()
{
$version = PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '.' . PHP_RELEASE_VERSION;
return $version;
}
/**
* @param string $name name
* @param array $types types
*
* @return boolean
*
* @throws Exception
* @since version 2.0
*/
protected function checkDbo($name, $types)
{
$app = Factory::getApplication();
if (in_array($name, $types)) {
return true;
}
$app->enqueueMessage(sprintf("Database driver '%s' is not supported. Please use MySQL instead.", $name), 'notice');
return false;
}
/**
* @param array $extensions extensions
*
* @return integer
*
* @throws Exception
* @since version 2.0
*/
protected function checkPhpExtensions($extensions)
{
$app = Factory::getApplication();
$pass = 1;
foreach ($extensions as $name) {
if (!extension_loaded($name)) {
$pass = 0;
$app->enqueueMessage(sprintf("Required PHP extension '%s' is missing. Please install it into your system.", $name), 'notice');
}
}
return $pass;
}
/**
* @param string $version version
*
* @return boolean
*
* @throws Exception
* @since version 2.0
*/
protected function checkKunena($version)
{
$app = Factory::getApplication();
$db = Factory::getContainer()->get(DatabaseInterface::class);
// Do not install over Git repository (K1.6+).
if (class_exists('Kunena\Forum\Libraries\Forum\KunenaForum') && method_exists('KunenaForum', 'isDev') && KunenaForum::isDev()) {
$app->enqueueMessage('Oops! You should not install Kunena over your Git repository!', 'notice');
return false;
}
// Get installed Kunena version.
$table = $db->getPrefix() . 'kunena_version';
$db->setQuery("SHOW TABLES LIKE {$db->quote($table)}");
if ($db->loadResult() != $table) {
return true;
}
$installed = $db->setQuery(
$db->createQuery()
->select('version')
->from('#__kunena_version')->order('id DESC')
->setLimit(1)
)->loadResult();
if (!$installed) {
return true;
}
// Don't allow to upgrade before the version 5.1.0
if (version_compare($installed, '5.1.0', '<')) {
$app->enqueueMessage('You should not upgrade Kunena from the version ' . $installed . ', you can do the upgrade only since 5.1.0', 'notice');
return false;
}
// Don't allow to upgrade before the version 6.4.5
if (version_compare($installed, '6.4.5', '<')) {
$app->enqueueMessage('You cannot not upgrade Kunena from version ' . $installed . ', you can only upgrade from version 6.4.5 or higher', 'notice');
return false;
}
return true;
}
}
);
}
};