Upgrade to 3.4.1

This commit is contained in:
Bastian Allgeier
2020-08-04 15:56:15 +02:00
parent f2f3bb96c0
commit 68078dd107
33 changed files with 328 additions and 318 deletions

View File

@@ -1,58 +0,0 @@
<?php
$finder = PhpCsFixer\Finder::create()
->exclude('dependencies')
->in(__DIR__);
return PhpCsFixer\Config::create()
->setRules([
'@PSR1' => true,
'@PSR2' => true,
'align_multiline_comment' => ['comment_type' => 'phpdocs_like'],
'array_indentation' => true,
'array_syntax' => ['syntax' => 'short'],
'cast_spaces' => ['space' => 'none'],
// 'class_keyword_remove' => true, // replaces static::class with 'static' (won't work)
'combine_consecutive_issets' => true,
'combine_consecutive_unsets' => true,
'combine_nested_dirname' => true,
'concat_space' => ['spacing' => 'one'],
'declare_equal_normalize' => ['space' => 'single'],
'dir_constant' => true,
'function_typehint_space' => true,
'include' => true,
'logical_operators' => true,
'lowercase_cast' => true,
'lowercase_static_reference' => true,
'magic_constant_casing' => true,
'magic_method_casing' => true,
'method_chaining_indentation' => true,
'modernize_types_casting' => true,
'multiline_comment_opening_closing' => true,
'native_function_casing' => true,
'native_function_type_declaration_casing' => true,
'new_with_braces' => true,
'no_blank_lines_after_class_opening' => true,
'no_blank_lines_after_phpdoc' => true,
'no_empty_comment' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
'no_leading_namespace_whitespace' => true,
'no_mixed_echo_print' => ['use' => 'echo'],
'no_unneeded_control_parentheses' => true,
'no_unused_imports' => true,
'no_useless_return' => true,
'ordered_imports' => ['sort_algorithm' => 'alpha'],
// 'phpdoc_add_missing_param_annotation' => ['only_untyped' => false], // adds params in the wrong order
'phpdoc_align' => ['align' => 'left'],
'phpdoc_indent' => true,
'phpdoc_scalar' => true,
'phpdoc_trim' => true,
'short_scalar_cast' => true,
'single_line_comment_style' => true,
'single_quote' => true,
'ternary_to_null_coalescing' => true,
'whitespace_after_comma_in_array' => true
])
->setRiskyAllowed(true)
->setFinder($finder);

View File

@@ -1,7 +1,7 @@
## ##
## Bundle of CA Root Certificates ## Bundle of CA Root Certificates
## ##
## Certificate data from Mozilla as of: Wed Jun 24 03:12:10 2020 GMT ## Certificate data from Mozilla as of: Wed Jul 22 03:12:14 2020 GMT
## ##
## This is a bundle of X.509 certificates of public Certificate Authorities ## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates ## (CA). These were automatically extracted from Mozilla's root certificates
@@ -14,7 +14,7 @@
## Just configure this file as the SSLCACertificateFile. ## Just configure this file as the SSLCACertificateFile.
## ##
## Conversion done with mk-ca-bundle.pl version 1.28. ## Conversion done with mk-ca-bundle.pl version 1.28.
## SHA256: 5796295533cad5a648a20a115b0894dc9b318c41501796e7158e824c323f11c3 ## SHA256: cc6408bd4be7fbfb8699bdb40ccb7f6de5780d681d87785ea362646e4dad5e8e
## ##
@@ -61,30 +61,6 @@ BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
-----END CERTIFICATE----- -----END CERTIFICATE-----
Verisign Class 3 Public Primary Certification Authority - G3
============================================================
-----BEGIN CERTIFICATE-----
MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1
EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc
cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw
EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj
055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f
j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0
xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa
t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
-----END CERTIFICATE-----
Entrust.net Premium 2048 Secure Server CA Entrust.net Premium 2048 Secure Server CA
========================================= =========================================
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
@@ -130,30 +106,6 @@ Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H
RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE----- -----END CERTIFICATE-----
AddTrust External Root
======================
-----BEGIN CERTIFICATE-----
MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD
VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw
NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU
cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg
Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821
+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw
Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo
aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy
2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7
7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P
BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL
VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk
VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB
IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl
j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355
e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u
G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
-----END CERTIFICATE-----
Entrust Root Certification Authority Entrust Root Certification Authority
==================================== ====================================
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
@@ -1126,38 +1078,6 @@ NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu
dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
-----END CERTIFICATE----- -----END CERTIFICATE-----
Staat der Nederlanden Root CA - G2
==================================
-----BEGIN CERTIFICATE-----
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
66+KAQ==
-----END CERTIFICATE-----
Hongkong Post Root CA 1 Hongkong Post Root CA 1
======================= =======================
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
@@ -2831,37 +2751,6 @@ MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1
AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA== AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA==
-----END CERTIFICATE----- -----END CERTIFICATE-----
LuxTrust Global Root 2
======================
-----BEGIN CERTIFICATE-----
MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQELBQAwRjELMAkG
A1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNVBAMMFkx1eFRydXN0IEdsb2Jh
bCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUwMzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEW
MBQGA1UECgwNTHV4VHJ1c3QgUy5BLjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCC
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wm
Kb3FibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTemhfY7RBi2
xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1EMShduxq3sVs35a0VkBC
wGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsnXpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm
1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkm
FRseTJIpgp7VkoGSQXAZ96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niF
wpN6cj5mj5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4gDEa/
a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+8kPREd8vZS9kzl8U
ubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2jX5t/Lax5Gw5CMZdjpPuKadUiDTSQ
MC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmHhFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB
/zBCBgNVHSAEOzA5MDcGByuBKwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5
Lmx1eHRydXN0Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT
+Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQELBQADggIBAGoZ
FO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9BzZAcg4atmpZ1gDlaCDdLnIN
H2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTOjFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW
7MM3LGVYvlcAGvI1+ut7MV3CwRI9loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIu
ZY+kt9J/Z93I055cqqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWA
VWe+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/JEAdemrR
TxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKrezrnK+T+Tb/mjuuqlPpmt
/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQfLSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc
7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31I
iyBMz2TWuJdGsE7RKlY6oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr
-----END CERTIFICATE-----
TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1
============================================= =============================================
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
@@ -3464,3 +3353,95 @@ JOgc47OlIQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk5F6G
+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuYn/PIjhs4ViFqUZPT +TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuYn/PIjhs4ViFqUZPT
kcpG2om3PVODLAgfi49T3f+sHw== kcpG2om3PVODLAgfi49T3f+sHw==
-----END CERTIFICATE----- -----END CERTIFICATE-----
Microsoft ECC Root Certificate Authority 2017
=============================================
-----BEGIN CERTIFICATE-----
MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV
UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQgRUND
IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4
MjMxNjA0WjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw
NAYDVQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQ
BgcqhkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZRogPZnZH6
thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYbhGBKia/teQ87zvH2RPUB
eMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIy5lycFIM
+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlf
Xu5gKcs68tvWMoQZP3zVL8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaR
eNtUjGUBiudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M=
-----END CERTIFICATE-----
Microsoft RSA Root Certificate Authority 2017
=============================================
-----BEGIN CERTIFICATE-----
MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBlMQswCQYDVQQG
EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQg
UlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIw
NzE4MjMwMDIzWjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u
MTYwNAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcw
ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZNt9GkMml
7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0ZdDMbRnMlfl7rEqUrQ7e
S0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw7
1VdyvD/IybLeS2v4I2wDwAW9lcfNcztmgGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+
dkC0zVJhUXAoP8XFWvLJjEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49F
yGcohJUcaDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaGYaRS
MLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6W6IYZVcSn2i51BVr
lMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4KUGsTuqwPN1q3ErWQgR5WrlcihtnJ
0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJ
ClTUFLkqqNfs+avNJVgyeY+QW5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYw
DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC
NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZCLgLNFgVZJ8og
6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OCgMNPOsduET/m4xaRhPtthH80
dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk
+ONVFT24bcMKpBLBaYVu32TxU5nhSnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex
/2kskZGT4d9Mozd2TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDy
AmH3pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGRxpl/j8nW
ZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiAppGWSZI1b7rCoucL5mxAyE
7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKT
c0QWbej09+CVgI+WXTik9KveCjCHk9hNAHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D
5KbvtwEwXlGjefVwaaZBRA+GsCyRxj3qrg+E
-----END CERTIFICATE-----
e-Szigno Root CA 2017
=====================
-----BEGIN CERTIFICATE-----
MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNVBAYTAkhVMREw
DwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUt
MjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJvb3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZa
Fw00MjA4MjIxMjA3MDZaMHExCzAJBgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UE
CgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3pp
Z25vIFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtvxie+RJCx
s1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+HWyx7xf58etqjYzBhMA8G
A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSHERUI0arBeAyxr87GyZDv
vzAEwDAfBgNVHSMEGDAWgBSHERUI0arBeAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEA
tVfd14pVCzbhhkT61NlojbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxO
svxyqltZ+efcMQ==
-----END CERTIFICATE-----
certSIGN Root CA G2
===================
-----BEGIN CERTIFICATE-----
MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNVBAYTAlJPMRQw
EgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjAeFw0xNzAy
MDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJBgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lH
TiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
ADCCAgoCggIBAMDFdRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05
N0IwvlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZuIt4Imfk
abBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhpn+Sc8CnTXPnGFiWeI8Mg
wT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKscpc/I1mbySKEwQdPzH/iV8oScLumZfNp
dWO9lfsbl83kqK/20U6o2YpxJM02PbyWxPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91Qqh
ngLjYl/rNUssuHLoPj1PrCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732
jcZZroiFDsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fxDTvf
95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgyLcsUDFDYg2WD7rlc
z8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6CeWRgKRM+o/1Pcmqr4tTluCRVLERL
iohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1Ud
DgQWBBSCIS1mxteg4BXrzkwJd8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOB
ywaK8SJJ6ejqkX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC
b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQlqiCA2ClV9+BB
/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0OJD7uNGzcgbJceaBxXntC6Z5
8hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+cNywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5
BiKDUyUM/FHE5r7iOZULJK2v0ZXkltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklW
atKcsWMy5WHgUyIOpwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tU
Sxfj03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZkPuXaTH4M
NMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE1LlSVHJ7liXMvGnjSG4N
0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MXQRBdJ3NghVdJIgc=
-----END CERTIFICATE-----

View File

@@ -1,7 +1,7 @@
{ {
"name": "getkirby/cms", "name": "getkirby/cms",
"description": "The Kirby 3 core", "description": "The Kirby 3 core",
"version": "3.4.0", "version": "3.4.1",
"license": "proprietary", "license": "proprietary",
"keywords": ["kirby", "cms", "core"], "keywords": ["kirby", "cms", "core"],
"homepage": "https://getkirby.com", "homepage": "https://getkirby.com",

14
kirby/composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "8ec61411e7f3b3a717572d0847654a96", "content-hash": "4b96abb049f7a25f83ad2bda07040ecc",
"packages": [ "packages": [
{ {
"name": "claviska/simpleimage", "name": "claviska/simpleimage",
@@ -510,16 +510,16 @@
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.17.1", "version": "v1.18.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git", "url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "7110338d81ce1cbc3e273136e4574663627037a7" "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7110338d81ce1cbc3e273136e4574663627037a7", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/a6977d63bf9a0ad4c65cd352709e230876f9904a",
"reference": "7110338d81ce1cbc3e273136e4574663627037a7", "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -531,7 +531,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.17-dev" "dev-master": "1.18-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@@ -569,7 +569,7 @@
"portable", "portable",
"shim" "shim"
], ],
"time": "2020-06-06T08:46:27+00:00" "time": "2020-07-14T12:35:20+00:00"
}, },
{ {
"name": "true/punycode", "name": "true/punycode",

View File

@@ -165,20 +165,21 @@ return [
$options = array_merge($defaults, $params); $options = array_merge($defaults, $params);
$collection = clone $collection; $collection = clone $collection;
$searchwords = preg_replace('/(\s)/u', ',', $query); $searchWords = preg_replace('/(\s)/u', ',', $query);
$searchwords = Str::split($searchwords, ',', $options['minlength']); $searchWords = Str::split($searchWords, ',', $options['minlength']);
$lowerQuery = mb_strtolower($query); $lowerQuery = Str::lower($query);
$exactQuery = $options['words'] ? '(\b' . preg_quote($query) . '\b)' : preg_quote($query);
if (empty($options['stopwords']) === false) { if (empty($options['stopwords']) === false) {
$searchwords = array_diff($searchwords, $options['stopwords']); $searchWords = array_diff($searchWords, $options['stopwords']);
} }
$searchwords = array_map(function ($value) use ($options) { $searchWords = array_map(function ($value) use ($options) {
return $options['words'] ? '\b' . preg_quote($value) . '\b' : preg_quote($value); return $options['words'] ? '\b' . preg_quote($value) . '\b' : preg_quote($value);
}, $searchwords); }, $searchWords);
$preg = '!(' . implode('|', $searchwords) . ')!i'; $preg = '!(' . implode('|', $searchWords) . ')!i';
$results = $collection->filter(function ($item) use ($query, $preg, $options, $lowerQuery) { $results = $collection->filter(function ($item) use ($query, $preg, $options, $lowerQuery, $exactQuery) {
$data = $item->content()->toArray(); $data = $item->content()->toArray();
$keys = array_keys($data); $keys = array_keys($data);
$keys[] = 'id'; $keys[] = 'id';
@@ -207,7 +208,7 @@ return [
$score = $options['score'][$key] ?? 1; $score = $options['score'][$key] ?? 1;
$value = $data[$key] ?? (string)$item->$key(); $value = $data[$key] ?? (string)$item->$key();
$lowerValue = mb_strtolower($value); $lowerValue = Str::lower($value);
// check for exact matches // check for exact matches
if ($lowerQuery == $lowerValue) { if ($lowerQuery == $lowerValue) {
@@ -215,12 +216,12 @@ return [
$item->searchHits += 1; $item->searchHits += 1;
// check for exact beginning matches // check for exact beginning matches
} elseif (Str::startsWith($lowerValue, $lowerQuery) === true) { } elseif ($options['words'] === false && Str::startsWith($lowerValue, $lowerQuery) === true) {
$item->searchScore += 8 * $score; $item->searchScore += 8 * $score;
$item->searchHits += 1; $item->searchHits += 1;
// check for exact query matches // check for exact query matches
} elseif ($matches = preg_match_all('!' . preg_quote($query) . '!i', $value, $r)) { } elseif ($matches = preg_match_all('!' . $exactQuery . '!i', $value, $r)) {
$item->searchScore += 2 * $score; $item->searchScore += 2 * $score;
$item->searchHits += $matches; $item->searchHits += $matches;
} }

View File

@@ -5,6 +5,7 @@ return [
'date' => __DIR__ . '/fields/date.php', 'date' => __DIR__ . '/fields/date.php',
'email' => __DIR__ . '/fields/email.php', 'email' => __DIR__ . '/fields/email.php',
'files' => __DIR__ . '/fields/files.php', 'files' => __DIR__ . '/fields/files.php',
'gap' => __DIR__ . '/fields/gap.php',
'headline' => __DIR__ . '/fields/headline.php', 'headline' => __DIR__ . '/fields/headline.php',
'hidden' => __DIR__ . '/fields/hidden.php', 'hidden' => __DIR__ . '/fields/hidden.php',
'info' => __DIR__ . '/fields/info.php', 'info' => __DIR__ . '/fields/info.php',

5
kirby/config/fields/gap.php Executable file
View File

@@ -0,0 +1,5 @@
<?php
return [
'save' => false
];

View File

@@ -110,9 +110,9 @@ return [
if (empty($this->columns)) { if (empty($this->columns)) {
foreach ($this->fields as $field) { foreach ($this->fields as $field) {
// Skip hidden fields. // Skip hidden and unsaveable fields
// They should never be included as column // They should never be included as column
if ($field['type'] === 'hidden') { if ($field['type'] === 'hidden' || $field['saveable'] === false) {
continue; continue;
} }
@@ -129,7 +129,7 @@ return [
$field = $this->fields[$columnName] ?? null; $field = $this->fields[$columnName] ?? null;
if (empty($field) === true) { if (empty($field) === true || $field['saveable'] === false) {
continue; continue;
} }
@@ -181,7 +181,7 @@ return [
$data = []; $data = [];
foreach ($value as $row) { foreach ($value as $row) {
$data[] = $this->form($row)->data(); $data[] = $this->form($row)->content();
} }
return $data; return $data;

9
kirby/panel/dist/favicon.svg vendored Executable file
View File

@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 42">
<style>
path { fill: #000000; }
@media (prefers-color-scheme: dark) {
path { fill: #ffffff; }
}
</style>
<path d="M18 0l18 10.498v21.004L18 42 0 31.502V10.498L18 0zM2 11.693v18.614l16 9.332 16-9.332V11.693L18 2.36 2 11.693z"/><path d="M26 21l-5 2.59V24h5v4H10v-4h5v-.437L10 21v-5l8 4.297L26 16"/>
</svg>

After

Width:  |  Height:  |  Size: 388 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,23 +0,0 @@
module.exports = {
moduleFileExtensions: [
'js',
'jsx',
'json',
'vue'
],
transform: {
'^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
'^.+\\.jsx?$': 'babel-jest'
},
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
snapshotSerializers: [
'jest-serializer-vue'
],
testMatch: [
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
],
testURL: 'http://localhost/'
}

View File

@@ -1,21 +0,0 @@
parameters:
paths:
- %currentWorkingDirectory%
autoload_files:
- %currentWorkingDirectory%/vendor/autoload.php
- %rootDir%/../../autoload.php
autoload_directories:
- %currentWorkingDirectory%/tests
excludes_analyse:
- %currentWorkingDirectory%/dependencies
- %currentWorkingDirectory%/tests/*/fixtures/*
- %currentWorkingDirectory%/vendor
- %currentWorkingDirectory%/views
level: 0
memory_limit: 2G
ignoreErrors:
# we use bound $this in our callbacks
- message: '#(Using \$this outside a class\.|Undefined variable: \$this)#'
path: %currentWorkingDirectory%/config

View File

@@ -75,14 +75,6 @@ class App
protected $users; protected $users;
protected $visitor; protected $visitor;
/**
* List of options that shouldn't be converted
* to a tree structure by dot syntax
*
* @var array
*/
public static $nestIgnoreOptions = ['hooks'];
/** /**
* Creates a new App instance * Creates a new App instance
* *
@@ -127,13 +119,8 @@ class App
$this->extensionsFromSystem(); $this->extensionsFromSystem();
$this->extensionsFromProps($props); $this->extensionsFromProps($props);
$this->extensionsFromPlugins(); $this->extensionsFromPlugins();
$this->extensionsFromFolders();
// bake the options for the first time
$this->bakeOptions();
// register the extensions from the normalized options
$this->extensionsFromOptions(); $this->extensionsFromOptions();
$this->extensionsFromFolders();
// trigger hook for use in plugins // trigger hook for use in plugins
$this->trigger('system.loadPlugins:after'); $this->trigger('system.loadPlugins:after');
@@ -141,7 +128,7 @@ class App
// execute a ready callback from the config // execute a ready callback from the config
$this->optionsFromReadyCallback(); $this->optionsFromReadyCallback();
// bake the options again with those from the ready callback // bake config
$this->bakeOptions(); $this->bakeOptions();
} }
@@ -238,7 +225,30 @@ class App
*/ */
protected function bakeOptions() protected function bakeOptions()
{ {
$this->options = A::nest($this->options, static::$nestIgnoreOptions); // convert the old plugin option syntax to the new one
foreach ($this->options as $key => $value) {
// detect option keys with the `vendor.plugin.option` format
if (preg_match('/^([a-z0-9-]+\.[a-z0-9-]+)\.(.*)$/i', $key, $matches) === 1) {
list(, $plugin, $option) = $matches;
// verify that it's really a plugin option
if (isset(static::$plugins[str_replace('.', '/', $plugin)]) !== true) {
continue;
}
// ensure that the target option array exists
// (which it will if the plugin has any options)
if (isset($this->options[$plugin]) !== true) {
$this->options[$plugin] = []; // @codeCoverageIgnore
}
// move the option to the plugin option array
// don't overwrite nested arrays completely but merge them
$this->options[$plugin] = array_replace_recursive($this->options[$plugin], [$option => $value]);
unset($this->options[$key]);
}
}
Config::$data = $this->options; Config::$data = $this->options;
return $this; return $this;
} }

View File

@@ -292,19 +292,9 @@ trait AppPlugins
protected function extendOptions(array $options, Plugin $plugin = null): array protected function extendOptions(array $options, Plugin $plugin = null): array
{ {
if ($plugin !== null) { if ($plugin !== null) {
$prefixed = []; $options = [$plugin->prefix() => $options];
foreach ($options as $key => $value) {
$prefixed[$plugin->prefix() . '.' . $key] = $value;
}
$options = $prefixed;
} }
// register each option in the nesting blacklist;
// this prevents Kirby from nesting the array keys inside each option
static::$nestIgnoreOptions = array_merge(static::$nestIgnoreOptions, array_keys($options));
return $this->extensions['options'] = $this->options = A::merge($options, $this->options, A::MERGE_REPLACE); return $this->extensions['options'] = $this->options = A::merge($options, $this->options, A::MERGE_REPLACE);
} }

View File

@@ -6,6 +6,7 @@ use Kirby\Data\Data;
use Kirby\Exception\InvalidArgumentException; use Kirby\Exception\InvalidArgumentException;
use Kirby\Exception\NotFoundException; use Kirby\Exception\NotFoundException;
use Kirby\Exception\PermissionException; use Kirby\Exception\PermissionException;
use Kirby\Http\Idn;
use Kirby\Http\Request\Auth\BasicAuth; use Kirby\Http\Request\Auth\BasicAuth;
use Kirby\Toolkit\F; use Kirby\Toolkit\F;
use Throwable; use Throwable;
@@ -256,6 +257,9 @@ class Auth
*/ */
public function validatePassword(string $email, string $password) public function validatePassword(string $email, string $password)
{ {
// ensure that email addresses with IDN domains are in Unicode format
$email = Idn::decodeEmail($email);
// check for blocked ips // check for blocked ips
if ($this->isBlocked($email) === true) { if ($this->isBlocked($email) === true) {
if ($this->kirby->option('debug') === true) { if ($this->kirby->option('debug') === true) {

View File

@@ -95,7 +95,7 @@ class LanguageRoutes
} }
} }
return $kirby->defaultLanguage()->router()->call($path); return $kirby->language()->router()->call($path);
} }
]; ];
} }

View File

@@ -329,7 +329,7 @@ trait PageActions
if ($action === 'create') { if ($action === 'create') {
$argumentsAfter = ['page' => $result]; $argumentsAfter = ['page' => $result];
} elseif ($action === 'duplicate') { } elseif ($action === 'duplicate') {
$argumentsAfter = ['duplicatePage' => $result]; $argumentsAfter = ['duplicatePage' => $result, 'originalPage' => $old];
} elseif ($action === 'delete') { } elseif ($action === 'delete') {
$argumentsAfter = ['status' => $result, 'page' => $old]; $argumentsAfter = ['status' => $result, 'page' => $old];
} else { } else {

View File

@@ -5,7 +5,6 @@ namespace Kirby\Cms;
use Exception; use Exception;
use Kirby\Exception\InvalidArgumentException; use Kirby\Exception\InvalidArgumentException;
use Kirby\Exception\NotFoundException; use Kirby\Exception\NotFoundException;
use Kirby\Session\Session;
use Kirby\Toolkit\F; use Kirby\Toolkit\F;
use Kirby\Toolkit\Str; use Kirby\Toolkit\Str;
@@ -764,7 +763,7 @@ class User extends ModelWithContent
protected function setEmail(string $email = null) protected function setEmail(string $email = null)
{ {
if ($email !== null) { if ($email !== null) {
$this->email = strtolower(trim($email)); $this->email = Str::lower(trim($email));
} }
return $this; return $this;
} }
@@ -825,7 +824,7 @@ class User extends ModelWithContent
*/ */
protected function setRole(string $role = null) protected function setRole(string $role = null)
{ {
$this->role = $role !== null ? strtolower(trim($role)) : null; $this->role = $role !== null ? Str::lower(trim($role)) : null;
return $this; return $this;
} }

View File

@@ -6,6 +6,7 @@ use Closure;
use Kirby\Data\Data; use Kirby\Data\Data;
use Kirby\Exception\LogicException; use Kirby\Exception\LogicException;
use Kirby\Exception\PermissionException; use Kirby\Exception\PermissionException;
use Kirby\Http\Idn;
use Kirby\Toolkit\Dir; use Kirby\Toolkit\Dir;
use Kirby\Toolkit\F; use Kirby\Toolkit\F;
use Kirby\Toolkit\Str; use Kirby\Toolkit\Str;
@@ -29,7 +30,7 @@ trait UserActions
*/ */
public function changeEmail(string $email) public function changeEmail(string $email)
{ {
return $this->commit('changeEmail', ['user' => $this, 'email' => $email], function ($user, $email) { return $this->commit('changeEmail', ['user' => $this, 'email' => Idn::decodeEmail($email)], function ($user, $email) {
$user = $user->clone([ $user = $user->clone([
'email' => $email 'email' => $email
]); ]);
@@ -176,6 +177,10 @@ trait UserActions
{ {
$data = $props; $data = $props;
if (isset($props['email']) === true) {
$data['email'] = Idn::decodeEmail($props['email']);
}
if (isset($props['password']) === true) { if (isset($props['password']) === true) {
$data['password'] = User::hashPassword($props['password']); $data['password'] = User::hashPassword($props['password']);
} }

View File

@@ -87,7 +87,7 @@ class Users extends Collection
public function findByKey(string $key) public function findByKey(string $key)
{ {
if (Str::contains($key, '@') === true) { if (Str::contains($key, '@') === true) {
return parent::findBy('email', strtolower($key)); return parent::findBy('email', Str::lower($key));
} }
return parent::findByKey($key); return parent::findByKey($key);

View File

@@ -2,6 +2,7 @@
namespace Kirby\Email; namespace Kirby\Email;
use Closure;
use Exception; use Exception;
use Kirby\Toolkit\Properties; use Kirby\Toolkit\Properties;
use Kirby\Toolkit\V; use Kirby\Toolkit\V;
@@ -23,6 +24,7 @@ class Email
protected $attachments; protected $attachments;
protected $body; protected $body;
protected $bcc; protected $bcc;
protected $beforeSend;
protected $cc; protected $cc;
protected $from; protected $from;
protected $fromName; protected $fromName;
@@ -60,6 +62,11 @@ class Email
return $this->bcc; return $this->bcc;
} }
public function beforeSend(): ?Closure
{
return $this->beforeSend;
}
public function cc(): array public function cc(): array
{ {
return $this->cc; return $this->cc;
@@ -159,6 +166,12 @@ class Email
return $this; return $this;
} }
protected function setBeforeSend(?Closure $beforeSend = null)
{
$this->beforeSend = $beforeSend;
return $this;
}
protected function setCc($cc = null) protected function setCc($cc = null)
{ {
$this->cc = $this->resolveEmail($cc); $this->cc = $this->resolveEmail($cc);

View File

@@ -2,6 +2,7 @@
namespace Kirby\Email; namespace Kirby\Email;
use Kirby\Exception\InvalidArgumentException;
use PHPMailer\PHPMailer\PHPMailer as Mailer; use PHPMailer\PHPMailer\PHPMailer as Mailer;
/** /**
@@ -67,6 +68,17 @@ class PHPMailer extends Email
$mailer->Port = $this->transport()['port'] ?? null; $mailer->Port = $this->transport()['port'] ?? null;
} }
// accessible phpMailer instance
$beforeSend = $this->beforeSend();
if (empty($beforeSend) === false && is_a($beforeSend, 'Closure') === true) {
$mailer = $beforeSend->call($this, $mailer) ?? $mailer;
if (is_a($mailer, 'PHPMailer\PHPMailer\PHPMailer') === false) {
throw new InvalidArgumentException('"beforeSend" option return should be instance of PHPMailer\PHPMailer\PHPMailer class');
}
}
if ($debug === true) { if ($debug === true) {
return $this->isSent = true; return $this->isSent = true;
} }

View File

@@ -284,8 +284,9 @@ class Field extends Component
unset($array['model']); unset($array['model']);
$array['invalid'] = $this->isInvalid();
$array['errors'] = $this->errors(); $array['errors'] = $this->errors();
$array['invalid'] = $this->isInvalid();
$array['saveable'] = $this->save();
$array['signature'] = md5(json_encode($array)); $array['signature'] = md5(json_encode($array));
ksort($array); ksort($array);

View File

@@ -85,13 +85,22 @@ class Form
} }
} }
public function data($defaults = false): array public function content(): array
{
return $this->data(false, false);
}
public function data($defaults = false, bool $includeNulls = true): array
{ {
$data = $this->values; $data = $this->values;
foreach ($this->fields as $field) { foreach ($this->fields as $field) {
if ($field->save() === false || $field->unset() === true) { if ($field->save() === false || $field->unset() === true) {
$data[$field->name()] = null; if ($includeNulls === true) {
$data[$field->name()] = null;
} else {
unset($data[$field->name()]);
}
} else { } else {
$data[$field->name()] = $field->data($defaults); $data[$field->name()] = $field->data($defaults);
} }

View File

@@ -2,6 +2,7 @@
namespace Kirby\Http; namespace Kirby\Http;
use Kirby\Toolkit\Str;
use TrueBV\Punycode; use TrueBV\Punycode;
/** /**
@@ -24,4 +25,40 @@ class Idn
{ {
return (new Punycode())->encode($domain); return (new Punycode())->encode($domain);
} }
/**
* Decodes a email address to the Unicode format
*
* @param string $email
* @return string
*/
public static function decodeEmail(string $email): string
{
if (Str::contains($email, 'xn--') === true) {
$parts = Str::split($email, '@');
$address = $parts[0];
$domain = Idn::decode($parts[1] ?? '');
$email = $address . '@' . $domain;
}
return $email;
}
/**
* Encodes a email address to the Punycode format
*
* @param string $email
* @return string
*/
public static function encodeEmail(string $email): string
{
if (mb_detect_encoding($email, 'ASCII', true) === false) {
$parts = Str::split($email, '@');
$address = $parts[0];
$domain = Idn::encode($parts[1] ?? '');
$email = $address . '@' . $domain;
}
return $email;
}
} }

View File

@@ -177,19 +177,25 @@ class Remote
]; ];
// determine the TLS CA to use // determine the TLS CA to use
if (is_file($this->options['ca']) === true) { if ($this->options['ca'] === self::CA_INTERNAL) {
$this->curlopt[CURLOPT_SSL_VERIFYPEER] = true;
$this->curlopt[CURLOPT_CAINFO] = $this->options['ca'];
} elseif (is_dir($this->options['ca']) === true) {
$this->curlopt[CURLOPT_SSL_VERIFYPEER] = true;
$this->curlopt[CURLOPT_CAPATH] = $this->options['ca'];
} elseif ($this->options['ca'] === self::CA_INTERNAL) {
$this->curlopt[CURLOPT_SSL_VERIFYPEER] = true; $this->curlopt[CURLOPT_SSL_VERIFYPEER] = true;
$this->curlopt[CURLOPT_CAINFO] = dirname(__DIR__, 2) . '/cacert.pem'; $this->curlopt[CURLOPT_CAINFO] = dirname(__DIR__, 2) . '/cacert.pem';
} elseif ($this->options['ca'] === self::CA_SYSTEM) { } elseif ($this->options['ca'] === self::CA_SYSTEM) {
$this->curlopt[CURLOPT_SSL_VERIFYPEER] = true; $this->curlopt[CURLOPT_SSL_VERIFYPEER] = true;
} elseif ($this->options['ca'] === false) { } elseif ($this->options['ca'] === false) {
$this->curlopt[CURLOPT_SSL_VERIFYPEER] = false; $this->curlopt[CURLOPT_SSL_VERIFYPEER] = false;
} elseif (
is_string($this->options['ca']) === true &&
is_file($this->options['ca']) === true
) {
$this->curlopt[CURLOPT_SSL_VERIFYPEER] = true;
$this->curlopt[CURLOPT_CAINFO] = $this->options['ca'];
} elseif (
is_string($this->options['ca']) === true &&
is_dir($this->options['ca']) === true
) {
$this->curlopt[CURLOPT_SSL_VERIFYPEER] = true;
$this->curlopt[CURLOPT_CAPATH] = $this->options['ca'];
} else { } else {
throw new InvalidArgumentException('Invalid "ca" option for the Remote class'); throw new InvalidArgumentException('Invalid "ca" option for the Remote class');
} }

View File

@@ -376,7 +376,7 @@ class Request
/** /**
* Returns the Query object * Returns the Query object
* *
* @return \Kirby\Http\Query * @return \Kirby\Http\Request\Query
*/ */
public function query() public function query()
{ {

View File

@@ -55,6 +55,26 @@ class Query
return $this->data; return $this->data;
} }
/**
* Returns `true` if the request doesn't contain query variables
*
* @return bool
*/
public function isEmpty(): bool
{
return empty($this->data) === true;
}
/**
* Returns `true` if the request contains query variables
*
* @return bool
*/
public function isNotEmpty(): bool
{
return empty($this->data) === false;
}
/** /**
* Converts the query data array * Converts the query data array
* back to a query string * back to a query string

View File

@@ -185,7 +185,7 @@ class Exif
* *
* @return bool|null * @return bool|null
*/ */
public function isBW(): bool public function isBW(): ?bool
{ {
return ($this->isColor !== null) ? $this->isColor === false : null; return ($this->isColor !== null) ? $this->isColor === false : null;
} }

View File

@@ -35,6 +35,30 @@ class Html extends Xml
*/ */
public static $void = '>'; public static $void = '>';
/**
* List of HTML tags that are considered to be self-closing
*
* @var array
*/
public static $voidList = [
'area',
'base',
'br',
'col',
'command',
'embed',
'hr',
'img',
'input',
'keygen',
'link',
'meta',
'param',
'source',
'track',
'wbr'
];
/** /**
* Generic HTML tag generator * Generic HTML tag generator
* Can be called like `Html::p('A paragraph', ['class' => 'text'])` * Can be called like `Html::p('A paragraph', ['class' => 'text'])`
@@ -260,26 +284,7 @@ class Html extends Xml
*/ */
public static function isVoid(string $tag): bool public static function isVoid(string $tag): bool
{ {
$void = [ return in_array(strtolower($tag), static::$voidList);
'area',
'base',
'br',
'col',
'command',
'embed',
'hr',
'img',
'input',
'keygen',
'link',
'meta',
'param',
'source',
'track',
'wbr',
];
return in_array(strtolower($tag), $void);
} }
/** /**
@@ -334,8 +339,8 @@ class Html extends Xml
* Builds an HTML tag * Builds an HTML tag
* *
* @param string $name Tag name * @param string $name Tag name
* @param array|string|null $content Scalar value or array with multiple lines of content or `null` to * @param array|string $content Scalar value or array with multiple lines of content; self-closing
* generate a self-closing tag; pass an empty string to generate empty content * tags are generated automatically based on the `Html::isVoid()` list
* @param array $attr An associative array with additional attributes for the tag * @param array $attr An associative array with additional attributes for the tag
* @param string|null $indent Indentation string, defaults to two spaces or `null` for output on one line * @param string|null $indent Indentation string, defaults to two spaces or `null` for output on one line
* @param int $level Indentation level * @param int $level Indentation level
@@ -343,6 +348,12 @@ class Html extends Xml
*/ */
public static function tag(string $name, $content = '', array $attr = null, string $indent = null, int $level = 0): string public static function tag(string $name, $content = '', array $attr = null, string $indent = null, int $level = 0): string
{ {
// treat an explicit `null` value as an empty tag
// as void tags are already covered below
if ($content === null) {
$content = '';
}
// force void elements to be self-closing // force void elements to be self-closing
if (static::isVoid($name) === true) { if (static::isVoid($name) === true) {
$content = null; $content = null;

View File

@@ -306,10 +306,7 @@ V::$validators = [
'email' => function ($value): bool { 'email' => function ($value): bool {
if (filter_var($value, FILTER_VALIDATE_EMAIL) === false) { if (filter_var($value, FILTER_VALIDATE_EMAIL) === false) {
try { try {
$parts = Str::split($value, '@'); $email = Idn::encodeEmail($value);
$address = $parts[0] ?? null;
$domain = Idn::encode($parts[1] ?? '');
$email = $address . '@' . $domain;
} catch (Throwable $e) { } catch (Throwable $e) {
return false; return false;
} }

View File

@@ -16,7 +16,8 @@
<?php endif ?> <?php endif ?>
<link nonce="<?= $nonce ?>" rel="apple-touch-icon" href="<?= $assetUrl ?>/apple-touch-icon.png" /> <link nonce="<?= $nonce ?>" rel="apple-touch-icon" href="<?= $assetUrl ?>/apple-touch-icon.png" />
<link nonce="<?= $nonce ?>" rel="shortcut icon" href="<?= $assetUrl ?>/favicon.png"> <link nonce="<?= $nonce ?>" rel="icon" href="<?= $assetUrl ?>/favicon.svg" type="image/svg+xml">
<link nonce="<?= $nonce ?>" rel="alternate icon" href="<?= $assetUrl ?>/favicon.png" type="image/png">
<base href="<?= $panelUrl ?>"> <base href="<?= $panelUrl ?>">
</head> </head>