⬆️ N°4824 Composer libs : update swiftmailer/swiftmailer

This commit is contained in:
Pierre Goiffon
2022-04-29 14:52:45 +02:00
parent 71ceedc4bb
commit 0ef9bb1a47
348 changed files with 46727 additions and 5172 deletions

View File

@@ -15,7 +15,7 @@
"pear/archive_tar": "~1.4.14",
"pelago/emogrifier": "~3.1.0",
"scssphp/scssphp": "~1.10.2",
"swiftmailer/swiftmailer": "5.4.12",
"swiftmailer/swiftmailer": "~6.3.0",
"symfony/console": "~3.4.47",
"symfony/dotenv": "~3.4.47",
"symfony/framework-bundle": "~3.4.47",

502
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "8187e0bd608a597a5151a468aa1f4c7a",
"content-hash": "781e902cab2de8cfdfefbb4a62cc1b01",
"packages": [
{
"name": "combodo/tcpdf",
@@ -84,6 +84,138 @@
],
"time": "2022-03-10T14:36:39+00:00"
},
{
"name": "doctrine/lexer",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/doctrine/lexer.git",
"reference": "1febd6c3ef84253d7c815bed85fc622ad207a9f8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/lexer/zipball/1febd6c3ef84253d7c815bed85fc622ad207a9f8",
"reference": "1febd6c3ef84253d7c815bed85fc622ad207a9f8",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"require-dev": {
"phpunit/phpunit": "^4.5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
"homepage": "https://www.doctrine-project.org/projects/lexer.html",
"keywords": [
"annotations",
"docblock",
"lexer",
"parser",
"php"
],
"support": {
"issues": "https://github.com/doctrine/lexer/issues",
"source": "https://github.com/doctrine/lexer/tree/1.0.2"
},
"time": "2019-06-08T11:03:04+00:00"
},
{
"name": "egulias/email-validator",
"version": "2.1.25",
"source": {
"type": "git",
"url": "https://github.com/egulias/EmailValidator.git",
"reference": "0dbf5d78455d4d6a41d186da50adc1122ec066f4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/0dbf5d78455d4d6a41d186da50adc1122ec066f4",
"reference": "0dbf5d78455d4d6a41d186da50adc1122ec066f4",
"shasum": ""
},
"require": {
"doctrine/lexer": "^1.0.1",
"php": ">=5.5",
"symfony/polyfill-intl-idn": "^1.10"
},
"require-dev": {
"dominicsayers/isemail": "^3.0.7",
"phpunit/phpunit": "^4.8.36|^7.5.15",
"satooshi/php-coveralls": "^1.0.1"
},
"suggest": {
"ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Egulias\\EmailValidator\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Eduardo Gulias Davis"
}
],
"description": "A library for validating emails against several RFCs",
"homepage": "https://github.com/egulias/EmailValidator",
"keywords": [
"email",
"emailvalidation",
"emailvalidator",
"validation",
"validator"
],
"support": {
"issues": "https://github.com/egulias/EmailValidator/issues",
"source": "https://github.com/egulias/EmailValidator/tree/2.1.25"
},
"funding": [
{
"url": "https://github.com/egulias",
"type": "github"
}
],
"time": "2020-12-29T14:50:06+00:00"
},
{
"name": "nikic/php-parser",
"version": "v4.13.2",
@@ -759,29 +891,36 @@
},
{
"name": "swiftmailer/swiftmailer",
"version": "v5.4.12",
"version": "v6.3.0",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "181b89f18a90f8925ef805f950d47a7190e9b950"
"reference": "8a5d5072dca8f48460fce2f4131fcc495eec654c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/181b89f18a90f8925ef805f950d47a7190e9b950",
"reference": "181b89f18a90f8925ef805f950d47a7190e9b950",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/8a5d5072dca8f48460fce2f4131fcc495eec654c",
"reference": "8a5d5072dca8f48460fce2f4131fcc495eec654c",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
"egulias/email-validator": "^2.0|^3.1",
"php": ">=7.0.0",
"symfony/polyfill-iconv": "^1.0",
"symfony/polyfill-intl-idn": "^1.10",
"symfony/polyfill-mbstring": "^1.0"
},
"require-dev": {
"mockery/mockery": "~0.9.1",
"symfony/phpunit-bridge": "~3.2"
"mockery/mockery": "^1.0",
"symfony/phpunit-bridge": "^4.4|^5.4"
},
"suggest": {
"ext-intl": "Needed to support internationalized email addresses"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.4-dev"
"dev-master": "6.2-dev"
}
},
"autoload": {
@@ -809,7 +948,22 @@
"mail",
"mailer"
],
"time": "2018-07-31T09:26:32+00:00"
"support": {
"issues": "https://github.com/swiftmailer/swiftmailer/issues",
"source": "https://github.com/swiftmailer/swiftmailer/tree/v6.3.0"
},
"funding": [
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/swiftmailer/swiftmailer",
"type": "tidelift"
}
],
"abandoned": "symfony/mailer",
"time": "2021-10-18T15:26:12+00:00"
},
{
"name": "symfony/cache",
@@ -2056,6 +2210,258 @@
],
"time": "2020-10-23T09:01:57+00:00"
},
{
"name": "symfony/polyfill-iconv",
"version": "v1.19.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-iconv.git",
"reference": "085241787d52fa6f7a774fd034135fef0cfd5496"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/085241787d52fa6f7a774fd034135fef0cfd5496",
"reference": "085241787d52fa6f7a774fd034135fef0cfd5496",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-iconv": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.19-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Iconv\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Iconv extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"iconv",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-iconv/tree/v1.19.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-23T09:01:57+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.19.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "4ad5115c0f5d5172a9fe8147675ec6de266d8826"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/4ad5115c0f5d5172a9fe8147675ec6de266d8826",
"reference": "4ad5115c0f5d5172a9fe8147675ec6de266d8826",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"symfony/polyfill-intl-normalizer": "^1.10",
"symfony/polyfill-php70": "^1.10",
"symfony/polyfill-php72": "^1.10"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.19-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Intl\\Idn\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Laurent Bassin",
"email": "laurent@bassin.info"
},
{
"name": "Trevor Rowbotham",
"email": "trevor.rowbotham@pm.me"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"idn",
"intl",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.19.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-21T09:57:48+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.19.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "8db0ae7936b42feb370840cf24de1a144fb0ef27"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8db0ae7936b42feb370840cf24de1a144fb0ef27",
"reference": "8db0ae7936b42feb370840cf24de1a144fb0ef27",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.19-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Intl\\Normalizer\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's Normalizer class and related functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"intl",
"normalizer",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.19.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-23T09:01:57+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.19.0",
@@ -2293,6 +2699,82 @@
],
"time": "2020-10-23T09:01:57+00:00"
},
{
"name": "symfony/polyfill-php72",
"version": "v1.19.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "beecef6b463b06954638f02378f52496cb84bacc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/beecef6b463b06954638f02378f52496cb84bacc",
"reference": "beecef6b463b06954638f02378f52496cb84bacc",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.19-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php72\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php72/tree/v1.19.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-23T09:01:57+00:00"
},
{
"name": "symfony/polyfill-util",
"version": "v1.19.0",

View File

@@ -234,7 +234,73 @@ return array(
'DisplayableNode' => $baseDir . '/core/displayablegraph.class.inc.php',
'DisplayableRedundancyNode' => $baseDir . '/core/displayablegraph.class.inc.php',
'DivisionByZeroError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php',
'Doctrine\\Common\\Lexer\\AbstractLexer' => $vendorDir . '/doctrine/lexer/lib/Doctrine/Common/Lexer/AbstractLexer.php',
'EMail' => $baseDir . '/core/email.class.inc.php',
'Egulias\\EmailValidator\\EmailLexer' => $vendorDir . '/egulias/email-validator/src/EmailLexer.php',
'Egulias\\EmailValidator\\EmailParser' => $vendorDir . '/egulias/email-validator/src/EmailParser.php',
'Egulias\\EmailValidator\\EmailValidator' => $vendorDir . '/egulias/email-validator/src/EmailValidator.php',
'Egulias\\EmailValidator\\Exception\\AtextAfterCFWS' => $vendorDir . '/egulias/email-validator/src/Exception/AtextAfterCFWS.php',
'Egulias\\EmailValidator\\Exception\\CRLFAtTheEnd' => $vendorDir . '/egulias/email-validator/src/Exception/CRLFAtTheEnd.php',
'Egulias\\EmailValidator\\Exception\\CRLFX2' => $vendorDir . '/egulias/email-validator/src/Exception/CRLFX2.php',
'Egulias\\EmailValidator\\Exception\\CRNoLF' => $vendorDir . '/egulias/email-validator/src/Exception/CRNoLF.php',
'Egulias\\EmailValidator\\Exception\\CharNotAllowed' => $vendorDir . '/egulias/email-validator/src/Exception/CharNotAllowed.php',
'Egulias\\EmailValidator\\Exception\\CommaInDomain' => $vendorDir . '/egulias/email-validator/src/Exception/CommaInDomain.php',
'Egulias\\EmailValidator\\Exception\\ConsecutiveAt' => $vendorDir . '/egulias/email-validator/src/Exception/ConsecutiveAt.php',
'Egulias\\EmailValidator\\Exception\\ConsecutiveDot' => $vendorDir . '/egulias/email-validator/src/Exception/ConsecutiveDot.php',
'Egulias\\EmailValidator\\Exception\\DomainAcceptsNoMail' => $vendorDir . '/egulias/email-validator/src/Exception/DomainAcceptsNoMail.php',
'Egulias\\EmailValidator\\Exception\\DomainHyphened' => $vendorDir . '/egulias/email-validator/src/Exception/DomainHyphened.php',
'Egulias\\EmailValidator\\Exception\\DotAtEnd' => $vendorDir . '/egulias/email-validator/src/Exception/DotAtEnd.php',
'Egulias\\EmailValidator\\Exception\\DotAtStart' => $vendorDir . '/egulias/email-validator/src/Exception/DotAtStart.php',
'Egulias\\EmailValidator\\Exception\\ExpectingAT' => $vendorDir . '/egulias/email-validator/src/Exception/ExpectingAT.php',
'Egulias\\EmailValidator\\Exception\\ExpectingATEXT' => $vendorDir . '/egulias/email-validator/src/Exception/ExpectingATEXT.php',
'Egulias\\EmailValidator\\Exception\\ExpectingCTEXT' => $vendorDir . '/egulias/email-validator/src/Exception/ExpectingCTEXT.php',
'Egulias\\EmailValidator\\Exception\\ExpectingDTEXT' => $vendorDir . '/egulias/email-validator/src/Exception/ExpectingDTEXT.php',
'Egulias\\EmailValidator\\Exception\\ExpectingDomainLiteralClose' => $vendorDir . '/egulias/email-validator/src/Exception/ExpectingDomainLiteralClose.php',
'Egulias\\EmailValidator\\Exception\\ExpectingQPair' => $vendorDir . '/egulias/email-validator/src/Exception/ExpectingQPair.php',
'Egulias\\EmailValidator\\Exception\\InvalidEmail' => $vendorDir . '/egulias/email-validator/src/Exception/InvalidEmail.php',
'Egulias\\EmailValidator\\Exception\\LocalOrReservedDomain' => $vendorDir . '/egulias/email-validator/src/Exception/LocalOrReservedDomain.php',
'Egulias\\EmailValidator\\Exception\\NoDNSRecord' => $vendorDir . '/egulias/email-validator/src/Exception/NoDNSRecord.php',
'Egulias\\EmailValidator\\Exception\\NoDomainPart' => $vendorDir . '/egulias/email-validator/src/Exception/NoDomainPart.php',
'Egulias\\EmailValidator\\Exception\\NoLocalPart' => $vendorDir . '/egulias/email-validator/src/Exception/NoLocalPart.php',
'Egulias\\EmailValidator\\Exception\\UnclosedComment' => $vendorDir . '/egulias/email-validator/src/Exception/UnclosedComment.php',
'Egulias\\EmailValidator\\Exception\\UnclosedQuotedString' => $vendorDir . '/egulias/email-validator/src/Exception/UnclosedQuotedString.php',
'Egulias\\EmailValidator\\Exception\\UnopenedComment' => $vendorDir . '/egulias/email-validator/src/Exception/UnopenedComment.php',
'Egulias\\EmailValidator\\Parser\\DomainPart' => $vendorDir . '/egulias/email-validator/src/Parser/DomainPart.php',
'Egulias\\EmailValidator\\Parser\\LocalPart' => $vendorDir . '/egulias/email-validator/src/Parser/LocalPart.php',
'Egulias\\EmailValidator\\Parser\\Parser' => $vendorDir . '/egulias/email-validator/src/Parser/Parser.php',
'Egulias\\EmailValidator\\Validation\\DNSCheckValidation' => $vendorDir . '/egulias/email-validator/src/Validation/DNSCheckValidation.php',
'Egulias\\EmailValidator\\Validation\\EmailValidation' => $vendorDir . '/egulias/email-validator/src/Validation/EmailValidation.php',
'Egulias\\EmailValidator\\Validation\\Error\\RFCWarnings' => $vendorDir . '/egulias/email-validator/src/Validation/Error/RFCWarnings.php',
'Egulias\\EmailValidator\\Validation\\Error\\SpoofEmail' => $vendorDir . '/egulias/email-validator/src/Validation/Error/SpoofEmail.php',
'Egulias\\EmailValidator\\Validation\\Exception\\EmptyValidationList' => $vendorDir . '/egulias/email-validator/src/Validation/Exception/EmptyValidationList.php',
'Egulias\\EmailValidator\\Validation\\MultipleErrors' => $vendorDir . '/egulias/email-validator/src/Validation/MultipleErrors.php',
'Egulias\\EmailValidator\\Validation\\MultipleValidationWithAnd' => $vendorDir . '/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php',
'Egulias\\EmailValidator\\Validation\\NoRFCWarningsValidation' => $vendorDir . '/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php',
'Egulias\\EmailValidator\\Validation\\RFCValidation' => $vendorDir . '/egulias/email-validator/src/Validation/RFCValidation.php',
'Egulias\\EmailValidator\\Validation\\SpoofCheckValidation' => $vendorDir . '/egulias/email-validator/src/Validation/SpoofCheckValidation.php',
'Egulias\\EmailValidator\\Warning\\AddressLiteral' => $vendorDir . '/egulias/email-validator/src/Warning/AddressLiteral.php',
'Egulias\\EmailValidator\\Warning\\CFWSNearAt' => $vendorDir . '/egulias/email-validator/src/Warning/CFWSNearAt.php',
'Egulias\\EmailValidator\\Warning\\CFWSWithFWS' => $vendorDir . '/egulias/email-validator/src/Warning/CFWSWithFWS.php',
'Egulias\\EmailValidator\\Warning\\Comment' => $vendorDir . '/egulias/email-validator/src/Warning/Comment.php',
'Egulias\\EmailValidator\\Warning\\DeprecatedComment' => $vendorDir . '/egulias/email-validator/src/Warning/DeprecatedComment.php',
'Egulias\\EmailValidator\\Warning\\DomainLiteral' => $vendorDir . '/egulias/email-validator/src/Warning/DomainLiteral.php',
'Egulias\\EmailValidator\\Warning\\DomainTooLong' => $vendorDir . '/egulias/email-validator/src/Warning/DomainTooLong.php',
'Egulias\\EmailValidator\\Warning\\EmailTooLong' => $vendorDir . '/egulias/email-validator/src/Warning/EmailTooLong.php',
'Egulias\\EmailValidator\\Warning\\IPV6BadChar' => $vendorDir . '/egulias/email-validator/src/Warning/IPV6BadChar.php',
'Egulias\\EmailValidator\\Warning\\IPV6ColonEnd' => $vendorDir . '/egulias/email-validator/src/Warning/IPV6ColonEnd.php',
'Egulias\\EmailValidator\\Warning\\IPV6ColonStart' => $vendorDir . '/egulias/email-validator/src/Warning/IPV6ColonStart.php',
'Egulias\\EmailValidator\\Warning\\IPV6Deprecated' => $vendorDir . '/egulias/email-validator/src/Warning/IPV6Deprecated.php',
'Egulias\\EmailValidator\\Warning\\IPV6DoubleColon' => $vendorDir . '/egulias/email-validator/src/Warning/IPV6DoubleColon.php',
'Egulias\\EmailValidator\\Warning\\IPV6GroupCount' => $vendorDir . '/egulias/email-validator/src/Warning/IPV6GroupCount.php',
'Egulias\\EmailValidator\\Warning\\IPV6MaxGroups' => $vendorDir . '/egulias/email-validator/src/Warning/IPV6MaxGroups.php',
'Egulias\\EmailValidator\\Warning\\LabelTooLong' => $vendorDir . '/egulias/email-validator/src/Warning/LabelTooLong.php',
'Egulias\\EmailValidator\\Warning\\LocalTooLong' => $vendorDir . '/egulias/email-validator/src/Warning/LocalTooLong.php',
'Egulias\\EmailValidator\\Warning\\NoDNSMXRecord' => $vendorDir . '/egulias/email-validator/src/Warning/NoDNSMXRecord.php',
'Egulias\\EmailValidator\\Warning\\ObsoleteDTEXT' => $vendorDir . '/egulias/email-validator/src/Warning/ObsoleteDTEXT.php',
'Egulias\\EmailValidator\\Warning\\QuotedPart' => $vendorDir . '/egulias/email-validator/src/Warning/QuotedPart.php',
'Egulias\\EmailValidator\\Warning\\QuotedString' => $vendorDir . '/egulias/email-validator/src/Warning/QuotedString.php',
'Egulias\\EmailValidator\\Warning\\TLD' => $vendorDir . '/egulias/email-validator/src/Warning/TLD.php',
'Egulias\\EmailValidator\\Warning\\Warning' => $vendorDir . '/egulias/email-validator/src/Warning/Warning.php',
'Error' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/Error.php',
'ErrorPage' => $baseDir . '/application/errorpage.class.inc.php',
'Event' => $baseDir . '/core/event.class.inc.php',
@@ -321,6 +387,7 @@ return array(
'NewObjectMenuNode' => $baseDir . '/application/menunode.class.inc.php',
'NewsroomProviderBase' => $baseDir . '/application/newsroomprovider.class.inc.php',
'NiceWebPage' => $baseDir . '/application/nicewebpage.class.inc.php',
'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
'OQLActualClassTreeResolver' => $baseDir . '/core/oqlactualclasstreeresolver.class.inc.php',
'OQLClassNode' => $baseDir . '/core/oqlclassnode.class.inc.php',
'OQLClassTreeBuilder' => $baseDir . '/core/oqlclasstreebuilder.class.inc.php',
@@ -1744,9 +1811,16 @@ return array(
'Symfony\\Component\\Yaml\\Yaml' => $vendorDir . '/symfony/yaml/Yaml.php',
'Symfony\\Polyfill\\Apcu\\Apcu' => $vendorDir . '/symfony/polyfill-apcu/Apcu.php',
'Symfony\\Polyfill\\Ctype\\Ctype' => $vendorDir . '/symfony/polyfill-ctype/Ctype.php',
'Symfony\\Polyfill\\Iconv\\Iconv' => $vendorDir . '/symfony/polyfill-iconv/Iconv.php',
'Symfony\\Polyfill\\Intl\\Idn\\Idn' => $vendorDir . '/symfony/polyfill-intl-idn/Idn.php',
'Symfony\\Polyfill\\Intl\\Idn\\Info' => $vendorDir . '/symfony/polyfill-intl-idn/Info.php',
'Symfony\\Polyfill\\Intl\\Idn\\Resources\\unidata\\DisallowedRanges' => $vendorDir . '/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php',
'Symfony\\Polyfill\\Intl\\Idn\\Resources\\unidata\\Regex' => $vendorDir . '/symfony/polyfill-intl-idn/Resources/unidata/Regex.php',
'Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Normalizer.php',
'Symfony\\Polyfill\\Mbstring\\Mbstring' => $vendorDir . '/symfony/polyfill-mbstring/Mbstring.php',
'Symfony\\Polyfill\\Php56\\Php56' => $vendorDir . '/symfony/polyfill-php56/Php56.php',
'Symfony\\Polyfill\\Php70\\Php70' => $vendorDir . '/symfony/polyfill-php70/Php70.php',
'Symfony\\Polyfill\\Php72\\Php72' => $vendorDir . '/symfony/polyfill-php72/Php72.php',
'Symfony\\Polyfill\\Util\\Binary' => $vendorDir . '/symfony/polyfill-util/Binary.php',
'Symfony\\Polyfill\\Util\\BinaryNoFuncOverload' => $vendorDir . '/symfony/polyfill-util/BinaryNoFuncOverload.php',
'Symfony\\Polyfill\\Util\\BinaryOnFuncOverload' => $vendorDir . '/symfony/polyfill-util/BinaryOnFuncOverload.php',

View File

@@ -7,11 +7,15 @@ $baseDir = dirname($vendorDir);
return array(
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'023d27dca8066ef29e6739335ea73bad' => $vendorDir . '/symfony/polyfill-php70/bootstrap.php',
'bd9634f2d41831496de0d3dfe4c94881' => $vendorDir . '/symfony/polyfill-php56/bootstrap.php',
'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
'32dcc8afd4335739640db7d200c1971d' => $vendorDir . '/symfony/polyfill-apcu/bootstrap.php',
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
);

View File

@@ -8,9 +8,13 @@ $baseDir = dirname($vendorDir);
return array(
'Twig\\' => array($vendorDir . '/twig/twig/src'),
'Symfony\\Polyfill\\Util\\' => array($vendorDir . '/symfony/polyfill-util'),
'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
'Symfony\\Polyfill\\Php70\\' => array($vendorDir . '/symfony/polyfill-php70'),
'Symfony\\Polyfill\\Php56\\' => array($vendorDir . '/symfony/polyfill-php56'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'),
'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'),
'Symfony\\Polyfill\\Iconv\\' => array($vendorDir . '/symfony/polyfill-iconv'),
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
'Symfony\\Polyfill\\Apcu\\' => array($vendorDir . '/symfony/polyfill-apcu'),
'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
@@ -41,4 +45,6 @@ return array(
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
'Pelago\\' => array($vendorDir . '/pelago/emogrifier/src'),
'Egulias\\EmailValidator\\' => array($vendorDir . '/egulias/email-validator/src'),
'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib/Doctrine/Common/Lexer'),
);

View File

@@ -8,11 +8,15 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
{
public static $files = array (
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'023d27dca8066ef29e6739335ea73bad' => __DIR__ . '/..' . '/symfony/polyfill-php70/bootstrap.php',
'bd9634f2d41831496de0d3dfe4c94881' => __DIR__ . '/..' . '/symfony/polyfill-php56/bootstrap.php',
'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
'32dcc8afd4335739640db7d200c1971d' => __DIR__ . '/..' . '/symfony/polyfill-apcu/bootstrap.php',
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
'2c102faa651ef8ea5874edb585946bce' => __DIR__ . '/..' . '/swiftmailer/swiftmailer/lib/swift_required.php',
);
@@ -25,9 +29,13 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
'S' =>
array (
'Symfony\\Polyfill\\Util\\' => 22,
'Symfony\\Polyfill\\Php72\\' => 23,
'Symfony\\Polyfill\\Php70\\' => 23,
'Symfony\\Polyfill\\Php56\\' => 23,
'Symfony\\Polyfill\\Mbstring\\' => 26,
'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33,
'Symfony\\Polyfill\\Intl\\Idn\\' => 26,
'Symfony\\Polyfill\\Iconv\\' => 23,
'Symfony\\Polyfill\\Ctype\\' => 23,
'Symfony\\Polyfill\\Apcu\\' => 22,
'Symfony\\Component\\Yaml\\' => 23,
@@ -62,6 +70,14 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
'PhpParser\\' => 10,
'Pelago\\' => 7,
),
'E' =>
array (
'Egulias\\EmailValidator\\' => 23,
),
'D' =>
array (
'Doctrine\\Common\\Lexer\\' => 22,
),
);
public static $prefixDirsPsr4 = array (
@@ -73,6 +89,10 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-util',
),
'Symfony\\Polyfill\\Php72\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php72',
),
'Symfony\\Polyfill\\Php70\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php70',
@@ -85,6 +105,18 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
),
'Symfony\\Polyfill\\Intl\\Normalizer\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer',
),
'Symfony\\Polyfill\\Intl\\Idn\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-idn',
),
'Symfony\\Polyfill\\Iconv\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-iconv',
),
'Symfony\\Polyfill\\Ctype\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
@@ -205,6 +237,14 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
array (
0 => __DIR__ . '/..' . '/pelago/emogrifier/src',
),
'Egulias\\EmailValidator\\' =>
array (
0 => __DIR__ . '/..' . '/egulias/email-validator/src',
),
'Doctrine\\Common\\Lexer\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/lexer/lib/Doctrine/Common/Lexer',
),
);
public static $prefixesPsr0 = array (
@@ -464,7 +504,73 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
'DisplayableNode' => __DIR__ . '/../..' . '/core/displayablegraph.class.inc.php',
'DisplayableRedundancyNode' => __DIR__ . '/../..' . '/core/displayablegraph.class.inc.php',
'DivisionByZeroError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php',
'Doctrine\\Common\\Lexer\\AbstractLexer' => __DIR__ . '/..' . '/doctrine/lexer/lib/Doctrine/Common/Lexer/AbstractLexer.php',
'EMail' => __DIR__ . '/../..' . '/core/email.class.inc.php',
'Egulias\\EmailValidator\\EmailLexer' => __DIR__ . '/..' . '/egulias/email-validator/src/EmailLexer.php',
'Egulias\\EmailValidator\\EmailParser' => __DIR__ . '/..' . '/egulias/email-validator/src/EmailParser.php',
'Egulias\\EmailValidator\\EmailValidator' => __DIR__ . '/..' . '/egulias/email-validator/src/EmailValidator.php',
'Egulias\\EmailValidator\\Exception\\AtextAfterCFWS' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/AtextAfterCFWS.php',
'Egulias\\EmailValidator\\Exception\\CRLFAtTheEnd' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/CRLFAtTheEnd.php',
'Egulias\\EmailValidator\\Exception\\CRLFX2' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/CRLFX2.php',
'Egulias\\EmailValidator\\Exception\\CRNoLF' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/CRNoLF.php',
'Egulias\\EmailValidator\\Exception\\CharNotAllowed' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/CharNotAllowed.php',
'Egulias\\EmailValidator\\Exception\\CommaInDomain' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/CommaInDomain.php',
'Egulias\\EmailValidator\\Exception\\ConsecutiveAt' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/ConsecutiveAt.php',
'Egulias\\EmailValidator\\Exception\\ConsecutiveDot' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/ConsecutiveDot.php',
'Egulias\\EmailValidator\\Exception\\DomainAcceptsNoMail' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/DomainAcceptsNoMail.php',
'Egulias\\EmailValidator\\Exception\\DomainHyphened' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/DomainHyphened.php',
'Egulias\\EmailValidator\\Exception\\DotAtEnd' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/DotAtEnd.php',
'Egulias\\EmailValidator\\Exception\\DotAtStart' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/DotAtStart.php',
'Egulias\\EmailValidator\\Exception\\ExpectingAT' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/ExpectingAT.php',
'Egulias\\EmailValidator\\Exception\\ExpectingATEXT' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/ExpectingATEXT.php',
'Egulias\\EmailValidator\\Exception\\ExpectingCTEXT' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/ExpectingCTEXT.php',
'Egulias\\EmailValidator\\Exception\\ExpectingDTEXT' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/ExpectingDTEXT.php',
'Egulias\\EmailValidator\\Exception\\ExpectingDomainLiteralClose' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/ExpectingDomainLiteralClose.php',
'Egulias\\EmailValidator\\Exception\\ExpectingQPair' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/ExpectingQPair.php',
'Egulias\\EmailValidator\\Exception\\InvalidEmail' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/InvalidEmail.php',
'Egulias\\EmailValidator\\Exception\\LocalOrReservedDomain' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/LocalOrReservedDomain.php',
'Egulias\\EmailValidator\\Exception\\NoDNSRecord' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/NoDNSRecord.php',
'Egulias\\EmailValidator\\Exception\\NoDomainPart' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/NoDomainPart.php',
'Egulias\\EmailValidator\\Exception\\NoLocalPart' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/NoLocalPart.php',
'Egulias\\EmailValidator\\Exception\\UnclosedComment' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/UnclosedComment.php',
'Egulias\\EmailValidator\\Exception\\UnclosedQuotedString' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/UnclosedQuotedString.php',
'Egulias\\EmailValidator\\Exception\\UnopenedComment' => __DIR__ . '/..' . '/egulias/email-validator/src/Exception/UnopenedComment.php',
'Egulias\\EmailValidator\\Parser\\DomainPart' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/DomainPart.php',
'Egulias\\EmailValidator\\Parser\\LocalPart' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/LocalPart.php',
'Egulias\\EmailValidator\\Parser\\Parser' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/Parser.php',
'Egulias\\EmailValidator\\Validation\\DNSCheckValidation' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/DNSCheckValidation.php',
'Egulias\\EmailValidator\\Validation\\EmailValidation' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/EmailValidation.php',
'Egulias\\EmailValidator\\Validation\\Error\\RFCWarnings' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/Error/RFCWarnings.php',
'Egulias\\EmailValidator\\Validation\\Error\\SpoofEmail' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/Error/SpoofEmail.php',
'Egulias\\EmailValidator\\Validation\\Exception\\EmptyValidationList' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/Exception/EmptyValidationList.php',
'Egulias\\EmailValidator\\Validation\\MultipleErrors' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/MultipleErrors.php',
'Egulias\\EmailValidator\\Validation\\MultipleValidationWithAnd' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php',
'Egulias\\EmailValidator\\Validation\\NoRFCWarningsValidation' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php',
'Egulias\\EmailValidator\\Validation\\RFCValidation' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/RFCValidation.php',
'Egulias\\EmailValidator\\Validation\\SpoofCheckValidation' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/SpoofCheckValidation.php',
'Egulias\\EmailValidator\\Warning\\AddressLiteral' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/AddressLiteral.php',
'Egulias\\EmailValidator\\Warning\\CFWSNearAt' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/CFWSNearAt.php',
'Egulias\\EmailValidator\\Warning\\CFWSWithFWS' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/CFWSWithFWS.php',
'Egulias\\EmailValidator\\Warning\\Comment' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/Comment.php',
'Egulias\\EmailValidator\\Warning\\DeprecatedComment' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/DeprecatedComment.php',
'Egulias\\EmailValidator\\Warning\\DomainLiteral' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/DomainLiteral.php',
'Egulias\\EmailValidator\\Warning\\DomainTooLong' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/DomainTooLong.php',
'Egulias\\EmailValidator\\Warning\\EmailTooLong' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/EmailTooLong.php',
'Egulias\\EmailValidator\\Warning\\IPV6BadChar' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/IPV6BadChar.php',
'Egulias\\EmailValidator\\Warning\\IPV6ColonEnd' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/IPV6ColonEnd.php',
'Egulias\\EmailValidator\\Warning\\IPV6ColonStart' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/IPV6ColonStart.php',
'Egulias\\EmailValidator\\Warning\\IPV6Deprecated' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/IPV6Deprecated.php',
'Egulias\\EmailValidator\\Warning\\IPV6DoubleColon' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/IPV6DoubleColon.php',
'Egulias\\EmailValidator\\Warning\\IPV6GroupCount' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/IPV6GroupCount.php',
'Egulias\\EmailValidator\\Warning\\IPV6MaxGroups' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/IPV6MaxGroups.php',
'Egulias\\EmailValidator\\Warning\\LabelTooLong' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/LabelTooLong.php',
'Egulias\\EmailValidator\\Warning\\LocalTooLong' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/LocalTooLong.php',
'Egulias\\EmailValidator\\Warning\\NoDNSMXRecord' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/NoDNSMXRecord.php',
'Egulias\\EmailValidator\\Warning\\ObsoleteDTEXT' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/ObsoleteDTEXT.php',
'Egulias\\EmailValidator\\Warning\\QuotedPart' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/QuotedPart.php',
'Egulias\\EmailValidator\\Warning\\QuotedString' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/QuotedString.php',
'Egulias\\EmailValidator\\Warning\\TLD' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/TLD.php',
'Egulias\\EmailValidator\\Warning\\Warning' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/Warning.php',
'Error' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/Error.php',
'ErrorPage' => __DIR__ . '/../..' . '/application/errorpage.class.inc.php',
'Event' => __DIR__ . '/../..' . '/core/event.class.inc.php',
@@ -551,6 +657,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
'NewObjectMenuNode' => __DIR__ . '/../..' . '/application/menunode.class.inc.php',
'NewsroomProviderBase' => __DIR__ . '/../..' . '/application/newsroomprovider.class.inc.php',
'NiceWebPage' => __DIR__ . '/../..' . '/application/nicewebpage.class.inc.php',
'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
'OQLActualClassTreeResolver' => __DIR__ . '/../..' . '/core/oqlactualclasstreeresolver.class.inc.php',
'OQLClassNode' => __DIR__ . '/../..' . '/core/oqlclassnode.class.inc.php',
'OQLClassTreeBuilder' => __DIR__ . '/../..' . '/core/oqlclasstreebuilder.class.inc.php',
@@ -1974,9 +2081,16 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
'Symfony\\Component\\Yaml\\Yaml' => __DIR__ . '/..' . '/symfony/yaml/Yaml.php',
'Symfony\\Polyfill\\Apcu\\Apcu' => __DIR__ . '/..' . '/symfony/polyfill-apcu/Apcu.php',
'Symfony\\Polyfill\\Ctype\\Ctype' => __DIR__ . '/..' . '/symfony/polyfill-ctype/Ctype.php',
'Symfony\\Polyfill\\Iconv\\Iconv' => __DIR__ . '/..' . '/symfony/polyfill-iconv/Iconv.php',
'Symfony\\Polyfill\\Intl\\Idn\\Idn' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/Idn.php',
'Symfony\\Polyfill\\Intl\\Idn\\Info' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/Info.php',
'Symfony\\Polyfill\\Intl\\Idn\\Resources\\unidata\\DisallowedRanges' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php',
'Symfony\\Polyfill\\Intl\\Idn\\Resources\\unidata\\Regex' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/Resources/unidata/Regex.php',
'Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Normalizer.php',
'Symfony\\Polyfill\\Mbstring\\Mbstring' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/Mbstring.php',
'Symfony\\Polyfill\\Php56\\Php56' => __DIR__ . '/..' . '/symfony/polyfill-php56/Php56.php',
'Symfony\\Polyfill\\Php70\\Php70' => __DIR__ . '/..' . '/symfony/polyfill-php70/Php70.php',
'Symfony\\Polyfill\\Php72\\Php72' => __DIR__ . '/..' . '/symfony/polyfill-php72/Php72.php',
'Symfony\\Polyfill\\Util\\Binary' => __DIR__ . '/..' . '/symfony/polyfill-util/Binary.php',
'Symfony\\Polyfill\\Util\\BinaryNoFuncOverload' => __DIR__ . '/..' . '/symfony/polyfill-util/BinaryNoFuncOverload.php',
'Symfony\\Polyfill\\Util\\BinaryOnFuncOverload' => __DIR__ . '/..' . '/symfony/polyfill-util/BinaryOnFuncOverload.php',

View File

@@ -81,6 +81,144 @@
],
"install-path": "../combodo/tcpdf"
},
{
"name": "doctrine/lexer",
"version": "1.0.2",
"version_normalized": "1.0.2.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/lexer.git",
"reference": "1febd6c3ef84253d7c815bed85fc622ad207a9f8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/lexer/zipball/1febd6c3ef84253d7c815bed85fc622ad207a9f8",
"reference": "1febd6c3ef84253d7c815bed85fc622ad207a9f8",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"require-dev": {
"phpunit/phpunit": "^4.5"
},
"time": "2019-06-08T11:03:04+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
"homepage": "https://www.doctrine-project.org/projects/lexer.html",
"keywords": [
"annotations",
"docblock",
"lexer",
"parser",
"php"
],
"support": {
"issues": "https://github.com/doctrine/lexer/issues",
"source": "https://github.com/doctrine/lexer/tree/1.0.2"
},
"install-path": "../doctrine/lexer"
},
{
"name": "egulias/email-validator",
"version": "2.1.25",
"version_normalized": "2.1.25.0",
"source": {
"type": "git",
"url": "https://github.com/egulias/EmailValidator.git",
"reference": "0dbf5d78455d4d6a41d186da50adc1122ec066f4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/0dbf5d78455d4d6a41d186da50adc1122ec066f4",
"reference": "0dbf5d78455d4d6a41d186da50adc1122ec066f4",
"shasum": ""
},
"require": {
"doctrine/lexer": "^1.0.1",
"php": ">=5.5",
"symfony/polyfill-intl-idn": "^1.10"
},
"require-dev": {
"dominicsayers/isemail": "^3.0.7",
"phpunit/phpunit": "^4.8.36|^7.5.15",
"satooshi/php-coveralls": "^1.0.1"
},
"suggest": {
"ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
},
"time": "2020-12-29T14:50:06+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.1.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Egulias\\EmailValidator\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Eduardo Gulias Davis"
}
],
"description": "A library for validating emails against several RFCs",
"homepage": "https://github.com/egulias/EmailValidator",
"keywords": [
"email",
"emailvalidation",
"emailvalidator",
"validation",
"validator"
],
"support": {
"issues": "https://github.com/egulias/EmailValidator/issues",
"source": "https://github.com/egulias/EmailValidator/tree/2.1.25"
},
"funding": [
{
"url": "https://github.com/egulias",
"type": "github"
}
],
"install-path": "../egulias/email-validator"
},
{
"name": "nikic/php-parser",
"version": "v4.13.2",
@@ -792,31 +930,38 @@
},
{
"name": "swiftmailer/swiftmailer",
"version": "v5.4.12",
"version_normalized": "5.4.12.0",
"version": "v6.3.0",
"version_normalized": "6.3.0.0",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "181b89f18a90f8925ef805f950d47a7190e9b950"
"reference": "8a5d5072dca8f48460fce2f4131fcc495eec654c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/181b89f18a90f8925ef805f950d47a7190e9b950",
"reference": "181b89f18a90f8925ef805f950d47a7190e9b950",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/8a5d5072dca8f48460fce2f4131fcc495eec654c",
"reference": "8a5d5072dca8f48460fce2f4131fcc495eec654c",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
"egulias/email-validator": "^2.0|^3.1",
"php": ">=7.0.0",
"symfony/polyfill-iconv": "^1.0",
"symfony/polyfill-intl-idn": "^1.10",
"symfony/polyfill-mbstring": "^1.0"
},
"require-dev": {
"mockery/mockery": "~0.9.1",
"symfony/phpunit-bridge": "~3.2"
"mockery/mockery": "^1.0",
"symfony/phpunit-bridge": "^4.4|^5.4"
},
"time": "2018-07-31T09:26:32+00:00",
"suggest": {
"ext-intl": "Needed to support internationalized email addresses"
},
"time": "2021-10-18T15:26:12+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.4-dev"
"dev-master": "6.2-dev"
}
},
"installation-source": "dist",
@@ -845,6 +990,21 @@
"mail",
"mailer"
],
"support": {
"issues": "https://github.com/swiftmailer/swiftmailer/issues",
"source": "https://github.com/swiftmailer/swiftmailer/tree/v6.3.0"
},
"funding": [
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/swiftmailer/swiftmailer",
"type": "tidelift"
}
],
"abandoned": "symfony/mailer",
"install-path": "../swiftmailer/swiftmailer"
},
{
@@ -2140,6 +2300,267 @@
],
"install-path": "../symfony/polyfill-ctype"
},
{
"name": "symfony/polyfill-iconv",
"version": "v1.19.0",
"version_normalized": "1.19.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-iconv.git",
"reference": "085241787d52fa6f7a774fd034135fef0cfd5496"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/085241787d52fa6f7a774fd034135fef0cfd5496",
"reference": "085241787d52fa6f7a774fd034135fef0cfd5496",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-iconv": "For best performance"
},
"time": "2020-10-23T09:01:57+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.19-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"installation-source": "dist",
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Iconv\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Iconv extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"iconv",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-iconv/tree/v1.19.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"install-path": "../symfony/polyfill-iconv"
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.19.0",
"version_normalized": "1.19.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "4ad5115c0f5d5172a9fe8147675ec6de266d8826"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/4ad5115c0f5d5172a9fe8147675ec6de266d8826",
"reference": "4ad5115c0f5d5172a9fe8147675ec6de266d8826",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"symfony/polyfill-intl-normalizer": "^1.10",
"symfony/polyfill-php70": "^1.10",
"symfony/polyfill-php72": "^1.10"
},
"suggest": {
"ext-intl": "For best performance"
},
"time": "2020-10-21T09:57:48+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.19-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"installation-source": "dist",
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Intl\\Idn\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Laurent Bassin",
"email": "laurent@bassin.info"
},
{
"name": "Trevor Rowbotham",
"email": "trevor.rowbotham@pm.me"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"idn",
"intl",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.19.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"install-path": "../symfony/polyfill-intl-idn"
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.19.0",
"version_normalized": "1.19.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "8db0ae7936b42feb370840cf24de1a144fb0ef27"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8db0ae7936b42feb370840cf24de1a144fb0ef27",
"reference": "8db0ae7936b42feb370840cf24de1a144fb0ef27",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-intl": "For best performance"
},
"time": "2020-10-23T09:01:57+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.19-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"installation-source": "dist",
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Intl\\Normalizer\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's Normalizer class and related functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"intl",
"normalizer",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.19.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"install-path": "../symfony/polyfill-intl-normalizer"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.19.0",
@@ -2386,6 +2807,85 @@
],
"install-path": "../symfony/polyfill-php70"
},
{
"name": "symfony/polyfill-php72",
"version": "v1.19.0",
"version_normalized": "1.19.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "beecef6b463b06954638f02378f52496cb84bacc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/beecef6b463b06954638f02378f52496cb84bacc",
"reference": "beecef6b463b06954638f02378f52496cb84bacc",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"time": "2020-10-23T09:01:57+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.19-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"installation-source": "dist",
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php72\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php72/tree/v1.19.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"install-path": "../symfony/polyfill-php72"
},
{
"name": "symfony/polyfill-util",
"version": "v1.19.0",

View File

@@ -5,7 +5,7 @@
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => 'a5ce09c4396a111c9c22aeb83fd5eefd1a55fb8f',
'reference' => '8c60e05b1a1d7e135bcf0cbf0d1bf337a623ff15',
'name' => '__root__',
'dev' => true,
),
@@ -16,7 +16,7 @@
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => 'a5ce09c4396a111c9c22aeb83fd5eefd1a55fb8f',
'reference' => '8c60e05b1a1d7e135bcf0cbf0d1bf337a623ff15',
'dev_requirement' => false,
),
'combodo/tcpdf' => array(
@@ -28,6 +28,24 @@
'reference' => '0e31c013ccd000aa6762e9186778aa6e259ac8e8',
'dev_requirement' => false,
),
'doctrine/lexer' => array(
'pretty_version' => '1.0.2',
'version' => '1.0.2.0',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/lexer',
'aliases' => array(),
'reference' => '1febd6c3ef84253d7c815bed85fc622ad207a9f8',
'dev_requirement' => false,
),
'egulias/email-validator' => array(
'pretty_version' => '2.1.25',
'version' => '2.1.25.0',
'type' => 'library',
'install_path' => __DIR__ . '/../egulias/email-validator',
'aliases' => array(),
'reference' => '0dbf5d78455d4d6a41d186da50adc1122ec066f4',
'dev_requirement' => false,
),
'nikic/php-parser' => array(
'pretty_version' => 'v4.13.2',
'version' => '4.13.2.0',
@@ -167,12 +185,12 @@
'dev_requirement' => false,
),
'swiftmailer/swiftmailer' => array(
'pretty_version' => 'v5.4.12',
'version' => '5.4.12.0',
'pretty_version' => 'v6.3.0',
'version' => '6.3.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../swiftmailer/swiftmailer',
'aliases' => array(),
'reference' => '181b89f18a90f8925ef805f950d47a7190e9b950',
'reference' => '8a5d5072dca8f48460fce2f4131fcc495eec654c',
'dev_requirement' => false,
),
'symfony/cache' => array(
@@ -319,6 +337,33 @@
'reference' => 'aed596913b70fae57be53d86faa2e9ef85a2297b',
'dev_requirement' => false,
),
'symfony/polyfill-iconv' => array(
'pretty_version' => 'v1.19.0',
'version' => '1.19.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-iconv',
'aliases' => array(),
'reference' => '085241787d52fa6f7a774fd034135fef0cfd5496',
'dev_requirement' => false,
),
'symfony/polyfill-intl-idn' => array(
'pretty_version' => 'v1.19.0',
'version' => '1.19.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn',
'aliases' => array(),
'reference' => '4ad5115c0f5d5172a9fe8147675ec6de266d8826',
'dev_requirement' => false,
),
'symfony/polyfill-intl-normalizer' => array(
'pretty_version' => 'v1.19.0',
'version' => '1.19.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer',
'aliases' => array(),
'reference' => '8db0ae7936b42feb370840cf24de1a144fb0ef27',
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => 'v1.19.0',
'version' => '1.19.0.0',
@@ -346,6 +391,15 @@
'reference' => '3fe414077251a81a1b15b1c709faf5c2fbae3d4e',
'dev_requirement' => false,
),
'symfony/polyfill-php72' => array(
'pretty_version' => 'v1.19.0',
'version' => '1.19.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php72',
'aliases' => array(),
'reference' => 'beecef6b463b06954638f02378f52496cb84bacc',
'dev_requirement' => false,
),
'symfony/polyfill-util' => array(
'pretty_version' => 'v1.19.0',
'version' => '1.19.0.0',

View File

@@ -0,0 +1,17 @@
{
"active": true,
"name": "Lexer",
"slug": "lexer",
"docsSlug": "doctrine-lexer",
"versions": [
{
"name": "master",
"branchName": "master",
"slug": "latest",
"aliases": [
"current",
"stable"
]
}
]
}

View File

@@ -0,0 +1,3 @@
patreon: phpdoctrine
tidelift: packagist/doctrine%2Flexer
custom: https://www.doctrine-project.org/sponsorship.html

2
lib/doctrine/lexer/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
vendor
composer.lock

View File

@@ -0,0 +1,19 @@
Copyright (c) 2006-2018 Doctrine Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights 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 to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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 THE
SOFTWARE.

View File

@@ -0,0 +1,7 @@
# Doctrine Lexer
Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.
This lexer is used in Doctrine Annotations and in Doctrine ORM (DQL).
https://www.doctrine-project.org/projects/lexer.html

View File

@@ -0,0 +1,36 @@
{
"name": "doctrine/lexer",
"type": "library",
"description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
"keywords": [
"php",
"parser",
"lexer",
"annotations",
"docblock"
],
"homepage": "https://www.doctrine-project.org/projects/lexer.html",
"license": "MIT",
"authors": [
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
],
"require": {
"php": ">=5.3.2"
},
"require-dev": {
"phpunit/phpunit": "^4.5"
},
"autoload": {
"psr-4": { "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" }
},
"autoload-dev": {
"psr-4": { "Doctrine\\Tests\\": "tests/Doctrine" }
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
}
}

View File

@@ -0,0 +1,294 @@
DQL Lexer
=========
Here is a more complicated example from the Doctrine ORM project.
The ``Doctrine\ORM\Query\Lexer`` implementation for DQL looks something
like the following:
.. code-block:: php
use Doctrine\Common\Lexer\AbstractLexer;
class Lexer extends AbstractLexer
{
// All tokens that are not valid identifiers must be < 100
public const T_NONE = 1;
public const T_INTEGER = 2;
public const T_STRING = 3;
public const T_INPUT_PARAMETER = 4;
public const T_FLOAT = 5;
public const T_CLOSE_PARENTHESIS = 6;
public const T_OPEN_PARENTHESIS = 7;
public const T_COMMA = 8;
public const T_DIVIDE = 9;
public const T_DOT = 10;
public const T_EQUALS = 11;
public const T_GREATER_THAN = 12;
public const T_LOWER_THAN = 13;
public const T_MINUS = 14;
public const T_MULTIPLY = 15;
public const T_NEGATE = 16;
public const T_PLUS = 17;
public const T_OPEN_CURLY_BRACE = 18;
public const T_CLOSE_CURLY_BRACE = 19;
// All tokens that are identifiers or keywords that could be considered as identifiers should be >= 100
public const T_ALIASED_NAME = 100;
public const T_FULLY_QUALIFIED_NAME = 101;
public const T_IDENTIFIER = 102;
// All keyword tokens should be >= 200
public const T_ALL = 200;
public const T_AND = 201;
public const T_ANY = 202;
public const T_AS = 203;
public const T_ASC = 204;
public const T_AVG = 205;
public const T_BETWEEN = 206;
public const T_BOTH = 207;
public const T_BY = 208;
public const T_CASE = 209;
public const T_COALESCE = 210;
public const T_COUNT = 211;
public const T_DELETE = 212;
public const T_DESC = 213;
public const T_DISTINCT = 214;
public const T_ELSE = 215;
public const T_EMPTY = 216;
public const T_END = 217;
public const T_ESCAPE = 218;
public const T_EXISTS = 219;
public const T_FALSE = 220;
public const T_FROM = 221;
public const T_GROUP = 222;
public const T_HAVING = 223;
public const T_HIDDEN = 224;
public const T_IN = 225;
public const T_INDEX = 226;
public const T_INNER = 227;
public const T_INSTANCE = 228;
public const T_IS = 229;
public const T_JOIN = 230;
public const T_LEADING = 231;
public const T_LEFT = 232;
public const T_LIKE = 233;
public const T_MAX = 234;
public const T_MEMBER = 235;
public const T_MIN = 236;
public const T_NEW = 237;
public const T_NOT = 238;
public const T_NULL = 239;
public const T_NULLIF = 240;
public const T_OF = 241;
public const T_OR = 242;
public const T_ORDER = 243;
public const T_OUTER = 244;
public const T_PARTIAL = 245;
public const T_SELECT = 246;
public const T_SET = 247;
public const T_SOME = 248;
public const T_SUM = 249;
public const T_THEN = 250;
public const T_TRAILING = 251;
public const T_TRUE = 252;
public const T_UPDATE = 253;
public const T_WHEN = 254;
public const T_WHERE = 255;
public const T_WITH = 256;
/**
* Creates a new query scanner object.
*
* @param string $input A query string.
*/
public function __construct($input)
{
$this->setInput($input);
}
/**
* {@inheritdoc}
*/
protected function getCatchablePatterns()
{
return [
'[a-z_][a-z0-9_]*\:[a-z_][a-z0-9_]*(?:\\\[a-z_][a-z0-9_]*)*', // aliased name
'[a-z_\\\][a-z0-9_]*(?:\\\[a-z_][a-z0-9_]*)*', // identifier or qualified name
'(?:[0-9]+(?:[\.][0-9]+)*)(?:e[+-]?[0-9]+)?', // numbers
"'(?:[^']|'')*'", // quoted strings
'\?[0-9]*|:[a-z_][a-z0-9_]*', // parameters
];
}
/**
* {@inheritdoc}
*/
protected function getNonCatchablePatterns()
{
return ['\s+', '(.)'];
}
/**
* {@inheritdoc}
*/
protected function getType(&$value)
{
$type = self::T_NONE;
switch (true) {
// Recognize numeric values
case (is_numeric($value)):
if (strpos($value, '.') !== false || stripos($value, 'e') !== false) {
return self::T_FLOAT;
}
return self::T_INTEGER;
// Recognize quoted strings
case ($value[0] === "'"):
$value = str_replace("''", "'", substr($value, 1, strlen($value) - 2));
return self::T_STRING;
// Recognize identifiers, aliased or qualified names
case (ctype_alpha($value[0]) || $value[0] === '_' || $value[0] === '\\'):
$name = 'Doctrine\ORM\Query\Lexer::T_' . strtoupper($value);
if (defined($name)) {
$type = constant($name);
if ($type > 100) {
return $type;
}
}
if (strpos($value, ':') !== false) {
return self::T_ALIASED_NAME;
}
if (strpos($value, '\\') !== false) {
return self::T_FULLY_QUALIFIED_NAME;
}
return self::T_IDENTIFIER;
// Recognize input parameters
case ($value[0] === '?' || $value[0] === ':'):
return self::T_INPUT_PARAMETER;
// Recognize symbols
case ($value === '.'):
return self::T_DOT;
case ($value === ','):
return self::T_COMMA;
case ($value === '('):
return self::T_OPEN_PARENTHESIS;
case ($value === ')'):
return self::T_CLOSE_PARENTHESIS;
case ($value === '='):
return self::T_EQUALS;
case ($value === '>'):
return self::T_GREATER_THAN;
case ($value === '<'):
return self::T_LOWER_THAN;
case ($value === '+'):
return self::T_PLUS;
case ($value === '-'):
return self::T_MINUS;
case ($value === '*'):
return self::T_MULTIPLY;
case ($value === '/'):
return self::T_DIVIDE;
case ($value === '!'):
return self::T_NEGATE;
case ($value === '{'):
return self::T_OPEN_CURLY_BRACE;
case ($value === '}'):
return self::T_CLOSE_CURLY_BRACE;
// Default
default:
// Do nothing
}
return $type;
}
}
This is roughly what the DQL Parser looks like that uses the above
Lexer implementation:
.. note::
You can see the full implementation `here <https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Query/Parser.php>`_.
.. code-block:: php
class Parser
{
private $lexer;
public function __construct($dql)
{
$this->lexer = new Lexer();
$this->lexer->setInput($dql);
}
// ...
public function getAST()
{
// Parse & build AST
$AST = $this->QueryLanguage();
// ...
return $AST;
}
public function QueryLanguage()
{
$this->lexer->moveNext();
switch ($this->lexer->lookahead['type']) {
case Lexer::T_SELECT:
$statement = $this->SelectStatement();
break;
case Lexer::T_UPDATE:
$statement = $this->UpdateStatement();
break;
case Lexer::T_DELETE:
$statement = $this->DeleteStatement();
break;
default:
$this->syntaxError('SELECT, UPDATE or DELETE');
break;
}
// Check for end of string
if ($this->lexer->lookahead !== null) {
$this->syntaxError('end of string');
}
return $statement;
}
// ...
}
Now the AST is used to transform the DQL query in to portable SQL for whatever relational
database you are using!
.. code-block:: php
$parser = new Parser('SELECT u FROM User u');
$AST = $parser->getAST(); // returns \Doctrine\ORM\Query\AST\SelectStatement
What is an AST?
===============
AST stands for `Abstract syntax tree <http://en.wikipedia.org/wiki/Abstract_syntax_tree>`_.
In computer science, an abstract syntax tree (AST), or just syntax tree, is a
tree representation of the abstract syntactic structure of source code written
in a programming language. Each node of the tree denotes a construct occurring in
the source code.

View File

@@ -0,0 +1,53 @@
Introduction
============
Doctrine Lexer is a library that can be used in Top-Down, Recursive
Descent Parsers. This lexer is used in Doctrine Annotations and in
Doctrine ORM (DQL).
To write your own parser you just need to extend ``Doctrine\Common\Lexer\AbstractLexer``
and implement the following three abstract methods.
.. code-block:: php
/**
* Lexical catchable patterns.
*
* @return array
*/
abstract protected function getCatchablePatterns();
/**
* Lexical non-catchable patterns.
*
* @return array
*/
abstract protected function getNonCatchablePatterns();
/**
* Retrieve token type. Also processes the token value if necessary.
*
* @param string $value
* @return integer
*/
abstract protected function getType(&$value);
These methods define the `lexical <http://en.wikipedia.org/wiki/Lexical_analysis>`_
catchable and non-catchable patterns and a method for returning the
type of a token and filtering the value if necessary.
The Lexer is responsible for giving you an API to walk across a
string one character at a time and analyze the type of each character, value and position of
each token in the string. The low level API of the lexer is pretty simple:
- ``setInput($input)`` - Sets the input data to be tokenized. The Lexer is immediately reset and the new input tokenized.
- ``reset()`` - Resets the lexer.
- ``resetPeek()`` - Resets the peek pointer to 0.
- ``resetPosition($position = 0)`` - Resets the lexer position on the input to the given position.
- ``isNextToken($token)`` - Checks whether a given token matches the current lookahead.
- ``isNextTokenAny(array $tokens)`` - Checks whether any of the given tokens matches the current lookahead.
- ``moveNext()`` - Moves to the next token in the input string.
- ``skipUntil($type)`` - Tells the lexer to skip input tokens until it sees a token with the given value.
- ``isA($value, $token)`` - Checks if given value is identical to the given token.
- ``peek()`` - Moves the lookahead token forward.
- ``glimpse()`` - Peeks at the next token, returns it and immediately resets the peek.

View File

@@ -0,0 +1,6 @@
.. toctree::
:depth: 3
index
simple-parser-example
dql-parser

View File

@@ -0,0 +1,102 @@
Simple Parser Example
=====================
Extend the ``Doctrine\Common\Lexer\AbstractLexer`` class and implement
the ``getCatchablePatterns``, ``getNonCatchablePatterns``, and ``getType``
methods. Here is a very simple example lexer implementation named ``CharacterTypeLexer``.
It tokenizes a string to ``T_UPPER``, ``T_LOWER`` and``T_NUMBER`` tokens:
.. code-block:: php
<?php
use Doctrine\Common\Lexer\AbstractLexer;
class CharacterTypeLexer extends AbstractLexer
{
const T_UPPER = 1;
const T_LOWER = 2;
const T_NUMBER = 3;
protected function getCatchablePatterns()
{
return array(
'[a-bA-Z0-9]',
);
}
protected function getNonCatchablePatterns()
{
return array();
}
protected function getType(&$value)
{
if (is_numeric($value)) {
return self::T_NUMBER;
}
if (strtoupper($value) === $value) {
return self::T_UPPER;
}
if (strtolower($value) === $value) {
return self::T_LOWER;
}
}
}
Use ``CharacterTypeLexer`` to extract an array of upper case characters:
.. code-block:: php
<?php
class UpperCaseCharacterExtracter
{
private $lexer;
public function __construct(CharacterTypeLexer $lexer)
{
$this->lexer = $lexer;
}
public function getUpperCaseCharacters($string)
{
$this->lexer->setInput($string);
$this->lexer->moveNext();
$upperCaseChars = array();
while (true) {
if (!$this->lexer->lookahead) {
break;
}
$this->lexer->moveNext();
if ($this->lexer->token['type'] === CharacterTypeLexer::T_UPPER) {
$upperCaseChars[] = $this->lexer->token['value'];
}
}
return $upperCaseChars;
}
}
$upperCaseCharacterExtractor = new UpperCaseCharacterExtracter(new CharacterTypeLexer());
$upperCaseCharacters = $upperCaseCharacterExtractor->getUpperCaseCharacters('1aBcdEfgHiJ12');
print_r($upperCaseCharacters);
The variable ``$upperCaseCharacters`` contains all of the upper case
characters:
.. code-block:: php
Array
(
[0] => B
[1] => E
[2] => H
[3] => J
)
This is a simple example but it should demonstrate the low level API
that can be used to build more complex parsers.

View File

@@ -0,0 +1,332 @@
<?php
/*
* 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Lexer;
/**
* Base class for writing simple lexers, i.e. for creating small DSLs.
*
* @since 2.0
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
abstract class AbstractLexer
{
/**
* Lexer original input string.
*
* @var string
*/
private $input;
/**
* Array of scanned tokens.
*
* Each token is an associative array containing three items:
* - 'value' : the string value of the token in the input string
* - 'type' : the type of the token (identifier, numeric, string, input
* parameter, none)
* - 'position' : the position of the token in the input string
*
* @var array
*/
private $tokens = array();
/**
* Current lexer position in input string.
*
* @var integer
*/
private $position = 0;
/**
* Current peek of current lexer position.
*
* @var integer
*/
private $peek = 0;
/**
* The next token in the input.
*
* @var array
*/
public $lookahead;
/**
* The last matched/seen token.
*
* @var array
*/
public $token;
/**
* Sets the input data to be tokenized.
*
* The Lexer is immediately reset and the new input tokenized.
* Any unprocessed tokens from any previous input are lost.
*
* @param string $input The input to be tokenized.
*
* @return void
*/
public function setInput($input)
{
$this->input = $input;
$this->tokens = array();
$this->reset();
$this->scan($input);
}
/**
* Resets the lexer.
*
* @return void
*/
public function reset()
{
$this->lookahead = null;
$this->token = null;
$this->peek = 0;
$this->position = 0;
}
/**
* Resets the peek pointer to 0.
*
* @return void
*/
public function resetPeek()
{
$this->peek = 0;
}
/**
* Resets the lexer position on the input to the given position.
*
* @param integer $position Position to place the lexical scanner.
*
* @return void
*/
public function resetPosition($position = 0)
{
$this->position = $position;
}
/**
* Retrieve the original lexer's input until a given position.
*
* @param integer $position
*
* @return string
*/
public function getInputUntilPosition($position)
{
return substr($this->input, 0, $position);
}
/**
* Checks whether a given token matches the current lookahead.
*
* @param integer|string $token
*
* @return boolean
*/
public function isNextToken($token)
{
return null !== $this->lookahead && $this->lookahead['type'] === $token;
}
/**
* Checks whether any of the given tokens matches the current lookahead.
*
* @param array $tokens
*
* @return boolean
*/
public function isNextTokenAny(array $tokens)
{
return null !== $this->lookahead && in_array($this->lookahead['type'], $tokens, true);
}
/**
* Moves to the next token in the input string.
*
* @return boolean
*/
public function moveNext()
{
$this->peek = 0;
$this->token = $this->lookahead;
$this->lookahead = (isset($this->tokens[$this->position]))
? $this->tokens[$this->position++] : null;
return $this->lookahead !== null;
}
/**
* Tells the lexer to skip input tokens until it sees a token with the given value.
*
* @param string $type The token type to skip until.
*
* @return void
*/
public function skipUntil($type)
{
while ($this->lookahead !== null && $this->lookahead['type'] !== $type) {
$this->moveNext();
}
}
/**
* Checks if given value is identical to the given token.
*
* @param mixed $value
* @param integer $token
*
* @return boolean
*/
public function isA($value, $token)
{
return $this->getType($value) === $token;
}
/**
* Moves the lookahead token forward.
*
* @return array|null The next token or NULL if there are no more tokens ahead.
*/
public function peek()
{
if (isset($this->tokens[$this->position + $this->peek])) {
return $this->tokens[$this->position + $this->peek++];
} else {
return null;
}
}
/**
* Peeks at the next token, returns it and immediately resets the peek.
*
* @return array|null The next token or NULL if there are no more tokens ahead.
*/
public function glimpse()
{
$peek = $this->peek();
$this->peek = 0;
return $peek;
}
/**
* Scans the input string for tokens.
*
* @param string $input A query string.
*
* @return void
*/
protected function scan($input)
{
static $regex;
if ( ! isset($regex)) {
$regex = sprintf(
'/(%s)|%s/%s',
implode(')|(', $this->getCatchablePatterns()),
implode('|', $this->getNonCatchablePatterns()),
$this->getModifiers()
);
}
$flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE;
$matches = preg_split($regex, $input, -1, $flags);
if (false === $matches) {
// Work around https://bugs.php.net/78122
$matches = array(array($input, 0));
}
foreach ($matches as $match) {
// Must remain before 'value' assignment since it can change content
$type = $this->getType($match[0]);
$this->tokens[] = array(
'value' => $match[0],
'type' => $type,
'position' => $match[1],
);
}
}
/**
* Gets the literal for a given token.
*
* @param integer $token
*
* @return string
*/
public function getLiteral($token)
{
$className = get_class($this);
$reflClass = new \ReflectionClass($className);
$constants = $reflClass->getConstants();
foreach ($constants as $name => $value) {
if ($value === $token) {
return $className . '::' . $name;
}
}
return $token;
}
/**
* Regex modifiers
*
* @return string
*/
protected function getModifiers()
{
return 'i';
}
/**
* Lexical catchable patterns.
*
* @return array
*/
abstract protected function getCatchablePatterns();
/**
* Lexical non-catchable patterns.
*
* @return array
*/
abstract protected function getNonCatchablePatterns();
/**
* Retrieve token type. Also processes the token value if necessary.
*
* @param string $value
*
* @return integer
*/
abstract protected function getType(&$value);
}

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.8/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"
convertNoticesToExceptions="true"
>
<php>
<ini name="error_reporting" value="-1" />
</php>
<testsuites>
<testsuite name="Doctrine lexer Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">lib/Doctrine</directory>
</whitelist>
</filter>
</phpunit>

View File

@@ -0,0 +1,268 @@
<?php
namespace Doctrine\Tests\Common\Lexer;
class AbstractLexerTest extends \PHPUnit_Framework_TestCase
{
/**
* @var ConcreteLexer
*/
private $concreteLexer;
public function setUp()
{
$this->concreteLexer = new ConcreteLexer();
}
public function dataProvider()
{
return array(
array(
'price=10',
array(
array(
'value' => 'price',
'type' => 'string',
'position' => 0,
),
array(
'value' => '=',
'type' => 'operator',
'position' => 5,
),
array(
'value' => 10,
'type' => 'int',
'position' => 6,
),
),
),
);
}
public function testResetPeek()
{
$expectedTokens = array(
array(
'value' => 'price',
'type' => 'string',
'position' => 0,
),
array(
'value' => '=',
'type' => 'operator',
'position' => 5,
),
array(
'value' => 10,
'type' => 'int',
'position' => 6,
),
);
$this->concreteLexer->setInput('price=10');
$this->assertEquals($expectedTokens[0], $this->concreteLexer->peek());
$this->assertEquals($expectedTokens[1], $this->concreteLexer->peek());
$this->concreteLexer->resetPeek();
$this->assertEquals($expectedTokens[0], $this->concreteLexer->peek());
}
public function testResetPosition()
{
$expectedTokens = array(
array(
'value' => 'price',
'type' => 'string',
'position' => 0,
),
array(
'value' => '=',
'type' => 'operator',
'position' => 5,
),
array(
'value' => 10,
'type' => 'int',
'position' => 6,
),
);
$this->concreteLexer->setInput('price=10');
$this->assertNull($this->concreteLexer->lookahead);
$this->assertTrue($this->concreteLexer->moveNext());
$this->assertEquals($expectedTokens[0], $this->concreteLexer->lookahead);
$this->assertTrue($this->concreteLexer->moveNext());
$this->assertEquals($expectedTokens[1], $this->concreteLexer->lookahead);
$this->concreteLexer->resetPosition(0);
$this->assertTrue($this->concreteLexer->moveNext());
$this->assertEquals($expectedTokens[0], $this->concreteLexer->lookahead);
}
/**
* @dataProvider dataProvider
*
* @param $input
* @param $expectedTokens
*/
public function testMoveNext($input, $expectedTokens)
{
$this->concreteLexer->setInput($input);
$this->assertNull($this->concreteLexer->lookahead);
for ($i = 0; $i < count($expectedTokens); $i++) {
$this->assertTrue($this->concreteLexer->moveNext());
$this->assertEquals($expectedTokens[$i], $this->concreteLexer->lookahead);
}
$this->assertFalse($this->concreteLexer->moveNext());
$this->assertNull($this->concreteLexer->lookahead);
}
public function testSkipUntil()
{
$this->concreteLexer->setInput('price=10');
$this->assertTrue($this->concreteLexer->moveNext());
$this->concreteLexer->skipUntil('operator');
$this->assertEquals(
array(
'value' => '=',
'type' => 'operator',
'position' => 5,
),
$this->concreteLexer->lookahead
);
}
public function testUtf8Mismatch()
{
$this->concreteLexer->setInput("\xE9=10");
$this->assertTrue($this->concreteLexer->moveNext());
$this->assertEquals(
array(
'value' => "\xE9=10",
'type' => 'string',
'position' => 0,
),
$this->concreteLexer->lookahead
);
}
/**
* @dataProvider dataProvider
*
* @param $input
* @param $expectedTokens
*/
public function testPeek($input, $expectedTokens)
{
$this->concreteLexer->setInput($input);
foreach ($expectedTokens as $expectedToken) {
$this->assertEquals($expectedToken, $this->concreteLexer->peek());
}
$this->assertNull($this->concreteLexer->peek());
}
/**
* @dataProvider dataProvider
*
* @param $input
* @param $expectedTokens
*/
public function testGlimpse($input, $expectedTokens)
{
$this->concreteLexer->setInput($input);
foreach ($expectedTokens as $expectedToken) {
$this->assertEquals($expectedToken, $this->concreteLexer->glimpse());
$this->concreteLexer->moveNext();
}
$this->assertNull($this->concreteLexer->peek());
}
public function inputUntilPositionDataProvider()
{
return array(
array('price=10', 5, 'price'),
);
}
/**
* @dataProvider inputUntilPositionDataProvider
*
* @param $input
* @param $position
* @param $expectedInput
*/
public function testGetInputUntilPosition($input, $position, $expectedInput)
{
$this->concreteLexer->setInput($input);
$this->assertSame($expectedInput, $this->concreteLexer->getInputUntilPosition($position));
}
/**
* @dataProvider dataProvider
*
* @param $input
* @param $expectedTokens
*/
public function testIsNextToken($input, $expectedTokens)
{
$this->concreteLexer->setInput($input);
$this->concreteLexer->moveNext();
for ($i = 0; $i < count($expectedTokens); $i++) {
$this->assertTrue($this->concreteLexer->isNextToken($expectedTokens[$i]['type']));
$this->concreteLexer->moveNext();
}
}
/**
* @dataProvider dataProvider
*
* @param $input
* @param $expectedTokens
*/
public function testIsNextTokenAny($input, $expectedTokens)
{
$allTokenTypes = array_map(function ($token) {
return $token['type'];
}, $expectedTokens);
$this->concreteLexer->setInput($input);
$this->concreteLexer->moveNext();
for ($i = 0; $i < count($expectedTokens); $i++) {
$this->assertTrue($this->concreteLexer->isNextTokenAny(array($expectedTokens[$i]['type'])));
$this->assertTrue($this->concreteLexer->isNextTokenAny($allTokenTypes));
$this->concreteLexer->moveNext();
}
}
public function testGetLiteral()
{
$this->assertSame('Doctrine\Tests\Common\Lexer\ConcreteLexer::INT', $this->concreteLexer->getLiteral('int'));
$this->assertSame('fake_token', $this->concreteLexer->getLiteral('fake_token'));
}
public function testIsA()
{
$this->assertTrue($this->concreteLexer->isA(11, 'int'));
$this->assertTrue($this->concreteLexer->isA(1.1, 'int'));
$this->assertTrue($this->concreteLexer->isA('=', 'operator'));
$this->assertTrue($this->concreteLexer->isA('>', 'operator'));
$this->assertTrue($this->concreteLexer->isA('<', 'operator'));
$this->assertTrue($this->concreteLexer->isA('fake_text', 'string'));
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Doctrine\Tests\Common\Lexer;
use Doctrine\Common\Lexer\AbstractLexer;
class ConcreteLexer extends AbstractLexer
{
const INT = 'int';
protected function getCatchablePatterns()
{
return array(
'=|<|>',
'[a-z]+',
'\d+',
);
}
protected function getNonCatchablePatterns()
{
return array(
'\s+',
'(.)',
);
}
protected function getType(&$value)
{
if (is_numeric($value)) {
$value = (int)$value;
return 'int';
}
if (in_array($value, array('=', '<', '>'))) {
return 'operator';
}
if (is_string($value)) {
return 'string';
}
return;
}
protected function getModifiers()
{
return parent::getModifiers().'u';
}
}

View File

@@ -0,0 +1,19 @@
Copyright (c) 2013-2016 Eduardo Gulias Davis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
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
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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
THE SOFTWARE.

View File

@@ -0,0 +1,38 @@
{
"name": "egulias/email-validator",
"description": "A library for validating emails against several RFCs",
"homepage": "https://github.com/egulias/EmailValidator",
"keywords": ["email", "validation", "validator", "emailvalidation", "emailvalidator"],
"license": "MIT",
"authors": [
{"name": "Eduardo Gulias Davis"}
],
"extra": {
"branch-alias": {
"dev-master": "2.1.x-dev"
}
},
"require": {
"php": ">=5.5",
"doctrine/lexer": "^1.0.1",
"symfony/polyfill-intl-idn": "^1.10"
},
"require-dev": {
"dominicsayers/isemail": "^3.0.7",
"phpunit/phpunit": "^4.8.36|^7.5.15",
"satooshi/php-coveralls": "^1.0.1"
},
"suggest": {
"ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
},
"autoload": {
"psr-4": {
"Egulias\\EmailValidator\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Egulias\\EmailValidator\\Tests\\": "tests"
}
}
}

View File

@@ -0,0 +1,283 @@
<?php
namespace Egulias\EmailValidator;
use Doctrine\Common\Lexer\AbstractLexer;
class EmailLexer extends AbstractLexer
{
//ASCII values
const C_DEL = 127;
const C_NUL = 0;
const S_AT = 64;
const S_BACKSLASH = 92;
const S_DOT = 46;
const S_DQUOTE = 34;
const S_SQUOTE = 39;
const S_BACKTICK = 96;
const S_OPENPARENTHESIS = 49;
const S_CLOSEPARENTHESIS = 261;
const S_OPENBRACKET = 262;
const S_CLOSEBRACKET = 263;
const S_HYPHEN = 264;
const S_COLON = 265;
const S_DOUBLECOLON = 266;
const S_SP = 267;
const S_HTAB = 268;
const S_CR = 269;
const S_LF = 270;
const S_IPV6TAG = 271;
const S_LOWERTHAN = 272;
const S_GREATERTHAN = 273;
const S_COMMA = 274;
const S_SEMICOLON = 275;
const S_OPENQBRACKET = 276;
const S_CLOSEQBRACKET = 277;
const S_SLASH = 278;
const S_EMPTY = null;
const GENERIC = 300;
const CRLF = 301;
const INVALID = 302;
const ASCII_INVALID_FROM = 127;
const ASCII_INVALID_TO = 199;
/**
* US-ASCII visible characters not valid for atext (@link http://tools.ietf.org/html/rfc5322#section-3.2.3)
*
* @var array
*/
protected $charValue = array(
'(' => self::S_OPENPARENTHESIS,
')' => self::S_CLOSEPARENTHESIS,
'<' => self::S_LOWERTHAN,
'>' => self::S_GREATERTHAN,
'[' => self::S_OPENBRACKET,
']' => self::S_CLOSEBRACKET,
':' => self::S_COLON,
';' => self::S_SEMICOLON,
'@' => self::S_AT,
'\\' => self::S_BACKSLASH,
'/' => self::S_SLASH,
',' => self::S_COMMA,
'.' => self::S_DOT,
"'" => self::S_SQUOTE,
"`" => self::S_BACKTICK,
'"' => self::S_DQUOTE,
'-' => self::S_HYPHEN,
'::' => self::S_DOUBLECOLON,
' ' => self::S_SP,
"\t" => self::S_HTAB,
"\r" => self::S_CR,
"\n" => self::S_LF,
"\r\n" => self::CRLF,
'IPv6' => self::S_IPV6TAG,
'{' => self::S_OPENQBRACKET,
'}' => self::S_CLOSEQBRACKET,
'' => self::S_EMPTY,
'\0' => self::C_NUL,
);
/**
* @var bool
*/
protected $hasInvalidTokens = false;
/**
* @var array
*
* @psalm-var array{value:string, type:null|int, position:int}|array<empty, empty>
*/
protected $previous = [];
/**
* The last matched/seen token.
*
* @var array
*
* @psalm-var array{value:string, type:null|int, position:int}
*/
public $token;
/**
* The next token in the input.
*
* @var array|null
*/
public $lookahead;
/**
* @psalm-var array{value:'', type:null, position:0}
*/
private static $nullToken = [
'value' => '',
'type' => null,
'position' => 0,
];
public function __construct()
{
$this->previous = $this->token = self::$nullToken;
$this->lookahead = null;
}
/**
* @return void
*/
public function reset()
{
$this->hasInvalidTokens = false;
parent::reset();
$this->previous = $this->token = self::$nullToken;
}
/**
* @return bool
*/
public function hasInvalidTokens()
{
return $this->hasInvalidTokens;
}
/**
* @param int $type
* @throws \UnexpectedValueException
* @return boolean
*
* @psalm-suppress InvalidScalarArgument
*/
public function find($type)
{
$search = clone $this;
$search->skipUntil($type);
if (!$search->lookahead) {
throw new \UnexpectedValueException($type . ' not found');
}
return true;
}
/**
* getPrevious
*
* @return array
*/
public function getPrevious()
{
return $this->previous;
}
/**
* moveNext
*
* @return boolean
*/
public function moveNext()
{
$this->previous = $this->token;
$hasNext = parent::moveNext();
$this->token = $this->token ?: self::$nullToken;
return $hasNext;
}
/**
* Lexical catchable patterns.
*
* @return string[]
*/
protected function getCatchablePatterns()
{
return array(
'[a-zA-Z_]+[46]?', //ASCII and domain literal
'[^\x00-\x7F]', //UTF-8
'[0-9]+',
'\r\n',
'::',
'\s+?',
'.',
);
}
/**
* Lexical non-catchable patterns.
*
* @return string[]
*/
protected function getNonCatchablePatterns()
{
return array('[\xA0-\xff]+');
}
/**
* Retrieve token type. Also processes the token value if necessary.
*
* @param string $value
* @throws \InvalidArgumentException
* @return integer
*/
protected function getType(&$value)
{
if ($this->isNullType($value)) {
return self::C_NUL;
}
if ($this->isValid($value)) {
return $this->charValue[$value];
}
if ($this->isUTF8Invalid($value)) {
$this->hasInvalidTokens = true;
return self::INVALID;
}
return self::GENERIC;
}
/**
* @param string $value
*
* @return bool
*/
protected function isValid($value)
{
if (isset($this->charValue[$value])) {
return true;
}
return false;
}
/**
* @param string $value
* @return bool
*/
protected function isNullType($value)
{
if ($value === "\0") {
return true;
}
return false;
}
/**
* @param string $value
* @return bool
*/
protected function isUTF8Invalid($value)
{
if (preg_match('/\p{Cc}+/u', $value)) {
return true;
}
return false;
}
/**
* @return string
*/
protected function getModifiers()
{
return 'iu';
}
}

View File

@@ -0,0 +1,137 @@
<?php
namespace Egulias\EmailValidator;
use Egulias\EmailValidator\Exception\ExpectingATEXT;
use Egulias\EmailValidator\Exception\NoLocalPart;
use Egulias\EmailValidator\Parser\DomainPart;
use Egulias\EmailValidator\Parser\LocalPart;
use Egulias\EmailValidator\Warning\EmailTooLong;
/**
* EmailParser
*
* @author Eduardo Gulias Davis <me@egulias.com>
*/
class EmailParser
{
const EMAIL_MAX_LENGTH = 254;
/**
* @var array
*/
protected $warnings = [];
/**
* @var string
*/
protected $domainPart = '';
/**
* @var string
*/
protected $localPart = '';
/**
* @var EmailLexer
*/
protected $lexer;
/**
* @var LocalPart
*/
protected $localPartParser;
/**
* @var DomainPart
*/
protected $domainPartParser;
public function __construct(EmailLexer $lexer)
{
$this->lexer = $lexer;
$this->localPartParser = new LocalPart($this->lexer);
$this->domainPartParser = new DomainPart($this->lexer);
}
/**
* @param string $str
* @return array
*/
public function parse($str)
{
$this->lexer->setInput($str);
if (!$this->hasAtToken()) {
throw new NoLocalPart();
}
$this->localPartParser->parse($str);
$this->domainPartParser->parse($str);
$this->setParts($str);
if ($this->lexer->hasInvalidTokens()) {
throw new ExpectingATEXT();
}
return array('local' => $this->localPart, 'domain' => $this->domainPart);
}
/**
* @return Warning\Warning[]
*/
public function getWarnings()
{
$localPartWarnings = $this->localPartParser->getWarnings();
$domainPartWarnings = $this->domainPartParser->getWarnings();
$this->warnings = array_merge($localPartWarnings, $domainPartWarnings);
$this->addLongEmailWarning($this->localPart, $this->domainPart);
return $this->warnings;
}
/**
* @return string
*/
public function getParsedDomainPart()
{
return $this->domainPart;
}
/**
* @param string $email
*/
protected function setParts($email)
{
$parts = explode('@', $email);
$this->domainPart = $this->domainPartParser->getDomainPart();
$this->localPart = $parts[0];
}
/**
* @return bool
*/
protected function hasAtToken()
{
$this->lexer->moveNext();
$this->lexer->moveNext();
if ($this->lexer->token['type'] === EmailLexer::S_AT) {
return false;
}
return true;
}
/**
* @param string $localPart
* @param string $parsedDomainPart
*/
protected function addLongEmailWarning($localPart, $parsedDomainPart)
{
if (strlen($localPart . '@' . $parsedDomainPart) > self::EMAIL_MAX_LENGTH) {
$this->warnings[EmailTooLong::CODE] = new EmailTooLong();
}
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace Egulias\EmailValidator;
use Egulias\EmailValidator\Exception\InvalidEmail;
use Egulias\EmailValidator\Validation\EmailValidation;
class EmailValidator
{
/**
* @var EmailLexer
*/
private $lexer;
/**
* @var Warning\Warning[]
*/
protected $warnings = [];
/**
* @var InvalidEmail|null
*/
protected $error;
public function __construct()
{
$this->lexer = new EmailLexer();
}
/**
* @param string $email
* @param EmailValidation $emailValidation
* @return bool
*/
public function isValid($email, EmailValidation $emailValidation)
{
$isValid = $emailValidation->isValid($email, $this->lexer);
$this->warnings = $emailValidation->getWarnings();
$this->error = $emailValidation->getError();
return $isValid;
}
/**
* @return boolean
*/
public function hasWarnings()
{
return !empty($this->warnings);
}
/**
* @return array
*/
public function getWarnings()
{
return $this->warnings;
}
/**
* @return InvalidEmail|null
*/
public function getError()
{
return $this->error;
}
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class AtextAfterCFWS extends InvalidEmail
{
const CODE = 133;
const REASON = "ATEXT found after CFWS";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class CRLFAtTheEnd extends InvalidEmail
{
const CODE = 149;
const REASON = "CRLF at the end";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class CRLFX2 extends InvalidEmail
{
const CODE = 148;
const REASON = "Folding whitespace CR LF found twice";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class CRNoLF extends InvalidEmail
{
const CODE = 150;
const REASON = "Missing LF after CR";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class CharNotAllowed extends InvalidEmail
{
const CODE = 201;
const REASON = "Non allowed character in domain";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class CommaInDomain extends InvalidEmail
{
const CODE = 200;
const REASON = "Comma ',' is not allowed in domain part";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class ConsecutiveAt extends InvalidEmail
{
const CODE = 128;
const REASON = "Consecutive AT";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class ConsecutiveDot extends InvalidEmail
{
const CODE = 132;
const REASON = "Consecutive DOT";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class DomainAcceptsNoMail extends InvalidEmail
{
const CODE = 154;
const REASON = 'Domain accepts no mail (Null MX, RFC7505)';
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class DomainHyphened extends InvalidEmail
{
const CODE = 144;
const REASON = "Hyphen found in domain";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class DotAtEnd extends InvalidEmail
{
const CODE = 142;
const REASON = "Dot at the end";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class DotAtStart extends InvalidEmail
{
const CODE = 141;
const REASON = "Found DOT at start";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class ExpectingAT extends InvalidEmail
{
const CODE = 202;
const REASON = "Expecting AT '@' ";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class ExpectingATEXT extends InvalidEmail
{
const CODE = 137;
const REASON = "Expecting ATEXT";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class ExpectingCTEXT extends InvalidEmail
{
const CODE = 139;
const REASON = "Expecting CTEXT";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class ExpectingDTEXT extends InvalidEmail
{
const CODE = 129;
const REASON = "Expected DTEXT";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class ExpectingDomainLiteralClose extends InvalidEmail
{
const CODE = 137;
const REASON = "Closing bracket ']' for domain literal not found";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class ExpectingQPair extends InvalidEmail
{
const CODE = 136;
const REASON = "Expecting QPAIR";
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Egulias\EmailValidator\Exception;
abstract class InvalidEmail extends \InvalidArgumentException
{
const REASON = "Invalid email";
const CODE = 0;
public function __construct()
{
parent::__construct(static::REASON, static::CODE);
}
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class LocalOrReservedDomain extends InvalidEmail
{
const CODE = 153;
const REASON = 'Local, mDNS or reserved domain (RFC2606, RFC6762)';
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class NoDNSRecord extends InvalidEmail
{
const CODE = 5;
const REASON = 'No MX or A DSN record was found for this email';
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class NoDomainPart extends InvalidEmail
{
const CODE = 131;
const REASON = "No Domain part";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class NoLocalPart extends InvalidEmail
{
const CODE = 130;
const REASON = "No local part";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class UnclosedComment extends InvalidEmail
{
const CODE = 146;
const REASON = "No closing comment token found";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class UnclosedQuotedString extends InvalidEmail
{
const CODE = 145;
const REASON = "Unclosed quoted string";
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Egulias\EmailValidator\Exception;
class UnopenedComment extends InvalidEmail
{
const CODE = 152;
const REASON = "No opening comment token found";
}

View File

@@ -0,0 +1,443 @@
<?php
namespace Egulias\EmailValidator\Parser;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Exception\CharNotAllowed;
use Egulias\EmailValidator\Exception\CommaInDomain;
use Egulias\EmailValidator\Exception\ConsecutiveAt;
use Egulias\EmailValidator\Exception\CRLFAtTheEnd;
use Egulias\EmailValidator\Exception\CRNoLF;
use Egulias\EmailValidator\Exception\DomainHyphened;
use Egulias\EmailValidator\Exception\DotAtEnd;
use Egulias\EmailValidator\Exception\DotAtStart;
use Egulias\EmailValidator\Exception\ExpectingATEXT;
use Egulias\EmailValidator\Exception\ExpectingDomainLiteralClose;
use Egulias\EmailValidator\Exception\ExpectingDTEXT;
use Egulias\EmailValidator\Exception\NoDomainPart;
use Egulias\EmailValidator\Exception\UnopenedComment;
use Egulias\EmailValidator\Warning\AddressLiteral;
use Egulias\EmailValidator\Warning\CFWSWithFWS;
use Egulias\EmailValidator\Warning\DeprecatedComment;
use Egulias\EmailValidator\Warning\DomainLiteral;
use Egulias\EmailValidator\Warning\DomainTooLong;
use Egulias\EmailValidator\Warning\IPV6BadChar;
use Egulias\EmailValidator\Warning\IPV6ColonEnd;
use Egulias\EmailValidator\Warning\IPV6ColonStart;
use Egulias\EmailValidator\Warning\IPV6Deprecated;
use Egulias\EmailValidator\Warning\IPV6DoubleColon;
use Egulias\EmailValidator\Warning\IPV6GroupCount;
use Egulias\EmailValidator\Warning\IPV6MaxGroups;
use Egulias\EmailValidator\Warning\LabelTooLong;
use Egulias\EmailValidator\Warning\ObsoleteDTEXT;
use Egulias\EmailValidator\Warning\TLD;
class DomainPart extends Parser
{
const DOMAIN_MAX_LENGTH = 254;
const LABEL_MAX_LENGTH = 63;
/**
* @var string
*/
protected $domainPart = '';
public function parse($domainPart)
{
$this->lexer->moveNext();
$this->performDomainStartChecks();
$domain = $this->doParseDomainPart();
$prev = $this->lexer->getPrevious();
$length = strlen($domain);
if ($prev['type'] === EmailLexer::S_DOT) {
throw new DotAtEnd();
}
if ($prev['type'] === EmailLexer::S_HYPHEN) {
throw new DomainHyphened();
}
if ($length > self::DOMAIN_MAX_LENGTH) {
$this->warnings[DomainTooLong::CODE] = new DomainTooLong();
}
if ($prev['type'] === EmailLexer::S_CR) {
throw new CRLFAtTheEnd();
}
$this->domainPart = $domain;
}
private function performDomainStartChecks()
{
$this->checkInvalidTokensAfterAT();
$this->checkEmptyDomain();
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
$this->warnings[DeprecatedComment::CODE] = new DeprecatedComment();
$this->parseDomainComments();
}
}
private function checkEmptyDomain()
{
$thereIsNoDomain = $this->lexer->token['type'] === EmailLexer::S_EMPTY ||
($this->lexer->token['type'] === EmailLexer::S_SP &&
!$this->lexer->isNextToken(EmailLexer::GENERIC));
if ($thereIsNoDomain) {
throw new NoDomainPart();
}
}
private function checkInvalidTokensAfterAT()
{
if ($this->lexer->token['type'] === EmailLexer::S_DOT) {
throw new DotAtStart();
}
if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN) {
throw new DomainHyphened();
}
}
/**
* @return string
*/
public function getDomainPart()
{
return $this->domainPart;
}
/**
* @param string $addressLiteral
* @param int $maxGroups
*/
public function checkIPV6Tag($addressLiteral, $maxGroups = 8)
{
$prev = $this->lexer->getPrevious();
if ($prev['type'] === EmailLexer::S_COLON) {
$this->warnings[IPV6ColonEnd::CODE] = new IPV6ColonEnd();
}
$IPv6 = substr($addressLiteral, 5);
//Daniel Marschall's new IPv6 testing strategy
$matchesIP = explode(':', $IPv6);
$groupCount = count($matchesIP);
$colons = strpos($IPv6, '::');
if (count(preg_grep('/^[0-9A-Fa-f]{0,4}$/', $matchesIP, PREG_GREP_INVERT)) !== 0) {
$this->warnings[IPV6BadChar::CODE] = new IPV6BadChar();
}
if ($colons === false) {
// We need exactly the right number of groups
if ($groupCount !== $maxGroups) {
$this->warnings[IPV6GroupCount::CODE] = new IPV6GroupCount();
}
return;
}
if ($colons !== strrpos($IPv6, '::')) {
$this->warnings[IPV6DoubleColon::CODE] = new IPV6DoubleColon();
return;
}
if ($colons === 0 || $colons === (strlen($IPv6) - 2)) {
// RFC 4291 allows :: at the start or end of an address
//with 7 other groups in addition
++$maxGroups;
}
if ($groupCount > $maxGroups) {
$this->warnings[IPV6MaxGroups::CODE] = new IPV6MaxGroups();
} elseif ($groupCount === $maxGroups) {
$this->warnings[IPV6Deprecated::CODE] = new IPV6Deprecated();
}
}
/**
* @return string
*/
protected function doParseDomainPart()
{
$domain = '';
$label = '';
$openedParenthesis = 0;
do {
$prev = $this->lexer->getPrevious();
$this->checkNotAllowedChars($this->lexer->token);
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
$this->parseComments();
$openedParenthesis += $this->getOpenedParenthesis();
$this->lexer->moveNext();
$tmpPrev = $this->lexer->getPrevious();
if ($tmpPrev['type'] === EmailLexer::S_CLOSEPARENTHESIS) {
$openedParenthesis--;
}
}
if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) {
if ($openedParenthesis === 0) {
throw new UnopenedComment();
} else {
$openedParenthesis--;
}
}
$this->checkConsecutiveDots();
$this->checkDomainPartExceptions($prev);
if ($this->hasBrackets()) {
$this->parseDomainLiteral();
}
if ($this->lexer->token['type'] === EmailLexer::S_DOT) {
$this->checkLabelLength($label);
$label = '';
} else {
$label .= $this->lexer->token['value'];
}
if ($this->isFWS()) {
$this->parseFWS();
}
$domain .= $this->lexer->token['value'];
$this->lexer->moveNext();
if ($this->lexer->token['type'] === EmailLexer::S_SP) {
throw new CharNotAllowed();
}
} while (null !== $this->lexer->token['type']);
$this->checkLabelLength($label);
return $domain;
}
private function checkNotAllowedChars(array $token)
{
$notAllowed = [EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true];
if (isset($notAllowed[$token['type']])) {
throw new CharNotAllowed();
}
}
/**
* @return string|false
*/
protected function parseDomainLiteral()
{
if ($this->lexer->isNextToken(EmailLexer::S_COLON)) {
$this->warnings[IPV6ColonStart::CODE] = new IPV6ColonStart();
}
if ($this->lexer->isNextToken(EmailLexer::S_IPV6TAG)) {
$lexer = clone $this->lexer;
$lexer->moveNext();
if ($lexer->isNextToken(EmailLexer::S_DOUBLECOLON)) {
$this->warnings[IPV6ColonStart::CODE] = new IPV6ColonStart();
}
}
return $this->doParseDomainLiteral();
}
/**
* @return string|false
*/
protected function doParseDomainLiteral()
{
$IPv6TAG = false;
$addressLiteral = '';
do {
if ($this->lexer->token['type'] === EmailLexer::C_NUL) {
throw new ExpectingDTEXT();
}
if ($this->lexer->token['type'] === EmailLexer::INVALID ||
$this->lexer->token['type'] === EmailLexer::C_DEL ||
$this->lexer->token['type'] === EmailLexer::S_LF
) {
$this->warnings[ObsoleteDTEXT::CODE] = new ObsoleteDTEXT();
}
if ($this->lexer->isNextTokenAny(array(EmailLexer::S_OPENQBRACKET, EmailLexer::S_OPENBRACKET))) {
throw new ExpectingDTEXT();
}
if ($this->lexer->isNextTokenAny(
array(EmailLexer::S_HTAB, EmailLexer::S_SP, $this->lexer->token['type'] === EmailLexer::CRLF)
)) {
$this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
$this->parseFWS();
}
if ($this->lexer->isNextToken(EmailLexer::S_CR)) {
throw new CRNoLF();
}
if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH) {
$this->warnings[ObsoleteDTEXT::CODE] = new ObsoleteDTEXT();
$addressLiteral .= $this->lexer->token['value'];
$this->lexer->moveNext();
$this->validateQuotedPair();
}
if ($this->lexer->token['type'] === EmailLexer::S_IPV6TAG) {
$IPv6TAG = true;
}
if ($this->lexer->token['type'] === EmailLexer::S_CLOSEQBRACKET) {
break;
}
$addressLiteral .= $this->lexer->token['value'];
} while ($this->lexer->moveNext());
$addressLiteral = str_replace('[', '', $addressLiteral);
$addressLiteral = $this->checkIPV4Tag($addressLiteral);
if (false === $addressLiteral) {
return $addressLiteral;
}
if (!$IPv6TAG) {
$this->warnings[DomainLiteral::CODE] = new DomainLiteral();
return $addressLiteral;
}
$this->warnings[AddressLiteral::CODE] = new AddressLiteral();
$this->checkIPV6Tag($addressLiteral);
return $addressLiteral;
}
/**
* @param string $addressLiteral
*
* @return string|false
*/
protected function checkIPV4Tag($addressLiteral)
{
$matchesIP = array();
// Extract IPv4 part from the end of the address-literal (if there is one)
if (preg_match(
'/\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/',
$addressLiteral,
$matchesIP
) > 0
) {
$index = strrpos($addressLiteral, $matchesIP[0]);
if ($index === 0) {
$this->warnings[AddressLiteral::CODE] = new AddressLiteral();
return false;
}
// Convert IPv4 part to IPv6 format for further testing
$addressLiteral = substr($addressLiteral, 0, (int) $index) . '0:0';
}
return $addressLiteral;
}
protected function checkDomainPartExceptions(array $prev)
{
$invalidDomainTokens = array(
EmailLexer::S_DQUOTE => true,
EmailLexer::S_SQUOTE => true,
EmailLexer::S_BACKTICK => true,
EmailLexer::S_SEMICOLON => true,
EmailLexer::S_GREATERTHAN => true,
EmailLexer::S_LOWERTHAN => true,
);
if (isset($invalidDomainTokens[$this->lexer->token['type']])) {
throw new ExpectingATEXT();
}
if ($this->lexer->token['type'] === EmailLexer::S_COMMA) {
throw new CommaInDomain();
}
if ($this->lexer->token['type'] === EmailLexer::S_AT) {
throw new ConsecutiveAt();
}
if ($this->lexer->token['type'] === EmailLexer::S_OPENQBRACKET && $prev['type'] !== EmailLexer::S_AT) {
throw new ExpectingATEXT();
}
if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN && $this->lexer->isNextToken(EmailLexer::S_DOT)) {
throw new DomainHyphened();
}
if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH
&& $this->lexer->isNextToken(EmailLexer::GENERIC)) {
throw new ExpectingATEXT();
}
}
/**
* @return bool
*/
protected function hasBrackets()
{
if ($this->lexer->token['type'] !== EmailLexer::S_OPENBRACKET) {
return false;
}
try {
$this->lexer->find(EmailLexer::S_CLOSEBRACKET);
} catch (\RuntimeException $e) {
throw new ExpectingDomainLiteralClose();
}
return true;
}
/**
* @param string $label
*/
protected function checkLabelLength($label)
{
if ($this->isLabelTooLong($label)) {
$this->warnings[LabelTooLong::CODE] = new LabelTooLong();
}
}
/**
* @param string $label
* @return bool
*/
private function isLabelTooLong($label)
{
if (preg_match('/[^\x00-\x7F]/', $label)) {
idn_to_ascii($label, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, $idnaInfo);
return (bool) ($idnaInfo['errors'] & IDNA_ERROR_LABEL_TOO_LONG);
}
return strlen($label) > self::LABEL_MAX_LENGTH;
}
protected function parseDomainComments()
{
$this->isUnclosedComment();
while (!$this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) {
$this->warnEscaping();
$this->lexer->moveNext();
}
$this->lexer->moveNext();
if ($this->lexer->isNextToken(EmailLexer::S_DOT)) {
throw new ExpectingATEXT();
}
}
protected function addTLDWarnings()
{
if ($this->warnings[DomainLiteral::CODE]) {
$this->warnings[TLD::CODE] = new TLD();
}
}
}

View File

@@ -0,0 +1,145 @@
<?php
namespace Egulias\EmailValidator\Parser;
use Egulias\EmailValidator\Exception\DotAtEnd;
use Egulias\EmailValidator\Exception\DotAtStart;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Exception\ExpectingAT;
use Egulias\EmailValidator\Exception\ExpectingATEXT;
use Egulias\EmailValidator\Exception\UnclosedQuotedString;
use Egulias\EmailValidator\Exception\UnopenedComment;
use Egulias\EmailValidator\Warning\CFWSWithFWS;
use Egulias\EmailValidator\Warning\LocalTooLong;
class LocalPart extends Parser
{
public function parse($localPart)
{
$parseDQuote = true;
$closingQuote = false;
$openedParenthesis = 0;
$totalLength = 0;
while ($this->lexer->token['type'] !== EmailLexer::S_AT && null !== $this->lexer->token['type']) {
if ($this->lexer->token['type'] === EmailLexer::S_DOT && null === $this->lexer->getPrevious()['type']) {
throw new DotAtStart();
}
$closingQuote = $this->checkDQUOTE($closingQuote);
if ($closingQuote && $parseDQuote) {
$parseDQuote = $this->parseDoubleQuote();
}
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
$this->parseComments();
$openedParenthesis += $this->getOpenedParenthesis();
}
if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) {
if ($openedParenthesis === 0) {
throw new UnopenedComment();
}
$openedParenthesis--;
}
$this->checkConsecutiveDots();
if ($this->lexer->token['type'] === EmailLexer::S_DOT &&
$this->lexer->isNextToken(EmailLexer::S_AT)
) {
throw new DotAtEnd();
}
$this->warnEscaping();
$this->isInvalidToken($this->lexer->token, $closingQuote);
if ($this->isFWS()) {
$this->parseFWS();
}
$totalLength += strlen($this->lexer->token['value']);
$this->lexer->moveNext();
}
if ($totalLength > LocalTooLong::LOCAL_PART_LENGTH) {
$this->warnings[LocalTooLong::CODE] = new LocalTooLong();
}
}
/**
* @return bool
*/
protected function parseDoubleQuote()
{
$parseAgain = true;
$special = array(
EmailLexer::S_CR => true,
EmailLexer::S_HTAB => true,
EmailLexer::S_LF => true
);
$invalid = array(
EmailLexer::C_NUL => true,
EmailLexer::S_HTAB => true,
EmailLexer::S_CR => true,
EmailLexer::S_LF => true
);
$setSpecialsWarning = true;
$this->lexer->moveNext();
while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && null !== $this->lexer->token['type']) {
$parseAgain = false;
if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) {
$this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
$setSpecialsWarning = false;
}
if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH && $this->lexer->isNextToken(EmailLexer::S_DQUOTE)) {
$this->lexer->moveNext();
}
$this->lexer->moveNext();
if (!$this->escaped() && isset($invalid[$this->lexer->token['type']])) {
throw new ExpectingATEXT();
}
}
$prev = $this->lexer->getPrevious();
if ($prev['type'] === EmailLexer::S_BACKSLASH) {
if (!$this->checkDQUOTE(false)) {
throw new UnclosedQuotedString();
}
}
if (!$this->lexer->isNextToken(EmailLexer::S_AT) && $prev['type'] !== EmailLexer::S_BACKSLASH) {
throw new ExpectingAT();
}
return $parseAgain;
}
/**
* @param bool $closingQuote
*/
protected function isInvalidToken(array $token, $closingQuote)
{
$forbidden = array(
EmailLexer::S_COMMA,
EmailLexer::S_CLOSEBRACKET,
EmailLexer::S_OPENBRACKET,
EmailLexer::S_GREATERTHAN,
EmailLexer::S_LOWERTHAN,
EmailLexer::S_COLON,
EmailLexer::S_SEMICOLON,
EmailLexer::INVALID
);
if (in_array($token['type'], $forbidden) && !$closingQuote) {
throw new ExpectingATEXT();
}
}
}

View File

@@ -0,0 +1,249 @@
<?php
namespace Egulias\EmailValidator\Parser;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Exception\AtextAfterCFWS;
use Egulias\EmailValidator\Exception\ConsecutiveDot;
use Egulias\EmailValidator\Exception\CRLFAtTheEnd;
use Egulias\EmailValidator\Exception\CRLFX2;
use Egulias\EmailValidator\Exception\CRNoLF;
use Egulias\EmailValidator\Exception\ExpectingQPair;
use Egulias\EmailValidator\Exception\ExpectingATEXT;
use Egulias\EmailValidator\Exception\ExpectingCTEXT;
use Egulias\EmailValidator\Exception\UnclosedComment;
use Egulias\EmailValidator\Exception\UnclosedQuotedString;
use Egulias\EmailValidator\Warning\CFWSNearAt;
use Egulias\EmailValidator\Warning\CFWSWithFWS;
use Egulias\EmailValidator\Warning\Comment;
use Egulias\EmailValidator\Warning\QuotedPart;
use Egulias\EmailValidator\Warning\QuotedString;
abstract class Parser
{
/**
* @var array
*/
protected $warnings = [];
/**
* @var EmailLexer
*/
protected $lexer;
/**
* @var int
*/
protected $openedParenthesis = 0;
public function __construct(EmailLexer $lexer)
{
$this->lexer = $lexer;
}
/**
* @return \Egulias\EmailValidator\Warning\Warning[]
*/
public function getWarnings()
{
return $this->warnings;
}
/**
* @param string $str
*/
abstract public function parse($str);
/** @return int */
public function getOpenedParenthesis()
{
return $this->openedParenthesis;
}
/**
* validateQuotedPair
*/
protected function validateQuotedPair()
{
if (!($this->lexer->token['type'] === EmailLexer::INVALID
|| $this->lexer->token['type'] === EmailLexer::C_DEL)) {
throw new ExpectingQPair();
}
$this->warnings[QuotedPart::CODE] =
new QuotedPart($this->lexer->getPrevious()['type'], $this->lexer->token['type']);
}
protected function parseComments()
{
$this->openedParenthesis = 1;
$this->isUnclosedComment();
$this->warnings[Comment::CODE] = new Comment();
while (!$this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) {
if ($this->lexer->isNextToken(EmailLexer::S_OPENPARENTHESIS)) {
$this->openedParenthesis++;
}
$this->warnEscaping();
$this->lexer->moveNext();
}
$this->lexer->moveNext();
if ($this->lexer->isNextTokenAny(array(EmailLexer::GENERIC, EmailLexer::S_EMPTY))) {
throw new ExpectingATEXT();
}
if ($this->lexer->isNextToken(EmailLexer::S_AT)) {
$this->warnings[CFWSNearAt::CODE] = new CFWSNearAt();
}
}
/**
* @return bool
*/
protected function isUnclosedComment()
{
try {
$this->lexer->find(EmailLexer::S_CLOSEPARENTHESIS);
return true;
} catch (\RuntimeException $e) {
throw new UnclosedComment();
}
}
protected function parseFWS()
{
$previous = $this->lexer->getPrevious();
$this->checkCRLFInFWS();
if ($this->lexer->token['type'] === EmailLexer::S_CR) {
throw new CRNoLF();
}
if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] !== EmailLexer::S_AT) {
throw new AtextAfterCFWS();
}
if ($this->lexer->token['type'] === EmailLexer::S_LF || $this->lexer->token['type'] === EmailLexer::C_NUL) {
throw new ExpectingCTEXT();
}
if ($this->lexer->isNextToken(EmailLexer::S_AT) || $previous['type'] === EmailLexer::S_AT) {
$this->warnings[CFWSNearAt::CODE] = new CFWSNearAt();
} else {
$this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
}
}
protected function checkConsecutiveDots()
{
if ($this->lexer->token['type'] === EmailLexer::S_DOT && $this->lexer->isNextToken(EmailLexer::S_DOT)) {
throw new ConsecutiveDot();
}
}
/**
* @return bool
*/
protected function isFWS()
{
if ($this->escaped()) {
return false;
}
if ($this->lexer->token['type'] === EmailLexer::S_SP ||
$this->lexer->token['type'] === EmailLexer::S_HTAB ||
$this->lexer->token['type'] === EmailLexer::S_CR ||
$this->lexer->token['type'] === EmailLexer::S_LF ||
$this->lexer->token['type'] === EmailLexer::CRLF
) {
return true;
}
return false;
}
/**
* @return bool
*/
protected function escaped()
{
$previous = $this->lexer->getPrevious();
if ($previous && $previous['type'] === EmailLexer::S_BACKSLASH
&&
$this->lexer->token['type'] !== EmailLexer::GENERIC
) {
return true;
}
return false;
}
/**
* @return bool
*/
protected function warnEscaping()
{
if ($this->lexer->token['type'] !== EmailLexer::S_BACKSLASH) {
return false;
}
if ($this->lexer->isNextToken(EmailLexer::GENERIC)) {
throw new ExpectingATEXT();
}
if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB, EmailLexer::C_DEL))) {
return false;
}
$this->warnings[QuotedPart::CODE] =
new QuotedPart($this->lexer->getPrevious()['type'], $this->lexer->token['type']);
return true;
}
/**
* @param bool $hasClosingQuote
*
* @return bool
*/
protected function checkDQUOTE($hasClosingQuote)
{
if ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE) {
return $hasClosingQuote;
}
if ($hasClosingQuote) {
return $hasClosingQuote;
}
$previous = $this->lexer->getPrevious();
if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] === EmailLexer::GENERIC) {
throw new ExpectingATEXT();
}
try {
$this->lexer->find(EmailLexer::S_DQUOTE);
$hasClosingQuote = true;
} catch (\Exception $e) {
throw new UnclosedQuotedString();
}
$this->warnings[QuotedString::CODE] = new QuotedString($previous['value'], $this->lexer->token['value']);
return $hasClosingQuote;
}
protected function checkCRLFInFWS()
{
if ($this->lexer->token['type'] !== EmailLexer::CRLF) {
return;
}
if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) {
throw new CRLFX2();
}
if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) {
throw new CRLFAtTheEnd();
}
}
}

View File

@@ -0,0 +1,166 @@
<?php
namespace Egulias\EmailValidator\Validation;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Exception\InvalidEmail;
use Egulias\EmailValidator\Exception\LocalOrReservedDomain;
use Egulias\EmailValidator\Exception\DomainAcceptsNoMail;
use Egulias\EmailValidator\Warning\NoDNSMXRecord;
use Egulias\EmailValidator\Exception\NoDNSRecord;
class DNSCheckValidation implements EmailValidation
{
/**
* @var array
*/
private $warnings = [];
/**
* @var InvalidEmail|null
*/
private $error;
/**
* @var array
*/
private $mxRecords = [];
public function __construct()
{
if (!function_exists('idn_to_ascii')) {
throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__));
}
}
public function isValid($email, EmailLexer $emailLexer)
{
// use the input to check DNS if we cannot extract something similar to a domain
$host = $email;
// Arguable pattern to extract the domain. Not aiming to validate the domain nor the email
if (false !== $lastAtPos = strrpos($email, '@')) {
$host = substr($email, $lastAtPos + 1);
}
// Get the domain parts
$hostParts = explode('.', $host);
// Reserved Top Level DNS Names (https://tools.ietf.org/html/rfc2606#section-2),
// mDNS and private DNS Namespaces (https://tools.ietf.org/html/rfc6762#appendix-G)
$reservedTopLevelDnsNames = [
// Reserved Top Level DNS Names
'test',
'example',
'invalid',
'localhost',
// mDNS
'local',
// Private DNS Namespaces
'intranet',
'internal',
'private',
'corp',
'home',
'lan',
];
$isLocalDomain = count($hostParts) <= 1;
$isReservedTopLevel = in_array($hostParts[(count($hostParts) - 1)], $reservedTopLevelDnsNames, true);
// Exclude reserved top level DNS names
if ($isLocalDomain || $isReservedTopLevel) {
$this->error = new LocalOrReservedDomain();
return false;
}
return $this->checkDns($host);
}
public function getError()
{
return $this->error;
}
public function getWarnings()
{
return $this->warnings;
}
/**
* @param string $host
*
* @return bool
*/
protected function checkDns($host)
{
$variant = INTL_IDNA_VARIANT_UTS46;
$host = rtrim(idn_to_ascii($host, IDNA_DEFAULT, $variant), '.') . '.';
return $this->validateDnsRecords($host);
}
/**
* Validate the DNS records for given host.
*
* @param string $host A set of DNS records in the format returned by dns_get_record.
*
* @return bool True on success.
*/
private function validateDnsRecords($host)
{
// Get all MX, A and AAAA DNS records for host
// Using @ as workaround to fix https://bugs.php.net/bug.php?id=73149
$dnsRecords = @dns_get_record($host, DNS_MX + DNS_A + DNS_AAAA);
// No MX, A or AAAA DNS records
if (empty($dnsRecords)) {
$this->error = new NoDNSRecord();
return false;
}
// For each DNS record
foreach ($dnsRecords as $dnsRecord) {
if (!$this->validateMXRecord($dnsRecord)) {
return false;
}
}
// No MX records (fallback to A or AAAA records)
if (empty($this->mxRecords)) {
$this->warnings[NoDNSMXRecord::CODE] = new NoDNSMXRecord();
}
return true;
}
/**
* Validate an MX record
*
* @param array $dnsRecord Given DNS record.
*
* @return bool True if valid.
*/
private function validateMxRecord($dnsRecord)
{
if ($dnsRecord['type'] !== 'MX') {
return true;
}
// "Null MX" record indicates the domain accepts no mail (https://tools.ietf.org/html/rfc7505)
if (empty($dnsRecord['target']) || $dnsRecord['target'] === '.') {
$this->error = new DomainAcceptsNoMail();
return false;
}
$this->mxRecords[] = $dnsRecord;
return true;
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Egulias\EmailValidator\Validation;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Exception\InvalidEmail;
use Egulias\EmailValidator\Warning\Warning;
interface EmailValidation
{
/**
* Returns true if the given email is valid.
*
* @param string $email The email you want to validate.
* @param EmailLexer $emailLexer The email lexer.
*
* @return bool
*/
public function isValid($email, EmailLexer $emailLexer);
/**
* Returns the validation error.
*
* @return InvalidEmail|null
*/
public function getError();
/**
* Returns the validation warnings.
*
* @return Warning[]
*/
public function getWarnings();
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Egulias\EmailValidator\Validation\Error;
use Egulias\EmailValidator\Exception\InvalidEmail;
class RFCWarnings extends InvalidEmail
{
const CODE = 997;
const REASON = 'Warnings were found.';
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Egulias\EmailValidator\Validation\Error;
use Egulias\EmailValidator\Exception\InvalidEmail;
class SpoofEmail extends InvalidEmail
{
const CODE = 998;
const REASON = "The email contains mixed UTF8 chars that makes it suspicious";
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Egulias\EmailValidator\Validation\Exception;
use Exception;
class EmptyValidationList extends \InvalidArgumentException
{
/**
* @param int $code
*/
public function __construct($code = 0, Exception $previous = null)
{
parent::__construct("Empty validation list is not allowed", $code, $previous);
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Egulias\EmailValidator\Validation;
use Egulias\EmailValidator\Exception\InvalidEmail;
class MultipleErrors extends InvalidEmail
{
const CODE = 999;
const REASON = "Accumulated errors for multiple validations";
/**
* @var InvalidEmail[]
*/
private $errors = [];
/**
* @param InvalidEmail[] $errors
*/
public function __construct(array $errors)
{
$this->errors = $errors;
parent::__construct();
}
/**
* @return InvalidEmail[]
*/
public function getErrors()
{
return $this->errors;
}
}

View File

@@ -0,0 +1,124 @@
<?php
namespace Egulias\EmailValidator\Validation;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Validation\Exception\EmptyValidationList;
class MultipleValidationWithAnd implements EmailValidation
{
/**
* If one of validations gets failure skips all succeeding validation.
* This means MultipleErrors will only contain a single error which first found.
*/
const STOP_ON_ERROR = 0;
/**
* All of validations will be invoked even if one of them got failure.
* So MultipleErrors will contain all causes.
*/
const ALLOW_ALL_ERRORS = 1;
/**
* @var EmailValidation[]
*/
private $validations = [];
/**
* @var array
*/
private $warnings = [];
/**
* @var MultipleErrors|null
*/
private $error;
/**
* @var int
*/
private $mode;
/**
* @param EmailValidation[] $validations The validations.
* @param int $mode The validation mode (one of the constants).
*/
public function __construct(array $validations, $mode = self::ALLOW_ALL_ERRORS)
{
if (count($validations) == 0) {
throw new EmptyValidationList();
}
$this->validations = $validations;
$this->mode = $mode;
}
/**
* {@inheritdoc}
*/
public function isValid($email, EmailLexer $emailLexer)
{
$result = true;
$errors = [];
foreach ($this->validations as $validation) {
$emailLexer->reset();
$validationResult = $validation->isValid($email, $emailLexer);
$result = $result && $validationResult;
$this->warnings = array_merge($this->warnings, $validation->getWarnings());
$errors = $this->addNewError($validation->getError(), $errors);
if ($this->shouldStop($result)) {
break;
}
}
if (!empty($errors)) {
$this->error = new MultipleErrors($errors);
}
return $result;
}
/**
* @param \Egulias\EmailValidator\Exception\InvalidEmail|null $possibleError
* @param \Egulias\EmailValidator\Exception\InvalidEmail[] $errors
*
* @return \Egulias\EmailValidator\Exception\InvalidEmail[]
*/
private function addNewError($possibleError, array $errors)
{
if (null !== $possibleError) {
$errors[] = $possibleError;
}
return $errors;
}
/**
* @param bool $result
*
* @return bool
*/
private function shouldStop($result)
{
return !$result && $this->mode === self::STOP_ON_ERROR;
}
/**
* Returns the validation errors.
*
* @return MultipleErrors|null
*/
public function getError()
{
return $this->error;
}
/**
* {@inheritdoc}
*/
public function getWarnings()
{
return $this->warnings;
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Egulias\EmailValidator\Validation;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Exception\InvalidEmail;
use Egulias\EmailValidator\Validation\Error\RFCWarnings;
class NoRFCWarningsValidation extends RFCValidation
{
/**
* @var InvalidEmail|null
*/
private $error;
/**
* {@inheritdoc}
*/
public function isValid($email, EmailLexer $emailLexer)
{
if (!parent::isValid($email, $emailLexer)) {
return false;
}
if (empty($this->getWarnings())) {
return true;
}
$this->error = new RFCWarnings();
return false;
}
/**
* {@inheritdoc}
*/
public function getError()
{
return $this->error ?: parent::getError();
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Egulias\EmailValidator\Validation;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\EmailParser;
use Egulias\EmailValidator\Exception\InvalidEmail;
class RFCValidation implements EmailValidation
{
/**
* @var EmailParser|null
*/
private $parser;
/**
* @var array
*/
private $warnings = [];
/**
* @var InvalidEmail|null
*/
private $error;
public function isValid($email, EmailLexer $emailLexer)
{
$this->parser = new EmailParser($emailLexer);
try {
$this->parser->parse((string)$email);
} catch (InvalidEmail $invalid) {
$this->error = $invalid;
return false;
}
$this->warnings = $this->parser->getWarnings();
return true;
}
public function getError()
{
return $this->error;
}
public function getWarnings()
{
return $this->warnings;
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Egulias\EmailValidator\Validation;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Exception\InvalidEmail;
use Egulias\EmailValidator\Validation\Error\SpoofEmail;
use \Spoofchecker;
class SpoofCheckValidation implements EmailValidation
{
/**
* @var InvalidEmail|null
*/
private $error;
public function __construct()
{
if (!extension_loaded('intl')) {
throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__));
}
}
/**
* @psalm-suppress InvalidArgument
*/
public function isValid($email, EmailLexer $emailLexer)
{
$checker = new Spoofchecker();
$checker->setChecks(Spoofchecker::SINGLE_SCRIPT);
if ($checker->isSuspicious($email)) {
$this->error = new SpoofEmail();
}
return $this->error === null;
}
/**
* @return InvalidEmail|null
*/
public function getError()
{
return $this->error;
}
public function getWarnings()
{
return [];
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Egulias\EmailValidator\Warning;
class AddressLiteral extends Warning
{
const CODE = 12;
public function __construct()
{
$this->message = 'Address literal in domain part';
$this->rfcNumber = 5321;
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Egulias\EmailValidator\Warning;
class CFWSNearAt extends Warning
{
const CODE = 49;
public function __construct()
{
$this->message = "Deprecated folding white space near @";
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Egulias\EmailValidator\Warning;
class CFWSWithFWS extends Warning
{
const CODE = 18;
public function __construct()
{
$this->message = 'Folding whites space followed by folding white space';
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Egulias\EmailValidator\Warning;
class Comment extends Warning
{
const CODE = 17;
public function __construct()
{
$this->message = "Comments found in this email";
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Egulias\EmailValidator\Warning;
class DeprecatedComment extends Warning
{
const CODE = 37;
public function __construct()
{
$this->message = 'Deprecated comments';
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Egulias\EmailValidator\Warning;
class DomainLiteral extends Warning
{
const CODE = 70;
public function __construct()
{
$this->message = 'Domain Literal';
$this->rfcNumber = 5322;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Egulias\EmailValidator\Warning;
class DomainTooLong extends Warning
{
const CODE = 255;
public function __construct()
{
$this->message = 'Domain is too long, exceeds 255 chars';
$this->rfcNumber = 5322;
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Egulias\EmailValidator\Warning;
use Egulias\EmailValidator\EmailParser;
class EmailTooLong extends Warning
{
const CODE = 66;
public function __construct()
{
$this->message = 'Email is too long, exceeds ' . EmailParser::EMAIL_MAX_LENGTH;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Egulias\EmailValidator\Warning;
class IPV6BadChar extends Warning
{
const CODE = 74;
public function __construct()
{
$this->message = 'Bad char in IPV6 domain literal';
$this->rfcNumber = 5322;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Egulias\EmailValidator\Warning;
class IPV6ColonEnd extends Warning
{
const CODE = 77;
public function __construct()
{
$this->message = ':: found at the end of the domain literal';
$this->rfcNumber = 5322;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Egulias\EmailValidator\Warning;
class IPV6ColonStart extends Warning
{
const CODE = 76;
public function __construct()
{
$this->message = ':: found at the start of the domain literal';
$this->rfcNumber = 5322;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Egulias\EmailValidator\Warning;
class IPV6Deprecated extends Warning
{
const CODE = 13;
public function __construct()
{
$this->message = 'Deprecated form of IPV6';
$this->rfcNumber = 5321;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Egulias\EmailValidator\Warning;
class IPV6DoubleColon extends Warning
{
const CODE = 73;
public function __construct()
{
$this->message = 'Double colon found after IPV6 tag';
$this->rfcNumber = 5322;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Egulias\EmailValidator\Warning;
class IPV6GroupCount extends Warning
{
const CODE = 72;
public function __construct()
{
$this->message = 'Group count is not IPV6 valid';
$this->rfcNumber = 5322;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Egulias\EmailValidator\Warning;
class IPV6MaxGroups extends Warning
{
const CODE = 75;
public function __construct()
{
$this->message = 'Reached the maximum number of IPV6 groups allowed';
$this->rfcNumber = 5321;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Egulias\EmailValidator\Warning;
class LabelTooLong extends Warning
{
const CODE = 63;
public function __construct()
{
$this->message = 'Label too long';
$this->rfcNumber = 5322;
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Egulias\EmailValidator\Warning;
class LocalTooLong extends Warning
{
const CODE = 64;
const LOCAL_PART_LENGTH = 64;
public function __construct()
{
$this->message = 'Local part is too long, exceeds 64 chars (octets)';
$this->rfcNumber = 5322;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Egulias\EmailValidator\Warning;
class NoDNSMXRecord extends Warning
{
const CODE = 6;
public function __construct()
{
$this->message = 'No MX DSN record was found for this email';
$this->rfcNumber = 5321;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Egulias\EmailValidator\Warning;
class ObsoleteDTEXT extends Warning
{
const CODE = 71;
public function __construct()
{
$this->rfcNumber = 5322;
$this->message = 'Obsolete DTEXT in domain literal';
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Egulias\EmailValidator\Warning;
class QuotedPart extends Warning
{
const CODE = 36;
/**
* @param scalar $prevToken
* @param scalar $postToken
*/
public function __construct($prevToken, $postToken)
{
$this->message = "Deprecated Quoted String found between $prevToken and $postToken";
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Egulias\EmailValidator\Warning;
class QuotedString extends Warning
{
const CODE = 11;
/**
* @param scalar $prevToken
* @param scalar $postToken
*/
public function __construct($prevToken, $postToken)
{
$this->message = "Quoted String found between $prevToken and $postToken";
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Egulias\EmailValidator\Warning;
class TLD extends Warning
{
const CODE = 9;
public function __construct()
{
$this->message = "RFC5321, TLD";
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Egulias\EmailValidator\Warning;
abstract class Warning
{
const CODE = 0;
/**
* @var string
*/
protected $message = '';
/**
* @var int
*/
protected $rfcNumber = 0;
/**
* @return string
*/
public function message()
{
return $this->message;
}
/**
* @return int
*/
public function code()
{
return static::CODE;
}
/**
* @return int
*/
public function RFCNumber()
{
return $this->rfcNumber;
}
public function __toString()
{
return $this->message() . " rfc: " . $this->rfcNumber . "interal code: " . static::CODE;
}
}

View File

@@ -5,5 +5,7 @@
*.priv -crlf
*.txt -crlf
# ignore /notes in the git-generated distributed .zip archive
/notes export-ignore
# ignore directories in the git-generated distributed .zip archive
/doc/notes export-ignore
/tests export-ignore
/phpunit.xml.dist export-ignore

View File

@@ -1,5 +1,6 @@
/.php_cs.cache
/.phpunit
/.phpunit.result.cache
/build/*
/composer.lock
/phpunit.xml

View File

@@ -1,15 +1,21 @@
<?php
return PhpCsFixer\Config::create()
->setRules(array(
->setRules([
'@Symfony' => true,
'@Symfony:risky' => true,
'array_syntax' => array('syntax' => 'long'),
'@PHPUnit75Migration:risky' => true,
'php_unit_dedicate_assert' => ['target' => '5.6'],
'array_syntax' => ['syntax' => 'short'],
'php_unit_fqcn_annotation' => true,
'no_unreachable_default_argument_value' => false,
'braces' => array('allow_single_line_closure' => true),
'braces' => ['allow_single_line_closure' => true],
'heredoc_to_nowdoc' => false,
'phpdoc_annotation_without_dot' => false,
))
'ordered_imports' => true,
'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
'native_function_invocation' => ['include' => ['@compiler_optimized'], 'scope' => 'all'],
'fopen_flags' => false,
])
->setRiskyAllowed(true)
->setFinder(PhpCsFixer\Finder::create()->in(__DIR__))
;

View File

@@ -1,31 +0,0 @@
language: php
sudo: false
before_script:
- cp tests/acceptance.conf.php.default tests/acceptance.conf.php
- cp tests/smoke.conf.php.default tests/smoke.conf.php
- composer self-update
- composer update --no-interaction --prefer-source
- gem install mime-types -v 2.99.1
- gem install mailcatcher
- mailcatcher --smtp-port 4456
script: ./vendor/bin/simple-phpunit
matrix:
include:
- php: 5.3
- php: 5.4
- php: 5.5
- php: 5.6
- php: 7.0
- php: 7.1
- php: hhvm
allow_failures:
- php: hhvm
fast_finish: true
cache:
directories:
- .phpunit

View File

@@ -1,21 +1,125 @@
Changelog
=========
5.4.12 (2018-07-31)
-------------------
**Swiftmailer will stop being maintained at the end of November 2021.**
* fixed typo
Please, move to Symfony Mailer at your earliest convenience.
Symfony Mailer is the next evolution of Swiftmailer.
It provides the same features with support for modern PHP code and support for third-party providers.
See https://symfony.com/doc/current/mailer.html for more information.
5.4.11 (2018-07-31)
-------------------
6.3.0 (2021-10-18)
------------------
* fixed startTLS support for PHP 5.6-
* Fix support for PHP 8.1
5.4.10 (2018-07-27)
-------------------
6.2.7 (2021-03-09)
------------------
* Allow egulias/email-validator 3.1+
6.2.6 (2021-03-05)
------------------
* Fix Bcc support
6.2.5 (2021-01-12)
------------------
* Don't trust properties at destruct time
* Remove invalid PHPDocs param in EventDispatcher interface
* Bump license year
* Removes PHP version from README
6.2.4 (2020-12-08)
------------------
* Prevent flushing of the bubble queue when event handler raises another event
* Add support for PHP 8
* Code cleanups
6.2.3 (2019-11-12)
------------------
* no changes
6.2.2 (2019-11-12)
------------------
* fixed compat with PHP 7.4
* fixed error message when connecting to a stream raises an error before connect()
6.2.1 (2019-04-21)
------------------
* reverted "deprecated Swift_CharacterStream_ArrayCharacterStream and Swift_CharacterStream_NgCharacterStream in favor of Swift_CharacterStream_CharacterStream"
6.2.0 (2019-03-10)
------------------
* added support for symfony/polyfill-intl-dn
* deprecated Swift_CharacterStream_ArrayCharacterStream and Swift_CharacterStream_NgCharacterStream in favor of Swift_CharacterStream_CharacterStream
6.1.3 (2018-09-11)
------------------
* added auto-start to the SMTP transport when sending a message
* tweaked error message when the response from an SMTP server is empty
* fixed missing property in Swift_Mime_IdGenerator
* exposed original body content type with Swift_Mime_SimpleMimeEntity::getBodyContentType()
* fixed typo in variable name in Swift_AddressEncoder_IdnAddressEncoder
* fixed return type in MessageLogger
* fixed missing property addressEncoder in SimpleHeaderFactory class
6.1.2 (2018-07-13)
------------------
* handled recipient errors when pipelining
6.1.1 (2018-07-04)
------------------
* removed hard dependency on an IDN encoder
6.1.0 (2018-07-02)
------------------
* added address encoder exceptions during send
* added support for bubbling up authenticator error messages
* added support for non-ASCII email addresses
* introduced new dependencies: transport.smtphandlers and transport.authhandlers
* deprecated Swift_Signers_OpenDKIMSigner; use Swift_Signers_DKIMSigner instead
* added support for SMTP pipelining
* added Swift_Transport_Esmtp_EightBitMimeHandler
* fixed startTLS only allowed tls1.0, now allowed: tls1.0, tls1.1, tls1.2
6.0.2 (2017-09-30)
------------------
* fixed DecoratorPlugin
* removed usage of getmypid()
6.0.1 (2017-05-20)
------------------
* fixed BC break that can be avoided easily
6.0.0 (2017-05-19)
------------------
* added Swift_Transport::ping()
* removed Swift_Mime_HeaderFactory, Swift_Mime_HeaderSet, Swift_Mime_Message, Swift_Mime_MimeEntity,
and Swift_Mime_ParameterizedHeader interfaces
* removed Swift_MailTransport and Swift_Transport_MailTransport
* removed Swift_Encoding
* removed the Swift_Transport_MailInvoker interface and Swift_Transport_SimpleMailInvoker class
* removed the Swift_SignedMessage class
* removed newInstance() methods everywhere
* methods operating on Date header now use DateTimeImmutable object instead of Unix timestamp;
Swift_Mime_Headers_DateHeader::getTimestamp()/setTimestamp() renamed to getDateTime()/setDateTime()
* bumped minimum version to PHP 7.0
* removed Swift_Validate and replaced by egulias/email-validator
5.4.9 (2018-01-23)
------------------

View File

@@ -1,4 +1,4 @@
Copyright (c) 2013-2016 Fabien Potencier
Copyright (c) 2013-2021 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,15 +0,0 @@
Swift Mailer
------------
Swift Mailer is a component based mailing solution for PHP 5.
It is released under the MIT license.
Homepage: https://swiftmailer.symfony.com/
Documentation: https://swiftmailer.symfony.com/docs/introduction.html
Bugs: https://github.com/swiftmailer/swiftmailer/issues
Repository: https://github.com/swiftmailer/swiftmailer
Swift Mailer is highly object-oriented by design and lends itself
to use in complex web application with a great deal of flexibility.
For full details on usage, see the documentation.

View File

@@ -0,0 +1,25 @@
Swift Mailer
------------
**Swiftmailer will stop being maintained at the end of November 2021.**
Please, move to [Symfony Mailer](https://symfony.com/doc/current/mailer.html) at your earliest convenience.
[Symfony Mailer](https://symfony.com/doc/current/mailer.html) is the next evolution of Swiftmailer.
It provides the same features with support for modern PHP code and support for third-party providers.
Swift Mailer is a component based mailing solution for PHP.
It is released under the MIT license.
Swift Mailer is highly object-oriented by design and lends itself
to use in complex web application with a great deal of flexibility.
For full details on usage, read the [documentation](https://swiftmailer.symfony.com/docs/introduction.html).
Sponsors
--------
<div>
<a href="https://blackfire.io/docs/introduction?utm_source=swiftmailer&utm_medium=github_readme&utm_campaign=logo">
<img src="https://static.blackfire.io/assets/intemporals/logo/png/blackfire-io_secondary_horizontal_transparent.png?1" width="255px" alt="Blackfire.io">
</a>
</div>

View File

@@ -1 +0,0 @@
Swift-5.4.12

View File

@@ -15,23 +15,30 @@
}
],
"require": {
"php": ">=5.3.3"
"php": ">=7.0.0",
"egulias/email-validator": "^2.0|^3.1",
"symfony/polyfill-iconv": "^1.0",
"symfony/polyfill-mbstring": "^1.0",
"symfony/polyfill-intl-idn": "^1.10"
},
"require-dev": {
"mockery/mockery": "~0.9.1",
"symfony/phpunit-bridge": "~3.2"
"mockery/mockery": "^1.0",
"symfony/phpunit-bridge": "^4.4|^5.4"
},
"suggest": {
"ext-intl": "Needed to support internationalized email addresses"
},
"autoload": {
"files": ["lib/swift_required.php"]
},
"autoload-dev": {
"psr-0": {
"Swift_": "tests/unit"
}
"psr-0": { "Swift_": "tests/unit" }
},
"extra": {
"branch-alias": {
"dev-master": "5.4-dev"
"dev-master": "6.2-dev"
}
}
},
"minimum-stability": "dev",
"prefer-stable": true
}

View File

@@ -11,16 +11,14 @@
/**
* General utility class in Swift Mailer, not to be instantiated.
*
*
* @author Chris Corbyn
*/
abstract class Swift
{
/** Swift Mailer Version number generated during dist release process */
const VERSION = '@SWIFT_VERSION_NUMBER@';
const VERSION = '6.3.0';
public static $initialized = false;
public static $inits = array();
public static $inits = [];
/**
* Registers an initializer callable that will be called the first time
@@ -58,7 +56,7 @@ abstract class Swift
if (self::$inits && !self::$initialized) {
self::$initialized = true;
foreach (self::$inits as $init) {
call_user_func($init);
\call_user_func($init);
}
}
}
@@ -75,6 +73,6 @@ abstract class Swift
if (null !== $callable) {
self::$inits[] = $callable;
}
spl_autoload_register(array('Swift', 'autoload'));
spl_autoload_register(['Swift', 'autoload']);
}
}

Some files were not shown because too many files have changed in this diff Show More