merge master in prod

This commit is contained in:
2020-09-08 12:00:45 +02:00
parent b925edaa9e
commit 3e5e731c2c
226 changed files with 8516 additions and 4149 deletions
+1
View File
@@ -1,5 +1,6 @@
themes/grav/.sass-cache
.DS_Store
crowdin.yaml
# Node Modules
**/node_modules/**
+65 -15
View File
@@ -1,3 +1,53 @@
# v1.9.16
## 09/01/2020
1. [](#bugfix)
* Fixed a glitch which allows user to delete entire pages directory [#1941](https://github.com/getgrav/grav-plugin-admin/issues/1941)
* Fixed the hidden login plugin toggle
# v1.9.15
## 06/08/2020
1. [](#bugfix)
* Support markdown in `fieldset.text` [#2934](https://github.com/getgrav/grav/issues/2934)
* Fix data URLs in avatar images [#1889](https://github.com/getgrav/grav/issues/1889)
* Fix for deleting files in plugin configurations
# v1.9.14
## 04/27/2020
1. [](#improved)
* Added `slug` and `type` to blueprints
1. [](#bugfix)
* Support markdown in `fieldset.text` [#2934](https://github.com/getgrav/grav/issues/2934)
# v1.9.13
## 03/05/2020
1. [](#improved)
* Updated vendor libs
1. [](#bugfix)
* Fixed toggleable buttons no longer holding false state [form#406](ttps://github.com/getgrav/grav-plugin-form/issues/406)
# v1.9.12
## 12/04/2019
1. [](#bugfix)
* Fixed saving configuration in PHP 7.4
# v1.9.11
## 11/06/2019
1. [](#improved)
* Added new "secure delete" functionality [#1752](https://github.com/getgrav/grav-plugin-admin/issues/1752)
* Center text logo [#1751](https://github.com/getgrav/grav-plugin-admin/issues/1751)
* Added required span to editor field [#1748](https://github.com/getgrav/grav-plugin-admin/issues/1748)
* Warn users if JS is disabled [#1722](https://github.com/getgrav/grav-plugin-admin/issues/1722)
* Added target rule to quick links [#1518](https://github.com/getgrav/grav-plugin-admin/issues/1518)
1. [](#bugfix)
* Fixed `Badly encoded JSON data` warning when uploading files [grav#2663](https://github.com/getgrav/grav/issues/2663)
* Fixed `accept` for SVG in `file` uploaders [#1732](https://github.com/getgrav/grav-plugin-admin/issues/1732)
# v1.9.10
## 09/19/2019
@@ -24,13 +74,13 @@
* Fixed issue with `array` field nested in `list` that were losing their index order when the list reordered
* Fixed file form field failing resolution checks in certain circumstances
* Fixed issue with deleting files in config based YAML files
# v1.9.7
## 06/21/2019
1. [](#bugfix)
* Fixed issue with charts in dashboard where label would cut off [#1700](https://github.com/getgrav/grav-plugin-admin/issues/1700)
* Resetting a user's password clears the user's site access [grav#2528](https://github.com/getgrav/grav/issues/2528)
* Resetting a user's password clears the user's site access [grav#2528](https://github.com/getgrav/grav/issues/2528)
* Fixed issue with permissions toggle [#1702](https://github.com/getgrav/grav-plugin-admin/issues/1702)
# v1.9.6
@@ -72,7 +122,7 @@
* Added a new **YAML Linter** report to the `Tools - Reports` section
1. [](#improved)
* Updated package.json scripts to properly use gulp compiler
# v1.9.2
## 04/15/2019
@@ -85,7 +135,7 @@
1. [](#bugfix)
* Fix for Page saving issues [#1648](https://github.com/getgrav/grav-plugin-admin/issues/1648)
* Remove status message when picking folder for move [#1650](https://github.com/getgrav/grav-plugin-admin/issues/1650)
* Remove status message when picking folder for move [#1650](https://github.com/getgrav/grav-plugin-admin/issues/1650)
# v1.9.0
## 04/11/2019
@@ -120,10 +170,10 @@
* Homepage link should be `https://` [#1564](https://github.com/getgrav/grav-plugin-admin/issues/1564)
* Improve lang string to describe XSS security settings [#1566](https://github.com/getgrav/grav-plugin-admin/issues/1566)
* Take admin setting for 2FA into account when showing user 2FA badge [#1568](https://github.com/getgrav/grav-plugin-admin/issues/1568)
* Moved `ignore` and `key` field into form plugin
* Moved `ignore` and `key` field into form plugin
* Improved usability of `System` configuration blueprint with side-tabs
* Cleaned up UI in `Scheduler` tools page
* Updated languages
* Cleaned up UI in `Scheduler` tools page
* Updated languages
1. [](#bugfix)
* Fixed user edit links if Flex Objects plugin is installed but user isn't Flex User
* Fixed deprecated `sameas()` Twig test
@@ -133,15 +183,15 @@
* Fixed issue with Safari browser and blueprint fields with `toggleable: true` [#1643](https://github.com/getgrav/grav-plugin-admin/issues/1643)
* Incorrect 2FA lang code [#1618](https://github.com/getgrav/grav-plugin-admin/issues/1618)
* Fixed potential undefined property in `onPageNotFound` event handling
* Proper fix for `vUndefined` when updating plugins/themes
* Proper fix for `vUndefined` when updating plugins/themes
* Text in Tab Tools/Direct install disappears [#1613](https://github.com/getgrav/grav-plugin-admin/issues/1613)
* Fallback to page `slug` in Pages list if title is empty [grav#2267](https://github.com/getgrav/grav/issues/2267)
* Fixes backup button issues with `;` param separator [#1602](https://github.com/getgrav/grav-plugin-admin/issues/1602) [#1502](https://github.com/getgrav/grav-plugin-admin/issues/1502)
* Set default state for `show_modular` to `true` [#1599](https://github.com/getgrav/grav-plugin-admin/issues/1599)
* Removed `tabs`, `tab`, and `toggle` fields as they are now in Form plugin
* Fix issue with new page always showing modular page templates [#1573](https://github.com/getgrav/grav-plugin-admin/issues/1573)
* Fixed issue deleting files in plugins/themes/config
* Fixed array support in admin languages, e.g. `DAYS_OF_THE_WEEK`
* Fixed issue deleting files in plugins/themes/config
* Fixed array support in admin languages, e.g. `DAYS_OF_THE_WEEK`
* Fixed user login / remember me triggering before admin gets initialized
* Fixed a bug when deleting files via AJAX
* Fixed error page not to be the frontend version
@@ -154,24 +204,24 @@
* Removed duplicate language strings
* Fixed default `job_at` so it does not fail if missing
* Minor JS group `bottom` fix
# v1.8.20
## 03/20/2019
1. [](#improved)
* Added security field to column [#1622](https://github.com/getgrav/grav-plugin-admin/pull/1622)
# v1.8.19
## 02/13/2019
1. [](#bugfix)
* Moved `show_modular` to proper place - Doh! [grav#2362](https://github.com/getgrav/grav/issues/2362)
* Moved `show_modular` to proper place - Doh! [grav#2362](https://github.com/getgrav/grav/issues/2362)
# v1.8.18
## 02/12/2019
1. [](#bugfix)
* Set default value for `show_modular` [grav#2362](https://github.com/getgrav/grav/issues/2362)
* Set default value for `show_modular` [grav#2362](https://github.com/getgrav/grav/issues/2362)
# v1.8.17
## 02/07/2019
@@ -192,7 +242,7 @@
1. [](#bugfix)
* Fixed calendar js module not properly loading for datetime field [#1581](https://github.com/getgrav/grav-plugin-admin/issues/1581)
* Fixed deleting file when using file field type [#1558](https://github.com/getgrav/grav-plugin-admin/issues/1558)
* Unset state from user if not super or user admin
* Unset state from user if not super or user admin
# v1.8.15
## 12/14/2018
+1
View File
@@ -26,6 +26,7 @@ session:
timeout: 1800
warnings:
delete_page: true
secure_delete: false
edit_mode: normal
frontend_preview_target: inline
show_github_msg: true
+16 -2
View File
@@ -1,5 +1,7 @@
name: Admin Panel
version: 1.9.10
slug: admin
type: plugin
version: 1.9.16
testing: false
description: Adds an advanced administration panel to manage your site
icon: empire
@@ -14,7 +16,7 @@ docs: https://github.com/getgrav/grav-plugin-admin/blob/develop/README.md
license: MIT
dependencies:
- { name: grav, version: '>=1.6.8' }
- { name: grav, version: '>=1.6.22' }
- { name: form, version: '>=3.0.0' }
- { name: login, version: '>=3.0.0' }
- { name: email, version: '>=3.0.0' }
@@ -243,6 +245,18 @@ form:
type: bool
help: Ask the user confirmation when deleting a page
warnings.secure_delete:
type: toggle
label: Secure Delete
highlight: 1
default: 1
options:
1: PLUGIN_ADMIN.ENABLED
0: PLUGIN_ADMIN.DISABLED
validate:
type: bool
help: Shows the user a field to enter the word DELETE and enable the confirm delete button.
hide_page_types:
type: array
label: Hide page types in Admin
+4 -1
View File
@@ -1671,8 +1671,11 @@ class Admin
{
$reports = new ArrayCollection();
/** @var Pages $pages */
$pages = $this->grav['pages'];
// Default to XSS Security Report
$result = Security::detectXssFromPages($this->grav['pages'], true);
$result = Security::detectXssFromPages($pages, true);
$reports['Grav Security Check'] = $this->grav['twig']->processTemplate('reports/security.html.twig', [
'result' => $result,
@@ -325,7 +325,7 @@ class AdminBaseController
}
$isMime = strstr($type, '/');
$find = str_replace(['.', '*'], ['\.', '.*'], $type);
$find = str_replace(['.', '*', '+'], ['\.', '.*', '\+'], $type);
if ($isMime) {
$match = preg_match('#' . $find . '$#', $mime);
@@ -737,8 +737,8 @@ class AdminBaseController
// Process previously uploaded files for the current URI
// and finally store them. Everything else will get discarded
$queue = $this->admin->session()->getFlashObject('files-upload');
$queue = $queue[base64_encode($this->grav['uri']->url())];
if (is_array($queue)) {
$queue = $queue[base64_encode($this->grav['uri']->url())];
foreach ($queue as $key => $files) {
foreach ($files as $destination => $file) {
if (!rename($file['tmp_name'], $destination)) {
@@ -943,7 +943,7 @@ class AdminBaseController
$settings = (object)$blueprints->schema()->getProperty($field);
} else {
$page = null;
if ($type === 'themes') {
if ($type === 'themes' || $type === 'plugins') {
$obj = $this->grav[$type]->get(Utils::substrToString($blueprint, '/')); //here
$settings = (object) $obj->blueprints()->schema()->getProperty($field);
} else {
+15 -1
View File
@@ -487,6 +487,11 @@ class AdminController extends AdminBaseController
$data = (array)$this->data;
$folder = $data['folder'] ?? '';
if ($folder === '' || mb_strpos($folder, '/') !== false) {
throw new \RuntimeException('Creating folder failed, bad folder name', 400);
}
if ($data['route'] === '/') {
$path = $this->grav['locator']->findResource('page://');
} else {
@@ -494,7 +499,7 @@ class AdminController extends AdminBaseController
}
$orderOfNewFolder = static::getNextOrderInFolder($path);
$new_path = $path . '/' . $orderOfNewFolder . '.' . $data['folder'];
$new_path = $path . '/' . $orderOfNewFolder . '.' . $folder;
Folder::create($new_path);
Cache::clearCache('invalidate');
@@ -585,6 +590,11 @@ class AdminController extends AdminBaseController
/** @var PageInterface $obj */
$obj = $this->admin->page(true);
$folder = $data['folder'] ?? null;
if ($folder === '' || mb_strpos($folder, '/') !== false) {
throw new \RuntimeException('Saving page failed: bad folder name', 400);
}
if (!isset($data['folder']) || !$data['folder']) {
$data['folder'] = $obj->slug();
$this->data['folder'] = $obj->slug();
@@ -814,6 +824,10 @@ class AdminController extends AdminBaseController
$folder = \Grav\Plugin\Admin\Utils::slug($data[substr($folder, 9)]);
}
$folder = ltrim($folder, '_');
if ($folder === '' || mb_strpos($folder, '/') !== false) {
throw new \RuntimeException('Creating page failed: bad folder name', 400);
}
if (!empty($data['modular'])) {
$folder = '_' . $folder;
}
+517 -341
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -1,4 +1,5 @@
PLUGIN_ADMIN:
ADMIN_NOSCRIPT_MSG: "Please enable JavaScript in your browser."
ADMIN_BETA_MSG: "This is a Beta release! Use this in production at your own risk..."
ADMIN_REPORT_ISSUE: "Found an issue? Please report it on GitHub."
EMAIL_FOOTER: "<a href=\"http://getgrav.org\">Powered by Grav</a> - The Modern Flat File CMS"
@@ -43,10 +44,12 @@ PLUGIN_ADMIN:
EXPERT: "Expert"
EXPAND_ALL: "Expand All"
COLLAPSE_ALL: "Collapse All"
SECURE_DELETE_DESC: "Type DELETE and confirm"
ERROR: "Error"
CLOSE: "Close"
CANCEL: "Cancel"
CONTINUE: "Continue"
CONFIRM: "Confirm"
MODAL_DELETE_PAGE_CONFIRMATION_REQUIRED_TITLE: "Confirmation Required"
MODAL_CHANGED_DETECTED_TITLE: "Changes Detected"
MODAL_CHANGED_DETECTED_DESC: "You have unsaved changes. Are you sure you want to leave without saving?"
@@ -825,3 +828,6 @@ PLUGIN_ADMIN:
DEBUGGER_CLOCKWORK: "Clockwork Browser Extension"
SHOW_SENSITIVE: "Show Sensitive Data"
SHOW_SENSITIVE_HELP: "Clockwork Provider ONLY: Censor potentially sensitive information (POST parameters, cookies, files, configuration and most array/object data in log messages)"
VALID_LINK_ATTRIBUTES: "Valid Link Attributes"
VALID_LINK_ATTRIBUTES_HELP: "Attributes that will be automatically added to the media HTML element"
+2
View File
@@ -43,10 +43,12 @@ PLUGIN_ADMIN:
EXPERT: "Esperto"
EXPAND_ALL: "Expandir Tudo"
COLLAPSE_ALL: "Recolher Tudo"
SECURE_DELETE_DESC: "Digite DELETE e confirme"
ERROR: "Erro"
CLOSE: "Fechar"
CANCEL: "Cancelar"
CONTINUE: "Continuar"
CONFIRM: "Confirmar"
MODAL_DELETE_PAGE_CONFIRMATION_REQUIRED_TITLE: "Confirmação Requerida"
MODAL_CHANGED_DETECTED_TITLE: "Alterações Detectadas"
MODAL_CHANGED_DETECTED_DESC: "Você tem alterações não salvas. Tem certeza que deseja sair sem salvar?"
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -3,7 +3,7 @@ $fonts-default: 'Roboto' !default;
$fonts-mono: 'Inconsolata' !default;
$font-definitions: (
Josefin+Slab: 400,
'Josefin Slab': '400',
Roboto: '300,400,500',
Inconsolata: '400,700'
);
@@ -244,7 +244,7 @@ $content-padding: 1.5rem;
display: flex;
align-items: center;
a:not(.front-end) {
display: inherit;
}
@@ -798,6 +798,7 @@ body.sidebar-quickopen #admin-main {
.button {
margin: 0;
height: 37px;
&.dropdown-toggle {
margin-left: -4px;
@@ -103,6 +103,7 @@
justify-content: center;
&.text-logo {
text-align: center;
font-size: 4rem;
}
@@ -24,7 +24,10 @@
font-size: 90%;
}
&:disabled {
opacity: .6;
cursor: no-drop;
}
}
@@ -2,9 +2,9 @@
{% if not blueprints or (blueprints.schema.type(field.type)['input@'] ?? true) is same as(true) %}
{% set originalValue = originalValue is defined ? originalValue : value %}
{% set toggleableChecked = field.toggleable and (originalValue is not null and originalValue is not empty) %}
{% set toggleableChecked = field.toggleable and originalValue is not null %}
{% set isDisabledToggleable = field.toggleable and not toggleableChecked %}
{% set value = (value is null ? field.default : value) %}
{% set value = value ?? field.default %}
{% if (field.yaml or field.validate.type == 'yaml') and value is iterable%}
{% set value = value|toYaml %}
@@ -11,7 +11,10 @@
{% if field.help %}
{% set hint = 'data-hint="' ~ field.help|tu|raw ~ '"' %}
{% endif %}
<div class="form-label form-field hint--bottom" {{ hint|raw }}>{{ field.label|tu|raw }}</div>
<div class="form-label form-field hint--bottom" {{ hint|raw }}>
{{ field.label|tu|raw }}
{{ field.validate.required in ['on', 'true', 1] ? '<span class="required">*</span>' }}
</div>
{% endif %}
{% endblock %}
<div class="form-field {{ field.classes|default('') }}">
@@ -48,9 +48,12 @@
>
{% block group %}
{% if field.text %}
<p>{% if grav.twig.twig.filters['tu'] is defined %}{{ field.text|tu }}{% else %}{{ field.text|t }}{% endif %}
<p>
{% if field.text %}
{% if grav.twig.twig.filters['tu'] is defined %}
{{ field.markdown ? field.text|tu|markdown : '<p>' ~ field.text|tu ~ '</p>' }}
{% else %}
{{ field.markdown ? field.text|t|markdown : '<p>' ~ field.t ~ '</p>' }}
{% endif %}
{% endif %}
{% if field.fields %}
@@ -107,6 +107,7 @@
{% set modular = context.modular ? 'modular_' : '' %}
{% set warn = config.plugins.admin.warnings.delete_page %}
{% set secure_delete = config.plugins.admin.warnings.secure_delete %}
{% set admin_lang = admin.session.admin_lang ?: 'en' %}
{% set page_lang = context.language %}
{% set type = 'page' %}
@@ -405,10 +406,19 @@
<p class="bigger">
{{ "PLUGIN_ADMIN.MODAL_DELETE_PAGE_CONFIRMATION_REQUIRED_DESC"|tu }}
</p>
{% if secure_delete %}
<p class="form-secure-delete">
<input id="secure-delete-field" autofocus type="text" placeholder="{{ "PLUGIN_ADMIN.SECURE_DELETE_DESC"|tu }}" />
</p>
{% endif %}
<br>
<div class="button-bar">
<button data-remodal-action="cancel" class="button secondary remodal-cancel"><i class="fa fa-fw fa-close"></i> {{ "PLUGIN_ADMIN.CANCEL"|tu }}</button>
<a class="button disable-after-click" data-delete-action href="#"><i class="fa fa-fw fa-check"></i> {{ "PLUGIN_ADMIN.CONTINUE"|tu }}</a>
{% if secure_delete %}
<button id="secure-delete-btn" disabled="true" class="button danger disable-after-click" data-delete-action><i class="fa fa-fw fa-check"></i> {{ "PLUGIN_ADMIN.CONFIRM"|tu }}</button>
{% else %}
<a class="button danger disable-after-click" data-delete-action href="#"><i class="fa fa-fw fa-check"></i> {{ "PLUGIN_ADMIN.CONTINUE"|tu }}</a>
{% endif %}
</div>
</form>
</div>
@@ -421,5 +431,18 @@
{{ parent() }}
<script>
$('.admin-pages .form-tabs .tabs-nav').css('margin-right', ($('#admin-topbar').width() + 20) + 'px');
{% if secure_delete %}
$('#secure-delete-field').keyup(function () {
var inputValue = $(this).val();
if (inputValue == 'DELETE') {
$('#secure-delete-btn').attr('disabled', false);
}else{
$('#secure-delete-btn').attr('disabled', true);
}
});
$(document).on('closing', '.remodal', function () {
$('#secure-delete-field').val('');
});
{% endif %}
</script>
{% endblock %}
@@ -40,6 +40,10 @@
{% include 'partials/messages.html.twig' %}
{% else %}
{% block noscript %}
{% include 'partials/noscript.html.twig' %}
{% endblock noscript %}
{% block page %}
<div class="remodal-bg">
@@ -18,7 +18,7 @@
{% endif %}
<li class="{{ item.class }} hint--bottom" data-hint="{{ item.hint }}" {{ data_tags|raw }}>
{% if item.route %}
<a href="{{ url(item.route) }}">
<a href="{{ url(item.route) }}" {% if item.target %}target="{{ item.target }}"{% endif %}>
<i class="fa fa-fw {{ item.icon }}"></i>
</a>
{% else %}
@@ -1,2 +1,2 @@
{% set user_avatar = admin.user.getAvatarUrl() %}
<img src="{{ '?' not in user_avatar ? user_avatar ~ '?s=80' : user_avatar }}" />
<img src="{{ ('?' not in user_avatar) and (not user_avatar starts with 'data:') ? user_avatar ~ '?s=80' : user_avatar }}" />
@@ -0,0 +1,42 @@
<style>
.error-message {
background-color: #fce4e4;
border: 1px solid #fcc2c3;
width: 100%;
padding: 20px 30px;
}
.error-text {
color: #cc0033;
font-family: Helvetica, Arial, sans-serif;
width: 100%;
font-weight: bold;
line-height: 20px;
text-shadow: 1px 1px rgba(250,250,250,.3);
}
.full-height {
display: block;
width: 100%;
height: 100%;
}
</style>
<div id="noscript" class="full-height">
<main id="admin-main" class="full-height">
<div id="titlebar" class="titlebar">
<h1><i class="fa fa-fw fa-exclamation-triangle"></i>{{ "PLUGIN_ADMIN.ERROR"|tu }}</h1>
</div>
<div class="full-height">
<div class="error-message {% if config.plugins.admin.content_padding %}content-padding{% endif %}">
<span class="error-text">{{ "PLUGIN_ADMIN.ADMIN_NOSCRIPT_MSG"|tu }}</span>
</div>
</div>
</main>
</div>
<script type="text/javascript">
function checkjs() {
var element = document.getElementById("noscript");
element.style.display = 'none';
}
checkjs();
</script>
@@ -42,7 +42,7 @@
{% if isTestingRelease %}<span class="gpm-testing">test release</span>{% endif %}
</td>
<td class="gpm-actions">
{% if (not installing and (plugin.form.fields.enabled.type != 'hidden' and plugin.form.fields.tabs.fields.login.fields.enabled.type != 'hidden')) %}
{% if (not installing and (plugin.form.fields.enabled.type != 'hidden' and plugin.form.fields.tabs.fields.options.fields.enabled.type != 'hidden')) %}
<a class="{{ data.get('enabled') ? 'enabled' : 'disabled' }}" href="{{ uri.addNonce(base_url_relative ~ '/plugins/' ~ slug ~ '/task' ~ config.system.param_sep ~ (data.get('enabled') ? 'disable' : 'enable'), 'admin-form', 'admin-nonce') }}">
<i class="fa fa-fw fa-toggle-{{ data.get('enabled') ? 'on' : 'off' }}"></i>
</a>
+2 -2
View File
@@ -279,7 +279,7 @@ class ClassLoader
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
@@ -377,7 +377,7 @@ class ClassLoader
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath.'\\';
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
+9 -9
View File
@@ -1,27 +1,26 @@
[
{
"name": "composer/semver",
"version": "1.4.2",
"version_normalized": "1.4.2.0",
"version": "1.5.1",
"version_normalized": "1.5.1.0",
"source": {
"type": "git",
"url": "https://github.com/composer/semver.git",
"reference": "c7cb9a2095a074d131b65a8a0cd294479d785573"
"reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573",
"reference": "c7cb9a2095a074d131b65a8a0cd294479d785573",
"url": "https://api.github.com/repos/composer/semver/zipball/c6bea70230ef4dd483e6bbcab6005f682ed3a8de",
"reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de",
"shasum": ""
},
"require": {
"php": "^5.3.2 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.5 || ^5.0.5",
"phpunit/phpunit-mock-objects": "2.3.0 || ^3.0"
"phpunit/phpunit": "^4.5 || ^5.0.5"
},
"time": "2016-08-30T16:08:34+00:00",
"time": "2020-01-13T12:06:48+00:00",
"type": "library",
"extra": {
"branch-alias": {
@@ -164,6 +163,7 @@
"security",
"xml",
"zf"
]
],
"abandoned": "laminas/laminas-xml"
}
]
+12
View File
@@ -3,6 +3,15 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
### [1.5.1] 2020-01-13
* Fixed: Parsing of aliased version was not validating the alias to be a valid version
### [1.5.0] 2019-03-19
* Added: some support for date versions (e.g. 201903) in `~` operator
* Fixed: support for stabilities in `~` operator was inconsistent
### [1.4.2] 2016-08-30
* Fixed: collapsing of complex constraints lead to buggy constraints
@@ -57,6 +66,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Namespace: `Composer\Test\Package\LinkConstraint` -> `Composer\Test\Semver\Constraint`
* Changed: code style using php-cs-fixer.
[1.5.1]: https://github.com/composer/semver/compare/1.5.0...1.5.1
[1.5.0]: https://github.com/composer/semver/compare/1.4.2...1.5.0
[1.4.2]: https://github.com/composer/semver/compare/1.4.1...1.4.2
[1.4.1]: https://github.com/composer/semver/compare/1.4.0...1.4.1
[1.4.0]: https://github.com/composer/semver/compare/1.3.0...1.4.0
[1.3.0]: https://github.com/composer/semver/compare/1.2.0...1.3.0
+1 -2
View File
@@ -34,8 +34,7 @@
"php": "^5.3.2 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.5 || ^5.0.5",
"phpunit/phpunit-mock-objects": "2.3.0 || ^3.0"
"phpunit/phpunit": "^4.5 || ^5.0.5"
},
"autoload": {
"psr-4": {
@@ -11,7 +11,7 @@
namespace Composer\Semver\Constraint;
trigger_error('The ' . __CLASS__ . ' abstract class is deprecated, there is no replacement for it, it will be removed in the next major version.', E_USER_DEPRECATED);
trigger_error('The ' . __NAMESPACE__ . '\AbstractConstraint abstract class is deprecated, there is no replacement for it, it will be removed in the next major version.', E_USER_DEPRECATED);
/**
* Base constraint class.
@@ -184,7 +184,7 @@ class Constraint implements ConstraintInterface
// '!=' operator is match when other operator is not '==' operator or version is not match
// these kinds of comparisons always have a solution
if ($isNonEqualOp || $isProviderNonEqualOp) {
return !$isEqualOp && !$isProviderEqualOp
return (!$isEqualOp && !$isProviderEqualOp)
|| $this->versionCompare($provider->version, $this->version, '!=', $compareBranches);
}
@@ -197,13 +197,9 @@ class Constraint implements ConstraintInterface
if ($this->versionCompare($provider->version, $this->version, self::$transOpInt[$this->operator], $compareBranches)) {
// special case, e.g. require >= 1.0 and provide < 1.0
// 1.0 >= 1.0 but 1.0 is outside of the provided interval
if ($provider->version === $this->version
return !($provider->version === $this->version
&& self::$transOpInt[$provider->operator] === $providerNoEqualOp
&& self::$transOpInt[$this->operator] !== $noEqualOp) {
return false;
}
return true;
&& self::$transOpInt[$this->operator] !== $noEqualOp);
}
return false;
@@ -46,7 +46,7 @@ class EmptyConstraint implements ConstraintInterface
return $this->prettyString;
}
return $this->__toString();
return (string) $this;
}
/**
@@ -102,7 +102,7 @@ class MultiConstraint implements ConstraintInterface
return $this->prettyString;
}
return $this->__toString();
return (string) $this;
}
/**
+2 -2
View File
@@ -37,9 +37,9 @@ class Semver
$versionParser = self::$versionParser;
$provider = new Constraint('==', $versionParser->normalize($version));
$constraints = $versionParser->parseConstraints($constraints);
$parsedConstraints = $versionParser->parseConstraints($constraints);
return $constraints->matches($provider);
return $parsedConstraints->matches($provider);
}
/**
@@ -52,11 +52,12 @@ class VersionParser
{
$version = preg_replace('{#.+$}i', '', $version);
if ('dev-' === substr($version, 0, 4) || '-dev' === substr($version, -4)) {
if (strpos($version, 'dev-') === 0 || '-dev' === substr($version, -4)) {
return 'dev';
}
preg_match('{' . self::$modifierRegex . '(?:\+.*)?$}i', strtolower($version), $match);
if (!empty($match[3])) {
return 'dev';
}
@@ -107,6 +108,9 @@ class VersionParser
// strip off aliasing
if (preg_match('{^([^,\s]++) ++as ++([^,\s]++)$}', $version, $match)) {
// verify that the alias is a version without constraint
$this->normalize($match[2]);
$version = $match[1];
}
@@ -116,7 +120,7 @@ class VersionParser
}
// if requirement is branch-like, use full name
if ('dev-' === strtolower(substr($version, 0, 4))) {
if (stripos($version, 'dev-') === 0) {
return 'dev-' . substr($version, 4);
}
@@ -236,6 +240,7 @@ class VersionParser
$orConstraints = preg_split('{\s*\|\|?\s*}', trim($constraints));
$orGroups = array();
foreach ($orConstraints as $constraints) {
$andConstraints = preg_split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', $constraints);
if (count($andConstraints) > 1) {
@@ -268,9 +273,9 @@ class VersionParser
&& 2 === count($orGroups[0]->getConstraints())
&& 2 === count($orGroups[1]->getConstraints())
&& ($a = (string) $orGroups[0])
&& substr($a, 0, 3) === '[>=' && (false !== ($posA = strpos($a, '<', 4)))
&& strpos($a, '[>=') === 0 && (false !== ($posA = strpos($a, '<', 4)))
&& ($b = (string) $orGroups[1])
&& substr($b, 0, 3) === '[>=' && (false !== ($posB = strpos($b, '<', 4)))
&& strpos($b, '[>=') === 0 && (false !== ($posB = strpos($b, '<', 4)))
&& substr($a, $posA + 2, -1) === substr($b, 4, $posB - 5)
) {
$constraint = new MultiConstraint(array(
@@ -314,7 +319,7 @@ class VersionParser
// version, to ensure that unstable instances of the current version are allowed. However, if a stability
// suffix is added to the constraint, then a >= match on the current version is used instead.
if (preg_match('{^~>?' . $versionRegex . '$}i', $constraint, $matches)) {
if (substr($constraint, 0, 2) === '~>') {
if (strpos($constraint, '~>') === 0) {
throw new \UnexpectedValueException(
'Could not parse version constraint ' . $constraint . ': ' .
'Invalid operator "~>", you probably meant to use the "~" operator'
@@ -322,11 +327,11 @@ class VersionParser
}
// Work out which position in the version we are operating at
if (isset($matches[4]) && '' !== $matches[4]) {
if (isset($matches[4]) && '' !== $matches[4] && null !== $matches[4]) {
$position = 4;
} elseif (isset($matches[3]) && '' !== $matches[3]) {
} elseif (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
$position = 3;
} elseif (isset($matches[2]) && '' !== $matches[2]) {
} elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
$position = 2;
} else {
$position = 1;
@@ -334,19 +339,11 @@ class VersionParser
// Calculate the stability suffix
$stabilitySuffix = '';
if (!empty($matches[5])) {
$stabilitySuffix .= '-' . $this->expandStability($matches[5]) . (!empty($matches[6]) ? $matches[6] : '');
}
if (!empty($matches[7])) {
if (empty($matches[5]) && empty($matches[7])) {
$stabilitySuffix .= '-dev';
}
if (!$stabilitySuffix) {
$stabilitySuffix = '-dev';
}
$lowVersion = $this->manipulateVersionString($matches, $position, 0) . $stabilitySuffix;
$lowVersion = $this->normalize(substr($constraint . $stabilitySuffix, 1));
$lowerBound = new Constraint('>=', $lowVersion);
// For upper bound, we increment the position of one more significance,
@@ -368,9 +365,9 @@ class VersionParser
// versions 0.X >=0.1.0, and no updates for versions 0.0.X
if (preg_match('{^\^' . $versionRegex . '($)}i', $constraint, $matches)) {
// Work out which position in the version we are operating at
if ('0' !== $matches[1] || '' === $matches[2]) {
if ('0' !== $matches[1] || '' === $matches[2] || null === $matches[2]) {
$position = 1;
} elseif ('0' !== $matches[2] || '' === $matches[3]) {
} elseif ('0' !== $matches[2] || '' === $matches[3] || null === $matches[3]) {
$position = 2;
} else {
$position = 3;
@@ -401,9 +398,9 @@ class VersionParser
// Any of X, x, or * may be used to "stand in" for one of the numeric values in the [major, minor, patch] tuple.
// A partial version range is treated as an X-Range, so the special character is in fact optional.
if (preg_match('{^v?(\d++)(?:\.(\d++))?(?:\.(\d++))?(?:\.[xX*])++$}', $constraint, $matches)) {
if (isset($matches[3]) && '' !== $matches[3]) {
if (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
$position = 3;
} elseif (isset($matches[2]) && '' !== $matches[2]) {
} elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
$position = 2;
} else {
$position = 1;
@@ -462,11 +459,11 @@ class VersionParser
try {
$version = $this->normalize($matches[2]);
if (!empty($stabilityModifier) && $this->parseStability($version) === 'stable') {
if (!empty($stabilityModifier) && self::parseStability($version) === 'stable') {
$version .= '-' . $stabilityModifier;
} elseif ('<' === $matches[1] || '>=' === $matches[1]) {
if (!preg_match('/-' . self::$modifierRegex . '$/', strtolower($matches[2]))) {
if (substr($matches[2], 0, 4) !== 'dev-') {
if (strpos($matches[2], 'dev-') !== 0) {
$version .= '-dev';
}
}
@@ -511,7 +508,7 @@ class VersionParser
// Return null on a carry overflow
if ($i === 1) {
return;
return null;
}
}
}
+41
View File
@@ -1,3 +1,44 @@
# v3.0.9
## 06/08/2020
1. [](#improved)
* Disable password autocomplete in password field
* Don't save empty string in password field [#134](https://github.com/getgrav/grav-plugin-email/issues/134)
# v3.0.8
## 04/27/2020
1. [](#improved)
* Updated vendor library files
* Use Grav's Parsedown class
# v3.0.7
## 03/05/2020
1. [](#improved)
* Updated email validator library
1. [](#bugfix)
* Fixed `Invalid resource theme://` on CLI command `test-email` on Grav 1.6.21 and later versions [#128](https://github.com/getgrav/grav-plugin-email/issues/128)
# v3.0.6
## 02/11/2020
1. [](#improved)
* Updated email validator library
# v3.0.5
## 02/03/2020
1. [](#bugfix)
* Fixed a date in changelog (no other changes)
# v3.0.4
## 01/17/2020
1. [](#improved)
* Added ZOHO configuration example
* Updated SwiftMailer library for PHP 7.4 support
# v3.0.3
## 08/16/2019
+19
View File
@@ -159,6 +159,25 @@ mailer:
It's that easy!
#### ZOHO
ZOHO is a popular solution for hosted email due to it's great 'FREE' tier. It's paid options are also very reasonable and combined with the latest UI updates and outstanding security features, it's a solid email option.
In order to get ZOHO working with Grav, you need to send email via a user account. You can either use your users' password or generate an **App Password** via your ZOHO account (clicking on your avatar once logged in), then navigating to `Two Factor Authentication -> App Passwords -> Generate`. Just enter a unique app name (i.e. `Grav Website`).
NOTE: The SMTP host required can be found in `Settings -> Mail - > Mail Accounts -> POP/IMAP -> SMTP`. This will provide the SMTP server for this account (it may not be `imap.zoho.com` depending on what region you are in)
```
mailer:
engine: smtp
smtp:
server: smtp.zoho.com
port: 587
encryption: tls
user: 'ZOHO_EMAIL_ADDRESS'
password: 'ZOHO_EMAIL_PASSWORD'
```
#### Sendmail
Although not as reliable as SMTP not providing as much debug information, sendmail is a simple option as long as your hosting provider is not blocking the default SMTP port `25`:
+6 -3
View File
@@ -1,5 +1,7 @@
name: Email
version: 3.0.3
slug: email
type: plugin
version: 3.0.9
testing: false
description: Enables the emailing system for Grav
icon: envelope
@@ -18,6 +20,7 @@ dependencies:
form:
validation: loose
fields:
enabled:
type: hidden
@@ -168,13 +171,13 @@ form:
mailer.smtp.user:
type: text
size: medium
autocomplete: nope
autocomplete: 'off'
label: PLUGIN_EMAIL.SMTP_LOGIN_NAME
mailer.smtp.password:
type: password
size: medium
autocomplete: nope
autocomplete: 'new-password'
label: PLUGIN_EMAIL.SMTP_PASSWORD
sendmail_config:
+3 -2
View File
@@ -4,6 +4,7 @@ namespace Grav\Plugin\Email;
use Grav\Common\Config\Config;
use Grav\Common\Grav;
use Grav\Common\Language\Language;
use Grav\Common\Markdown\Parsedown;
use Grav\Common\Twig\Twig;
use Grav\Framework\Form\Interfaces\FormInterface;
use \Monolog\Logger;
@@ -178,7 +179,7 @@ class Email
$body = $twig->processString($value, $vars);
if ($params['process_markdown']) {
$parsedown = new \Parsedown();
$parsedown = new Parsedown();
$body = $parsedown->text($body);
}
@@ -202,7 +203,7 @@ class Email
$body = !empty($body_part['body']) ? $twig->processString($body_part['body'], $vars) : null;
if ($params['process_markdown']) {
$parsedown = new \Parsedown();
$parsedown = new Parsedown();
$body = $parsedown->text($body);
}
@@ -40,6 +40,11 @@ class ClearQueueFailuresCommand extends ConsoleCommand
*/
protected function serve()
{
// TODO: remove when requiring Grav 1.7+
if (method_exists($this, 'initializeGrav')) {
$this->initializeGrav();
}
$grav = Grav::instance();
$this->output->writeln('');
@@ -40,6 +40,11 @@ class FlushQueueCommand extends ConsoleCommand
*/
protected function serve()
{
// TODO: remove when requiring Grav 1.7+
if (method_exists($this, 'initializeGrav')) {
$this->initializeGrav();
}
$grav = Grav::instance();
$this->output->writeln('');
+5 -4
View File
@@ -59,6 +59,11 @@ class TestEmailCommand extends ConsoleCommand
*/
protected function serve()
{
// TODO: remove when requiring Grav 1.7+
if (method_exists($this, 'initializeGrav')) {
$this->initializeThemes();
}
$grav = Grav::instance();
$this->output->writeln('');
@@ -69,8 +74,6 @@ class TestEmailCommand extends ConsoleCommand
$this->output->writeln('');
require_once __DIR__ . '/../vendor/autoload.php';
$grav['Email'] = new Email();
$to = $this->input->getOption('to') ?: $grav['config']->get('plugins.email.to');
@@ -86,8 +89,6 @@ class TestEmailCommand extends ConsoleCommand
$body = $grav['language']->translate(['PLUGIN_EMAIL.TEST_EMAIL_BODY', $configuration]);
}
// This is the old way....
// $sent = EmailUtils::sendEmail($subject, $body, $email_to);
$sent = EmailUtils::sendEmail(['subject'=>$subject, 'body'=>$body, 'to'=>$to]);
if ($sent) {
+126 -60
View File
@@ -8,30 +8,35 @@
"packages": [
{
"name": "doctrine/lexer",
"version": "v1.0.1",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/lexer.git",
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c"
"reference": "5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c",
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c",
"url": "https://api.github.com/repos/doctrine/lexer/zipball/5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6",
"reference": "5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
"php": "^7.2"
},
"require-dev": {
"doctrine/coding-standard": "^6.0",
"phpstan/phpstan": "^0.11.8",
"phpunit/phpunit": "^8.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
"dev-master": "1.2.x-dev"
}
},
"autoload": {
"psr-0": {
"Doctrine\\Common\\Lexer\\": "lib/"
"psr-4": {
"Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -39,48 +44,52 @@
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
"homepage": "http://www.doctrine-project.org",
"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"
"parser",
"php"
],
"time": "2014-09-09T13:34:57+00:00"
"time": "2019-10-30T14:39:59+00:00"
},
{
"name": "egulias/email-validator",
"version": "2.1.7",
"version": "2.1.17",
"source": {
"type": "git",
"url": "https://github.com/egulias/EmailValidator.git",
"reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e"
"reference": "ade6887fd9bd74177769645ab5c474824f8a418a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/709f21f92707308cdf8f9bcfa1af4cb26586521e",
"reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e",
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ade6887fd9bd74177769645ab5c474824f8a418a",
"reference": "ade6887fd9bd74177769645ab5c474824f8a418a",
"shasum": ""
},
"require": {
"doctrine/lexer": "^1.0.1",
"php": ">= 5.5"
"php": ">=5.5",
"symfony/polyfill-intl-idn": "^1.10"
},
"require-dev": {
"dominicsayers/isemail": "dev-master",
"phpunit/phpunit": "^4.8.35||^5.7||^6.0",
"dominicsayers/isemail": "^3.0.7",
"phpunit/phpunit": "^4.8.36|^7.5.15",
"satooshi/php-coveralls": "^1.0.1"
},
"suggest": {
@@ -89,7 +98,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
"dev-master": "2.1.x-dev"
}
},
"autoload": {
@@ -115,20 +124,20 @@
"validation",
"validator"
],
"time": "2018-12-04T22:38:24+00:00"
"time": "2020-02-13T22:36:52+00:00"
},
{
"name": "swiftmailer/swiftmailer",
"version": "v6.2.0",
"version": "v6.2.3",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707"
"reference": "149cfdf118b169f7840bbe3ef0d4bc795d1780c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707",
"reference": "6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/149cfdf118b169f7840bbe3ef0d4bc795d1780c9",
"reference": "149cfdf118b169f7840bbe3ef0d4bc795d1780c9",
"shasum": ""
},
"require": {
@@ -177,20 +186,20 @@
"mail",
"mailer"
],
"time": "2019-03-10T07:52:41+00:00"
"time": "2019-11-12T09:31:26+00:00"
},
{
"name": "symfony/polyfill-iconv",
"version": "v1.10.0",
"version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-iconv.git",
"reference": "97001cfc283484c9691769f51cdf25259037eba2"
"reference": "ad6d62792bfbcfc385dd34b424d4fcf9712a32c8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/97001cfc283484c9691769f51cdf25259037eba2",
"reference": "97001cfc283484c9691769f51cdf25259037eba2",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/ad6d62792bfbcfc385dd34b424d4fcf9712a32c8",
"reference": "ad6d62792bfbcfc385dd34b424d4fcf9712a32c8",
"shasum": ""
},
"require": {
@@ -202,7 +211,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.9-dev"
"dev-master": "1.15-dev"
}
},
"autoload": {
@@ -236,26 +245,40 @@
"portable",
"shim"
],
"time": "2018-09-21T06:26:08+00:00"
"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-03-09T19:04:49+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.10.0",
"version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "89de1d44f2c059b266f22c9cc9124ddc4cd0987a"
"reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/89de1d44f2c059b266f22c9cc9124ddc4cd0987a",
"reference": "89de1d44f2c059b266f22c9cc9124ddc4cd0987a",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf",
"reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"symfony/polyfill-mbstring": "^1.3",
"symfony/polyfill-php72": "^1.9"
"symfony/polyfill-php72": "^1.10"
},
"suggest": {
"ext-intl": "For best performance"
@@ -263,7 +286,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.9-dev"
"dev-master": "1.15-dev"
}
},
"autoload": {
@@ -279,13 +302,13 @@
"MIT"
],
"authors": [
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
},
{
"name": "Laurent Bassin",
"email": "laurent@bassin.info"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
@@ -298,20 +321,34 @@
"portable",
"shim"
],
"time": "2018-09-30T16:36:12+00:00"
"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-03-09T19:04:49+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.10.0",
"version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494"
"reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494",
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
"reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
"shasum": ""
},
"require": {
@@ -323,7 +360,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.9-dev"
"dev-master": "1.15-dev"
}
},
"autoload": {
@@ -357,20 +394,34 @@
"portable",
"shim"
],
"time": "2018-09-21T13:07:52+00:00"
"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-03-09T19:04:49+00:00"
},
{
"name": "symfony/polyfill-php72",
"version": "v1.10.0",
"version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631"
"reference": "37b0976c78b94856543260ce09b460a7bc852747"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631",
"reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/37b0976c78b94856543260ce09b460a7bc852747",
"reference": "37b0976c78b94856543260ce09b460a7bc852747",
"shasum": ""
},
"require": {
@@ -379,7 +430,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.9-dev"
"dev-master": "1.15-dev"
}
},
"autoload": {
@@ -412,7 +463,21 @@
"portable",
"shim"
],
"time": "2018-09-21T13:07:52+00:00"
"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-02-27T09:26:54+00:00"
}
],
"packages-dev": [],
@@ -424,5 +489,6 @@
"platform": {
"php": ">=7.1.3"
},
"platform-dev": []
"platform-dev": [],
"plugin-api-version": "1.1.0"
}
+24
View File
@@ -1,6 +1,7 @@
<?php
namespace Grav\Plugin;
use Grav\Common\Data\Data;
use Grav\Common\Plugin;
use Grav\Plugin\Email\Email;
use RocketTheme\Toolbox\Event\Event;
@@ -22,6 +23,7 @@ class EmailPlugin extends Plugin
'onFormProcessed' => ['onFormProcessed', 0],
'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0],
'onSchedulerInitialized' => ['onSchedulerInitialized', 0],
'onAdminSave' => ['onAdminSave', 0],
];
}
@@ -48,6 +50,28 @@ class EmailPlugin extends Plugin
$twig->twig_paths[] = __DIR__ . '/templates';
}
/**
* Force compile during save if admin plugin save
*
* @param Event $event
*/
public function onAdminSave(Event $event)
{
/** @var Data $obj */
$obj = $event['object'];
if ($obj instanceof Data && $obj->blueprints()->getFilename() === 'email/blueprints') {
$current_pw = $this->grav['config']->get('plugins.email.mailer.smtp.password');
$new_pw = $obj->get('mailer.smtp.password');
if (!empty($current_pw) && empty($new_pw)) {
$obj->set('mailer.smtp.password', $current_pw);
}
}
}
/**
* Send email when processing the form data.
*
+2 -2
View File
@@ -279,7 +279,7 @@ class ClassLoader
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
@@ -377,7 +377,7 @@ class ClassLoader
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath.'\\';
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
+1 -1
View File
@@ -8,7 +8,7 @@ $baseDir = dirname($vendorDir);
return array(
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
);
@@ -6,5 +6,4 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib'),
);
+1
View File
@@ -13,4 +13,5 @@ return array(
'Grav\\Plugin\\Email\\' => array($baseDir . '/classes'),
'Grav\\Plugin\\Console\\' => array($baseDir . '/cli'),
'Egulias\\EmailValidator\\' => array($vendorDir . '/egulias/email-validator/EmailValidator'),
'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib/Doctrine/Common/Lexer'),
);
+3
View File
@@ -13,6 +13,9 @@ class ComposerAutoloaderInitdec5d78def1384d1f20996ded9d7efbf
}
}
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader()
{
if (null !== self::$loader) {
+7 -10
View File
@@ -9,8 +9,8 @@ class ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf
public static $files = array (
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
'2c102faa651ef8ea5874edb585946bce' => __DIR__ . '/..' . '/swiftmailer/swiftmailer/lib/swift_required.php',
);
@@ -31,6 +31,10 @@ class ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf
array (
'Egulias\\EmailValidator\\' => 23,
),
'D' =>
array (
'Doctrine\\Common\\Lexer\\' => 22,
),
);
public static $prefixDirsPsr4 = array (
@@ -62,15 +66,9 @@ class ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf
array (
0 => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator',
),
);
public static $prefixesPsr0 = array (
'D' =>
'Doctrine\\Common\\Lexer\\' =>
array (
'Doctrine\\Common\\Lexer\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/lexer/lib',
),
0 => __DIR__ . '/..' . '/doctrine/lexer/lib/Doctrine/Common/Lexer',
),
);
@@ -83,7 +81,6 @@ class ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf::$prefixesPsr0;
$loader->classMap = ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf::$classMap;
}, null, ClassLoader::class);
+131 -66
View File
@@ -1,33 +1,38 @@
[
{
"name": "doctrine/lexer",
"version": "v1.0.1",
"version_normalized": "1.0.1.0",
"version": "1.2.0",
"version_normalized": "1.2.0.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/lexer.git",
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c"
"reference": "5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c",
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c",
"url": "https://api.github.com/repos/doctrine/lexer/zipball/5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6",
"reference": "5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
"php": "^7.2"
},
"time": "2014-09-09T13:34:57+00:00",
"require-dev": {
"doctrine/coding-standard": "^6.0",
"phpstan/phpstan": "^0.11.8",
"phpunit/phpunit": "^8.2"
},
"time": "2019-10-30T14:39:59+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
"dev-master": "1.2.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Doctrine\\Common\\Lexer\\": "lib/"
"psr-4": {
"Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -35,58 +40,62 @@
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
"homepage": "http://www.doctrine-project.org",
"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"
"parser",
"php"
]
},
{
"name": "egulias/email-validator",
"version": "2.1.7",
"version_normalized": "2.1.7.0",
"version": "2.1.17",
"version_normalized": "2.1.17.0",
"source": {
"type": "git",
"url": "https://github.com/egulias/EmailValidator.git",
"reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e"
"reference": "ade6887fd9bd74177769645ab5c474824f8a418a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/709f21f92707308cdf8f9bcfa1af4cb26586521e",
"reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e",
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ade6887fd9bd74177769645ab5c474824f8a418a",
"reference": "ade6887fd9bd74177769645ab5c474824f8a418a",
"shasum": ""
},
"require": {
"doctrine/lexer": "^1.0.1",
"php": ">= 5.5"
"php": ">=5.5",
"symfony/polyfill-intl-idn": "^1.10"
},
"require-dev": {
"dominicsayers/isemail": "dev-master",
"phpunit/phpunit": "^4.8.35||^5.7||^6.0",
"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": "2018-12-04T22:38:24+00:00",
"time": "2020-02-13T22:36:52+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
"dev-master": "2.1.x-dev"
}
},
"installation-source": "dist",
@@ -116,17 +125,17 @@
},
{
"name": "swiftmailer/swiftmailer",
"version": "v6.2.0",
"version_normalized": "6.2.0.0",
"version": "v6.2.3",
"version_normalized": "6.2.3.0",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707"
"reference": "149cfdf118b169f7840bbe3ef0d4bc795d1780c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707",
"reference": "6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/149cfdf118b169f7840bbe3ef0d4bc795d1780c9",
"reference": "149cfdf118b169f7840bbe3ef0d4bc795d1780c9",
"shasum": ""
},
"require": {
@@ -144,7 +153,7 @@
"ext-intl": "Needed to support internationalized email addresses",
"true/punycode": "Needed to support internationalized email addresses, if ext-intl is not installed"
},
"time": "2019-03-10T07:52:41+00:00",
"time": "2019-11-12T09:31:26+00:00",
"type": "library",
"extra": {
"branch-alias": {
@@ -180,17 +189,17 @@
},
{
"name": "symfony/polyfill-iconv",
"version": "v1.10.0",
"version_normalized": "1.10.0.0",
"version": "v1.15.0",
"version_normalized": "1.15.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-iconv.git",
"reference": "97001cfc283484c9691769f51cdf25259037eba2"
"reference": "ad6d62792bfbcfc385dd34b424d4fcf9712a32c8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/97001cfc283484c9691769f51cdf25259037eba2",
"reference": "97001cfc283484c9691769f51cdf25259037eba2",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/ad6d62792bfbcfc385dd34b424d4fcf9712a32c8",
"reference": "ad6d62792bfbcfc385dd34b424d4fcf9712a32c8",
"shasum": ""
},
"require": {
@@ -199,11 +208,11 @@
"suggest": {
"ext-iconv": "For best performance"
},
"time": "2018-09-21T06:26:08+00:00",
"time": "2020-03-09T19:04:49+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.9-dev"
"dev-master": "1.15-dev"
}
},
"installation-source": "dist",
@@ -237,36 +246,50 @@
"polyfill",
"portable",
"shim"
],
"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"
}
]
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.10.0",
"version_normalized": "1.10.0.0",
"version": "v1.15.0",
"version_normalized": "1.15.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "89de1d44f2c059b266f22c9cc9124ddc4cd0987a"
"reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/89de1d44f2c059b266f22c9cc9124ddc4cd0987a",
"reference": "89de1d44f2c059b266f22c9cc9124ddc4cd0987a",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf",
"reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"symfony/polyfill-mbstring": "^1.3",
"symfony/polyfill-php72": "^1.9"
"symfony/polyfill-php72": "^1.10"
},
"suggest": {
"ext-intl": "For best performance"
},
"time": "2018-09-30T16:36:12+00:00",
"time": "2020-03-09T19:04:49+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.9-dev"
"dev-master": "1.15-dev"
}
},
"installation-source": "dist",
@@ -283,13 +306,13 @@
"MIT"
],
"authors": [
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
},
{
"name": "Laurent Bassin",
"email": "laurent@bassin.info"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
@@ -301,21 +324,35 @@
"polyfill",
"portable",
"shim"
],
"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"
}
]
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.10.0",
"version_normalized": "1.10.0.0",
"version": "v1.15.0",
"version_normalized": "1.15.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494"
"reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494",
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
"reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
"shasum": ""
},
"require": {
@@ -324,11 +361,11 @@
"suggest": {
"ext-mbstring": "For best performance"
},
"time": "2018-09-21T13:07:52+00:00",
"time": "2020-03-09T19:04:49+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.9-dev"
"dev-master": "1.15-dev"
}
},
"installation-source": "dist",
@@ -362,31 +399,45 @@
"polyfill",
"portable",
"shim"
],
"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"
}
]
},
{
"name": "symfony/polyfill-php72",
"version": "v1.10.0",
"version_normalized": "1.10.0.0",
"version": "v1.15.0",
"version_normalized": "1.15.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631"
"reference": "37b0976c78b94856543260ce09b460a7bc852747"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631",
"reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/37b0976c78b94856543260ce09b460a7bc852747",
"reference": "37b0976c78b94856543260ce09b460a7bc852747",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"time": "2018-09-21T13:07:52+00:00",
"time": "2020-02-27T09:26:54+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.9-dev"
"dev-master": "1.15-dev"
}
},
"installation-source": "dist",
@@ -419,6 +470,20 @@
"polyfill",
"portable",
"shim"
],
"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"
}
]
}
]
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2006-2013 Doctrine Project
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
+4
View File
@@ -1,5 +1,9 @@
# Doctrine Lexer
Build Status: [![Build Status](https://travis-ci.org/doctrine/lexer.svg?branch=master)](https://travis-ci.org/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
+23 -6
View File
@@ -1,9 +1,15 @@
{
"name": "doctrine/lexer",
"type": "library",
"description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
"keywords": ["lexer", "parser"],
"homepage": "http://www.doctrine-project.org",
"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"},
@@ -11,14 +17,25 @@
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
],
"require": {
"php": ">=5.3.2"
"php": "^7.2"
},
"require-dev": {
"doctrine/coding-standard": "^6.0",
"phpstan/phpstan": "^0.11.8",
"phpunit/phpunit": "^8.2"
},
"autoload": {
"psr-0": { "Doctrine\\Common\\Lexer\\": "lib/" }
"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"
"dev-master": "1.2.x-dev"
}
},
"config": {
"sort-packages": true
}
}
@@ -1,31 +1,21 @@
<?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>.
*/
declare(strict_types=1);
namespace Doctrine\Common\Lexer;
use ReflectionClass;
use const PREG_SPLIT_DELIM_CAPTURE;
use const PREG_SPLIT_NO_EMPTY;
use const PREG_SPLIT_OFFSET_CAPTURE;
use function implode;
use function in_array;
use function preg_split;
use function sprintf;
use function substr;
/**
* 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
{
@@ -47,36 +37,43 @@ abstract class AbstractLexer
*
* @var array
*/
private $tokens = array();
private $tokens = [];
/**
* Current lexer position in input string.
*
* @var integer
* @var int
*/
private $position = 0;
/**
* Current peek of current lexer position.
*
* @var integer
* @var int
*/
private $peek = 0;
/**
* The next token in the input.
*
* @var array
* @var array|null
*/
public $lookahead;
/**
* The last matched/seen token.
*
* @var array
* @var array|null
*/
public $token;
/**
* Composed regex for input parsing.
*
* @var string
*/
private $regex;
/**
* Sets the input data to be tokenized.
*
@@ -90,7 +87,7 @@ abstract class AbstractLexer
public function setInput($input)
{
$this->input = $input;
$this->tokens = array();
$this->tokens = [];
$this->reset();
$this->scan($input);
@@ -104,9 +101,9 @@ abstract class AbstractLexer
public function reset()
{
$this->lookahead = null;
$this->token = null;
$this->peek = 0;
$this->position = 0;
$this->token = null;
$this->peek = 0;
$this->position = 0;
}
/**
@@ -122,7 +119,7 @@ abstract class AbstractLexer
/**
* Resets the lexer position on the input to the given position.
*
* @param integer $position Position to place the lexical scanner.
* @param int $position Position to place the lexical scanner.
*
* @return void
*/
@@ -132,9 +129,9 @@ abstract class AbstractLexer
}
/**
* Retrieve the original lexer's input until a given position.
* Retrieve the original lexer's input until a given position.
*
* @param integer $position
* @param int $position
*
* @return string
*/
@@ -146,13 +143,13 @@ abstract class AbstractLexer
/**
* Checks whether a given token matches the current lookahead.
*
* @param integer|string $token
* @param int|string $token
*
* @return boolean
* @return bool
*/
public function isNextToken($token)
{
return null !== $this->lookahead && $this->lookahead['type'] === $token;
return $this->lookahead !== null && $this->lookahead['type'] === $token;
}
/**
@@ -160,23 +157,23 @@ abstract class AbstractLexer
*
* @param array $tokens
*
* @return boolean
* @return bool
*/
public function isNextTokenAny(array $tokens)
{
return null !== $this->lookahead && in_array($this->lookahead['type'], $tokens, true);
return $this->lookahead !== null && in_array($this->lookahead['type'], $tokens, true);
}
/**
* Moves to the next token in the input string.
*
* @return boolean
* @return bool
*/
public function moveNext()
{
$this->peek = 0;
$this->token = $this->lookahead;
$this->lookahead = (isset($this->tokens[$this->position]))
$this->peek = 0;
$this->token = $this->lookahead;
$this->lookahead = isset($this->tokens[$this->position])
? $this->tokens[$this->position++] : null;
return $this->lookahead !== null;
@@ -199,10 +196,10 @@ abstract class AbstractLexer
/**
* Checks if given value is identical to the given token.
*
* @param mixed $value
* @param integer $token
* @param mixed $value
* @param int|string $token
*
* @return boolean
* @return bool
*/
public function isA($value, $token)
{
@@ -218,9 +215,9 @@ abstract class AbstractLexer
{
if (isset($this->tokens[$this->position + $this->peek])) {
return $this->tokens[$this->position + $this->peek++];
} else {
return null;
}
return null;
}
/**
@@ -230,8 +227,9 @@ abstract class AbstractLexer
*/
public function glimpse()
{
$peek = $this->peek();
$peek = $this->peek();
$this->peek = 0;
return $peek;
}
@@ -244,10 +242,8 @@ abstract class AbstractLexer
*/
protected function scan($input)
{
static $regex;
if ( ! isset($regex)) {
$regex = sprintf(
if (! isset($this->regex)) {
$this->regex = sprintf(
'/(%s)|%s/%s',
implode(')|(', $this->getCatchablePatterns()),
implode('|', $this->getNonCatchablePatterns()),
@@ -255,32 +251,37 @@ abstract class AbstractLexer
);
}
$flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE;
$matches = preg_split($regex, $input, -1, $flags);
$flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE;
$matches = preg_split($this->regex, $input, -1, $flags);
if ($matches === false) {
// Work around https://bugs.php.net/78122
$matches = [[$input, 0]];
}
foreach ($matches as $match) {
// Must remain before 'value' assignment since it can change content
$type = $this->getType($match[0]);
$this->tokens[] = array(
$this->tokens[] = [
'value' => $match[0],
'type' => $type,
'position' => $match[1],
);
];
}
}
/**
* Gets the literal for a given token.
*
* @param integer $token
* @param int|string $token
*
* @return string
* @return int|string
*/
public function getLiteral($token)
{
$className = get_class($this);
$reflClass = new \ReflectionClass($className);
$className = static::class;
$reflClass = new ReflectionClass($className);
$constants = $reflClass->getConstants();
foreach ($constants as $name => $value) {
@@ -299,7 +300,7 @@ abstract class AbstractLexer
*/
protected function getModifiers()
{
return 'i';
return 'iu';
}
/**
@@ -321,7 +322,7 @@ abstract class AbstractLexer
*
* @param string $value
*
* @return integer
* @return int|string|null
*/
abstract protected function getType(&$value);
}
@@ -73,25 +73,73 @@ class EmailLexer extends AbstractLexer
'\0' => self::C_NUL,
);
/**
* @var bool
*/
protected $hasInvalidTokens = false;
protected $previous;
/**
* @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 $type
* @param int $type
* @throws \UnexpectedValueException
* @return boolean
*
* @psalm-suppress InvalidScalarArgument
*/
public function find($type)
{
@@ -107,7 +155,7 @@ class EmailLexer extends AbstractLexer
/**
* getPrevious
*
* @return array token
* @return array
*/
public function getPrevious()
{
@@ -122,8 +170,10 @@ class EmailLexer extends AbstractLexer
public function moveNext()
{
$this->previous = $this->token;
$hasNext = parent::moveNext();
$this->token = $this->token ?: self::$nullToken;
return parent::moveNext();
return $hasNext;
}
/**
@@ -179,6 +229,11 @@ class EmailLexer extends AbstractLexer
return self::GENERIC;
}
/**
* @param string $value
*
* @return bool
*/
protected function isValid($value)
{
if (isset($this->charValue[$value])) {
@@ -189,7 +244,7 @@ class EmailLexer extends AbstractLexer
}
/**
* @param $value
* @param string $value
* @return bool
*/
protected function isNullType($value)
@@ -202,7 +257,7 @@ class EmailLexer extends AbstractLexer
}
/**
* @param $value
* @param string $value
* @return bool
*/
protected function isUTF8Invalid($value)
@@ -214,6 +269,9 @@ class EmailLexer extends AbstractLexer
return false;
}
/**
* @return string
*/
protected function getModifiers()
{
return 'iu';
@@ -17,11 +17,33 @@ class EmailParser
{
const EMAIL_MAX_LENGTH = 254;
protected $warnings;
/**
* @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)
@@ -29,11 +51,10 @@ class EmailParser
$this->lexer = $lexer;
$this->localPartParser = new LocalPart($this->lexer);
$this->domainPartParser = new DomainPart($this->lexer);
$this->warnings = new \SplObjectStorage();
}
/**
* @param $str
* @param string $str
* @return array
*/
public function parse($str)
@@ -57,6 +78,9 @@ class EmailParser
return array('local' => $this->localPart, 'domain' => $this->domainPart);
}
/**
* @return Warning\Warning[]
*/
public function getWarnings()
{
$localPartWarnings = $this->localPartParser->getWarnings();
@@ -68,11 +92,17 @@ class EmailParser
return $this->warnings;
}
/**
* @return string
*/
public function getParsedDomainPart()
{
return $this->domainPart;
}
/**
* @param string $email
*/
protected function setParts($email)
{
$parts = explode('@', $email);
@@ -80,6 +110,9 @@ class EmailParser
$this->localPart = $parts[0];
}
/**
* @return bool
*/
protected function hasAtToken()
{
$this->lexer->moveNext();
@@ -13,12 +13,12 @@ class EmailValidator
private $lexer;
/**
* @var array
* @var Warning\Warning[]
*/
protected $warnings;
protected $warnings = [];
/**
* @var InvalidEmail
* @var InvalidEmail|null
*/
protected $error;
@@ -28,7 +28,7 @@ class EmailValidator
}
/**
* @param $email
* @param string $email
* @param EmailValidation $emailValidation
* @return bool
*/
@@ -58,7 +58,7 @@ class EmailValidator
}
/**
* @return InvalidEmail
* @return InvalidEmail|null
*/
public function getError()
{
@@ -2,7 +2,7 @@
namespace Egulias\EmailValidator\Exception;
class ExpectedQPair extends InvalidEmail
class ExpectingQPair extends InvalidEmail
{
const CODE = 136;
const REASON = "Expecting QPAIR";
@@ -2,8 +2,6 @@
namespace Egulias\EmailValidator\Exception;
use Egulias\EmailValidator\Exception\InvalidEmail;
class NoDNSRecord extends InvalidEmail
{
const CODE = 5;
@@ -35,27 +35,17 @@ use Egulias\EmailValidator\Warning\TLD;
class DomainPart extends Parser
{
const DOMAIN_MAX_LENGTH = 254;
/**
* @var string
*/
protected $domainPart = '';
public function parse($domainPart)
{
$this->lexer->moveNext();
if ($this->lexer->token['type'] === EmailLexer::S_DOT) {
throw new DotAtStart();
}
if ($this->lexer->token['type'] === EmailLexer::S_EMPTY) {
throw new NoDomainPart();
}
if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN) {
throw new DomainHyphened();
}
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
$this->warnings[DeprecatedComment::CODE] = new DeprecatedComment();
$this->parseDomainComments();
}
$this->performDomainStartChecks();
$domain = $this->doParseDomainPart();
@@ -77,11 +67,50 @@ class DomainPart extends Parser
$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();
@@ -125,6 +154,9 @@ class DomainPart extends Parser
}
}
/**
* @return string
*/
protected function doParseDomainPart()
{
$domain = '';
@@ -166,12 +198,12 @@ class DomainPart extends Parser
$domain .= $this->lexer->token['value'];
$this->lexer->moveNext();
} while ($this->lexer->token);
} while (null !== $this->lexer->token['type']);
return $domain;
}
private function checkNotAllowedChars($token)
private function checkNotAllowedChars(array $token)
{
$notAllowed = [EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true];
if (isset($notAllowed[$token['type']])) {
@@ -179,6 +211,9 @@ class DomainPart extends Parser
}
}
/**
* @return string|false
*/
protected function parseDomainLiteral()
{
if ($this->lexer->isNextToken(EmailLexer::S_COLON)) {
@@ -195,6 +230,9 @@ class DomainPart extends Parser
return $this->doParseDomainLiteral();
}
/**
* @return string|false
*/
protected function doParseDomainLiteral()
{
$IPv6TAG = false;
@@ -262,6 +300,11 @@ class DomainPart extends Parser
return $addressLiteral;
}
/**
* @param string $addressLiteral
*
* @return string|false
*/
protected function checkIPV4Tag($addressLiteral)
{
$matchesIP = array();
@@ -279,13 +322,13 @@ class DomainPart extends Parser
return false;
}
// Convert IPv4 part to IPv6 format for further testing
$addressLiteral = substr($addressLiteral, 0, $index) . '0:0';
$addressLiteral = substr($addressLiteral, 0, (int) $index) . '0:0';
}
return $addressLiteral;
}
protected function checkDomainPartExceptions($prev)
protected function checkDomainPartExceptions(array $prev)
{
$invalidDomainTokens = array(
EmailLexer::S_DQUOTE => true,
@@ -320,6 +363,9 @@ class DomainPart extends Parser
}
}
/**
* @return bool
*/
protected function hasBrackets()
{
if ($this->lexer->token['type'] !== EmailLexer::S_OPENBRACKET) {
@@ -335,7 +381,7 @@ class DomainPart extends Parser
return true;
}
protected function checkLabelLength($prev)
protected function checkLabelLength(array $prev)
{
if ($this->lexer->token['type'] === EmailLexer::S_DOT &&
$prev['type'] === EmailLexer::GENERIC &&
@@ -5,7 +5,6 @@ namespace Egulias\EmailValidator\Parser;
use Egulias\EmailValidator\Exception\DotAtEnd;
use Egulias\EmailValidator\Exception\DotAtStart;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Exception\ExpectingAT;
use Egulias\EmailValidator\Exception\ExpectingATEXT;
use Egulias\EmailValidator\Exception\UnclosedQuotedString;
@@ -20,9 +19,10 @@ class LocalPart extends Parser
$parseDQuote = true;
$closingQuote = false;
$openedParenthesis = 0;
$totalLength = 0;
while ($this->lexer->token['type'] !== EmailLexer::S_AT && $this->lexer->token) {
if ($this->lexer->token['type'] === EmailLexer::S_DOT && !$this->lexer->getPrevious()) {
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();
}
@@ -35,12 +35,13 @@ class LocalPart extends Parser
$this->parseComments();
$openedParenthesis += $this->getOpenedParenthesis();
}
if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) {
if ($openedParenthesis === 0) {
throw new UnopenedComment();
} else {
$openedParenthesis--;
}
$openedParenthesis--;
}
$this->checkConsecutiveDots();
@@ -58,15 +59,18 @@ class LocalPart extends Parser
$this->parseFWS();
}
$totalLength += strlen($this->lexer->token['value']);
$this->lexer->moveNext();
}
$prev = $this->lexer->getPrevious();
if (strlen($prev['value']) > LocalTooLong::LOCAL_PART_LENGTH) {
if ($totalLength > LocalTooLong::LOCAL_PART_LENGTH) {
$this->warnings[LocalTooLong::CODE] = new LocalTooLong();
}
}
/**
* @return bool
*/
protected function parseDoubleQuote()
{
$parseAgain = true;
@@ -86,7 +90,7 @@ class LocalPart extends Parser
$this->lexer->moveNext();
while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && $this->lexer->token) {
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();
@@ -118,7 +122,10 @@ class LocalPart extends Parser
return $parseAgain;
}
protected function isInvalidToken($token, $closingQuote)
/**
* @param bool $closingQuote
*/
protected function isInvalidToken(array $token, $closingQuote)
{
$forbidden = array(
EmailLexer::S_COMMA,
@@ -8,7 +8,7 @@ use Egulias\EmailValidator\Exception\ConsecutiveDot;
use Egulias\EmailValidator\Exception\CRLFAtTheEnd;
use Egulias\EmailValidator\Exception\CRLFX2;
use Egulias\EmailValidator\Exception\CRNoLF;
use Egulias\EmailValidator\Exception\ExpectedQPair;
use Egulias\EmailValidator\Exception\ExpectingQPair;
use Egulias\EmailValidator\Exception\ExpectingATEXT;
use Egulias\EmailValidator\Exception\ExpectingCTEXT;
use Egulias\EmailValidator\Exception\UnclosedComment;
@@ -21,8 +21,19 @@ use Egulias\EmailValidator\Warning\QuotedString;
abstract class Parser
{
/**
* @var \Egulias\EmailValidator\Warning\Warning[]
*/
protected $warnings = [];
/**
* @var EmailLexer
*/
protected $lexer;
/**
* @var int
*/
protected $openedParenthesis = 0;
public function __construct(EmailLexer $lexer)
@@ -30,11 +41,17 @@ abstract class Parser
$this->lexer = $lexer;
}
/**
* @return \Egulias\EmailValidator\Warning\Warning[]
*/
public function getWarnings()
{
return $this->warnings;
}
/**
* @param string $str
*/
abstract public function parse($str);
/** @return int */
@@ -50,7 +67,7 @@ abstract class Parser
{
if (!($this->lexer->token['type'] === EmailLexer::INVALID
|| $this->lexer->token['type'] === EmailLexer::C_DEL)) {
throw new ExpectedQPair();
throw new ExpectingQPair();
}
$this->warnings[QuotedPart::CODE] =
@@ -80,6 +97,9 @@ abstract class Parser
}
}
/**
* @return bool
*/
protected function isUnclosedComment()
{
try {
@@ -122,6 +142,9 @@ abstract class Parser
}
}
/**
* @return bool
*/
protected function isFWS()
{
if ($this->escaped()) {
@@ -140,11 +163,14 @@ abstract class Parser
return false;
}
/**
* @return bool
*/
protected function escaped()
{
$previous = $this->lexer->getPrevious();
if ($previous['type'] === EmailLexer::S_BACKSLASH
if ($previous && $previous['type'] === EmailLexer::S_BACKSLASH
&&
$this->lexer->token['type'] !== EmailLexer::GENERIC
) {
@@ -154,6 +180,9 @@ abstract class Parser
return false;
}
/**
* @return bool
*/
protected function warnEscaping()
{
if ($this->lexer->token['type'] !== EmailLexer::S_BACKSLASH) {
@@ -174,6 +203,11 @@ abstract class Parser
}
/**
* @param bool $hasClosingQuote
*
* @return bool
*/
protected function checkDQUOTE($hasClosingQuote)
{
if ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE) {
@@ -15,13 +15,13 @@ class DNSCheckValidation implements EmailValidation
private $warnings = [];
/**
* @var InvalidEmail
* @var InvalidEmail|null
*/
private $error;
public function __construct()
{
if (!extension_loaded('intl')) {
if (!function_exists('idn_to_ascii')) {
throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__));
}
}
@@ -49,6 +49,11 @@ class DNSCheckValidation implements EmailValidation
return $this->warnings;
}
/**
* @param string $host
*
* @return bool
*/
protected function checkDNS($host)
{
$variant = INTL_IDNA_VARIANT_2003;
@@ -6,6 +6,9 @@ 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);
@@ -9,16 +9,22 @@ class MultipleErrors extends InvalidEmail
const CODE = 999;
const REASON = "Accumulated errors for multiple validations";
/**
* @var array
* @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;
@@ -30,12 +30,12 @@ class MultipleValidationWithAnd implements EmailValidation
private $warnings = [];
/**
* @var MultipleErrors
* @var MultipleErrors|null
*/
private $error;
/**
* @var bool
* @var int
*/
private $mode;
@@ -79,6 +79,12 @@ class MultipleValidationWithAnd implements EmailValidation
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) {
@@ -88,13 +94,20 @@ class MultipleValidationWithAnd implements EmailValidation
return $errors;
}
/**
* @param bool $result
*
* @return bool
*/
private function shouldStop($result)
{
return !$result && $this->mode === self::STOP_ON_ERROR;
}
/**
* {@inheritdoc}
* Returns the validation errors.
*
* @return MultipleErrors|null
*/
public function getError()
{
@@ -9,7 +9,7 @@ use Egulias\EmailValidator\Validation\Error\RFCWarnings;
class NoRFCWarningsValidation extends RFCValidation
{
/**
* @var InvalidEmail
* @var InvalidEmail|null
*/
private $error;
@@ -9,7 +9,7 @@ use Egulias\EmailValidator\Exception\InvalidEmail;
class RFCValidation implements EmailValidation
{
/**
* @var EmailParser
* @var EmailParser|null
*/
private $parser;
@@ -19,7 +19,7 @@ class RFCValidation implements EmailValidation
private $warnings = [];
/**
* @var InvalidEmail
* @var InvalidEmail|null
*/
private $error;
@@ -10,7 +10,7 @@ use \Spoofchecker;
class SpoofCheckValidation implements EmailValidation
{
/**
* @var InvalidEmail
* @var InvalidEmail|null
*/
private $error;
@@ -21,6 +21,9 @@ class SpoofCheckValidation implements EmailValidation
}
}
/**
* @psalm-suppress InvalidArgument
*/
public function isValid($email, EmailLexer $emailLexer)
{
$checker = new Spoofchecker();
@@ -33,6 +36,9 @@ class SpoofCheckValidation implements EmailValidation
return $this->error === null;
}
/**
* @return InvalidEmail|null
*/
public function getError()
{
return $this->error;
@@ -6,6 +6,10 @@ 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";
@@ -6,6 +6,10 @@ 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";
@@ -5,19 +5,36 @@ namespace Egulias\EmailValidator\Warning;
abstract class Warning
{
const CODE = 0;
protected $message;
protected $rfcNumber;
/**
* @var string
*/
protected $message = '';
/**
* @var int
*/
protected $rfcNumber = 0;
/**
* @return string
*/
public function message()
{
return $this->message;
}
/**
* @return int
*/
public function code()
{
return self::CODE;
}
/**
* @return int
*/
public function RFCNumber()
{
return $this->rfcNumber;
@@ -1,5 +1,5 @@
# EmailValidator
[![Build Status](https://travis-ci.org/egulias/EmailValidator.png?branch=master)](https://travis-ci.org/egulias/EmailValidator) [![Coverage Status](https://coveralls.io/repos/egulias/EmailValidator/badge.png?branch=master)](https://coveralls.io/r/egulias/EmailValidator?branch=master) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/egulias/EmailValidator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/egulias/EmailValidator/?branch=master) [![SensioLabsInsight](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6/small.png)](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6)
[![Build Status](https://travis-ci.org/egulias/EmailValidator.svg?branch=master)](https://travis-ci.org/egulias/EmailValidator) [![Coverage Status](https://coveralls.io/repos/egulias/EmailValidator/badge.svg?branch=master)](https://coveralls.io/r/egulias/EmailValidator?branch=master) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/egulias/EmailValidator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/egulias/EmailValidator/?branch=master) [![SensioLabsInsight](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6/small.png)](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6)
=============================
## Suported RFCs ##
This library aims to support:
@@ -16,7 +16,7 @@ RFC 5321, 5322, 6530, 6531, 6532.
Run the command below to install via Composer
```shell
composer require egulias/email-validator "~2.1"
composer require egulias/email-validator
```
## Getting Started ##
@@ -2,7 +2,6 @@
"name": "egulias/email-validator",
"description": "A library for validating emails against several RFCs",
"homepage": "https://github.com/egulias/EmailValidator",
"type": "Library",
"keywords": ["email", "validation", "validator", "emailvalidation", "emailvalidator"],
"license": "MIT",
"authors": [
@@ -10,23 +9,18 @@
],
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
"dev-master": "2.1.x-dev"
}
},
"repositories": [
{
"type": "git",
"url": "https://github.com/dominicsayers/isemail"
}
],
"require": {
"php": ">= 5.5",
"doctrine/lexer": "^1.0.1"
"require": {
"php": ">=5.5",
"doctrine/lexer": "^1.0.1",
"symfony/polyfill-intl-idn": "^1.10"
},
"require-dev" : {
"require-dev": {
"satooshi/php-coveralls": "^1.0.1",
"phpunit/phpunit": "^4.8.35||^5.7||^6.0",
"dominicsayers/isemail": "dev-master"
"phpunit/phpunit": "^4.8.36|^7.5.15",
"dominicsayers/isemail": "^3.0.7"
},
"suggest": {
"ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
@@ -38,7 +32,7 @@
},
"autoload-dev": {
"psr-4": {
"Egulias\\Tests\\": "test"
"Egulias\\Tests\\": "Tests"
}
}
}
@@ -8,7 +8,6 @@
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="vendor/autoload.php"
>
<testsuites>
@@ -19,8 +18,8 @@
</testsuites>
<filter>
<blacklist>
<directory>./vendor</directory>
</blacklist>
<whitelist>
<directory>./EmailValidator/</directory>
</whitelist>
</filter>
</phpunit>
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="3.8.3@389af1bfc739bfdff3f9e3dc7bd6499aee51a831">
<file src="EmailValidator/EmailLexer.php">
<DocblockTypeContradiction occurrences="1">
<code>self::$nullToken</code>
</DocblockTypeContradiction>
</file>
<file src="EmailValidator/Parser/Parser.php">
<MissingReturnType occurrences="1">
<code>parse</code>
</MissingReturnType>
</file>
<file src="EmailValidator/Validation/SpoofCheckValidation.php">
<UndefinedClass occurrences="2">
<code>Spoofchecker</code>
<code>Spoofchecker</code>
</UndefinedClass>
</file>
</files>
@@ -0,0 +1,19 @@
<?xml version="1.0"?>
<psalm
requireVoidReturnType="false"
totallyTyped="false"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config ./vendor/vimeo/psalm/config.xsd"
errorBaseline="./psalm.baseline.xml"
>
<projectFiles>
<directory name="EmailValidator" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
<issueHandlers>
</issueHandlers>
</psalm>
@@ -1,6 +1,22 @@
Changelog
=========
6.2.2 (2019-11-12)
------------------
* no changes
6.2.2 (2019-11-12)
------------------
* fixed cmopat 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)
------------------
@@ -1,15 +0,0 @@
Swift Mailer
------------
Swift Mailer is a component based mailing solution for PHP 7.
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.
@@ -0,0 +1,19 @@
Swift Mailer
------------
Swift Mailer is a component based mailing solution for PHP 7.
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>
@@ -520,9 +520,8 @@ Setting ``To:`` Recipients
or ``addTo()`` methods of the message.
To set ``To:`` recipients, create the message object using either ``new
Swift_Message( ... )`` or ``new Swift_Message( ... )``, then call the
``setTo()`` method with a complete array of addresses, or use the ``addTo()``
method to iteratively add recipients.
Swift_Message( ... )``, then call the ``setTo()`` method with a complete array
of addresses, or use the ``addTo()`` method to iteratively add recipients.
The ``setTo()`` method accepts input in various formats as described earlier in
this chapter. The ``addTo()`` method takes either one or two parameters. The
@@ -558,9 +557,8 @@ Setting ``Cc:`` Recipients
message.
To set ``Cc:`` recipients, create the message object using either ``new
Swift_Message( ... )`` or ``new Swift_Message( ... )``, then call the
``setCc()`` method with a complete array of addresses, or use the ``addCc()``
method to iteratively add recipients.
Swift_Message( ... )``, then call the ``setCc()`` method with a complete array
of addresses, or use the ``addCc()`` method to iteratively add recipients.
The ``setCc()`` method accepts input in various formats as described earlier in
this chapter. The ``addCc()`` method takes either one or two parameters. The
@@ -596,9 +594,8 @@ Setting ``Bcc:`` Recipients
it, and are set with the ``setBcc()`` or ``addBcc()`` methods of the message.
To set ``Bcc:`` recipients, create the message object using either ``new
Swift_Message( ... )`` or ``new Swift_Message( ... )``, then call the
``setBcc()`` method with a complete array of addresses, or use the ``addBcc()``
method to iteratively add recipients.
Swift_Message( ... )``, then call the ``setBcc()`` method with a complete array
of addresses, or use the ``addBcc()`` method to iteratively add recipients.
The ``setBcc()`` method accepts input in various formats as described earlier
in this chapter. The ``addBcc()`` method takes either one or two parameters.
@@ -15,7 +15,7 @@
*/
abstract class Swift
{
const VERSION = '6.2.0';
const VERSION = '6.2.3';
public static $initialized = false;
public static $inits = [];
@@ -8,8 +8,6 @@
* file that was distributed with this source code.
*/
@trigger_error(sprintf('The "%s" class is deprecated since Swiftmailer 6.2; use "%s" instead.', Swift_CharacterStream_ArrayCharacterStream::class, Swift_CharacterStream_CharacterStream::class), E_USER_DEPRECATED);
/**
* A CharacterStream implementation which stores characters in an internal array.
*
@@ -1,227 +0,0 @@
<?php
/*
* This file is part of SwiftMailer.
* (c) 2004-2009 Chris Corbyn
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* A CharacterStream implementation which stores characters in an internal array.
*
* @author Xavier De Cock <xdecock@gmail.com>
*/
class Swift_CharacterStream_CharacterStream implements Swift_CharacterStream
{
/**
* The char reader (lazy-loaded) for the current charset.
*
* @var Swift_CharacterReader
*/
private $charReader;
/**
* A factory for creating CharacterReader instances.
*
* @var Swift_CharacterReaderFactory
*/
private $charReaderFactory;
/**
* The character set this stream is using.
*
* @var string
*/
private $charset;
/**
* The data's stored as-is.
*
* @var string
*/
private $datas = '';
/**
* Number of bytes in the stream.
*
* @var int
*/
private $datasSize = 0;
/**
* Map.
*
* @var mixed
*/
private $map;
/**
* Map Type.
*
* @var int
*/
private $mapType = 0;
/**
* Number of characters in the stream.
*
* @var int
*/
private $charCount = 0;
/**
* Position in the stream.
*
* @var int
*/
private $currentPos = 0;
/**
* Constructor.
*
* @param string $charset
*/
public function __construct(Swift_CharacterReaderFactory $factory, $charset)
{
$this->setCharacterReaderFactory($factory);
$this->setCharacterSet($charset);
}
/* -- Changing parameters of the stream -- */
/**
* Set the character set used in this CharacterStream.
*
* @param string $charset
*/
public function setCharacterSet($charset)
{
$this->charset = $charset;
$this->charReader = null;
$this->mapType = 0;
}
/**
* Set the CharacterReaderFactory for multi charset support.
*/
public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory)
{
$this->charReaderFactory = $factory;
}
public function flushContents()
{
$this->datas = null;
$this->map = null;
$this->charCount = 0;
$this->currentPos = 0;
$this->datasSize = 0;
}
public function importByteStream(Swift_OutputByteStream $os)
{
$this->flushContents();
$blocks = 512;
$os->setReadPointer(0);
while (false !== ($read = $os->read($blocks))) {
$this->write($read);
}
}
public function importString($string)
{
$this->flushContents();
$this->write($string);
}
public function read($length)
{
if ($this->currentPos >= $this->charCount) {
return false;
}
$ret = false;
$length = ($this->currentPos + $length > $this->charCount) ? $this->charCount - $this->currentPos : $length;
switch ($this->mapType) {
case Swift_CharacterReader::MAP_TYPE_FIXED_LEN:
$len = $length * $this->map;
$ret = substr($this->datas,
$this->currentPos * $this->map,
$len);
$this->currentPos += $length;
break;
case Swift_CharacterReader::MAP_TYPE_INVALID:
$ret = '';
for (; $this->currentPos < $length; ++$this->currentPos) {
if (isset($this->map[$this->currentPos])) {
$ret .= '?';
} else {
$ret .= $this->datas[$this->currentPos];
}
}
break;
case Swift_CharacterReader::MAP_TYPE_POSITIONS:
$end = $this->currentPos + $length;
$end = $end > $this->charCount ? $this->charCount : $end;
$ret = '';
$start = 0;
if ($this->currentPos > 0) {
$start = $this->map['p'][$this->currentPos - 1];
}
$to = $start;
for (; $this->currentPos < $end; ++$this->currentPos) {
if (isset($this->map['i'][$this->currentPos])) {
$ret .= substr($this->datas, $start, $to - $start).'?';
$start = $this->map['p'][$this->currentPos];
} else {
$to = $this->map['p'][$this->currentPos];
}
}
$ret .= substr($this->datas, $start, $to - $start);
break;
}
return $ret;
}
public function readBytes($length)
{
$read = $this->read($length);
if (false !== $read) {
$ret = array_map('ord', str_split($read, 1));
return $ret;
}
return false;
}
public function setPointer($charOffset)
{
if ($this->charCount < $charOffset) {
$charOffset = $this->charCount;
}
$this->currentPos = $charOffset;
}
public function write($chars)
{
if (!isset($this->charReader)) {
$this->charReader = $this->charReaderFactory->getReaderFor(
$this->charset);
$this->map = [];
$this->mapType = $this->charReader->getMapType();
}
$ignored = '';
$this->datas .= $chars;
$this->charCount += $this->charReader->getCharPositions(substr($this->datas, $this->datasSize), $this->datasSize, $this->map, $ignored);
if (false !== $ignored) {
$this->datasSize = strlen($this->datas) - strlen($ignored);
} else {
$this->datasSize = strlen($this->datas);
}
}
}
@@ -8,13 +8,255 @@
* file that was distributed with this source code.
*/
@trigger_error(sprintf('The "%s" class is deprecated since Swiftmailer 6.2; use "%s" instead.', Swift_CharacterStream_NgCharacterStream::class, Swift_CharacterStream_CharacterStream::class), E_USER_DEPRECATED);
/**
* A CharacterStream implementation which stores characters in an internal array.
*
* @author Xavier De Cock <xdecock@gmail.com>
*/
class Swift_CharacterStream_NgCharacterStream extends Swift_CharacterStream_CharacterStream
class Swift_CharacterStream_NgCharacterStream implements Swift_CharacterStream
{
/**
* The char reader (lazy-loaded) for the current charset.
*
* @var Swift_CharacterReader
*/
private $charReader;
/**
* A factory for creating CharacterReader instances.
*
* @var Swift_CharacterReaderFactory
*/
private $charReaderFactory;
/**
* The character set this stream is using.
*
* @var string
*/
private $charset;
/**
* The data's stored as-is.
*
* @var string
*/
private $datas = '';
/**
* Number of bytes in the stream.
*
* @var int
*/
private $datasSize = 0;
/**
* Map.
*
* @var mixed
*/
private $map;
/**
* Map Type.
*
* @var int
*/
private $mapType = 0;
/**
* Number of characters in the stream.
*
* @var int
*/
private $charCount = 0;
/**
* Position in the stream.
*
* @var int
*/
private $currentPos = 0;
/**
* Constructor.
*
* @param string $charset
*/
public function __construct(Swift_CharacterReaderFactory $factory, $charset)
{
$this->setCharacterReaderFactory($factory);
$this->setCharacterSet($charset);
}
/* -- Changing parameters of the stream -- */
/**
* Set the character set used in this CharacterStream.
*
* @param string $charset
*/
public function setCharacterSet($charset)
{
$this->charset = $charset;
$this->charReader = null;
$this->mapType = 0;
}
/**
* Set the CharacterReaderFactory for multi charset support.
*/
public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory)
{
$this->charReaderFactory = $factory;
}
/**
* @see Swift_CharacterStream::flushContents()
*/
public function flushContents()
{
$this->datas = null;
$this->map = null;
$this->charCount = 0;
$this->currentPos = 0;
$this->datasSize = 0;
}
/**
* @see Swift_CharacterStream::importByteStream()
*/
public function importByteStream(Swift_OutputByteStream $os)
{
$this->flushContents();
$blocks = 512;
$os->setReadPointer(0);
while (false !== ($read = $os->read($blocks))) {
$this->write($read);
}
}
/**
* @see Swift_CharacterStream::importString()
*
* @param string $string
*/
public function importString($string)
{
$this->flushContents();
$this->write($string);
}
/**
* @see Swift_CharacterStream::read()
*
* @param int $length
*
* @return string
*/
public function read($length)
{
if ($this->currentPos >= $this->charCount) {
return false;
}
$ret = false;
$length = ($this->currentPos + $length > $this->charCount) ? $this->charCount - $this->currentPos : $length;
switch ($this->mapType) {
case Swift_CharacterReader::MAP_TYPE_FIXED_LEN:
$len = $length * $this->map;
$ret = substr($this->datas,
$this->currentPos * $this->map,
$len);
$this->currentPos += $length;
break;
case Swift_CharacterReader::MAP_TYPE_INVALID:
$ret = '';
for (; $this->currentPos < $length; ++$this->currentPos) {
if (isset($this->map[$this->currentPos])) {
$ret .= '?';
} else {
$ret .= $this->datas[$this->currentPos];
}
}
break;
case Swift_CharacterReader::MAP_TYPE_POSITIONS:
$end = $this->currentPos + $length;
$end = $end > $this->charCount ? $this->charCount : $end;
$ret = '';
$start = 0;
if ($this->currentPos > 0) {
$start = $this->map['p'][$this->currentPos - 1];
}
$to = $start;
for (; $this->currentPos < $end; ++$this->currentPos) {
if (isset($this->map['i'][$this->currentPos])) {
$ret .= substr($this->datas, $start, $to - $start).'?';
$start = $this->map['p'][$this->currentPos];
} else {
$to = $this->map['p'][$this->currentPos];
}
}
$ret .= substr($this->datas, $start, $to - $start);
break;
}
return $ret;
}
/**
* @see Swift_CharacterStream::readBytes()
*
* @param int $length
*
* @return int[]
*/
public function readBytes($length)
{
$read = $this->read($length);
if (false !== $read) {
$ret = array_map('ord', str_split($read, 1));
return $ret;
}
return false;
}
/**
* @see Swift_CharacterStream::setPointer()
*
* @param int $charOffset
*/
public function setPointer($charOffset)
{
if ($this->charCount < $charOffset) {
$charOffset = $this->charCount;
}
$this->currentPos = $charOffset;
}
/**
* @see Swift_CharacterStream::write()
*
* @param string $chars
*/
public function write($chars)
{
if (!isset($this->charReader)) {
$this->charReader = $this->charReaderFactory->getReaderFor(
$this->charset);
$this->map = [];
$this->mapType = $this->charReader->getMapType();
}
$ignored = '';
$this->datas .= $chars;
$this->charCount += $this->charReader->getCharPositions(substr($this->datas, $this->datasSize), $this->datasSize, $this->map, $ignored);
if (false !== $ignored) {
$this->datasSize = strlen($this->datas) - strlen($ignored);
} else {
$this->datasSize = strlen($this->datas);
}
}
}
@@ -264,13 +264,16 @@ class Swift_Transport_StreamBuffer extends Swift_ByteStream_AbstractFilterableIn
$options = array_merge($options, $this->params['stream_context_options']);
}
$streamContext = stream_context_create($options);
$this->stream = @stream_socket_client($host.':'.$this->params['port'], $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $streamContext);
if (false === $this->stream) {
throw new Swift_TransportException(
'Connection could not be established with host '.$this->params['host'].
' ['.$errstr.' #'.$errno.']'
);
set_error_handler(function ($type, $msg) {
throw new Swift_TransportException('Connection could not be established with host '.$this->params['host'].' :'.$msg);
});
try {
$this->stream = stream_socket_client($host.':'.$this->params['port'], $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $streamContext);
} finally {
restore_error_handler();
}
if (!empty($this->params['blocking'])) {
stream_set_blocking($this->stream, 1);
} else {
@@ -84,7 +84,7 @@ Swift_DependencyContainer::getInstance()
->withDependencies(['mime.charstream'])
->register('mime.charstream')
->asNewInstanceOf('Swift_CharacterStream_CharacterStream')
->asNewInstanceOf('Swift_CharacterStream_NgCharacterStream')
->withDependencies(['mime.characterreaderfactory', 'properties.charset'])
->register('mime.bytecanonicalizer')
@@ -173,7 +173,7 @@ function generateUpToDateMimeArray()
ksort($valid_mime_types);
// combine mime types and extensions array
$output = "$preamble\$swift_mime_types = array(\n ".implode($valid_mime_types, ",\n ")."\n);";
$output = "$preamble\$swift_mime_types = array(\n ".implode(",\n ", $valid_mime_types)."\n);";
// write mime_types.php config file
@file_put_contents('./mime_types.php', $output);
@@ -20,7 +20,7 @@ class Swift_Encoder_QpEncoderAcceptanceTest extends \PHPUnit\Framework\TestCase
}
$encoding = $encodingDir;
$charStream = new Swift_CharacterStream_CharacterStream(
$charStream = new Swift_CharacterStream_ArrayCharacterStream(
$this->factory, $encoding);
$encoder = new Swift_Encoder_QpEncoder($charStream);
@@ -20,7 +20,7 @@ class Swift_Encoder_Rfc2231EncoderAcceptanceTest extends \PHPUnit\Framework\Test
}
$encoding = $encodingDir;
$charStream = new Swift_CharacterStream_CharacterStream(
$charStream = new Swift_CharacterStream_ArrayCharacterStream(
$this->factory, $encoding);
$encoder = new Swift_Encoder_Rfc2231Encoder($charStream);
@@ -18,10 +18,10 @@ class Swift_Mime_AttachmentAcceptanceTest extends \PHPUnit\Framework\TestCase
$this->contentEncoder = new Swift_Mime_ContentEncoder_Base64ContentEncoder();
$headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8')
new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
);
$paramEncoder = new Swift_Encoder_Rfc2231Encoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8')
new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
);
$this->emailValidator = new EmailValidator();
$this->idGenerator = new Swift_Mime_IdGenerator('example.com');
@@ -25,7 +25,7 @@ class Swift_Mime_ContentEncoder_QpContentEncoderAcceptanceTest extends \PHPUnit\
}
$encoding = $encodingDir;
$charStream = new Swift_CharacterStream_CharacterStream(
$charStream = new Swift_CharacterStream_NgCharacterStream(
$this->factory, $encoding);
$encoder = new Swift_Mime_ContentEncoder_QpContentEncoder($charStream);
@@ -18,10 +18,10 @@ class Swift_Mime_EmbeddedFileAcceptanceTest extends \PHPUnit\Framework\TestCase
$this->contentEncoder = new Swift_Mime_ContentEncoder_Base64ContentEncoder();
$headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8')
new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
);
$paramEncoder = new Swift_Encoder_Rfc2231Encoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8')
new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
);
$this->emailValidator = new EmailValidator();
$this->idGenerator = new Swift_Mime_IdGenerator('example.com');
@@ -16,7 +16,7 @@ class Swift_Mime_MimePartAcceptanceTest extends \PHPUnit\Framework\TestCase
);
$factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory();
$this->contentEncoder = new Swift_Mime_ContentEncoder_QpContentEncoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8'),
new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8'),
new Swift_StreamFilters_ByteArrayReplacementFilter(
[[0x0D, 0x0A], [0x0D], [0x0A]],
[[0x0A], [0x0A], [0x0D, 0x0A]]
@@ -24,10 +24,10 @@ class Swift_Mime_MimePartAcceptanceTest extends \PHPUnit\Framework\TestCase
);
$headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8')
new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
);
$paramEncoder = new Swift_Encoder_Rfc2231Encoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8')
new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
);
$this->emailValidator = new EmailValidator();
$this->idGenerator = new Swift_Mime_IdGenerator('example.com');
@@ -10,10 +10,10 @@ class Swift_Bug206Test extends \PHPUnit\Framework\TestCase
{
$factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory();
$headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8')
new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
);
$paramEncoder = new Swift_Encoder_Rfc2231Encoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8')
new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
);
$emailValidator = new EmailValidator();
$this->factory = new Swift_Mime_SimpleHeaderFactory($headerEncoder, $paramEncoder, $emailValidator);
@@ -13,7 +13,7 @@ class Swift_Bug650Test extends \PHPUnit\Framework\TestCase
public function testMailboxHeaderEncoding($name, $expectedEncodedName)
{
$factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory();
$charStream = new Swift_CharacterStream_CharacterStream($factory, 'utf-8');
$charStream = new Swift_CharacterStream_NgCharacterStream($factory, 'utf-8');
$encoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder($charStream);
$header = new Swift_Mime_Headers_MailboxHeader('To', $encoder, new EmailValidator());
$header->setCharset('utf-8');
@@ -1,8 +1,5 @@
<?php
/**
* @group legacy
*/
class Swift_CharacterStream_ArrayCharacterStreamTest extends \SwiftMailerTestCase
{
public function testValidatorAlgorithmOnImportString()
@@ -393,7 +393,7 @@ class Swift_Encoder_QpEncoderTest extends \SwiftMailerTestCase
private function createEncoder()
{
$factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory();
$charStream = new Swift_CharacterStream_CharacterStream($factory, 'utf-8');
$charStream = new Swift_CharacterStream_NgCharacterStream($factory, 'utf-8');
return new Swift_Encoder_QpEncoder($charStream);
}

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