Skip to content

Conversation

najdanovicivan
Copy link
Contributor

@najdanovicivan najdanovicivan commented Nov 4, 2024

Description
Decouple settings library so it is not required.
Related to #1215

Checklist:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value
  • Unit testing, with >80% coverage
  • User guide updated
  • Conforms to style guide

Comment on lines +47 to +76

if (! function_exists('shieldSetting')) {
/**
* Provides a wrapper function for settings module.
*
* @param mixed $value
*
* @return array|bool|float|int|object|string|void|null
* @phpstan-return ($value is null ? array|bool|float|int|object|string|null : void)
*/
function shieldSetting(?string $key = null, $value = null)
{
/** @var AuthConfig $config */
$config = config('Auth');
if($config->useSettings) {
return setting($key, $value);
}

// Getting the value?
if (!empty($key) && count(func_get_args()) === 1) {
$parts = explode('.', $key);
if (count($parts) === 1) {
throw new InvalidArgumentException('$key must contain both the class and field name, i.e. Foo.bar');
}
return config($parts[0])?->{$parts[1]} ?? null;
}

throw new InvalidArgumentException('Settings library is not being used for shield');
}
}
Copy link
Contributor Author

@najdanovicivan najdanovicivan Nov 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the important part. With the proposed change call to setting() method will only occur here.

@najdanovicivan najdanovicivan changed the title WIP: Settings - Decouple from shield WIP feat: Settings - Decouple from shield Nov 4, 2024
@kenjis kenjis added the enhancement New feature or request label Nov 8, 2024
@datamweb datamweb added the GPG-Signing needed Pull requests that need GPG-Signing label Nov 30, 2024
@datamweb datamweb changed the title WIP feat: Settings - Decouple from shield feat: Settings - Decouple from shield Nov 30, 2024
@TwistedAndy
Copy link

Yes, it would be great to decouple Shield and Settings packages. Personally, I don't see a lot of sense of having the Settings dependency here, because CodeIgniter already has BaseConfig to handle settings.

@najdanovicivan
Copy link
Contributor Author

@datamweb What else is needed for this one to be merged ?

@datamweb
Copy link
Collaborator

datamweb commented Oct 3, 2025

@najdanovicivan I'm currently on mobile and need to review this PR on my PC. I'll get back to it soon.


// Get the credentials for login
$credentials = $this->request->getJsonVar(setting('Auth.validFields'));
$credentials = $this->request->getJsonVar(shieldSetting('Auth.validFields'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this should be in snake case per our coding standards: shield_setting

Comment on lines +54 to +55
* @return array|bool|float|int|object|string|void|null
* @phpstan-return ($value is null ? array|bool|float|int|object|string|null : void)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In what instance will this return void?

Suggested change
* @return array|bool|float|int|object|string|void|null
* @phpstan-return ($value is null ? array|bool|float|int|object|string|null : void)
* @return mixed

* @return array|bool|float|int|object|string|void|null
* @phpstan-return ($value is null ? array|bool|float|int|object|string|null : void)
*/
function shieldSetting(?string $key = null, $value = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
function shieldSetting(?string $key = null, $value = null)
function shield_setting(?string $key = null, mixed $value = null): mixed

{
/** @var AuthConfig $config */
$config = config('Auth');
if($config->useSettings) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a function_exists check

}

// Getting the value?
if (!empty($key) && count(func_get_args()) === 1) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the use case for having null key? Would it be better to just require a string key?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question!

if (count($parts) === 1) {
throw new InvalidArgumentException('$key must contain both the class and field name, i.e. Foo.bar');
}
return config($parts[0])?->{$parts[1]} ?? null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ?-> would return null if config($parts[0]) is not an object so the ?? null is useless.

return config($parts[0])?->{$parts[1]} ?? null;
}

throw new InvalidArgumentException('Settings library is not being used for shield');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This capturing exception feels off. This would be reached if:

  1. Auth::$useSettings is true but settings is not installed.
  2. $useSettings is false but $key is null or empty string.
  3. $useSettings is false, $key is non-empty-string, and $value is provided

These different scenarios should be tackled separately within each conditional above.

"ext-curl": "Required to use the password validation rule via PwnedValidator class.",
"ext-openssl": "Required to use the JWT Authenticator."
"ext-openssl": "Required to use the JWT Authenticator.",
"codeigniter4/settings": "Required to store groups and permissions in database"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add this also to require-dev

}
}

if (! function_exists('shieldSetting')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a test for this new function.

@paulbalandan paulbalandan added tests needed Pull requests that need tests docs needed Pull requests needing documentation write-ups and/or revisions. and removed GPG-Signing needed Pull requests that need GPG-Signing labels Oct 3, 2025
@datamweb datamweb added the breaking change Pull requests that may break existing functionalities label Oct 8, 2025
Copy link
Collaborator

@datamweb datamweb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We reference the settings package directly in several parts of the documentation.
If this PR is going to be merged, these sections of the docs should be updated and clarified accordingly.
https://shield.codeigniter.com/getting_started/concepts/?h=settings#settings
https://shield.codeigniter.com/getting_started/concepts/?h=settings#repository-state
https://shield.codeigniter.com/?h=settings#important-features

Please pay attention to @paulbalandan’s review.
Also, part of the GitHub Action failures is related to the removal of the settings package.
Please try to ensure that the actions pass successfully.

},
"require": {
"php": "^8.1",
"codeigniter4/settings": "^2.1"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current software relies on the codeigniter4/settings package for data storage.
After installing or updating to the new version of Shield, this package(codeigniter4/settings) will be automatically removed, which could lead to a breaking change, unless it remains required by another package.

I’m deeply concerned about this, and at the very least, this change should be clearly, explicitly, and transparently documented in the docs and UPGRADING.

* Use Settings
* --------------------------------------------------------------------
*/
public bool $useSettings = true;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You previously removed "codeigniter4/settings": "^2.1" from the require section:

If the settings package isn’t installed, doesn’t this make it essentially useless?
In any case, it will cause failures for any software that relies on the settings package.

}

// Getting the value?
if (!empty($key) && count(func_get_args()) === 1) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question!

// Getting the value?
if (!empty($key) && count(func_get_args()) === 1) {
$parts = explode('.', $key);
if (count($parts) === 1) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (count($parts) === 1) {
if (count($parts) !== 2) {

How about keeping it this way?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Pull requests that may break existing functionalities docs needed Pull requests needing documentation write-ups and/or revisions. enhancement New feature or request tests needed Pull requests that need tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants