Skip to content

Commit 337de20

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into 4.3
Conflicts: system/Helpers/html_helper.php tests/system/Helpers/HTMLHelperTest.php user_guide_src/source/installation/upgrade_4xx.rst user_guide_src/source/installation/upgrade_validations/002.php
2 parents ead1b13 + 487ec6d commit 337de20

23 files changed

Lines changed: 212 additions & 77 deletions

File tree

system/HTTP/RequestTrait.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ trait RequestTrait
4444
/**
4545
* Gets the user's IP address.
4646
*
47-
* @return string IP address if it can be detected, or empty string.
47+
* @return string IP address if it can be detected.
4848
* If the IP address is not a valid IP address,
4949
* then will return '0.0.0.0'.
5050
*/
@@ -73,6 +73,11 @@ public function getIPAddress(): string
7373

7474
$this->ipAddress = $this->getServer('REMOTE_ADDR');
7575

76+
// If this is a CLI request, $this->ipAddress is null.
77+
if ($this->ipAddress === null) {
78+
return $this->ipAddress = '0.0.0.0';
79+
}
80+
7681
if ($proxyIPs) {
7782
// @TODO Extract all this IP address logic to another class.
7883
foreach ($proxyIPs as $proxyIP => $header) {
@@ -151,7 +156,7 @@ public function getIPAddress(): string
151156
return $this->ipAddress = '0.0.0.0';
152157
}
153158

154-
return empty($this->ipAddress) ? '' : $this->ipAddress;
159+
return $this->ipAddress;
155160
}
156161

157162
/**

system/Helpers/html_helper.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,20 @@ function script_tag($src = '', bool $indexPage = false): string
222222
/**
223223
* Link
224224
*
225-
* Generates link to a CSS file
225+
* Generates link tag
226226
*
227-
* @param array|string $href Stylesheet href or an array
228-
* @param bool $indexPage should indexPage be added to the CSS path.
227+
* @param array<string, bool|string>|string $href Stylesheet href or an array
228+
* @param bool $indexPage should indexPage be added to the CSS path.
229229
*/
230-
function link_tag($href = '', string $rel = 'stylesheet', string $type = 'text/css', string $title = '', string $media = '', bool $indexPage = false, string $hreflang = ''): string
231-
{
230+
function link_tag(
231+
$href = '',
232+
string $rel = 'stylesheet',
233+
string $type = 'text/css',
234+
string $title = '',
235+
string $media = '',
236+
bool $indexPage = false,
237+
string $hreflang = ''
238+
): string {
232239
// extract fields if needed
233240
if (is_array($href)) {
234241
$rel = $href['rel'] ?? $rel;
@@ -252,7 +259,7 @@ function link_tag($href = '', string $rel = 'stylesheet', string $type = 'text/c
252259

253260
$attributes['rel'] = $rel;
254261

255-
if (! in_array($rel, ['alternate', 'canonical'], true)) {
262+
if ($type !== '' && $rel !== 'canonical' && $hreflang === '' && ! ($rel === 'alternate' && $media !== '')) {
256263
$attributes['type'] = $type;
257264
}
258265

tests/system/Helpers/HTMLHelperTest.php

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -365,11 +365,71 @@ public function testLinkTagXHTML()
365365
$doctypes->html5 = $default;
366366
}
367367

368-
public function testLinkTagComplete()
368+
public function testLinkTagMedia()
369369
{
370-
$target = 'https://styles.com/css/mystyles.css';
371-
$expected = '<link href="https://styles.com/css/mystyles.css" rel="banana" type="fruit" media="VHS" title="Go away">';
372-
$this->assertSame($expected, link_tag($target, 'banana', 'fruit', 'Go away', 'VHS'));
370+
$target = 'https://styles.com/css/mystyles.css';
371+
$tag = link_tag($target, 'stylesheet', 'text/css', '', 'print');
372+
373+
$expected = '<link href="https://styles.com/css/mystyles.css" rel="stylesheet" type="text/css" media="print">';
374+
$this->assertSame($expected, $tag);
375+
}
376+
377+
public function testLinkTagTitle()
378+
{
379+
$tag = link_tag('default.css', 'stylesheet', 'text/css', 'Default Style');
380+
381+
$expected = '<link href="http://example.com/default.css" rel="stylesheet" type="text/css" title="Default Style">';
382+
$this->assertSame($expected, $tag);
383+
}
384+
385+
public function testLinkTagFavicon()
386+
{
387+
$tag = link_tag('favicon.ico', 'shortcut icon', 'image/ico');
388+
389+
$expected = '<link href="http://example.com/favicon.ico" rel="shortcut icon" type="image/ico">';
390+
$this->assertSame($expected, $tag);
391+
}
392+
393+
public function testLinkTagRss()
394+
{
395+
$tag = link_tag('feed', 'alternate', 'application/rss+xml', 'My RSS Feed');
396+
397+
$expected = '<link href="http://example.com/feed" rel="alternate" type="application/rss+xml" title="My RSS Feed">';
398+
$this->assertSame($expected, $tag);
399+
}
400+
401+
public function testLinkTagAlternate()
402+
{
403+
$tag = link_tag(
404+
'http://sp.example.com/',
405+
'alternate',
406+
'',
407+
'',
408+
'only screen and (max-width: 640px)'
409+
);
410+
411+
$expected = '<link href="http://sp.example.com/" rel="alternate" media="only screen and (max-width: 640px)">';
412+
$this->assertSame($expected, $tag);
413+
}
414+
415+
public function testLinkTagArrayAlternate()
416+
{
417+
$tag = link_tag([
418+
'href' => 'http://sp.example.com/',
419+
'rel' => 'alternate',
420+
'media' => 'only screen and (max-width: 640px)',
421+
]);
422+
423+
$expected = '<link href="http://sp.example.com/" rel="alternate" media="only screen and (max-width: 640px)">';
424+
$this->assertSame($expected, $tag);
425+
}
426+
427+
public function testLinkTagCanonical()
428+
{
429+
$tag = link_tag('http://www.example.com/', 'canonical');
430+
431+
$expected = '<link href="http://www.example.com/" rel="canonical">';
432+
$this->assertSame($expected, $tag);
373433
}
374434

375435
public function testLinkTagArray()
@@ -382,6 +442,18 @@ public function testLinkTagArray()
382442
$this->assertSame($expected, link_tag($parms));
383443
}
384444

445+
public function testLinkTagArrayHreflang()
446+
{
447+
$tag = link_tag([
448+
'href' => 'https://example.com/en',
449+
'rel' => 'alternate',
450+
'hreflang' => 'x-default',
451+
]);
452+
453+
$expected = '<link href="https://example.com/en" hreflang="x-default" rel="alternate">';
454+
$this->assertSame($expected, $tag);
455+
}
456+
385457
public function testDocType()
386458
{
387459
$target = 'html4-strict';

user_guide_src/source/incoming/controllers.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ A Controller is simply a class file that handles a HTTP request. :doc:`URI Routi
1616
Every controller you create should extend ``BaseController`` class.
1717
This class provides several features that are available to all of your controllers.
1818

19+
.. _controller-constructor:
20+
1921
Constructor
2022
***********
2123

user_guide_src/source/incoming/request.rst

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
1+
#############
12
Request Class
2-
*************
3+
#############
34

45
The request class is an object-oriented representation of an HTTP request. This is meant to
56
work for both incoming, such as a request to the application from a browser, and outgoing requests,
6-
like would be used to send a request from the application to a third-party application. This class
7+
like would be used to send a request from the application to a third-party application.
8+
9+
This class
710
provides the common functionality they both need, but both cases have custom classes that extend
8-
from the Request class to add specific functionality.
11+
from the Request class to add specific functionality. In practice, you will need to use these classes.
912

1013
See the documentation for the :doc:`IncomingRequest Class </incoming/incomingrequest>` and
1114
:doc:`CURLRequest Class </libraries/curlrequest>` for more usage details.
1215

1316
Class Reference
14-
===============
17+
***************
1518

1619
.. php:namespace:: CodeIgniter\HTTP
1720
1821
.. php:class:: Request
1922
2023
.. php:method:: getIPAddress()
2124
22-
:returns: The user's IP Address, if it can be detected, or null. If the IP address
23-
is not a valid IP address, then will return 0.0.0.0
25+
:returns: The user's IP Address, if it can be detected. If the IP address
26+
is not a valid IP address, then will return 0.0.0.0.
2427
:rtype: string
2528

2629
Returns the IP address for the current user. If the IP address is not valid, the method
@@ -33,6 +36,9 @@ Class Reference
3336

3437
.. php:method:: isValidIP($ip[, $which = ''])
3538
39+
.. deprecated:: 4.0.5
40+
Use :doc:`../libraries/validation` instead.
41+
3642
.. important:: This method is deprecated. It will be removed in future releases.
3743

3844
:param string $ip: IP address
@@ -65,19 +71,30 @@ Class Reference
6571

6672
.. php:method:: setMethod($method)
6773
68-
:param string $upper: Sets the request method. Used when spoofing the request.
69-
:returns: HTTP request method
74+
.. deprecated:: 4.0.5
75+
Use :php:meth:`CodeIgniter\\HTTP\\Request::withMethod()` instead.
76+
77+
:param string $method: Sets the request method. Used when spoofing the request.
78+
:returns: This request
79+
:rtype: Request
80+
81+
.. php:method:: withMethod($method)
82+
83+
.. versionadded:: 4.0.5
84+
85+
:param string $method: Sets the request method.
86+
:returns: New request instance
7087
:rtype: Request
7188

7289
.. php:method:: getServer([$index = null[, $filter = null[, $flags = null]]])
7390
7491
:param mixed $index: Value name
75-
:param int $filter: The type of filter to apply. A list of filters can be found `here <https://www.php.net/manual/en/filter.filters.php>`__.
76-
:param int|array $flags: Flags to apply. A list of flags can be found `here <https://www.php.net/manual/en/filter.filters.flags.php>`__.
77-
:returns: $_SERVER item value if found, null if not
92+
:param int $filter: The type of filter to apply. A list of filters can be found in `PHP manual <https://www.php.net/manual/en/filter.filters.php>`__.
93+
:param int|array $flags: Flags to apply. A list of flags can be found in `PHP manual <https://www.php.net/manual/en/filter.filters.flags.php>`__.
94+
:returns: ``$_SERVER`` item value if found, null if not
7895
:rtype: mixed
7996

80-
This method is identical to the ``post()``, ``get()`` and ``cookie()`` methods from the
97+
This method is identical to the ``getPost()``, ``getGet()`` and ``getCookie()`` methods from the
8198
:doc:`IncomingRequest Class </incoming/incomingrequest>`, only it fetches server data (``$_SERVER``):
8299

83100
.. literalinclude:: request/004.php
@@ -90,13 +107,13 @@ Class Reference
90107
.. php:method:: getEnv([$index = null[, $filter = null[, $flags = null]]])
91108
92109
:param mixed $index: Value name
93-
:param int $filter: The type of filter to apply. A list of filters can be found `here <https://www.php.net/manual/en/filter.filters.php>`__.
94-
:param int|array $flags: Flags to apply. A list of flags can be found `here <https://www.php.net/manual/en/filter.filters.flags.php>`__.
95-
:returns: $_ENV item value if found, null if not
110+
:param int $filter: The type of filter to apply. A list of filters can be found in `PHP manual <https://www.php.net/manual/en/filter.filters.php>`__.
111+
:param int|array $flags: Flags to apply. A list of flags can be found in `PHP manual <https://www.php.net/manual/en/filter.filters.flags.php>`__.
112+
:returns: ``$_ENV`` item value if found, null if not
96113
:rtype: mixed
97114

98-
This method is identical to the ``post()``, ``get()`` and ``cookie()`` methods from the
99-
:doc:`IncomingRequest Class </incoming/incomingrequest>`, only it fetches getEnv data (``$_ENV``):
115+
This method is identical to the ``getPost()``, ``getGet()`` and ``getCookie()`` methods from the
116+
:doc:`IncomingRequest Class </incoming/incomingrequest>`, only it fetches env data (``$_ENV``):
100117

101118
.. literalinclude:: request/006.php
102119

@@ -109,17 +126,17 @@ Class Reference
109126
110127
:param string $method: Method name
111128
:param mixed $value: Data to be added
112-
:returns: HTTP request method
113-
:rtype: Request
129+
:returns: This request
130+
:rtype: Request
114131

115-
Allows manually setting the value of PHP global, like $_GET, $_POST, etc.
132+
Allows manually setting the value of PHP global, like ``$_GET``, ``$_POST``, etc.
116133

117134
.. php:method:: fetchGlobal($method [, $index = null[, $filter = null[, $flags = null]]])
118135
119136
:param string $method: Input filter constant
120137
:param mixed $index: Value name
121-
:param int $filter: The type of filter to apply. A list of filters can be found `here <https://www.php.net/manual/en/filter.filters.php>`__.
122-
:param int|array $flags: Flags to apply. A list of flags can be found `here <https://www.php.net/manual/en/filter.filters.flags.php>`__.
138+
:param int $filter: The type of filter to apply. A list of filters can be found in `PHP manual <https://www.php.net/manual/en/filter.filters.php>`__.
139+
:param int|array $flags: Flags to apply. A list of flags can be found in `PHP manual <https://www.php.net/manual/en/filter.filters.flags.php>`__.
123140
:rtype: mixed
124141

125142
Fetches one or more items from a global, like cookies, get, post, etc.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?php
22

3-
echo $request->getMethod(true); // Outputs: POST
3+
echo $request->getMethod(true); // Outputs: POST
44
echo $request->getMethod(false); // Outputs: post
5-
echo $request->getMethod(); // Outputs: post
5+
echo $request->getMethod(); // Outputs: post

user_guide_src/source/installation/upgrade_4xx.rst

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ General Adjustments
3535
Downloads
3636
=========
3737

38-
- CI4 is still available as a ready-to-run zip or tarball.
39-
- It can also be installed using Composer.
38+
- CI4 is still available as a :doc:`ready-to-run zip or tarball <../installation/installing_manual>`.
39+
- It can also be installed using :doc:`Composer <../installation/installing_composer>`.
4040

4141
Namespaces
4242
==========
@@ -90,10 +90,10 @@ Class Loading
9090

9191
- There is no longer a CodeIgniter "superobject", with framework component
9292
references magically injected as properties of your controller.
93-
- Classes are instantiated where needed, and components are managed
94-
by ``Services``.
95-
- The class loader automatically handles PSR-4 style class locating,
96-
within the ``App`` (**app**) and ``CodeIgniter`` (i.e., **system**) top level
93+
- Classes are instantiated where needed, and framework components are managed
94+
by :doc:`../concepts/services`.
95+
- The :doc:`Autoloader <../concepts/autoloader>` automatically handles PSR-4 style class locating,
96+
within the ``App`` (**app** folder) and ``CodeIgniter`` (i.e., **system** folder) top level
9797
namespaces; with Composer autoloading support.
9898
- You can configure the class loading to support whatever application structure
9999
you are most comfortable with, including the "HMVC" style.
@@ -102,22 +102,41 @@ Libraries
102102
=========
103103

104104
- Your app classes can still go inside **app/Libraries**, but they don't have to.
105-
- Instead of CI3's ``$this->load->library(x);`` you can now use
105+
- Instead of CI3's ``$this->load->library('x');`` you can now use
106106
``$this->x = new X();``, following namespaced conventions for your component.
107107

108108
Helpers
109109
=======
110110

111-
- Helpers are pretty much the same as before, though some have been simplified.
111+
- :doc:`Helpers <../general/helpers>` are pretty much the same as before, though some have been simplified.
112112
- Since v4.3.0, you can autoload helpers by **app/Config/Autoload.php** as well as CI3.
113+
- Some helpers from CodeIgniter 3 no longer exists in Version 4. For all these
114+
helpers, you have to find a new way to implement your functions. These
115+
helpers are `CAPTCHA Helper <https://www.codeigniter.com/userguide3/helpers/captcha_helper.html>`_,
116+
`Email Helper <https://www.codeigniter.com/userguide3/helpers/email_helper.html>`_.
117+
`Path Helper <https://www.codeigniter.com/userguide3/helpers/path_helper.html>`_.
118+
and `Smiley Helper <https://www.codeigniter.com/userguide3/helpers/smiley_helper.html>`_.
119+
- `Download Helper <https://www.codeigniter.com/userguide3/helpers/download_helper.html>`_
120+
in CI3 was removed. You need to use Response object where you are using ``force_download()``.
121+
See :ref:`force-file-download`.
122+
- `Language Helper <https://www.codeigniter.com/userguide3/helpers/language_helper.html>`_
123+
in CI3 was removed. But ``lang()`` is always available in CI4. See :php:func:`lang()`.
124+
- `Typography Helper <https://www.codeigniter.com/userguide3/helpers/typography_helper.html>`_
125+
in CI3 wll be :doc:`Typography Library <../libraries/typography>` in CI4.
126+
- `Directory Helper <https://www.codeigniter.com/userguide3/helpers/directory_helper.html>`_
127+
and `File Helper <https://www.codeigniter.com/userguide3/helpers/file_helper.html>`_ in CI3
128+
will be :doc:`../helpers/filesystem_helper` in CI4.
129+
- `String Helper <https://www.codeigniter.com/userguide3/helpers/string_helper.html>`_ functions
130+
in CI3 are included in :doc:`../helpers/text_helper` in CI4.
113131
- In CI4, ``redirect()`` returns a ``RedirectResponse`` instance instead of redirecting and terminating script execution. You must return it.
114132
- `redirect() Documentation CodeIgniter 3.X <https://codeigniter.com/userguide3/helpers/url_helper.html#redirect>`_
115133
- `redirect() Documentation CodeIgniter 4.X <../general/common_functions.html#redirect>`_
116134

117135
Events
118136
======
119137

120-
- Hooks have been replaced by Events.
138+
- `Hooks <https://www.codeigniter.com/userguide3/general/hooks.html>`_ have been
139+
replaced by :doc:`../extending/events`.
121140
- Instead of CI3's ``$hook['post_controller_constructor']`` you now use
122141
``Events::on('post_controller_constructor', ['MyClass', 'MyFunction']);``, with the namespace ``CodeIgniter\Events\Events;``.
123142
- Events are always enabled, and are available globally.
@@ -127,17 +146,18 @@ Extending the Framework
127146

128147
- You don't need a **core** folder to hold ``MY_...`` framework
129148
component extensions or replacements.
130-
- You don't need ``MY_x`` classes inside your libraries folder
149+
- You don't need ``MY_X`` classes inside your libraries folder
131150
to extend or replace CI4 pieces.
132151
- Make any such classes where you like, and add appropriate
133152
service methods in **app/Config/Services.php** to load
134153
your components instead of the default ones.
154+
- See :doc:`../extending/core_classes` for details.
135155

136156
Upgrading Libraries
137157
*******************
138158

139159
- Your app classes can still go inside **app/Libraries**, but they don't have to.
140-
- Instead of CI3's ``$this->load->library(x);`` you can now use ``$this->x = new X();``,
160+
- Instead of CI3's ``$this->load->library('x');`` you can now use ``$this->x = new X();``,
141161
following namespaced conventions for your component.
142162
- Some libraries from CodeIgniter 3 no longer exists in Version 4. For all these
143163
libraries, you have to find a new way to implement your functions. These

0 commit comments

Comments
 (0)