Update dependencies

This commit is contained in:
grandeljay 2022-08-05 09:36:23 +02:00
parent e3fe1086d5
commit 9c8e559956
19 changed files with 819 additions and 120 deletions

View file

@ -1,6 +1,6 @@
{
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.1",
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.2",
"wp-coding-standards/wpcs": "^2.3"
},
"require": {

42
composer.lock generated
View file

@ -4,20 +4,20 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "d34836b165b17de57def80469fb24ee5",
"content-hash": "4a0fc9594c8e709451751e1abfb0288b",
"packages": [
{
"name": "composer/ca-bundle",
"version": "1.3.2",
"version": "1.3.3",
"source": {
"type": "git",
"url": "https://github.com/composer/ca-bundle.git",
"reference": "fd5dd441932a7e10ca6e5b490e272d34c8430640"
"reference": "30897edbfb15e784fe55587b4f73ceefd3c4d98c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/fd5dd441932a7e10ca6e5b490e272d34c8430640",
"reference": "fd5dd441932a7e10ca6e5b490e272d34c8430640",
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/30897edbfb15e784fe55587b4f73ceefd3c4d98c",
"reference": "30897edbfb15e784fe55587b4f73ceefd3c4d98c",
"shasum": ""
},
"require": {
@ -64,7 +64,7 @@
"support": {
"irc": "irc://irc.freenode.org/composer",
"issues": "https://github.com/composer/ca-bundle/issues",
"source": "https://github.com/composer/ca-bundle/tree/1.3.2"
"source": "https://github.com/composer/ca-bundle/tree/1.3.3"
},
"funding": [
{
@ -80,7 +80,7 @@
"type": "tidelift"
}
],
"time": "2022-05-24T11:56:16+00:00"
"time": "2022-07-20T07:14:26+00:00"
},
{
"name": "embed/embed",
@ -173,16 +173,16 @@
},
{
"name": "gettext/gettext",
"version": "v5.6.1",
"version": "v5.7.0",
"source": {
"type": "git",
"url": "https://github.com/php-gettext/Gettext.git",
"reference": "017e249601d32b9a88c2eb4c10eac89bf582a7d3"
"reference": "8657e580747bb3baacccdcebe69cac094661e404"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-gettext/Gettext/zipball/017e249601d32b9a88c2eb4c10eac89bf582a7d3",
"reference": "017e249601d32b9a88c2eb4c10eac89bf582a7d3",
"url": "https://api.github.com/repos/php-gettext/Gettext/zipball/8657e580747bb3baacccdcebe69cac094661e404",
"reference": "8657e580747bb3baacccdcebe69cac094661e404",
"shasum": ""
},
"require": {
@ -227,7 +227,7 @@
"support": {
"email": "oom@oscarotero.com",
"issues": "https://github.com/php-gettext/Gettext/issues",
"source": "https://github.com/php-gettext/Gettext/tree/v5.6.1"
"source": "https://github.com/php-gettext/Gettext/tree/v5.7.0"
},
"funding": [
{
@ -243,7 +243,7 @@
"type": "patreon"
}
],
"time": "2021-12-04T11:33:21+00:00"
"time": "2022-07-27T19:54:55+00:00"
},
{
"name": "gettext/languages",
@ -1160,7 +1160,7 @@
},
{
"name": "symfony/deprecation-contracts",
"version": "v3.1.0",
"version": "v3.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
@ -1207,7 +1207,7 @@
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.0"
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1"
},
"funding": [
{
@ -1310,16 +1310,16 @@
},
{
"name": "symfony/process",
"version": "v5.4.8",
"version": "v5.4.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3"
"reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/597f3fff8e3e91836bb0bd38f5718b56ddbde2f3",
"reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3",
"url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1",
"reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1",
"shasum": ""
},
"require": {
@ -1352,7 +1352,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v5.4.8"
"source": "https://github.com/symfony/process/tree/v5.4.11"
},
"funding": [
{
@ -1368,7 +1368,7 @@
"type": "tidelift"
}
],
"time": "2022-04-08T05:07:18+00:00"
"time": "2022-06-27T16:58:25+00:00"
}
],
"packages-dev": [

View file

@ -30,7 +30,7 @@ private static $installed = array (
'aliases' =>
array (
),
'reference' => '03788f71ffb580b6f1b6469fdc74463f381928d8',
'reference' => 'e3fe1086d5bf7fe17d3d2c64ecd2cab4e2696dc9',
'name' => '__root__',
),
'versions' =>
@ -42,16 +42,16 @@ private static $installed = array (
'aliases' =>
array (
),
'reference' => '03788f71ffb580b6f1b6469fdc74463f381928d8',
'reference' => 'e3fe1086d5bf7fe17d3d2c64ecd2cab4e2696dc9',
),
'composer/ca-bundle' =>
array (
'pretty_version' => '1.3.2',
'version' => '1.3.2.0',
'pretty_version' => '1.3.3',
'version' => '1.3.3.0',
'aliases' =>
array (
),
'reference' => 'fd5dd441932a7e10ca6e5b490e272d34c8430640',
'reference' => '30897edbfb15e784fe55587b4f73ceefd3c4d98c',
),
'dealerdirect/phpcodesniffer-composer-installer' =>
array (
@ -73,12 +73,12 @@ private static $installed = array (
),
'gettext/gettext' =>
array (
'pretty_version' => 'v5.6.1',
'version' => '5.6.1.0',
'pretty_version' => 'v5.7.0',
'version' => '5.7.0.0',
'aliases' =>
array (
),
'reference' => '017e249601d32b9a88c2eb4c10eac89bf582a7d3',
'reference' => '8657e580747bb3baacccdcebe69cac094661e404',
),
'gettext/languages' =>
array (
@ -238,8 +238,8 @@ private static $installed = array (
),
'symfony/deprecation-contracts' =>
array (
'pretty_version' => 'v3.1.0',
'version' => '3.1.0.0',
'pretty_version' => 'v3.1.1',
'version' => '3.1.1.0',
'aliases' =>
array (
),
@ -256,12 +256,12 @@ private static $installed = array (
),
'symfony/process' =>
array (
'pretty_version' => 'v5.4.8',
'version' => '5.4.8.0',
'pretty_version' => 'v5.4.11',
'version' => '5.4.11.0',
'aliases' =>
array (
),
'reference' => '597f3fff8e3e91836bb0bd38f5718b56ddbde2f3',
'reference' => '6e75fe6874cbc7e4773d049616ab450eff537bf1',
),
'wp-coding-standards/wpcs' =>
array (

View file

@ -18,7 +18,7 @@ return array(
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
'Grandel\\' => array($vendorDir . '/grandel/include-directory/src'),
'Gettext\\Languages\\' => array($vendorDir . '/gettext/languages/src'),
'Gettext\\' => array($vendorDir . '/gettext/gettext/src', $vendorDir . '/gettext/translator/src'),
'Gettext\\' => array($vendorDir . '/gettext/translator/src', $vendorDir . '/gettext/gettext/src'),
'Embed\\' => array($vendorDir . '/embed/embed/src'),
'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' => array($vendorDir . '/dealerdirect/phpcodesniffer-composer-installer/src'),
'Composer\\CaBundle\\' => array($vendorDir . '/composer/ca-bundle/src'),

View file

@ -113,8 +113,8 @@ class ComposerStaticInit5f3db9fc1d0cf1dd6a77a1d84501b4b1
),
'Gettext\\' =>
array (
0 => __DIR__ . '/..' . '/gettext/gettext/src',
1 => __DIR__ . '/..' . '/gettext/translator/src',
0 => __DIR__ . '/..' . '/gettext/translator/src',
1 => __DIR__ . '/..' . '/gettext/gettext/src',
),
'Embed\\' =>
array (

View file

@ -1,7 +1,7 @@
##
## Bundle of CA Root Certificates
##
## Certificate data from Mozilla as of: Tue Apr 26 03:12:05 2022 GMT
## Certificate data from Mozilla as of: Tue Jul 19 03:12:06 2022 GMT
##
## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates
@ -14,7 +14,7 @@
## Just configure this file as the SSLCACertificateFile.
##
## Conversion done with mk-ca-bundle.pl version 1.29.
## SHA256: 34a54d5191775c1bd37be6cfd3f09e831e072555dc3a2e51f4a2c4b0f8ada5cc
## SHA256: 9bf3799611fb58197f61d45e71ce3dc19f30e7dd73731915872ce5108a7bb066
##
@ -993,30 +993,6 @@ tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29
mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
-----END CERTIFICATE-----
Hellenic Academic and Research Institutions RootCA 2011
=======================================================
-----BEGIN CERTIFICATE-----
MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT
O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y
aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT
AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo
IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI
1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa
71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u
8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH
3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/
MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8
MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu
b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt
XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD
/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N
7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4
-----END CERTIFICATE-----
Actalis Authentication Root CA
==============================
-----BEGIN CERTIFICATE-----
@ -3345,3 +3321,140 @@ PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjOPQQD
AwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CAy/m0sRtW9XLS/BnR
AjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJbgfM0agPnIjhQW+0ZT0MW
-----END CERTIFICATE-----
DigiCert TLS ECC P384 Root G5
=============================
-----BEGIN CERTIFICATE-----
MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQswCQYDVQQGEwJV
UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURpZ2lDZXJ0IFRMUyBFQ0MgUDM4
NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMx
FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQg
Um9vdCBHNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1Tzvd
lHJS7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp0zVozptj
n4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICISB4CIfBFqMA4GA1UdDwEB
/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQCJao1H5+z8blUD2Wds
Jk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQLgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIx
AJSdYsiJvRmEFOml+wG4DXZDjC5Ty3zfDBeWUA==
-----END CERTIFICATE-----
DigiCert TLS RSA4096 Root G5
============================
-----BEGIN CERTIFICATE-----
MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBNMQswCQYDVQQG
EwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0
MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcNNDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJV
UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2
IFJvb3QgRzUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS8
7IE+ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG02C+JFvuU
AT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgpwgscONyfMXdcvyej/Ces
tyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZMpG2T6T867jp8nVid9E6P/DsjyG244gXa
zOvswzH016cpVIDPRFtMbzCe88zdH5RDnU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnV
DdXifBBiqmvwPXbzP6PosMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9q
TXeXAaDxZre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cdLvvy
z6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvXKyY//SovcfXWJL5/
MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNeXoVPzthwiHvOAbWWl9fNff2C+MIk
wcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPLtgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4E
FgQUUTMc7TZArxfTJc1paPKvTiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8w
DQYJKoZIhvcNAQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw
GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7HPNtQOa27PShN
lnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLFO4uJ+DQtpBflF+aZfTCIITfN
MBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQREtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/
u4cnYiWB39yhL/btp/96j1EuMPikAdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9G
OUrYU9DzLjtxpdRv/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh
47a+p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilwMUc/dNAU
FvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WFqUITVuwhd4GTWgzqltlJ
yqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCKovfepEWFJqgejF0pW8hL2JpqA15w8oVP
bEtoL8pU9ozaMv7Da4M/OMZ+
-----END CERTIFICATE-----
Certainly Root R1
=================
-----BEGIN CERTIFICATE-----
MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAwPTELMAkGA1UE
BhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2VydGFpbmx5IFJvb3QgUjEwHhcN
MjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2Vy
dGFpbmx5MRowGAYDVQQDExFDZXJ0YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
ADCCAgoCggIBANA21B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O
5MQTvqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbedaFySpvXl
8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b01C7jcvk2xusVtyWMOvwl
DbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGI
XsXwClTNSaa/ApzSRKft43jvRl5tcdF5cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkN
KPl6I7ENPT2a/Z2B7yyQwHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQ
AjeZjOVJ6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA2Cnb
rlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyHWyf5QBGenDPBt+U1
VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMReiFPCyEQtkA6qyI6BJyLm4SGcprS
p6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
DgQWBBTgqj8ljZ9EXME66C6ud0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAsz
HQNTVfSVcOQrPbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d
8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi1wrykXprOQ4v
MMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrdrRT90+7iIgXr0PK3aBLXWopB
GsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9ditaY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+
gjwN/KUD+nsa2UUeYNrEjvn8K8l7lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgH
JBu6haEaBQmAupVjyTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7
fpYnKx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLyyCwzk5Iw
x06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5nwXARPbv0+Em34yaXOp/S
X3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6OV+KmalBWQewLK8=
-----END CERTIFICATE-----
Certainly Root E1
=================
-----BEGIN CERTIFICATE-----
MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQswCQYDVQQGEwJV
UzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlubHkgUm9vdCBFMTAeFw0yMTA0
MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJBgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlu
bHkxGjAYBgNVBAMTEUNlcnRhaW5seSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4
fxzf7flHh4axpMCK+IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9
YBk2QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8EBAMCAQYw
DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4hevIIgcwCgYIKoZIzj0E
AwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozmut6Dacpps6kFtZaSF4fC0urQe87YQVt8
rgIwRt7qy12a7DLCZRawTDBcMPPaTnOGBtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR
-----END CERTIFICATE-----
E-Tugra Global Root CA RSA v3
=============================
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----
E-Tugra Global Root CA ECC v3
=============================
-----BEGIN CERTIFICATE-----
MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMwgYAxCzAJBgNV
BAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAbBgNV
BAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENB
IEVDQyB2MzAeFw0yMDAzMTgwOTQ2NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEP
MA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1
Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBFQ0MgdjMw
djAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQKczLWYHMjLiSF4mDKpL2
w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YKfWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31
Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQ
zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO
PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W
Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3
-----END CERTIFICATE-----

View file

@ -2,17 +2,17 @@
"packages": [
{
"name": "composer/ca-bundle",
"version": "1.3.2",
"version_normalized": "1.3.2.0",
"version": "1.3.3",
"version_normalized": "1.3.3.0",
"source": {
"type": "git",
"url": "https://github.com/composer/ca-bundle.git",
"reference": "fd5dd441932a7e10ca6e5b490e272d34c8430640"
"reference": "30897edbfb15e784fe55587b4f73ceefd3c4d98c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/fd5dd441932a7e10ca6e5b490e272d34c8430640",
"reference": "fd5dd441932a7e10ca6e5b490e272d34c8430640",
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/30897edbfb15e784fe55587b4f73ceefd3c4d98c",
"reference": "30897edbfb15e784fe55587b4f73ceefd3c4d98c",
"shasum": ""
},
"require": {
@ -26,7 +26,7 @@
"symfony/phpunit-bridge": "^4.2 || ^5",
"symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
},
"time": "2022-05-24T11:56:16+00:00",
"time": "2022-07-20T07:14:26+00:00",
"type": "library",
"extra": {
"branch-alias": {
@ -61,7 +61,7 @@
"support": {
"irc": "irc://irc.freenode.org/composer",
"issues": "https://github.com/composer/ca-bundle/issues",
"source": "https://github.com/composer/ca-bundle/tree/1.3.2"
"source": "https://github.com/composer/ca-bundle/tree/1.3.3"
},
"funding": [
{
@ -251,17 +251,17 @@
},
{
"name": "gettext/gettext",
"version": "v5.6.1",
"version_normalized": "5.6.1.0",
"version": "v5.7.0",
"version_normalized": "5.7.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-gettext/Gettext.git",
"reference": "017e249601d32b9a88c2eb4c10eac89bf582a7d3"
"reference": "8657e580747bb3baacccdcebe69cac094661e404"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-gettext/Gettext/zipball/017e249601d32b9a88c2eb4c10eac89bf582a7d3",
"reference": "017e249601d32b9a88c2eb4c10eac89bf582a7d3",
"url": "https://api.github.com/repos/php-gettext/Gettext/zipball/8657e580747bb3baacccdcebe69cac094661e404",
"reference": "8657e580747bb3baacccdcebe69cac094661e404",
"shasum": ""
},
"require": {
@ -275,7 +275,7 @@
"phpunit/phpunit": "^8.0|^9.0",
"squizlabs/php_codesniffer": "^3.0"
},
"time": "2021-12-04T11:33:21+00:00",
"time": "2022-07-27T19:54:55+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -308,7 +308,7 @@
"support": {
"email": "oom@oscarotero.com",
"issues": "https://github.com/php-gettext/Gettext/issues",
"source": "https://github.com/php-gettext/Gettext/tree/v5.6.1"
"source": "https://github.com/php-gettext/Gettext/tree/v5.7.0"
},
"funding": [
{
@ -1342,8 +1342,8 @@
},
{
"name": "symfony/deprecation-contracts",
"version": "v3.1.0",
"version_normalized": "3.1.0.0",
"version": "v3.1.1",
"version_normalized": "3.1.1.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
@ -1392,7 +1392,7 @@
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.0"
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1"
},
"funding": [
{
@ -1498,24 +1498,24 @@
},
{
"name": "symfony/process",
"version": "v5.4.8",
"version_normalized": "5.4.8.0",
"version": "v5.4.11",
"version_normalized": "5.4.11.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3"
"reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/597f3fff8e3e91836bb0bd38f5718b56ddbde2f3",
"reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3",
"url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1",
"reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/polyfill-php80": "^1.16"
},
"time": "2022-04-08T05:07:18+00:00",
"time": "2022-06-27T16:58:25+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -1543,7 +1543,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v5.4.8"
"source": "https://github.com/symfony/process/tree/v5.4.11"
},
"funding": [
{

View file

@ -6,7 +6,7 @@
'aliases' =>
array (
),
'reference' => '03788f71ffb580b6f1b6469fdc74463f381928d8',
'reference' => 'e3fe1086d5bf7fe17d3d2c64ecd2cab4e2696dc9',
'name' => '__root__',
),
'versions' =>
@ -18,16 +18,16 @@
'aliases' =>
array (
),
'reference' => '03788f71ffb580b6f1b6469fdc74463f381928d8',
'reference' => 'e3fe1086d5bf7fe17d3d2c64ecd2cab4e2696dc9',
),
'composer/ca-bundle' =>
array (
'pretty_version' => '1.3.2',
'version' => '1.3.2.0',
'pretty_version' => '1.3.3',
'version' => '1.3.3.0',
'aliases' =>
array (
),
'reference' => 'fd5dd441932a7e10ca6e5b490e272d34c8430640',
'reference' => '30897edbfb15e784fe55587b4f73ceefd3c4d98c',
),
'dealerdirect/phpcodesniffer-composer-installer' =>
array (
@ -49,12 +49,12 @@
),
'gettext/gettext' =>
array (
'pretty_version' => 'v5.6.1',
'version' => '5.6.1.0',
'pretty_version' => 'v5.7.0',
'version' => '5.7.0.0',
'aliases' =>
array (
),
'reference' => '017e249601d32b9a88c2eb4c10eac89bf582a7d3',
'reference' => '8657e580747bb3baacccdcebe69cac094661e404',
),
'gettext/languages' =>
array (
@ -214,8 +214,8 @@
),
'symfony/deprecation-contracts' =>
array (
'pretty_version' => 'v3.1.0',
'version' => '3.1.0.0',
'pretty_version' => 'v3.1.1',
'version' => '3.1.1.0',
'aliases' =>
array (
),
@ -232,12 +232,12 @@
),
'symfony/process' =>
array (
'pretty_version' => 'v5.4.8',
'version' => '5.4.8.0',
'pretty_version' => 'v5.4.11',
'version' => '5.4.11.0',
'aliases' =>
array (
),
'reference' => '597f3fff8e3e91836bb0bd38f5718b56ddbde2f3',
'reference' => '6e75fe6874cbc7e4773d049616ab450eff537bf1',
),
'wp-coding-standards/wpcs' =>
array (

View file

@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
Previous releases are documented in [github releases](https://github.com/oscarotero/Gettext/releases)
## [5.7.0] - 2022-07-27
### Added
- StrictPoLoader, a stricter PO loader more aligned with the syntax of the GNU gettext tooling [#282].
- Previous attributes (msgctxt, msgid, msgid_plural) to the Translation class and the PO generator [#282].
### Changed
- Minor performance improvements to the Translations class [#282].
## [5.6.1] - 2021-12-04
### Fixed
- PHP 8.1 support [#278].
@ -73,7 +81,7 @@ Previous releases are documented in [github releases](https://github.com/oscarot
### Added
- New function `CodeScanner::ignoreInvalidFunctions()` to ignore invalid functions instead throw an exception
## 5.0.0 - 2019-11-04
## [5.0.0] - 2019-11-04
### Added
- New interfaces: `ScannerInterface` and `FunctionsScannerInterface`.
@ -112,7 +120,9 @@ Previous releases are documented in [github releases](https://github.com/oscarot
[#265]: https://github.com/php-gettext/Gettext/issues/265
[#276]: https://github.com/php-gettext/Gettext/issues/276
[#278]: https://github.com/php-gettext/Gettext/issues/278
[#282]: https://github.com/php-gettext/Gettext/issues/282
[5.7.0]: https://github.com/php-gettext/Gettext/compare/v5.6.1...v5.7.0
[5.6.1]: https://github.com/php-gettext/Gettext/compare/v5.6.0...v5.6.1
[5.6.0]: https://github.com/php-gettext/Gettext/compare/v5.5.4...v5.6.0
[5.5.4]: https://github.com/php-gettext/Gettext/compare/v5.5.3...v5.5.4
@ -127,3 +137,4 @@ Previous releases are documented in [github releases](https://github.com/oscarot
[5.2.1]: https://github.com/php-gettext/Gettext/compare/v5.2.0...v5.2.1
[5.2.0]: https://github.com/php-gettext/Gettext/compare/v5.1.0...v5.2.0
[5.1.0]: https://github.com/php-gettext/Gettext/compare/v5.0.0...v5.1.0
[5.0.0]: https://github.com/php-gettext/Gettext/releases/tag/v5.0.0

View file

@ -94,7 +94,7 @@ $translations->setDomain('my-blog');
## Loaders
The loaders allows to get gettext values from any format. For example, to load a .po file:
The loaders allow to get gettext values from multiple formats. For example, to load a .po file:
```php
use Gettext\Loader\PoLoader;
@ -109,10 +109,39 @@ $string = file_get_contents('locales2/en.po');
$translations = $loader->loadString($string);
```
As of version 5.7.0, a `StrictPoLoader` has been included, with a parser more aligned to the GNU gettext tooling with the same expectations and failures (see the tests for more details).
- It will fail with an exception when there's anything wrong with the syntax, and display the reason together with the line/byte where it happened.
- It might also emit useful warnings, e.g. when there are more/less plural translations than needed, missing translation header, dangling comments not associated with any translation, etc.
- Due to its strictness and speed (about 50% slower than the `PoLoader`), it might be interesting to be used as a kind of `.po` linter in a build system.
- It also implements the previous translation comment (e.g. `#| msgid "previous"`) and extra escapes (16-bit unicode `\u`, 32-bit unicode `\U`, hexadecimal `\xFF` and octal `\77`).
The usage is basically the same as the `PoLoader`:
```php
use Gettext\Loader\StrictPoLoader;
$loader = new StrictPoLoader();
//From a file
$translations = $loader->loadFile('locales/en.po');
//From a string
$string = file_get_contents('locales2/en.po');
$translations = $loader->loadString($string);
//Display error messages using "at line X column Y" instead of "at byte X"
$loader->displayErrorLine = true;
//Throw an exception when a warning happens
$loader->throwOnWarning = true;
//Retrieve the warnings
$loader->getWarnings();
```
This package includes the following loaders:
- `MoLoader`
- `PoLoader`
- `StrictPoLoader`
And you can install other formats with loaders and generators:

View file

@ -65,6 +65,18 @@ final class PoGenerator extends Generator
$prefix = $translation->isDisabled() ? '#~ ' : '';
if ($context = $translation->getPreviousContext()) {
$lines[] = sprintf('%s#| msgctxt %s', $prefix, self::encode($context));
}
if ($original = $translation->getPreviousOriginal()) {
$lines[] = sprintf('%s#| msgid %s', $prefix, self::encode($original));
}
if ($plural = $translation->getPreviousPlural()) {
$lines[] = sprintf('%s#| msgid_plural %s', $prefix, self::encode($plural));
}
if ($context = $translation->getContext()) {
$lines[] = sprintf('%smsgctxt %s', $prefix, self::encode($context));
}

View file

@ -4,7 +4,6 @@ declare(strict_types = 1);
namespace Gettext\Loader;
use Exception;
use Gettext\Translation;
use Gettext\Translations;
/**

View file

@ -0,0 +1,487 @@
<?php
declare(strict_types = 1);
namespace Gettext\Loader;
use Exception;
use Gettext\Translation;
use Gettext\Translations;
/**
* Class to load a PO file following the same rules of the GNU gettext tools.
*/
final class StrictPoLoader extends Loader
{
/** @var bool */
public $throwOnWarning = false;
/** @var bool */
public $displayErrorLine = false;
/** @var Translations */
private $translations;
/** @var Translation */
private $translation;
/** @var Translation|null */
private $header;
/** @var string */
private $data;
/** @var int */
private $position;
/** @var int|null */
private $pluralCount;
/** @var bool */
private $inPreviousPart;
/** @var string[] */
private $warnings = [];
/** @var bool */
private $isDisabled;
/** @var bool */
private $displayLineColumn;
/**
* Generates a Translations object from a .po based string
*/
public function loadString(string $data, Translations $translations = null): Translations
{
$this->data = $data;
$this->position = 0;
$this->translations = parent::loadString($this->data, $translations);
$this->header = $this->translations->find(null, '');
$this->pluralCount = $this->translations->getHeaders()->getPluralForm()[0] ?? null;
$this->warnings = [];
for ($length = strlen($this->data); $this->newEntry(); $this->saveEntry()) {
for ($hasComment = false; $this->readComment(); $hasComment = true);
$this->readWhitespace();
// End of data
if ($this->position >= $length) {
if ($hasComment) {
$this->addWarning("Comment ignored at the end of the string{$this->getErrorPosition()}");
}
break;
}
$this->readContext();
$this->readOriginal();
if ($this->translations->has($this->translation)) {
throw new Exception("Duplicated entry{$this->getErrorPosition()}");
}
if (!$this->readPlural()) {
$this->readTranslation();
continue;
}
for ($count = 0; $this->readPluralTranslation(!$count); ++$count);
$count !== ($this->pluralCount ?? $count) && $this->addWarning("The translation has {$count} plural "
. "forms, while the header expects {$this->pluralCount}{$this->getErrorPosition()}");
}
if (!$this->header) {
$this->addWarning("The loaded string has no header translation{$this->getErrorPosition()}");
}
return $this->translations;
}
/**
* Retrieves the collected warnings
* @return string[]
*/
public function getWarnings(): array
{
return $this->warnings;
}
/**
* Prepares to parse a new translation
*/
private function newEntry(): Translation
{
$this->isDisabled = false;
return $this->translation = $this->createTranslation(null, '');
}
/**
* Adds the current translation to the output list
*/
private function saveEntry(): void
{
if ($this->isHeader()) {
$this->processHeader();
return;
}
$this->translations->add($this->translation);
}
/**
* Attempts to read whitespace characters, also might skip complex comment prologs when needed
* @return int The position before comments started being consumed
*/
private function readWhitespace(): int
{
do {
$this->position += strspn($this->data, " \n\r\t\v\0", $this->position);
$checkpoint ?? $checkpoint = $this->position;
} while (($this->isDisabled && $this->readString('#~')) || ($this->inPreviousPart && $this->readString('#|')));
return $checkpoint;
}
/**
* Attempts to read the exact informed string
*/
private function readString(string $data): bool
{
return !substr_compare($this->data, $data, $this->position, $l = strlen($data)) && $this->position += $l;
}
/**
* Attempts to read the exact informed char
*/
private function readChar(string $char): bool
{
return ($this->data[$this->position] ?? null) === $char && ++$this->position;
}
/**
* Read sequential characters that match the given character set until the length range is satisfied
*/
private function readCharset(string $charset, int $min, int $max, string $name): string
{
if (($length = strspn($this->data, $charset, $this->position, $max)) < $min) {
throw new Exception("Expected at least {$min} occurrence of {$name} characters{$this->getErrorPosition()}");
}
return substr($this->data, ($this->position += $length) - $length, $length);
}
/**
* Attempts to read a standard comment string which ends with a newline
*/
private function readCommentString(): string
{
$length = strcspn($this->data, "\n\r", $this->position);
return substr($this->data, ($this->position += $length) - $length, $length);
}
/**
* Attempts to read a quoted string while parsing escape sequences prefixed by \
*/
private function readQuotedString(?string $context = null): string
{
$this->readWhitespace();
for ($data = '', $isNewPart = true, $checkpoint = null;;) {
if ($isNewPart && !$this->readChar('"')) {
// The data is over (e.g. beginning of an identifier) or perhaps there's an error
// Restore the checkpoint and let the next parser handle it
if ($checkpoint !== null) {
$this->position = $checkpoint;
break;
}
throw new Exception("Expected an opening quote{$this->getErrorPosition()}");
}
$isNewPart = false;
// Collects chars until an edge case is found
$length = strcspn($this->data, "\"\r\n\\", $this->position);
$data .= substr($this->data, $this->position, $length);
$this->position += $length;
// Check edge cases
switch ($this->data[$this->position++] ?? null) {
// End of part, saves a checkpoint and attempts to read a new part
case '"':
$checkpoint = $this->readWhitespace();
$isNewPart = true;
break;
case '\\':
$data .= $this->readEscape();
break;
// Unexpected newline
case "\r":
case "\n":
throw new Exception("Newline character must be escaped{$this->getErrorPosition()}");
// Unexpected end of file
case null:
throw new Exception("Expected a closing quote{$this->getErrorPosition()}");
}
}
if ($context && strlen($data) && strpbrk($data[0] . $data[strlen($data) - 1], "\r\n") && !$this->isHeader()) {
$this->addWarning("$context cannot start nor end with a newline{$this->getErrorPosition()}");
}
return $data;
}
/**
* Reads escaped data
*/
private function readEscape(): string
{
$aliasMap = ['from' => 'efnrtv"ab\\', 'to' => "\e\f\n\r\t\v\"\x07\x08\\"];
$hexDigits = '0123456789abcdefABCDEF';
switch ($char = $this->data[$this->position++] ?? "\0") {
case strpbrk($char, $aliasMap['from']) ?: '':
return $aliasMap['to'][strpos($aliasMap['from'], $char)];
case strpbrk($char, $octalDigits = '01234567'):
// GNU gettext fails with an octal above the signed char range
if (($decimal = octdec($char . $this->readCharset($octalDigits, 0, 2, 'octal'))) > 127) {
throw new Exception("Octal value out of range [0, 0177]{$this->getErrorPosition()}");
}
return chr($decimal);
case 'x':
$value = $this->readCharset($hexDigits, 1, PHP_INT_MAX, 'hexadecimal');
// GNU reads all valid hexadecimal chars, but only uses the last pair
return hex2bin(str_pad(substr($value, -2), 2, '0', STR_PAD_LEFT));
case 'U':
case 'u':
// The GNU gettext is supposed to follow the escaping sequences of C
// Curiously it doesn't support the unicode escape
$value = $this->readCharset($hexDigits, 1, $digits = $char === 'u' ? 4 : 8, 'hexadecimal');
$value = str_pad($value, $digits, '0', STR_PAD_LEFT);
return mb_convert_encoding(hex2bin($value), 'UTF-8', 'UTF-' . ($digits * 4));
}
throw new Exception("Invalid escaped character{$this->getErrorPosition()}");
}
/**
* Attempts to read and interpret a comment
*/
private function readComment(): bool
{
$this->readWhitespace();
if (!$this->readChar('#')) {
return false;
}
$type = strpbrk($this->data[$this->position] ?? '', '~|,:.') ?: '';
$this->position += strlen($type);
// Only a single space might be optionally added
$this->readChar(' ');
switch ($type) {
case '':
$data = $this->readCommentString();
$this->translation->getComments()->add($data);
break;
case '~':
if ($this->translation->getPreviousOriginal() !== null) {
throw new Exception("Inconsistent use of #~{$this->getErrorPosition()}");
}
$this->translation->disable();
$this->isDisabled = true;
break;
case '|':
if ($this->translation->getPreviousOriginal() !== null) {
throw new Exception('Cannot redeclare the previous comment #|, '
. "ensure the definitions are in the right order{$this->getErrorPosition()}");
}
$this->inPreviousPart = true;
$this->translation->setPreviousContext($this->readIdentifier('msgctxt'));
$this->translation->setPreviousOriginal($this->readIdentifier('msgid', true));
$this->translation->setPreviousPlural($this->readIdentifier('msgid_plural'));
$this->inPreviousPart = false;
break;
case ',':
$data = $this->readCommentString();
foreach (array_map('trim', explode(',', trim($data))) as $value) {
$this->translation->getFlags()->add($value);
}
break;
case ':':
$data = $this->readCommentString();
foreach (preg_split('/\s+/', trim($data)) as $value) {
if (preg_match('/^(.+)(:(\d*))?$/U', $value, $matches)) {
$line = isset($matches[3]) ? intval($matches[3]) : null;
$this->translation->getReferences()->add($matches[1], $line);
}
}
break;
case '.':
$data = $this->readCommentString();
$this->translation->getExtractedComments()->add($data);
break;
}
return true;
}
/**
* Attempts to read an identifier
*/
private function readIdentifier(string $identifier, bool $throwIfNotFound = false): ?string
{
$checkpoint = $this->readWhitespace();
if ($this->readString($identifier)) {
return $this->readQuotedString($identifier);
}
if ($throwIfNotFound) {
throw new Exception("Expected $identifier{$this->getErrorPosition()}");
}
$this->position = $checkpoint;
return null;
}
/**
* Attempts to read the context
*/
private function readContext(): bool
{
return ($data = $this->readIdentifier('msgctxt')) !== null
&& ($this->translation = $this->translation->withContext($data));
}
/**
* Reads the original message
*/
private function readOriginal(): void
{
$this->translation = $this->translation->withOriginal($this->readIdentifier('msgid', true));
}
/**
* Attempts to read the plural message
*/
private function readPlural(): bool
{
return ($data = $this->readIdentifier('msgid_plural')) !== null && $this->translation->setPlural($data);
}
/**
* Reads the translation
*/
private function readTranslation(): void
{
$this->readWhitespace();
if (!$this->readString('msgstr')) {
throw new Exception("Expected msgstr{$this->getErrorPosition()}");
}
$this->translation->translate($this->readQuotedString('msgstr'));
}
/**
* Attempts to read the pluralized translation
*/
private function readPluralTranslation(bool $throwIfNotFound = false): bool
{
$this->readWhitespace();
if (!$this->readString('msgstr')) {
if ($throwIfNotFound) {
throw new Exception("Expected indexed msgstr{$this->getErrorPosition()}");
}
return false;
}
$this->readWhitespace();
if (!$this->readChar('[')) {
throw new Exception("Expected character \"[\"{$this->getErrorPosition()}");
}
$this->readWhitespace();
$index = (int) $this->readCharset('0123456789', 1, PHP_INT_MAX, 'numeric');
$this->readWhitespace();
if (!$this->readChar(']')) {
throw new Exception("Expected character \"]\"{$this->getErrorPosition()}");
}
$translations = $this->translation->getPluralTranslations();
if (($translation = $this->translation->getTranslation()) !== null) {
array_unshift($translations, $translation);
}
if (count($translations) !== (int) $index) {
throw new Exception("The msgstr has an invalid index{$this->getErrorPosition()}");
}
$data = $this->readQuotedString('msgstr');
$translations[] = $data;
$this->translation->translate(array_shift($translations));
$this->translation->translatePlural(...$translations);
return true;
}
/**
* Setup the current translation as the header translation
*/
private function processHeader(): void
{
$this->header = $header = $this->translation;
if (count($description = $header->getComments()->toArray())) {
$this->translations->setDescription(implode("\n", $description));
}
if (count($flags = $header->getFlags()->toArray())) {
$this->translations->getFlags()->add(...$flags);
}
$headers = $this->translations->getHeaders();
if (($header->getTranslation() ?? '') !== '') {
foreach (self::readHeaders($header->getTranslation()) as $name => $value) {
$headers->set($name, $value);
}
}
$this->pluralCount = $headers->getPluralForm()[0] ?? null;
foreach (['Language', 'Plural-Forms', 'Content-Type'] as $header) {
if (($headers->get($header) ?? '') === '') {
$this->addWarning("$header header not declared or empty{$this->getErrorPosition()}");
}
}
}
/**
* Parses the translation header data into an array
*/
private function readHeaders(string $data): array
{
$headers = [];
$name = null;
foreach (explode("\n", $data) as $line) {
// Checks if it is a header definition line.
// Useful for distinguishing between header definitions and possible continuations of a header entry.
if (preg_match('/^[\w-]+:/', $line)) {
[$name, $value] = explode(':', $line, 2);
if (isset($headers[$name])) {
$this->addWarning("Header already defined{$this->getErrorPosition()}");
}
$headers[$name] = trim($value);
continue;
}
// Data without a definition
if ($name === null) {
$this->addWarning("Malformed header name{$this->getErrorPosition()}");
continue;
}
$headers[$name] .= $line;
}
return $headers;
}
/**
* Adds a warning
*/
private function addWarning(string $message): void
{
if ($this->throwOnWarning) {
throw new Exception($message);
}
$this->warnings[] = $message;
}
/**
* Checks whether the current translation is a header translation
*/
private function isHeader(): bool
{
return $this->translation->getOriginal() === '' && $this->translation->getContext() === null;
}
/**
* Retrieves the position where an error was detected
*/
private function getErrorPosition(): string
{
if ($this->displayErrorLine) {
$pieces = preg_split('/\\r\\n|\\n\\r|\\n|\\r/', substr($this->data, 0, $this->position));
$line = count($pieces);
$column = strlen(end($pieces));
return " at line {$line} column {$column}";
}
return " at byte {$this->position}";
}
}

View file

@ -5,7 +5,6 @@ namespace Gettext\Scanner;
use Exception;
use Gettext\Translation;
use Gettext\Translations;
/**
* Base class with common functions to scan files with code and get gettext translations.

View file

@ -19,6 +19,9 @@ class Translation
protected $flags;
protected $comments;
protected $extractedComments;
protected $previousContext;
protected $previousOriginal;
protected $previousPlural;
public static function create(?string $context, string $original): Translation
{
@ -64,6 +67,9 @@ class Translation
'plural' => $this->plural,
'pluralTranslations' => $this->pluralTranslations,
'disabled' => $this->disabled,
'previousContext' => $this->previousContext,
'previousOriginal' => $this->previousOriginal,
'previousPlural' => $this->previousPlural,
'references' => $this->getReferences()->toArray(),
'flags' => $this->getFlags()->toArray(),
'comments' => $this->getComments()->toArray(),
@ -116,6 +122,42 @@ class Translation
return $this->plural;
}
public function setPreviousOriginal(?string $previousOriginal): self
{
$this->previousOriginal = $previousOriginal;
return $this;
}
public function getPreviousOriginal(): ?string
{
return $this->previousOriginal;
}
public function setPreviousContext(?string $previousContext): self
{
$this->previousContext = $previousContext;
return $this;
}
public function getPreviousContext(): ?string
{
return $this->previousContext;
}
public function setPreviousPlural(?string $previousPlural): self
{
$this->previousPlural = $previousPlural;
return $this;
}
public function getPreviousPlural(): ?string
{
return $this->previousPlural;
}
public function disable(bool $disabled = true): self
{
$this->disabled = $disabled;
@ -225,6 +267,18 @@ class Translation
$merged->plural = $translation->plural;
}
if (!$merged->previousContext || ($translation->previousContext && $override)) {
$merged->previousContext = $translation->previousContext;
}
if (!$merged->previousOriginal || ($translation->previousOriginal && $override)) {
$merged->previousOriginal = $translation->previousOriginal;
}
if (!$merged->previousPlural || ($translation->previousPlural && $override)) {
$merged->previousPlural = $translation->previousPlural;
}
if (empty($merged->pluralTranslations) || (!empty($translation->pluralTranslations) && $override)) {
$merged->pluralTranslations = $translation->pluralTranslations;
}

View file

@ -125,11 +125,7 @@ class Translations implements Countable, IteratorAggregate
public function remove(Translation $translation): self
{
$key = array_search($translation, $this->translations);
if ($key !== false) {
unset($this->translations[$key]);
}
unset($this->translations[$translation->getId()]);
return $this;
}
@ -168,13 +164,12 @@ class Translations implements Countable, IteratorAggregate
public function find(?string $context, string $original): ?Translation
{
foreach ($this->translations as $translation) {
if ($translation->getContext() === $context && $translation->getOriginal() === $original) {
return $translation;
}
}
return $this->translations[(Translation::create($context, $original))->getId()] ?? null;
}
return null;
public function has(Translation $translation): bool
{
return (bool) ($this->translations[$translation->getId()] ?? false);
}
public function mergeWith(Translations $translations, int $strategy = 0): Translations

View file

@ -48,8 +48,8 @@ class ExecutableFinder
*/
public function find(string $name, string $default = null, array $extraDirs = [])
{
if (ini_get('open_basedir')) {
$searchPath = array_merge(explode(\PATH_SEPARATOR, ini_get('open_basedir')), $extraDirs);
if (\ini_get('open_basedir')) {
$searchPath = array_merge(explode(\PATH_SEPARATOR, \ini_get('open_basedir')), $extraDirs);
$dirs = [];
foreach ($searchPath as $path) {
// Silencing against https://bugs.php.net/69240

View file

@ -104,7 +104,7 @@ abstract class AbstractPipes implements PipesInterface
stream_set_blocking($input, 0);
} elseif (!isset($this->inputBuffer[0])) {
if (!\is_string($input)) {
if (!is_scalar($input)) {
if (!\is_scalar($input)) {
throw new InvalidArgumentException(sprintf('"%s" yielded a value of type "%s", but only scalars and stream resources are supported.', get_debug_type($this->input), get_debug_type($input)));
}
$input = (string) $input;

View file

@ -48,7 +48,7 @@ class ProcessUtils
if (\is_string($input)) {
return $input;
}
if (is_scalar($input)) {
if (\is_scalar($input)) {
return (string) $input;
}
if ($input instanceof Process) {