[CORE] Bump PHP requirement to PHP7.3+

This commit is contained in:
Diogo Cordeiro 2019-07-25 01:29:20 +01:00
parent dbde8383c9
commit db3253e5d2
23 changed files with 1114 additions and 486 deletions

View File

@ -4,7 +4,7 @@
"type": "project", "type": "project",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
"require": { "require": {
"php": "^7.0.0", "php": "^7.3.0",
"ext-bcmath": "*", "ext-bcmath": "*",
"ext-curl": "*", "ext-curl": "*",
"ext-dom": "*", "ext-dom": "*",
@ -32,7 +32,7 @@
}, },
"require-dev": { "require-dev": {
"phpdocumentor/phpdocumentor": "^2.9", "phpdocumentor/phpdocumentor": "^2.9",
"phpunit/phpunit": "^6.5", "phpunit/phpunit": "^8.2",
"psy/psysh": "^0.9.9" "psy/psysh": "^0.9.9"
}, },
"suggest": { "suggest": {
@ -69,10 +69,7 @@
"config": { "config": {
"optimize-autoloader": true, "optimize-autoloader": true,
"preferred-install": "dist", "preferred-install": "dist",
"sort-packages": true, "sort-packages": true
"platform": {
"php": "7.0.0"
}
}, },
"scripts": { "scripts": {
"post-update-cmd": [ "post-update-cmd": [

1323
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
<?php <?php
// {{{ license{{{{{{ // {{{ license{{{{{{{{{
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
// //
@ -22,7 +22,7 @@
// +----------------------------------------------------------------------+ // +----------------------------------------------------------------------+
// //
// }}}}}}}}} // }}}}}}}}}}}}
require_once 'Net/IDNA2/Exception.php'; require_once 'Net/IDNA2/Exception.php';
require_once 'Net/IDNA2/Exception/Nameprep.php'; require_once 'Net/IDNA2/Exception/Nameprep.php';
@ -3304,7 +3304,7 @@ class Net_IDNA2
* @static * @static
* @access private * @access private
*/ */
private static function _showHex(array $input, bool $include_bit = false) //: void XXX PHP: Upgrade to PHP 7.1 private static function _showHex(array $input, bool $include_bit = false): void
{ {
foreach ($input as $k => $v) { foreach ($input as $k => $v) {
echo '[', $k, '] => ', sprintf('%X', $v); echo '[', $k, '] => ', sprintf('%X', $v);

View File

@ -110,8 +110,8 @@ abstract class Installer
} }
} }
if (version_compare(PHP_VERSION, '7.0.0', '<')) { if (version_compare(PHP_VERSION, '7.3.0', '<')) {
$this->warning('Require PHP version 7.0.0 or greater.'); $this->warning('Require PHP version 7.3.0 or greater.');
$pass = false; $pass = false;
} }

View File

@ -373,9 +373,7 @@ class MediaFile
// but if the _actual_ locally stored file doesn't exist, getPath will throw FileNotFoundException // but if the _actual_ locally stored file doesn't exist, getPath will throw FileNotFoundException
$filepath = $file->getPath(); $filepath = $file->getPath();
$mimetype = $file->mimetype; $mimetype = $file->mimetype;
// XXX PHP: Upgrade to PHP 7.1 } catch (FileNotFoundException | NoResultException $e) {
// catch (FileNotFoundException | NoResultException $e)
} catch (Exception $e) {
// We have to save the upload as a new local file. This is the normal course of action. // We have to save the upload as a new local file. This is the normal course of action.
if ($scoped instanceof Profile) { if ($scoped instanceof Profile) {
// Throws exception if additional size does not respect quota // Throws exception if additional size does not respect quota

View File

@ -54,7 +54,7 @@ final class ActivityGenerationTests extends TestCase
static $targetGroup1 = null; static $targetGroup1 = null;
static $targetGroup2 = null; static $targetGroup2 = null;
public static function setUpBeforeClass() public static function setUpBeforeClass(): void
{ {
$authorNick1 = 'activitygenerationtestsuser' . common_random_hexstr(4); $authorNick1 = 'activitygenerationtestsuser' . common_random_hexstr(4);
$authorNick2 = 'activitygenerationtestsuser' . common_random_hexstr(4); $authorNick2 = 'activitygenerationtestsuser' . common_random_hexstr(4);
@ -533,7 +533,7 @@ final class ActivityGenerationTests extends TestCase
$this->assertEquals($conv->getUrl(), ActivityUtils::getLink($element, 'ostatus:conversation')); $this->assertEquals($conv->getUrl(), ActivityUtils::getLink($element, 'ostatus:conversation'));
} }
public static function tearDownAfterClass() public static function tearDownAfterClass(): void
{ {
if (!is_null(self::$author1)) { if (!is_null(self::$author1)) {
self::$author1->getProfile()->delete(); self::$author1->getProfile()->delete();

View File

@ -19,6 +19,9 @@ namespace Tests\Unit;
if (!defined('INSTALLDIR')) { if (!defined('INSTALLDIR')) {
define('INSTALLDIR', dirname(dirname(__DIR__))); define('INSTALLDIR', dirname(dirname(__DIR__)));
} }
if (!defined('PUBLICDIR')) {
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');
}
if (!defined('GNUSOCIAL')) { if (!defined('GNUSOCIAL')) {
define('GNUSOCIAL', true); define('GNUSOCIAL', true);
} }

View File

@ -19,6 +19,9 @@ namespace Tests\Unit;
if (!defined('INSTALLDIR')) { if (!defined('INSTALLDIR')) {
define('INSTALLDIR', dirname(dirname(__DIR__))); define('INSTALLDIR', dirname(dirname(__DIR__)));
} }
if (!defined('PUBLICDIR')) {
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');
}
if (!defined('GNUSOCIAL')) { if (!defined('GNUSOCIAL')) {
define('GNUSOCIAL', true); define('GNUSOCIAL', true);
} }

View File

@ -19,6 +19,9 @@ namespace Tests\Unit;
if (!defined('INSTALLDIR')) { if (!defined('INSTALLDIR')) {
define('INSTALLDIR', dirname(dirname(__DIR__))); define('INSTALLDIR', dirname(dirname(__DIR__)));
} }
if (!defined('PUBLICDIR')) {
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');
}
if (!defined('GNUSOCIAL')) { if (!defined('GNUSOCIAL')) {
define('GNUSOCIAL', true); define('GNUSOCIAL', true);
} }

View File

@ -19,6 +19,9 @@ namespace Tests\Unit;
if (!defined('INSTALLDIR')) { if (!defined('INSTALLDIR')) {
define('INSTALLDIR', dirname(dirname(__DIR__))); define('INSTALLDIR', dirname(dirname(__DIR__)));
} }
if (!defined('PUBLICDIR')) {
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');
}
if (!defined('GNUSOCIAL')) { if (!defined('GNUSOCIAL')) {
define('GNUSOCIAL', true); define('GNUSOCIAL', true);
} }

View File

@ -19,6 +19,9 @@ namespace Tests\Unit;
if (!defined('INSTALLDIR')) { if (!defined('INSTALLDIR')) {
define('INSTALLDIR', dirname(dirname(__DIR__))); define('INSTALLDIR', dirname(dirname(__DIR__)));
} }
if (!defined('PUBLICDIR')) {
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');
}
if (!defined('GNUSOCIAL')) { if (!defined('GNUSOCIAL')) {
define('GNUSOCIAL', true); define('GNUSOCIAL', true);
} }

View File

@ -19,6 +19,9 @@ namespace Tests\Unit;
if (!defined('INSTALLDIR')) { if (!defined('INSTALLDIR')) {
define('INSTALLDIR', dirname(dirname(__DIR__))); define('INSTALLDIR', dirname(dirname(__DIR__)));
} }
if (!defined('PUBLICDIR')) {
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');
}
if (!defined('GNUSOCIAL')) { if (!defined('GNUSOCIAL')) {
define('GNUSOCIAL', true); define('GNUSOCIAL', true);
} }

View File

@ -19,6 +19,9 @@ namespace Tests\Unit;
if (!defined('INSTALLDIR')) { if (!defined('INSTALLDIR')) {
define('INSTALLDIR', dirname(dirname(__DIR__))); define('INSTALLDIR', dirname(dirname(__DIR__)));
} }
if (!defined('PUBLICDIR')) {
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');
}
if (!defined('GNUSOCIAL')) { if (!defined('GNUSOCIAL')) {
define('GNUSOCIAL', true); define('GNUSOCIAL', true);
} }

View File

@ -19,6 +19,9 @@ namespace Tests\Unit;
if (!defined('INSTALLDIR')) { if (!defined('INSTALLDIR')) {
define('INSTALLDIR', dirname(dirname(__DIR__))); define('INSTALLDIR', dirname(dirname(__DIR__)));
} }
if (!defined('PUBLICDIR')) {
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');
}
if (!defined('GNUSOCIAL')) { if (!defined('GNUSOCIAL')) {
define('GNUSOCIAL', true); define('GNUSOCIAL', true);
} }

View File

@ -19,6 +19,9 @@ namespace Tests\Unit;
if (!defined('INSTALLDIR')) { if (!defined('INSTALLDIR')) {
define('INSTALLDIR', dirname(dirname(__DIR__))); define('INSTALLDIR', dirname(dirname(__DIR__)));
} }
if (!defined('PUBLICDIR')) {
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');
}
if (!defined('GNUSOCIAL')) { if (!defined('GNUSOCIAL')) {
define('GNUSOCIAL', true); define('GNUSOCIAL', true);
} }

View File

@ -19,6 +19,9 @@ namespace Tests\Unit;
if (!defined('INSTALLDIR')) { if (!defined('INSTALLDIR')) {
define('INSTALLDIR', dirname(dirname(__DIR__))); define('INSTALLDIR', dirname(dirname(__DIR__)));
} }
if (!defined('PUBLICDIR')) {
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');
}
if (!defined('GNUSOCIAL')) { if (!defined('GNUSOCIAL')) {
define('GNUSOCIAL', true); define('GNUSOCIAL', true);
} }
@ -36,7 +39,7 @@ final class UserRightsTest extends TestCase
{ {
protected $user = null; protected $user = null;
function setUp() function setUp(): void
{ {
$user = User::getKV('nickname', 'userrightstestuser'); $user = User::getKV('nickname', 'userrightstestuser');
if ($user) { if ($user) {
@ -51,7 +54,7 @@ final class UserRightsTest extends TestCase
} }
} }
function tearDown() function tearDown(): void
{ {
if ($this->user) { if ($this->user) {
$profile = $this->user->getProfile(); $profile = $this->user->getProfile();

View File

@ -19,6 +19,9 @@ namespace Tests\Unit;
if (!defined('INSTALLDIR')) { if (!defined('INSTALLDIR')) {
define('INSTALLDIR', dirname(dirname(__DIR__))); define('INSTALLDIR', dirname(dirname(__DIR__)));
} }
if (!defined('PUBLICDIR')) {
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');
}
if (!defined('GNUSOCIAL')) { if (!defined('GNUSOCIAL')) {
define('GNUSOCIAL', true); define('GNUSOCIAL', true);
} }
@ -35,7 +38,7 @@ require_once INSTALLDIR . '/plugins/Xmpp/XmppPlugin.php';
final class XmppValidateTest extends TestCase final class XmppValidateTest extends TestCase
{ {
public function setUp() public function setUp(): void
{ {
if (!array_key_exists('Xmpp', GNUsocial::getActivePlugins())) { if (!array_key_exists('Xmpp', GNUsocial::getActivePlugins())) {
$this->markTestSkipped('XmppPlugin is not enabled.'); $this->markTestSkipped('XmppPlugin is not enabled.');

View File

@ -19,6 +19,9 @@ namespace Tests\Unit;
if (!defined('INSTALLDIR')) { if (!defined('INSTALLDIR')) {
define('INSTALLDIR', dirname(dirname(__DIR__))); define('INSTALLDIR', dirname(dirname(__DIR__)));
} }
if (!defined('PUBLICDIR')) {
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');
}
if (!defined('GNUSOCIAL')) { if (!defined('GNUSOCIAL')) {
define('GNUSOCIAL', true); define('GNUSOCIAL', true);
} }
@ -37,13 +40,13 @@ require_once INSTALLDIR . '/lib/common.php';
final class MediaFileTest extends TestCase final class MediaFileTest extends TestCase
{ {
public function setup() public function setup(): void
{ {
$this->old_attachments_supported = common_config('attachments', 'supported'); $this->old_attachments_supported = common_config('attachments', 'supported');
$GLOBALS['config']['attachments']['supported'] = true; $GLOBALS['config']['attachments']['supported'] = true;
} }
public function tearDown() public function tearDown(): void
{ {
$GLOBALS['config']['attachments']['supported'] = $this->old_attachments_supported; $GLOBALS['config']['attachments']['supported'] = $this->old_attachments_supported;
} }

View File

@ -18,7 +18,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../..')); if (!defined('INSTALLDIR')) {
define('INSTALLDIR', dirname(dirname(__DIR__)));
}
$shortoptions = 'n:p:'; $shortoptions = 'n:p:';
$longoptions = array('nickname=', 'password=', 'dry-run'); $longoptions = array('nickname=', 'password=', 'dry-run');

View File

@ -1,16 +1,52 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Composer
Upstream-Contact: Jordi Boggiano <j.boggiano@seld.be>
Source: https://github.com/composer/composer
Copyright (c) Nils Adermann, Jordi Boggiano Files: *
Copyright: 2016, Nils Adermann <naderman@naderman.de>
2016, Jordi Boggiano <j.boggiano@seld.be>
License: Expat
Files: src/Composer/Util/TlsHelper.php
Copyright: 2016, Nils Adermann <naderman@naderman.de>
2016, Jordi Boggiano <j.boggiano@seld.be>
2013, Evan Coury <me@evancoury.com>
License: Expat and BSD-2-Clause
License: BSD-2-Clause
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
.
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
License: Expat
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions: to do so, subject to the following conditions:
.
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -18,4 +54,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.

View File

@ -189,17 +189,17 @@
}, },
{ {
"name": "embed/embed", "name": "embed/embed",
"version": "v3.4.0", "version": "v3.4.1",
"version_normalized": "3.4.0.0", "version_normalized": "3.4.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/oscarotero/Embed.git", "url": "https://github.com/oscarotero/Embed.git",
"reference": "5594b253dee90888c14cdca43696183c98f078e9" "reference": "960bbd5a62c5697302bd5394d58efba2e998b787"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/oscarotero/Embed/zipball/5594b253dee90888c14cdca43696183c98f078e9", "url": "https://api.github.com/repos/oscarotero/Embed/zipball/960bbd5a62c5697302bd5394d58efba2e998b787",
"reference": "5594b253dee90888c14cdca43696183c98f078e9", "reference": "960bbd5a62c5697302bd5394d58efba2e998b787",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -212,7 +212,7 @@
"friendsofphp/php-cs-fixer": "^2.0", "friendsofphp/php-cs-fixer": "^2.0",
"phpunit/phpunit": "^4.8|^5.7" "phpunit/phpunit": "^4.8|^5.7"
}, },
"time": "2019-06-23T11:12:03+00:00", "time": "2019-07-20T17:05:41+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -227,9 +227,9 @@
"authors": [ "authors": [
{ {
"name": "Oscar Otero", "name": "Oscar Otero",
"role": "Developer",
"email": "oom@oscarotero.com", "email": "oom@oscarotero.com",
"homepage": "http://oscarotero.com", "homepage": "http://oscarotero.com"
"role": "Developer"
} }
], ],
"description": "PHP library to retrieve page info using oembed, opengraph, etc", "description": "PHP library to retrieve page info using oembed, opengraph, etc",

View File

@ -57,51 +57,7 @@ class Response extends AbstractResponse
return $this->htmlContent = false; return $this->htmlContent = false;
} }
$errors = libxml_use_internal_errors(true); $this->htmlContent = Utils::parse($content);
$entities = libxml_disable_entity_loader(true);
$this->htmlContent = new DOMDocument();
if (stripos($content, '<meta charset="utf') === false) {
$encodings = [
'ASCII' => 'ascii',
'UTF-8' => 'utf-8',
'SJIS' => 'shift_jis',
'Windows-1251' => 'windows-1251',
'Windows-1252' => 'windows-1252',
'Windows-1254' => 'windows-1254',
'ISO-8859-16' => 'iso-8859-16',
'ISO-8859-15' => 'iso-8859-15',
'ISO-8859-14' => 'iso-8859-14',
'ISO-8859-13' => 'iso-8859-13',
'ISO-8859-10' => 'iso-8859-10',
'ISO-8859-9' => 'iso-8859-9',
'ISO-8859-8' => 'iso-8859-8',
'ISO-8859-7' => 'iso-8859-7',
'ISO-8859-6' => 'iso-8859-6',
'ISO-8859-5' => 'iso-8859-5',
'ISO-8859-4' => 'iso-8859-4',
'ISO-8859-3' => 'iso-8859-3',
'ISO-8859-2' => 'iso-8859-2',
'ISO-8859-1' => 'iso-8859-1',
];
$detected = mb_detect_encoding($content, implode(',', array_keys($encodings)), true);
if ($detected && !empty($encodings[$detected])) {
$content = mb_convert_encoding($content, 'HTML-ENTITIES', $detected);
$content = preg_replace(
'/<head[^>]*>/',
'<head><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset='.$encodings[$detected].'">',
$content
);
}
}
$this->htmlContent->loadHTML(trim($content));
libxml_use_internal_errors($errors);
libxml_disable_entity_loader($entities);
} catch (Exception $exception) { } catch (Exception $exception) {
return $this->htmlContent = false; return $this->htmlContent = false;
} }

View File

@ -12,6 +12,29 @@ use DOMXPath;
*/ */
class Utils class Utils
{ {
private static $encodings = [
'ASCII' => 'ascii',
'UTF-8' => 'utf-8',
'SJIS' => 'shift_jis',
'Windows-1251' => 'windows-1251',
'Windows-1252' => 'windows-1252',
'Windows-1254' => 'windows-1254',
'ISO-8859-1' => 'iso-8859-1',
'ISO-8859-2' => 'iso-8859-2',
'ISO-8859-3' => 'iso-8859-3',
'ISO-8859-4' => 'iso-8859-4',
'ISO-8859-5' => 'iso-8859-5',
'ISO-8859-6' => 'iso-8859-6',
'ISO-8859-7' => 'iso-8859-7',
'ISO-8859-8' => 'iso-8859-8',
'ISO-8859-9' => 'iso-8859-9',
'ISO-8859-10' => 'iso-8859-10',
'ISO-8859-13' => 'iso-8859-13',
'ISO-8859-14' => 'iso-8859-14',
'ISO-8859-15' => 'iso-8859-15',
'ISO-8859-16' => 'iso-8859-16',
];
/** /**
* Creates a <video> element. * Creates a <video> element.
* *
@ -240,4 +263,50 @@ class Utils
return $returnFirst ? $entries->item(0) : $entries; return $returnFirst ? $entries->item(0) : $entries;
} }
} }
/**
* Parse a string as html code
*
* @param string $html
*
* @return DOMDocument
*/
public static function parse($html)
{
$errors = libxml_use_internal_errors(true);
$entities = libxml_disable_entity_loader(true);
$html = trim(self::normalize($html));
$document = new DOMDocument();
$document->loadHTML($html);
libxml_use_internal_errors($errors);
libxml_disable_entity_loader($entities);
return $document;
}
/**
* Normalize the encoding of a html code before parse
*
* @param string $string
*
* @return string
*/
private static function normalize($string)
{
$detected = mb_detect_encoding($string, implode(',', array_keys(self::$encodings)), true);
if ($detected && isset(self::$encodings[$detected])) {
$string = mb_convert_encoding($string, 'HTML-ENTITIES', $detected);
$string = preg_replace(
'/<head[^>]*>/',
'<head><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset='.self::$encodings[$detected].'">',
$string
);
}
return $string;
}
} }