Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/develop' into 4.5
Browse files Browse the repository at this point in the history
 Conflicts:
	user_guide_src/source/concepts/autoloader.rst
  • Loading branch information
kenjis committed Oct 25, 2023
2 parents 52c2222 + 7cd5c99 commit 86a84ce
Show file tree
Hide file tree
Showing 15 changed files with 99 additions and 71 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
},
"require-dev": {
"codeigniter/coding-standard": "^1.5",
"codeigniter/phpstan-codeigniter": "^v1.1",
"codeigniter/phpstan-codeigniter": "^1.4",
"ergebnis/composer-normalize": "^2.28",
"fakerphp/faker": "^1.9",
"kint-php/kint": "^5.0.4",
Expand Down
10 changes: 0 additions & 10 deletions phpstan-baseline.php
Original file line number Diff line number Diff line change
Expand Up @@ -836,16 +836,6 @@
'count' => 4,
'path' => __DIR__ . '/system/Config/BaseConfig.php',
];
$ignoreErrors[] = [
'message' => '#^Argument \\#1 \\$name \\(\'Config\\\\\\\\Modules\'\\) passed to function config does not extend CodeIgniter\\\\\\\\Config\\\\\\\\BaseConfig\\.$#',
'count' => 1,
'path' => __DIR__ . '/system/Config/BaseConfig.php',
];
$ignoreErrors[] = [
'message' => '#^Argument \\#1 \\$name \\(\'Config\\\\\\\\Modules\'\\) passed to function config does not extend CodeIgniter\\\\\\\\Config\\\\\\\\BaseConfig\\.$#',
'count' => 2,
'path' => __DIR__ . '/system/Config/BaseService.php',
];
$ignoreErrors[] = [
'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
'count' => 3,
Expand Down
3 changes: 0 additions & 3 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,3 @@ parameters:
booleansInConditions: true
disallowedConstructs: true
matchingInheritedMethodNames: true
codeigniter:
additionalConfigNamespaces:
- CodeIgniter\Config\
2 changes: 1 addition & 1 deletion system/Common.php
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ function function_usable(string $functionName): bool
if (! function_exists('helper')) {
/**
* Loads a helper file into memory. Supports namespaced helpers,
* both in and out of the 'helpers' directory of a namespaced directory.
* both in and out of the 'Helpers' directory of a namespaced directory.
*
* Will load ALL helpers of the matching name, in the following order:
* 1. app/Helpers
Expand Down
13 changes: 11 additions & 2 deletions system/Config/BaseConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class BaseConfig
/**
* The modules configuration.
*
* @var Modules
* @var Modules|null
*/
protected static $moduleConfig;

Expand All @@ -74,6 +74,15 @@ public static function __set_state(array $array)
return $obj;
}

/**
* @internal For testing purposes only.
* @testTag
*/
public static function setModules(Modules $modules): void
{
static::$moduleConfig = $modules;
}

/**
* Will attempt to get environment variables with names
* that match the properties of the child class.
Expand All @@ -82,7 +91,7 @@ public static function __set_state(array $array)
*/
public function __construct()
{
static::$moduleConfig = config(Modules::class);
static::$moduleConfig ??= new Modules();

if (! static::$override) {
return;
Expand Down
8 changes: 2 additions & 6 deletions system/Config/BaseService.php
Original file line number Diff line number Diff line change
Expand Up @@ -331,9 +331,7 @@ public static function injectMock(string $name, $mock)
protected static function discoverServices(string $name, array $arguments)
{
if (! static::$discovered) {
$config = config(Modules::class);

if ($config->shouldDiscover('services')) {
if ((new Modules())->shouldDiscover('services')) {
$locator = static::locator();
$files = $locator->search('Config/Services');

Expand Down Expand Up @@ -377,9 +375,7 @@ protected static function discoverServices(string $name, array $arguments)
protected static function buildServicesCache(): void
{
if (! static::$discovered) {
$config = config(Modules::class);

if ($config->shouldDiscover('services')) {
if ((new Modules())->shouldDiscover('services')) {
$locator = static::locator();
$files = $locator->search('Config/Services');

Expand Down
4 changes: 4 additions & 0 deletions system/Validation/StrictRules/Rules.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ public function equals($str, string $val): bool
*/
public function exact_length($str, string $val): bool
{
if (is_int($str) || is_float($str)) {
$str = (string) $str;
}

if (! is_string($str)) {
return false;
}
Expand Down
2 changes: 0 additions & 2 deletions tests/system/Cache/FactoriesCacheFileVarExportHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
use CodeIgniter\Config\Factories;
use CodeIgniter\Test\CIUnitTestCase;
use Config\App;
use Config\Modules;

/**
* @internal
Expand Down Expand Up @@ -58,7 +57,6 @@ public function testSave()

$this->assertArrayHasKey('aliases', $cachedData);
$this->assertArrayHasKey('instances', $cachedData);
$this->assertArrayHasKey(Modules::class, $cachedData['aliases']);
$this->assertArrayHasKey('App', $cachedData['aliases']);
}

Expand Down
38 changes: 20 additions & 18 deletions tests/system/Config/BaseConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@

namespace CodeIgniter\Config;

use CodeIgniter\Autoloader\FileLocator;
use CodeIgniter\Test\CIUnitTestCase;
use Config\Modules;
use Encryption;
use PHPUnit\Framework\MockObject\MockObject;
use RegistrarConfig;
use RuntimeException;
use SimpleConfig;
Expand Down Expand Up @@ -45,6 +48,9 @@ protected function setUp(): void
if (! class_exists('Encryption', false)) {
require $this->fixturesFolder . '/Encryption.php';
}

BaseConfig::$registrars = [];
BaseConfig::setModules(new Modules()); // reset to clean copy of Modules
}

public function testBasicValues(): void
Expand Down Expand Up @@ -265,32 +271,28 @@ public function testBadRegistrar(): void
$this->assertSame('bar', $config->foo);
}

public function testNotEnabled(): void
public function testDiscoveryNotEnabledWillNotPopulateRegistrarsArray(): void
{
$modulesConfig = config('Modules');
$modulesConfig->enabled = false;

$config = new RegistrarConfig();
$config::$registrars = [];
$expected = $config::$registrars;
/** @var MockObject&Modules $modules */
$modules = $this->createMock(Modules::class);
$modules->method('shouldDiscover')->with('registrars')->willReturn(false);

$method = $this->getPrivateMethodInvoker($config, 'registerProperties');
$method();
RegistrarConfig::setModules($modules);
$config = new RegistrarConfig();

$this->assertSame($expected, $config::$registrars);
$this->assertSame([], $config::$registrars);
}

public function testDidDiscovery(): void
public function testRedoingDiscoveryWillStillSetDidDiscoveryPropertyToTrue(): void
{
$modulesConfig = config('Modules');
$modulesConfig->enabled = true;
/** @var FileLocator&MockObject $locator */
$locator = $this->createMock(FileLocator::class);
$locator->method('search')->with('Config/Registrar.php')->willReturn([]);
Services::injectMock('locator', $locator);

$config = new RegistrarConfig();
$config::$registrars = [];
$this->setPrivateProperty($config, 'didDiscovery', false);
$this->setPrivateProperty(RegistrarConfig::class, 'didDiscovery', false);

$method = $this->getPrivateMethodInvoker($config, 'registerProperties');
$method();
$config = new RegistrarConfig();

$this->assertTrue($this->getPrivateProperty($config, 'didDiscovery'));
}
Expand Down
15 changes: 10 additions & 5 deletions tests/system/Validation/RulesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,10 @@ public function testMaxLengthReturnsFalseWithNonNumericVal(): void

/**
* @dataProvider provideExactLength
*
* @param int|string|null $data
*/
public function testExactLength(?string $data, bool $expected): void
public function testExactLength($data, bool $expected): void
{
$this->validation->setRules(['foo' => 'exact_length[3]']);
$this->assertSame($expected, $this->validation->run(['foo' => $data]));
Expand All @@ -408,10 +410,13 @@ public function testExactLength(?string $data, bool $expected): void
public static function provideExactLength(): iterable
{
yield from [
'null' => [null, false],
'exact' => ['bar', true],
'less' => ['ba', false],
'greater' => ['bars', false],
'null' => [null, false],
'exact' => ['bar', true],
'exact_int' => [123, true],
'less' => ['ba', false],
'less_int' => [12, false],
'greater' => ['bars', false],
'greater_int' => [1234, false],
];
}

Expand Down
19 changes: 12 additions & 7 deletions user_guide_src/source/concepts/autoloader.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ Configuration
Initial configuration is done in **app/Config/Autoload.php**. This file contains two primary
arrays: one for the classmap, and one for PSR-4 compatible namespaces.

**********
.. _autoloader-namespaces:

Namespaces
**********
==========

The recommended method for organizing your classes is to create one or more namespaces for your
application's files. This is most important for any business-logic related classes, entity classes,
Expand All @@ -58,11 +59,16 @@ those classes can be found in:
The key of each row is the namespace itself. This does not need a trailing back slash.
The value is the location to the directory the classes can be found in.

.. note:: You can check the namespace configuration by ``spark namespaces`` command:
.. _confirming-namespaces:

Confirming Namespaces
=====================

.. code-block:: console
You can check the namespace configuration by ``spark namespaces`` command:

.. code-block:: console
php spark namespaces
php spark namespaces
.. _autoloader-application-namespace:

Expand Down Expand Up @@ -110,9 +116,8 @@ in your **composer.json**, and run ``composer dump-autoload``.

You will need to modify any existing files that are referencing the current namespace.

********
Classmap
********
========

The classmap is used extensively by CodeIgniter to eke the last ounces of performance out of the system
by not hitting the file-system with extra ``is_file()`` calls. You can use the classmap to link to
Expand Down
41 changes: 29 additions & 12 deletions user_guide_src/source/general/helpers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ in your :doc:`controller <../incoming/controllers>` and
:doc:`views <../outgoing/views>`.

Helpers are typically stored in your **system/Helpers**, or
**app/Helpers** directory. CodeIgniter will look first in your
**app/Helpers** directory. If the directory does not exist or the
specified helper is not located there CI will instead look in your
global **system/Helpers** directory.
**app/Helpers** directory.

****************
Loading a Helper
****************
***************
Loading Helpers
***************

.. note:: The URL helper is always loaded so you do not need to load it yourself.

Loading a Helper
================

Loading a helper file is quite simple using the following method:

.. literalinclude:: helpers/001.php
Expand All @@ -58,6 +58,23 @@ For example, to load the **Cookie Helper** file, which is named
.. note:: The Helper loading method above does not return a value, so
don't try to assign it to a variable. Just use it as shown.

Auto-Discovery and Composer Packages
------------------------------------

By default, CodeIgniter will search for the helper files in all defined namespaces
by :ref:`auto-discovery`.
You can check your defined namespaces by the spark command. See :ref:`confirming-namespaces`.

If you use many Composer packages, you will have many defined namespaces.
CodeIgniter will scan all namespaces by default.

To avoid wasting time scanning for irrelevant Composer packages, you can manually
specify packages for Auto-Discovery. See :ref:`modules-specify-composer-packages`
for details.

Or you can :ref:`specify a namespace <helpers-loading-from-specified-namespace>`
for a helper that you want to load.

Loading Multiple Helpers
========================

Expand All @@ -81,14 +98,14 @@ it.
However if you want to load in your controller constructor, you can use the ``$helpers``
property in Controller instead. See :ref:`Controllers <controllers-helpers>`.

.. _helpers-loading-from-non-standard-locations:
.. _helpers-loading-from-specified-namespace:

Loading from Non-standard Locations
===================================
Loading from Specified Namespace
================================

Helpers can be loaded from directories outside of **app/Helpers** and
**system/Helpers**, as long as that path can be found through a namespace that
has been set up within the PSR-4 section of the :doc:`Autoloader config file <../concepts/autoloader>`.
**system/Helpers**, as long as that path can be found in defined namespaces.

You would prefix the name of the Helper with the namespace that it can be located
in. Within that namespaced directory, the loader expects it to live within a
sub-directory named **Helpers**. An example will help understand this.
Expand Down
7 changes: 4 additions & 3 deletions user_guide_src/source/general/modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,13 @@ For Windows:
Helpers
=======

Helpers will be automatically discovered within defined namespaces when using the ``helper()`` function, as long as it
is within the namespaces **Helpers** directory:
Helpers will be automatically discovered within defined namespaces when using the
:php:func:`helper()` function, as long as it is within the namespaces **Helpers**
directory:

.. literalinclude:: modules/009.php

You can specify namespaces. See :ref:`helpers-loading-from-non-standard-locations` for details.
You can specify namespaces. See :ref:`helpers-loading-from-specified-namespace` for details.

Language Files
==============
Expand Down
1 change: 1 addition & 0 deletions user_guide_src/source/helpers/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Helpers
#######

Helpers are collections of useful procedural functions.
See also :doc:`../general/helpers`.

.. toctree::
:glob:
Expand Down
5 changes: 4 additions & 1 deletion user_guide_src/source/models/model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ Connecting to the Database
==========================

When the class is first instantiated, if no database connection instance is passed to the constructor,
it will automatically connect to the default database group, as set in the configuration. You can
and if you don't set the ``$DBGroup`` property on your model class,
it will automatically connect to the default database group, as set in the database configuration.

You can
modify which group is used on a per-model basis by adding the ``$DBGroup`` property to your class.
This ensures that within the model any references to ``$this->db`` are made through the appropriate
connection.
Expand Down

0 comments on commit 86a84ce

Please sign in to comment.