Skip to content

Commit 20b3a75

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into 4.4
2 parents c609e87 + d692016 commit 20b3a75

File tree

10 files changed

+95
-80
lines changed

10 files changed

+95
-80
lines changed

phpstan-baseline.neon.dist

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,6 @@ parameters:
1010
count: 1
1111
path: system/Autoloader/Autoloader.php
1212

13-
-
14-
message: "#^Comparison operation \"\\>\" between int and \\(array\\|float\\|int\\) results in an error\\.$#"
15-
count: 1
16-
path: system/Cache/Handlers/FileHandler.php
17-
18-
-
19-
message: "#^If condition is always true\\.$#"
20-
count: 1
21-
path: system/Cache/Handlers/FileHandler.php
22-
2313
-
2414
message: "#^Property CodeIgniter\\\\Cache\\\\Handlers\\\\RedisHandler\\:\\:\\$redis \\(Redis\\) in isset\\(\\) is not nullable\\.$#"
2515
count: 1

system/Cache/Handlers/FileHandler.php

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -144,43 +144,30 @@ public function deleteMatching(string $pattern)
144144
*/
145145
public function increment(string $key, int $offset = 1)
146146
{
147-
$key = static::validateKey($key, $this->prefix);
148-
$data = $this->getItem($key);
147+
$key = static::validateKey($key, $this->prefix);
148+
$tmp = $this->getItem($key);
149149

150-
if ($data === false) {
151-
$data = [
152-
'data' => 0,
153-
'ttl' => 60,
154-
];
155-
} elseif (! is_int($data['data'])) {
150+
if ($tmp === false) {
151+
$tmp = ['data' => 0, 'ttl' => 60];
152+
}
153+
154+
['data' => $value, 'ttl' => $ttl] = $tmp;
155+
156+
if (! is_int($value)) {
156157
return false;
157158
}
158159

159-
$newValue = $data['data'] + $offset;
160+
$value += $offset;
160161

161-
return $this->save($key, $newValue, $data['ttl']) ? $newValue : false;
162+
return $this->save($key, $value, $ttl) ? $value : false;
162163
}
163164

164165
/**
165166
* {@inheritDoc}
166167
*/
167168
public function decrement(string $key, int $offset = 1)
168169
{
169-
$key = static::validateKey($key, $this->prefix);
170-
$data = $this->getItem($key);
171-
172-
if ($data === false) {
173-
$data = [
174-
'data' => 0,
175-
'ttl' => 60,
176-
];
177-
} elseif (! is_int($data['data'])) {
178-
return false;
179-
}
180-
181-
$newValue = $data['data'] - $offset;
182-
183-
return $this->save($key, $newValue, $data['ttl']) ? $newValue : false;
170+
return $this->increment($key, -$offset);
184171
}
185172

186173
/**
@@ -229,7 +216,8 @@ public function isSupported(): bool
229216
* Does the heavy lifting of actually retrieving the file and
230217
* verifying it's age.
231218
*
232-
* @return array|bool|float|int|object|string|null
219+
* @return array<string, mixed>|false
220+
* @phpstan-return array{data: mixed, ttl: int, time: int}|false
233221
*/
234222
protected function getItem(string $filename)
235223
{
@@ -238,15 +226,21 @@ protected function getItem(string $filename)
238226
}
239227

240228
$data = @unserialize(file_get_contents($this->path . $filename));
241-
if (! is_array($data) || ! isset($data['ttl'])) {
229+
230+
if (! is_array($data)) {
231+
return false;
232+
}
233+
234+
if (! isset($data['ttl']) || ! is_int($data['ttl'])) {
235+
return false;
236+
}
237+
238+
if (! isset($data['time']) || ! is_int($data['time'])) {
242239
return false;
243240
}
244241

245242
if ($data['ttl'] > 0 && Time::now()->getTimestamp() > $data['time'] + $data['ttl']) {
246-
// If the file is still there then try to remove it
247-
if (is_file($this->path . $filename)) {
248-
@unlink($this->path . $filename);
249-
}
243+
@unlink($this->path . $filename);
250244

251245
return false;
252246
}

tests/system/Cache/Handlers/FileHandlerTest.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ public function testNew()
7878
$this->assertInstanceOf(FileHandler::class, $this->handler);
7979
}
8080

81+
/**
82+
* chmod('path', 0444) does not work on Windows
83+
*
84+
* @requires OS Linux|Darwin
85+
*/
8186
public function testNewWithNonWritablePath()
8287
{
8388
$this->expectException(CacheException::class);
@@ -132,6 +137,11 @@ public function testRemember()
132137
$this->assertNull($this->handler->get(self::$key1));
133138
}
134139

140+
/**
141+
* chmod('path', 0444) does not work on Windows
142+
*
143+
* @requires OS Linux|Darwin
144+
*/
135145
public function testSave()
136146
{
137147
$this->assertTrue($this->handler->save(self::$key1, 'value'));
@@ -265,10 +275,11 @@ public function testIsSupported()
265275
/**
266276
* @dataProvider modeProvider
267277
*
268-
* @param mixed $int
269-
* @param mixed $string
278+
* permissions given on Windows are fixed to `0666`
279+
*
280+
* @requires OS Linux|Darwin
270281
*/
271-
public function testSaveMode($int, $string)
282+
public function testSaveMode(int $int, string $string): void
272283
{
273284
// Initialize mode
274285
$config = new Cache();

user_guide_src/source/concepts/factories.rst

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Factories
44

55
.. contents::
66
:local:
7-
:depth: 2
7+
:depth: 3
88

99
Introduction
1010
************
@@ -41,17 +41,14 @@ On the other hand, Services have code to create instances, so it can create a co
4141
that needs other services or class instances. When you get a service, Services require a service name,
4242
not a class name, so the returned instance can be changed without changing the client code.
4343

44+
.. _factories-loading-class:
45+
4446
Loading Classes
4547
***************
4648

4749
Loading a Class
4850
===============
4951

50-
.. _factories-example:
51-
52-
Model Example
53-
-------------
54-
5552
Take a look at **Models** as an example. You can access the Factory specific to Models
5653
by using the magic static method of the Factories class, ``Factories::models()``.
5754

@@ -64,7 +61,17 @@ In the following code, if you have ``App\Models\UserModel``, the instance will b
6461

6562
.. literalinclude:: factories/001.php
6663

67-
Or you could also request a specific class:
64+
If you don't have ``App\Models\UserModel``, it searches for ``Models\UserModel`` in all namespaces.
65+
66+
Next time you ask for the same class anywhere in your code, Factories will be sure
67+
you get back the instance as before:
68+
69+
.. literalinclude:: factories/003.php
70+
71+
preferApp option
72+
----------------
73+
74+
You could also request a specific class:
6875

6976
.. literalinclude:: factories/002.php
7077
:lines: 2-
@@ -78,13 +85,6 @@ If you want to get ``Blog\Models\UserModel``, you need to disable the option ``p
7885
.. literalinclude:: factories/010.php
7986
:lines: 2-
8087

81-
See :ref:`factories-options` for the details.
82-
83-
Next time you ask for the same class anywhere in your code, Factories will be sure
84-
you get back the instance as before:
85-
86-
.. literalinclude:: factories/003.php
87-
8888
Loading a Class in Sub-directories
8989
==================================
9090

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
<?php
22

33
$users = Factories::models('Blog\Models\UserModel');
4+
// Or
5+
$users = Factories::models(\Blog\Models\UserModel::class);

user_guide_src/source/general/common_functions.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ Service Accessors
110110
More simple way of getting model instances.
111111

112112
The ``model()`` uses ``Factories::models()`` internally.
113-
See :ref:`factories-example` for details on the first parameter ``$name``.
113+
See :ref:`factories-loading-class` for details on the first parameter ``$name``.
114114

115115
See also the :ref:`Using CodeIgniter's Model <accessing-models>`.
116116

user_guide_src/source/general/configuration.rst

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,52 @@ the application configuration files in the **app/Config** folder.
1818
Working with Configuration Files
1919
********************************
2020

21+
Getting a Config Object
22+
=======================
23+
2124
You can access configuration files for your classes in several different ways.
2225

23-
- By using the ``new`` keyword to create an instance:
26+
new keyword
27+
-----------
2428

25-
.. literalinclude:: configuration/001.php
29+
By using the ``new`` keyword to create an instance:
2630

27-
- By using the ``config()`` function:
31+
.. literalinclude:: configuration/001.php
2832

29-
.. literalinclude:: configuration/002.php
33+
config()
34+
--------
3035

31-
All configuration object properties are public, so you access the settings like any other property:
36+
By using the ``config()`` function:
3237

33-
.. literalinclude:: configuration/003.php
38+
.. literalinclude:: configuration/002.php
3439

35-
If no namespace is provided, it will look for the file in all defined namespaces
36-
as well as **app/Config/**.
40+
If no namespace is provided, it will look for the file in the **app/Config**
41+
folder first, and if not found, look for in the **Config** folder in all defined
42+
namespaces.
3743

3844
All of the configuration files that ship with CodeIgniter are namespaced with
3945
``Config``. Using this namespace in your application will provide the best
4046
performance since it knows exactly where to find the files.
4147

42-
You can put configuration files in any folder you want by using a different namespace.
43-
This allows you to put configuration files on the production server in a folder
44-
that is not web-accessible while keeping it under **/app** for easy access
45-
during development.
48+
.. note:: ``config()`` finds the file in **app/Config/** when there is a class with the same shortname,
49+
even if you specify a fully qualified class name like ``config(\Acme\Blog\Config\Blog::class)``.
50+
This is because ``config()`` is a wrapper for the ``Factories`` class which uses ``preferApp`` by default. See :ref:`factories-loading-class` for more information.
51+
52+
Getting a Config Property
53+
=========================
54+
55+
All configuration object properties are public, so you access the settings like any other property:
56+
57+
.. literalinclude:: configuration/003.php
4658

4759
Creating Configuration Files
4860
****************************
4961

5062
When you need a new configuration, first you create a new file at your desired location.
5163
The default file location (recommended for most cases) is **app/Config**.
64+
65+
You can put configuration files in any **Config** folder by using a different namespace.
66+
5267
The class should use the appropriate namespace, and it should extend
5368
``CodeIgniter\Config\BaseConfig`` to ensure that it can receive environment-specific settings.
5469

user_guide_src/source/general/modules.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ Config files are automatically discovered whenever using the ``config()`` functi
194194

195195
.. note:: ``config()`` finds the file in **app/Config/** when there is a class with the same shortname,
196196
even if you specify a fully qualified class name like ``config(\Acme\Blog\Config\Blog::class)``.
197-
This is because ``config()`` is a wrapper for the ``Factories`` class which uses ``preferApp`` by default. See :ref:`Factories Example <factories-example>` for more information.
197+
This is because ``config()`` is a wrapper for the ``Factories`` class which uses ``preferApp`` by default. See :ref:`factories-loading-class` for more information.
198198

199199
Migrations
200200
==========
@@ -250,7 +250,7 @@ Model files are automatically discovered whenever using the :php:func:`model()`
250250

251251
.. note:: ``model()`` finds the file in **app/Models/** when there is a class with the same shortname,
252252
even if you specify a fully qualified class name like ``model(\Acme\Blog\Model\PostModel::class)``.
253-
This is because ``model()`` is a wrapper for the ``Factories`` class which uses ``preferApp`` by default. See :ref:`Factories Example <factories-example>` for more information.
253+
This is because ``model()`` is a wrapper for the ``Factories`` class which uses ``preferApp`` by default. See :ref:`factories-loading-class` for more information.
254254

255255
Views
256256
=====

user_guide_src/source/models/model.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ You can access models within your classes by creating a new instance or using th
2929
.. literalinclude:: model/001.php
3030

3131
The ``model()`` uses ``Factories::models()`` internally.
32-
See :ref:`factories-example` for details on the first parameter.
32+
See :ref:`factories-loading-class` for details on the first parameter.
3333

3434
CodeIgniter's Model
3535
*******************

utils/Rector/UnderscoreToCamelCaseVariableNameRector.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,16 @@ public function refactor(Node $node): ?Node
113113

114114
private function updateDocblock(Variable $variable, string $variableName, string $camelCaseName): void
115115
{
116-
$parentClassMethodOrFunction = $this->betterNodeFinder->findParentByTypes($variable, [ClassMethod::class, Function_::class]);
116+
$parentFunctionLike = $this->betterNodeFinder->findParentType($variable, ClassMethod::class);
117117

118-
if ($parentClassMethodOrFunction === null) {
119-
return;
118+
if ($parentFunctionLike === null) {
119+
$parentFunctionLike = $this->betterNodeFinder->findParentType($variable, Function_::class);
120+
if ($parentFunctionLike === null) {
121+
return;
122+
}
120123
}
121124

122-
$docComment = $parentClassMethodOrFunction->getDocComment();
125+
$docComment = $parentFunctionLike->getDocComment();
123126
if ($docComment === null) {
124127
return;
125128
}
@@ -133,7 +136,7 @@ private function updateDocblock(Variable $variable, string $variableName, string
133136
return;
134137
}
135138

136-
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($parentClassMethodOrFunction);
139+
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($parentFunctionLike);
137140
$paramTagValueNodes = $phpDocInfo->getParamTagValueNodes();
138141

139142
foreach ($paramTagValueNodes as $paramTagValueNode) {
@@ -143,6 +146,6 @@ private function updateDocblock(Variable $variable, string $variableName, string
143146
}
144147
}
145148

146-
$parentClassMethodOrFunction->setDocComment(new Doc($phpDocInfo->getPhpDocNode()->__toString()));
149+
$parentFunctionLike->setDocComment(new Doc($phpDocInfo->getPhpDocNode()->__toString()));
147150
}
148151
}

0 commit comments

Comments
 (0)