Skip to content

Commit

Permalink
#9892 upgrade to laravel 11 and PHP 8.2+ (#10211)
Browse files Browse the repository at this point in the history
* #9892 Dependency updated and auth configured

* #9892 DB float type precision added

* #9892 removed doctrine/dbal package dependency

* #9892 downgraded wikimedia/less.php from 5.* to 4.*

* #9892 downgraded wikimedia/less.php from 4.* to 3.*

* #9892 upgraded wikimedia/less.php to 5.*

* #9892 packages upgrade

* #9892 PKP required version updated

* #9892 removed reference of psr6 cache interface

* #9892 PHPUnit 11 compatibility test

* #9892 updated PHPUnit command

* #9892 updated packages after rebase

* #9892 PHPUnit 11 doc block to attributes convert to update deprecations

* #9892 PHPUnit command update to make compatibale with version 11

* #9892 WIP: MariaDB driver compatibility

* #9892 WIP: MariaDB driver compatibility

* #9892 fixed column types

* #9892 maria db driver name update

* #9892 db driver determining issue fixing

* #9892 WIP: db driver determining issue fixing

* #9892 PHP 8.2 compatibility checks

* #9892 fixed broken test

* #9892 fixing failing tests

* #9892 removing Doctrine DBAL related method usage

* #9892 logging upgrade exception

* #9892 removed test logging upgrade exception

* #9892 moved the foreign key check form trait to core pkp migration class

* #9892 add missing namespace
  • Loading branch information
touhidurabir authored Aug 12, 2024
1 parent edeb709 commit cbf8b01
Show file tree
Hide file tree
Showing 87 changed files with 1,800 additions and 2,424 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ lib/components
tests/.phpunit.result.cache
.php-cs-fixer.cache
styles/tinymce
tests/.phpunit.cache
1 change: 1 addition & 0 deletions classes/core/DataObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
namespace PKP\core;

use APP\core\Application;
use Exception;
use PKP\db\DAO;
use PKP\db\DAORegistry;
use PKP\facades\Locale;
Expand Down
14 changes: 10 additions & 4 deletions classes/core/PKPApplication.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
use GuzzleHttp\Client;
use Illuminate\Database\Events\QueryExecuted;
use Illuminate\Database\MySqlConnection;
use Illuminate\Database\MariaDbConnection;
use Illuminate\Database\PostgresConnection;
use Illuminate\Support\Facades\DB;
use PKP\config\Config;
use PKP\db\DAORegistry;
Expand Down Expand Up @@ -76,7 +78,7 @@ public static function getContextAssocType();

abstract class PKPApplication implements iPKPApplicationInfoProvider
{
public const PHP_REQUIRED_VERSION = '8.0.2';
public const PHP_REQUIRED_VERSION = '8.2.0';

// Constant used to distinguish between editorial and author workflows
public const WORKFLOW_TYPE_EDITORIAL = 'editorial';
Expand Down Expand Up @@ -272,9 +274,13 @@ protected function initializeTimeZone(): void
if (Application::isInstalled()) {
// Retrieve the current offset
$offset = (new DateTime())->format('P');
$statement = DB::connection() instanceof MySqlConnection
? "SET time_zone = '{$offset}'"
: "SET TIME ZONE INTERVAL '{$offset}' HOUR TO MINUTE";
$statement = match (true) {
DB::connection() instanceof MySqlConnection,
DB::connection() instanceof MariaDbConnection
=> "SET time_zone = '{$offset}'",
DB::connection() instanceof PostgresConnection
=> "SET TIME ZONE INTERVAL '{$offset}' HOUR TO MINUTE"
};
DB::statement($statement);
}
}
Expand Down
75 changes: 39 additions & 36 deletions classes/core/PKPContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@
class PKPContainer extends Container
{
/**
* @var string The base path of the application, needed for base_path helper
* The base path of the application, needed for base_path helper
*/
protected $basePath;
protected string $basePath;

/**
* @brief Create own container instance, initialize bindings
* Create own container instance, initialize bindings
*/
public function __construct()
{
Expand All @@ -57,10 +57,27 @@ public function __construct()
}

/**
* @brief Bind the current container and set it globally
* Get the proper database driver
*/
public static function getDatabaseDriverName(?string $driver = null): string
{
$driver ??= Config::getVar('database', 'driver');

if (substr(strtolower($driver), 0, 8) === 'postgres') {
return 'pgsql';
}

return match ($driver) {
'mysql', 'mysqli' => 'mysql',
'mariadb' => 'mariadb'
};
}

/**
* Bind the current container and set it globally
* let helpers, facades and services know to which container refer to
*/
protected function registerBaseBindings()
protected function registerBaseBindings(): void
{
static::setInstance($this);
$this->instance('app', $this);
Expand Down Expand Up @@ -134,9 +151,9 @@ public function renderForConsole($output, Throwable $exception)
}

/**
* @brief Register used service providers within the container
* Register used service providers within the container
*/
public function registerConfiguredProviders()
public function registerConfiguredProviders(): void
{
// Load main settings, this should be done before registering services, e.g., it's used by Database Service
$this->loadConfiguration();
Expand Down Expand Up @@ -165,9 +182,9 @@ public function registerConfiguredProviders()
}

/**
* @brief Simplified service registration
* Simplified service registration
*/
public function register(\Illuminate\Support\ServiceProvider $provider)
public function register(\Illuminate\Support\ServiceProvider $provider): void
{
$provider->register();

Expand Down Expand Up @@ -199,9 +216,9 @@ public function register(\Illuminate\Support\ServiceProvider $provider)
}

/**
* @brief Bind aliases with contracts
* Bind aliases with contracts
*/
public function registerCoreContainerAliases()
public function registerCoreContainerAliases(): void
{
foreach ([
'auth' => [
Expand Down Expand Up @@ -234,9 +251,6 @@ public function registerCoreContainerAliases()
\Illuminate\Contracts\Cache\Repository::class,
\Psr\SimpleCache\CacheInterface::class
],
'cache.psr6' => [
\Psr\Cache\CacheItemPoolInterface::class
],
'db' => [
\Illuminate\Database\DatabaseManager::class,
\Illuminate\Database\ConnectionResolverInterface::class
Expand Down Expand Up @@ -319,10 +333,10 @@ public function registerCoreContainerAliases()
}

/**
* @brief Bind and load container configurations
* Bind and load container configurations
* usage from Facade, see Illuminate\Support\Facades\Config
*/
protected function loadConfiguration()
protected function loadConfiguration(): void
{
$items = [];
$_request = Application::get()->getRequest();
Expand All @@ -336,12 +350,7 @@ protected function loadConfiguration()
];

// Database connection
$driver = 'mysql';

if (substr(strtolower(Config::getVar('database', 'driver')), 0, 8) === 'postgres') {
$driver = 'pgsql';
}

$driver = static::getDatabaseDriverName();
$items['database']['default'] = $driver;
$items['database']['connections'][$driver] = [
'driver' => $driver,
Expand Down Expand Up @@ -453,21 +462,17 @@ protected function loadConfiguration()
}

/**
* @param string $path appended to the base path
*
* @brief see Illuminate\Foundation\Application::basePath
* @see Illuminate\Foundation\Application::basePath
*/
public function basePath($path = '')
public function basePath(string $path = ''): string
{
return $this->basePath . ($path ? "/{$path}" : $path);
}

/**
* @param string $path appended to the path
*
* @brief alias of basePath(), Laravel app path differs from installation path
* Alias of basePath(), Laravel app path differs from installation path
*/
public function path($path = '')
public function path(string $path = ''): string
{
return $this->basePath($path);
}
Expand Down Expand Up @@ -536,20 +541,16 @@ protected function settingProxyForStreamContext(): void
/**
* Override Laravel method; always false.
* Prevents the undefined method error when the Log Manager tries to determine the driver
*
* @return bool
*/
public function runningUnitTests()
public function runningUnitTests(): bool
{
return false;
}

/**
* Determine if the application is currently down for maintenance.
*
* @return bool
*/
public function isDownForMaintenance()
public function isDownForMaintenance(): bool
{
return Application::isUnderMaintenance();
}
Expand All @@ -574,6 +575,8 @@ public function runningInConsole(?string $scriptPath = null): bool
if (mb_stripos($_SERVER['SCRIPT_FILENAME'] ?? '', $scriptPath) !== false) {
return true;
}

return false;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions classes/core/PKPSessionGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,9 @@ public function removeAllSession(): void
}

/**
* @copydoc \Illuminate\Auth\SessionGuard::rehashUserPassword($password, $attribute)
* @copydoc \Illuminate\Auth\SessionGuard::rehashUserPasswordForDeviceLogout
*/
protected function rehashUserPassword($password, $attribute)
protected function rehashUserPasswordForDeviceLogout($password)
{
$rehash = null;

Expand Down
22 changes: 22 additions & 0 deletions classes/core/PKPUserProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
namespace PKP\core;

use PKP\user\User;
use APP\core\Application;
use APP\facades\Repo;
use PKP\security\Validation;
use PKP\validation\ValidatorFactory;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Database\ConnectionInterface;
Expand Down Expand Up @@ -150,6 +152,26 @@ public function validateCredentials(UserContract $user, array $credentials)
return $this->hasher->check($plain, $user->getAuthPassword());
}

/**
* Rehash the user's password if required and supported.
*
* @param \Illuminate\Contracts\Auth\Authenticatable|\PKP\user\User $user
* @param array $credentials
* @param bool $force
* @return void
*/
public function rehashPasswordIfRequired(UserContract $user, #[\SensitiveParameter] array $credentials, bool $force = false)
{
if (!$this->hasher->needsRehash($user->getAuthPassword()) && !$force) {
return;
}

$rehash = Validation::encryptCredentials($user->getUsername(), $credentials['password']);
$user->setPassword($rehash);

Repo::user()->edit($user);
}

/**
* Create a new instance of the \PKP\user\User
*
Expand Down
5 changes: 1 addition & 4 deletions classes/db/DBDataXMLParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ public function parseData($file)
return [];
}

$allTables = DB::getDoctrineSchemaManager()->listTableNames();

foreach ($tree->getChildren() as $type) {
switch ($type->getName()) {
case 'table':
Expand Down Expand Up @@ -133,8 +131,7 @@ public function parseData($file)
throw new Exception('dropindex called without table or index');
}

$schemaManager = DB::getDoctrineSchemaManager();
if ($child->getAttribute('ifexists') && !in_array($index, array_keys($schemaManager->listTableIndexes($table)))) {
if ($child->getAttribute('ifexists') && !Schema::hasIndex($table, $index)) {
break;
}
$this->sql = array_merge($this->sql, array_column(DB::pretend(function () use ($table, $index) {
Expand Down
35 changes: 0 additions & 35 deletions classes/install/Installer.php
Original file line number Diff line number Diff line change
Expand Up @@ -851,41 +851,6 @@ public function installFilterConfig($filterConfigFile)
return true;
}

/**
* Check to see whether a column exists.
* Used in installer XML in conditional checks on <data> nodes.
*
* @param string $tableName
* @param string $columnName
*
* @return bool
*/
public function columnExists($tableName, $columnName)
{
$schema = DB::getDoctrineSchemaManager();
// Make sure the table exists
$tables = $schema->listTableNames();
if (!in_array($tableName, $tables)) {
return false;
}

return Schema::hasColumn($tableName, $columnName);
}

/**
* Check to see whether a table exists.
* Used in installer XML in conditional checks on <data> nodes.
*
* @param string $tableName
*
* @return bool
*/
public function tableExists($tableName)
{
$tables = DB::getDoctrineSchemaManager()->listTableNames();
return in_array($tableName, $tables);
}

/**
* Insert or update plugin data in versions
* and plugin_settings tables.
Expand Down
8 changes: 2 additions & 6 deletions classes/install/PKPInstall.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
use Illuminate\Support\Facades\Config as FacadesConfig;
use PKP\config\Config;
use PKP\core\Core;
use PKP\core\PKPContainer;
use PKP\core\PKPString;
use PKP\db\DAORegistry;
use PKP\facades\Locale;
Expand Down Expand Up @@ -77,12 +78,7 @@ public function preInstall()
}

// Map valid config options to Illuminate database drivers
$driver = strtolower($this->getParam('databaseDriver'));
if (substr($driver, 0, 8) === 'postgres') {
$driver = 'pgsql';
} else {
$driver = 'mysql';
}
$driver = PKPContainer::getDatabaseDriverName(strtolower($this->getParam('databaseDriver')));

$config = FacadesConfig::get('database');
$config['default'] = $driver;
Expand Down
3 changes: 2 additions & 1 deletion classes/install/form/InstallForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class InstallForm extends MaintenanceForm
// <driver> => array(<php-module>, <name>)
'mysqli' => ['mysqli', 'MySQLi'],
'postgres9' => ['pgsql', 'PostgreSQL'],
'mysql' => ['mysql', 'MySQL']
'mysql' => ['mysql', 'MySQL'],
'mariadb' => ['mysqli', 'MariaDB'],
];

/**
Expand Down
11 changes: 11 additions & 0 deletions classes/migration/Migration.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
namespace PKP\migration;

use PKP\install\Installer;
use Illuminate\Support\Facades\Schema;

abstract class Migration extends \Illuminate\Database\Migrations\Migration
{
Expand All @@ -30,6 +31,16 @@ public function __construct(Installer $installer, array $attributes)
$this->_installer = $installer;
}

/**
* Check if the given key is set as a foreign in the given table
*/
public function hasForeignKey(string $tableName, string $keyName): bool
{
return collect(Schema::getForeignKeys($tableName))
->pluck('name')
->contains($keyName);
}

/**
* Run the migrations.
*/
Expand Down
Loading

0 comments on commit cbf8b01

Please sign in to comment.