From 2aac4c06382360f2eb5c22425962b8c606735773 Mon Sep 17 00:00:00 2001 From: exu Date: Tue, 11 Jul 2023 17:19:18 +0200 Subject: [PATCH] (Grav GitSync) Automatic Commit from exu --- plugins/email/CHANGELOG.md | 22 + plugins/email/blueprints.yaml | 2 +- plugins/email/classes/Email.php | 48 +- plugins/email/classes/Message.php | 6 + plugins/email/email.php | 5 +- plugins/email/languages.yaml | 5 +- plugins/form/CHANGELOG.md | 8 + plugins/form/blueprints.yaml | 13 +- plugins/form/form.php | 95 ++-- plugins/form/form.yaml | 1 + plugins/login/CHANGELOG.md | 8 +- plugins/login/blueprints.yaml | 2 +- plugins/login/classes/Controller.php | 71 +-- plugins/markdown-notices/CHANGELOG.md | 38 ++ plugins/markdown-notices/LICENSE | 21 + plugins/markdown-notices/README.md | 62 +++ plugins/markdown-notices/assets/notices.css | 32 ++ .../markdown-notices/assets/screenshot.png | Bin 0 -> 86632 bytes plugins/markdown-notices/blueprints.yaml | 59 +++ plugins/markdown-notices/composer.json | 27 ++ plugins/markdown-notices/composer.lock | 22 + plugins/markdown-notices/languages.yaml | 29 ++ plugins/markdown-notices/markdown-notices.php | 92 ++++ .../markdown-notices/markdown-notices.yaml | 4 + plugins/markdown-notices/vendor/autoload.php | 7 + .../vendor/composer/ClassLoader.php | 445 ++++++++++++++++++ .../markdown-notices/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 10 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 9 + .../vendor/composer/autoload_real.php | 52 ++ .../vendor/composer/autoload_static.php | 20 + .../vendor/composer/installed.json | 1 + 33 files changed, 1158 insertions(+), 88 deletions(-) create mode 100644 plugins/markdown-notices/CHANGELOG.md create mode 100644 plugins/markdown-notices/LICENSE create mode 100644 plugins/markdown-notices/README.md create mode 100644 plugins/markdown-notices/assets/notices.css create mode 100644 plugins/markdown-notices/assets/screenshot.png create mode 100644 plugins/markdown-notices/blueprints.yaml create mode 100644 plugins/markdown-notices/composer.json create mode 100644 plugins/markdown-notices/composer.lock create mode 100644 plugins/markdown-notices/languages.yaml create mode 100644 plugins/markdown-notices/markdown-notices.php create mode 100644 plugins/markdown-notices/markdown-notices.yaml create mode 100644 plugins/markdown-notices/vendor/autoload.php create mode 100644 plugins/markdown-notices/vendor/composer/ClassLoader.php create mode 100644 plugins/markdown-notices/vendor/composer/LICENSE create mode 100644 plugins/markdown-notices/vendor/composer/autoload_classmap.php create mode 100644 plugins/markdown-notices/vendor/composer/autoload_namespaces.php create mode 100644 plugins/markdown-notices/vendor/composer/autoload_psr4.php create mode 100644 plugins/markdown-notices/vendor/composer/autoload_real.php create mode 100644 plugins/markdown-notices/vendor/composer/autoload_static.php create mode 100644 plugins/markdown-notices/vendor/composer/installed.json diff --git a/plugins/email/CHANGELOG.md b/plugins/email/CHANGELOG.md index f892ce1..78971ef 100644 --- a/plugins/email/CHANGELOG.md +++ b/plugins/email/CHANGELOG.md @@ -1,3 +1,25 @@ +# v4.0.4 +## 07/10/2023 + +1. [](#bugfix) + * Fix for email file attachments using stream + +# v4.0.3 +## 06/29/2023 + +1. [](#improved) + * Simplified the `Email::processRecipients()` logic for readability +1. [](#bugfix) + * Fix an issue with 2 email addresses provided with 'just' email and no name [#176](https://github.com/getgrav/grav-plugin-email/issues/176) + * Fix for blank subjectlines when using `Message::setSubject()` in Twig templates [getgrav/grav-plugin-login#299](https://github.com/getgrav/grav-plugin-login/issues/299) + +# v4.0.2 +## 06/27/2023 + +1. [](#bugfix) + * some recipient handling improvements. e.g. missing `bcc_name` throwing error + * Allow overriding of defaults with a form configuration. Use `null` to remove default email configuration + # v4.0.1 ## 05/20/2023 diff --git a/plugins/email/blueprints.yaml b/plugins/email/blueprints.yaml index 68c89de..d3a66a0 100644 --- a/plugins/email/blueprints.yaml +++ b/plugins/email/blueprints.yaml @@ -1,7 +1,7 @@ name: Email slug: email type: plugin -version: 4.0.1 +version: 4.0.4 testing: false description: Enables the emailing system for Grav icon: envelope diff --git a/plugins/email/classes/Email.php b/plugins/email/classes/Email.php index 617bbee..1bc7b1d 100644 --- a/plugins/email/classes/Email.php +++ b/plugins/email/classes/Email.php @@ -138,8 +138,9 @@ class Email $email = $message->getEmail(); // Extend parameters with defaults. - $params += [ + $defaults = [ 'bcc' => $config->get('plugins.email.bcc', []), + 'bcc_name' => $config->get('plugins.email.bcc_name'), 'body' => $config->get('plugins.email.body', '{% include "forms/data.html.twig" %}'), 'cc' => $config->get('plugins.email.cc', []), 'cc_name' => $config->get('plugins.email.cc_name'), @@ -157,6 +158,12 @@ class Email 'message' => $message ]; + foreach ($defaults as $key => $value) { + if (!key_exists($key, $params)) { + $params[$key] = $value; + } + } + if (!$params['to']) { throw new \RuntimeException($language->translate('PLUGIN_EMAIL.PLEASE_CONFIGURE_A_TO_ADDRESS')); } @@ -237,38 +244,39 @@ class Email */ protected function processRecipients(string $type, array $params): array { + if (array_key_exists($type, $params) && $params[$type] === null) { + return []; + } + $recipients = $params[$type] ?? Grav::instance()['config']->get('plugins.email.'.$type) ?? []; $list = []; if (!empty($recipients)) { - if (is_array($recipients) && Utils::isAssoc($recipients)) { - $list[] = $this->createAddress($recipients); + if (is_array($recipients)) { + if (Utils::isAssoc($recipients) || (count($recipients) ===2 && $this->isValidEmail($recipients[0]) && !$this->isValidEmail($recipients[1]))) { + $list[] = $this->createAddress($recipients); + } else { + foreach ($recipients as $recipient) { + $list[] = $this->createAddress($recipient); + } + } } else { - if (is_array($recipients)) { - if (count($recipients) ===2 && $this->isValidEmail($recipients[0]) && is_string($recipients[1])) { - $list[] = $this->createAddress($recipients); - } else { - foreach ($recipients as $recipient) { - $list[] = $this->createAddress($recipient); - } + if (is_string($recipients) && Utils::contains($recipients, ',')) { + $recipients = array_map('trim', explode(',', $recipients)); + foreach ($recipients as $recipient) { + $list[] = $this->createAddress($recipient); } } else { - if (is_string($recipients) && Utils::contains($recipients, ',')) { - $recipients = array_map('trim', explode(',', $recipients)); - foreach ($recipients as $recipient) { - $list[] = $this->createAddress($recipient); - } - } else { - if (!Utils::contains($recipients, ['<','>']) && ($params[$type."_name"])) { - $recipients = [$recipients, $params[$type."_name"]]; - } - $list[] = $this->createAddress($recipients); + if (!Utils::contains($recipients, ['<','>']) && (isset($params[$type."_name"]))) { + $recipients = [$recipients, $params[$type."_name"]]; } + $list[] = $this->createAddress($recipients); } } } + return $list; } diff --git a/plugins/email/classes/Message.php b/plugins/email/classes/Message.php index fb691f8..066a209 100644 --- a/plugins/email/classes/Message.php +++ b/plugins/email/classes/Message.php @@ -18,6 +18,12 @@ class Message return $this; } + public function setSubject($subject): self + { + $this->subject($subject); + return $this; + } + public function to($to): self { $this->email->to($to); diff --git a/plugins/email/email.php b/plugins/email/email.php index b96ff36..da59047 100644 --- a/plugins/email/email.php +++ b/plugins/email/email.php @@ -125,6 +125,7 @@ class EmailPlugin extends Plugin { // Build message $message = $this->email->buildMessage($params, $vars); + $locator = $this->grav['locator']; if (isset($params['attachments'])) { $filesToAttach = (array)$params['attachments']; @@ -135,9 +136,11 @@ class EmailPlugin extends Plugin if (isset($fileValues['file'])) { $filename = $fileValues['file']; } else { - $filename = ROOT_DIR . $fileValues['path']; + $filename = $fileValues['path']; } + $filename = $locator->findResource($filename, true, true); + try { $message->attachFromPath($filename); } catch (\Exception $e) { diff --git a/plugins/email/languages.yaml b/plugins/email/languages.yaml index 4cb044c..9f1fc7f 100644 --- a/plugins/email/languages.yaml +++ b/plugins/email/languages.yaml @@ -78,6 +78,7 @@ fr: PLUGIN_EMAIL: MAIL_ENGINE: "Moteur de messagerie" MAIL_ENGINE_DISABLED: "Désactivé" + MAIL_ENGINE_DESC: "NOTE : Si vous sélectionnez un moteur fourni par un autre plugin, vous devez configurer les options dans ce même plugin." CONTENT_TYPE: "Type de contenu" CONTENT_TYPE_PLAIN_TEXT: "Texte brut" CHARSET: "Jeu de caractères" @@ -130,7 +131,9 @@ fr: QUEUE_FLUSH_MSG_LIMIT: "Messages par Flush" QUEUE_FLUSH_MSG_LIMIT_APPEND: "Messages" QUEUE_FLUSH_TIME_LIMIT: "Délai de Flush" - QUEUE_FLUSH_TIME_LIMIT_APPEND: "Seconds" + QUEUE_FLUSH_TIME_LIMIT_APPEND: "Secondes" + EMAIL_FORMAT: "Utilisez le format `addr` : `email@adresse.org` ou le format `name-addr` : `Votre nom `. Séparer par des virgules pour plusieurs adresses." + hr: PLUGIN_EMAIL: diff --git a/plugins/form/CHANGELOG.md b/plugins/form/CHANGELOG.md index 87e9dbf..7c88629 100644 --- a/plugins/form/CHANGELOG.md +++ b/plugins/form/CHANGELOG.md @@ -1,3 +1,11 @@ +# v7.2.1 +## 06/27/2023 + +1. [](#improved) + * Added some optional debug output to help isolate form loading problems +1. [](#bugfix) + * More robust fix for multi-language form caching + # v7.2.0 ## 06/21/2023 diff --git a/plugins/form/blueprints.yaml b/plugins/form/blueprints.yaml index 094eaa4..4a7ec33 100644 --- a/plugins/form/blueprints.yaml +++ b/plugins/form/blueprints.yaml @@ -1,7 +1,7 @@ name: Form slug: form type: plugin -version: 7.2.0 +version: 7.2.1 description: Enables forms handling and processing icon: check-square author: @@ -34,6 +34,17 @@ form: title: PLUGIN_FORM.GENERAL fields: + debug: + type: toggle + label: Debug + highlight: 1 + default: 0 + options: + 1: PLUGIN_ADMIN.ENABLED + 0: PLUGIN_ADMIN.DISABLED + validate: + type: bool + built_in_css: type: toggle label: PLUGIN_FORM.USE_BUILT_IN_CSS diff --git a/plugins/form/form.php b/plugins/form/form.php index 9ed14b1..02eae7a 100644 --- a/plugins/form/form.php +++ b/plugins/form/form.php @@ -26,6 +26,7 @@ use Grav\Plugin\Form\Form; use Grav\Plugin\Form\Forms; use Grav\Plugin\Form\TwigExtension; use Grav\Common\HTTP\Client; +use Monolog\Logger; use ReCaptcha\ReCaptcha; use ReCaptcha\RequestMethod\CurlPost; use RecursiveArrayIterator; @@ -66,6 +67,7 @@ class FormPlugin extends Plugin /** @var array */ protected $json_response = []; + /** * @return bool */ @@ -147,6 +149,8 @@ class FormPlugin extends Plugin 'onTwigSiteVariables' => ['onTwigVariables', 0], 'onFormValidationProcessed' => ['onFormValidationProcessed', 0], ]); + + } /** @@ -224,9 +228,8 @@ class FormPlugin extends Plugin /** @var PageInterface $page */ $page = $this->grav['page']; - // Force rebuild form when form has not been built and form cache expired. - // This happens when form cache expires before the page cache - // and then does not trigger 'onPageProcessed' event. + + // DEPRECATED: This should no longer ever happen if (!$this->forms) { $this->onPageProcessed(new Event(['page' => $page])); } @@ -311,9 +314,11 @@ class FormPlugin extends Plugin /** @var Forms $forms */ $forms = $this->grav['forms']; + $lang = $this->grav['language']->getLanguage(); + /** @var Route $route */ $route = $this->grav['route']; - $pageForms = $this->forms[$route->getRoute()] ?? []; + $pageForms = $this->forms[$lang][$route->getRoute()] ?? []; /** * @var string $name @@ -828,10 +833,11 @@ class FormPlugin extends Plugin public function addFormDefinition(PageInterface $page, string $name, array $form): void { $route = ($page->home() ? '/' : $page->route()) ?? '/'; + $lang = $this->grav['language']->getLanguage(); - if (!isset($this->forms[$route][$name])) { + if (!isset($this->forms[$lang][$route][$name])) { $form['_page_routable'] = !$page->isModule(); - $this->forms[$route][$name] = $form; + $this->forms[$lang][$route][$name] = $form; $this->saveCachedForms(); } } @@ -849,12 +855,13 @@ class FormPlugin extends Plugin return; } + $lang = $this->grav['language']->getLanguage(); $name = $form->getName(); - if (!isset($this->forms[$route][$name])) { + if (!isset($this->forms[$lang][$route][$name])) { $form['_page_routable'] = true; - $this->forms[$route][$name] = $form; + $this->forms[$lang][$route][$name] = $form; $this->saveCachedForms(); } } @@ -869,6 +876,7 @@ class FormPlugin extends Plugin { /** @var Pages $pages */ $pages = $this->grav['pages']; + $lang = $this->grav['language']->getLanguage(); // Handle parameters. if (is_array($data)) { @@ -914,7 +922,7 @@ class FormPlugin extends Plugin // Attempt to find the form from the page. if ('' !== $route) { - $forms = $this->forms[$route] ?? []; + $forms = $this->forms[$lang][$route] ?? []; if (!$unnamed) { // Get form by the name. @@ -930,9 +938,7 @@ class FormPlugin extends Plugin if (null === $form) { // First check if we requested a specific form which didn't exist. if ($route_provided || $unnamed) { - /** @var Debugger $debugger */ - $debugger = $this->grav['debugger']; - $debugger->addMessage(sprintf('Form %s not found in page %s', $name ?? 'unnamed', $route), 'warning'); + $this->grav['debugger']->addMessage(sprintf('Form %s not found in page %s', $name ?? 'unnamed', $route), 'warning'); return null; } @@ -946,8 +952,7 @@ class FormPlugin extends Plugin // Check for naming conflicts. if (count($forms) > 1) { - $debugger = $this->grav['debugger']; - $debugger->addMessage(sprintf('Fetching form by its name, but there are multiple pages with the same form name %s', $name), 'warning'); + $this->grav['debugger']->addMessage(sprintf('Fetching form by its name, but there are multiple pages with the same form name %s', $name), 'warning'); } [$route, $name, $form] = $first; @@ -959,9 +964,7 @@ class FormPlugin extends Plugin if (is_array($form)) { // Form was cached as an array, try to create the object. if (null === $page) { - /** @var Debugger $debugger */ - $debugger = $this->grav['debugger']; - $debugger->addMessage(sprintf('Form %s cannot be created as page %s does not exist', $name, $route), 'warning'); + $this->grav['debugger']->addMessage(sprintf('Form %s cannot be created as page %s does not exist', $name, $route), 'warning'); return null; } @@ -1096,7 +1099,10 @@ class FormPlugin extends Plugin protected function findFormByName(string $name): array { $list = []; - foreach ($this->forms as $route => $forms) { + $lang = $this->grav['language']->getLanguage(); + $lang_forms = $this->forms[$lang] ?? []; + + foreach ($lang_forms as $route => $forms) { foreach ($forms as $key => $form) { if ($name === $key && !empty($form['_page_routable'])) { $list[] = [$route, $key, $form]; @@ -1233,12 +1239,9 @@ class FormPlugin extends Plugin /** @var Cache $cache */ $cache = $this->grav['cache']; - [$forms] = $cache->fetch($this->getFormCacheId()); + $forms = $cache->fetch($this->getFormCacheId()); } catch (Exception $e) { - /** @var Debugger $debugger */ - $debugger = Grav::instance()['debugger']; - $debugger->addMessage(sprintf('Unserializing cached forms failed: %s', $e->getMessage()), 'error'); - + $this->grav['debugger']->addMessage(sprintf('Unserializing cached forms failed: %s', $e->getMessage()), 'error'); $forms = null; } @@ -1248,7 +1251,11 @@ class FormPlugin extends Plugin // Only update the forms if it's not empty if ($forms) { - $this->forms = array_merge($this->forms, $forms); + $this->forms = Utils::arrayMergeRecursiveUnique($this->forms, $forms); + if ($this->config()['debug']) { + $this->grav['log']->addDebug(sprintf("<<<< Loaded cached forms: %s\n%s", $this->getFormCacheId(), $this->arrayToString($this->forms))); + } + } } @@ -1261,8 +1268,17 @@ class FormPlugin extends Plugin { /** @var Cache $cache */ $cache = $this->grav['cache']; + $cache_id = $this->getFormCacheId(); - $cache->save($this->getFormCacheId(), [$this->forms]); + $forms = $cache->fetch($cache_id); + if ($forms) { + $this->forms = Utils::arrayMergeRecursiveUnique($this->forms, $forms); + } + + $cache->save($cache_id, $this->forms); + if ($this->config()['debug']) { + $this->grav['log']->addDebug(sprintf(">>>> Saved cached forms: %s\n%s", $this->getFormCacheId(), $this->arrayToString($this->forms))); + } } /** @@ -1272,10 +1288,10 @@ class FormPlugin extends Plugin */ protected function getFormCacheId(): string { - /** @var Pages $pages */ - $pages = $this->grav['pages']; - - return $pages->getPagesCacheId() . '-form-plugin'; + /** @var \Grav\Common\Cache $cache */ + $cache = $this->grav['cache']; + $cache_id = $cache->getKey() . '-form-plugin'; + return $cache_id; } /** @@ -1308,4 +1324,25 @@ class FormPlugin extends Plugin exit; } } + + protected function arrayToString($array, $level = 2) { + $result = $this->limitArrayLevels($array, $level); + return json_encode($result, JSON_UNESCAPED_SLASHES); + } + + protected function limitArrayLevels($array, $levelsToKeep, $currentLevel = 0) { + if ($currentLevel >= $levelsToKeep) { + return '-'; + } + + $result = []; + foreach ($array as $key => $value) { + if (is_array($value)) { + $value = $this->limitArrayLevels($value, $levelsToKeep, $currentLevel + 1); + } + $result[$key] = $value; + } + + return $result; + } } diff --git a/plugins/form/form.yaml b/plugins/form/form.yaml index 29793ca..27124a0 100644 --- a/plugins/form/form.yaml +++ b/plugins/form/form.yaml @@ -3,6 +3,7 @@ built_in_css: true inline_css: true refresh_prevention: false client_side_validation: true +debug: false inline_errors: false files: multiple: false # To allow multiple files, default is single diff --git a/plugins/login/CHANGELOG.md b/plugins/login/CHANGELOG.md index bd230d5..a360aac 100644 --- a/plugins/login/CHANGELOG.md +++ b/plugins/login/CHANGELOG.md @@ -1,9 +1,15 @@ +# v3.7.6 +## 06/29/2023 + +1. [](#bugfix) + * Don't save an empty user file on password reset of non-existing user + # v3.7.5 ## 06/14/2023 1. [](#bugfix) * Sanitized `email` during the "forgot password" process to protect against XSS attacks - * Fixed an account enumeration vulneratiblity in forgot password [#293](https://github.com/getgrav/grav-plugin-login/pull/293) + * Fixed an account enumeration vulnerability in forgot password [#293](https://github.com/getgrav/grav-plugin-login/pull/293) # v3.7.4 ## 05/09/2023 diff --git a/plugins/login/blueprints.yaml b/plugins/login/blueprints.yaml index bd7b61b..ce93d34 100644 --- a/plugins/login/blueprints.yaml +++ b/plugins/login/blueprints.yaml @@ -1,7 +1,7 @@ name: Login slug: login type: plugin -version: 3.7.5 +version: 3.7.6 testing: false description: Enables user authentication and login screen. icon: sign-in diff --git a/plugins/login/classes/Controller.php b/plugins/login/classes/Controller.php index 9421cdd..ed006d7 100644 --- a/plugins/login/classes/Controller.php +++ b/plugins/login/classes/Controller.php @@ -347,61 +347,66 @@ class Controller $config = $this->grav['config']; $data = $this->post; + /** @var Language $language */ + $language = $this->grav['language']; + $messages = $this->grav['messages']; + /** @var UserCollectionInterface $users */ $users = $this->grav['accounts']; - $email = $data['email'] ?? ''; // Sanitize $email $email = htmlspecialchars(strip_tags($email), ENT_QUOTES, 'UTF-8'); - $user = !empty($email) ? $users->find($email, ['email']) : null; + // Find user if they exist + $user = $users->find($email, ['email']); - /** @var Language $language */ - $language = $this->grav['language']; - $messages = $this->grav['messages']; + if ($user->exists()) { + if (!isset($this->grav['Email'])) { + $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); + $this->setRedirect($this->login->getRoute('forgot') ?? '/'); - if (!isset($this->grav['Email'])) { - $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); - $this->setRedirect($this->login->getRoute('forgot') ?? '/'); + return true; + } - return true; - } + $from = $config->get('plugins.email.from'); - $from = $config->get('plugins.email.from'); + if (empty($from)) { + $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); + $this->setRedirect($this->login->getRoute('forgot') ?? '/'); - if (empty($from)) { - $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); - $this->setRedirect($this->login->getRoute('forgot') ?? '/'); + return true; + } - return true; - } + $userKey = $user->username; + $rateLimiter = $this->login->getRateLimiter('pw_resets'); + $rateLimiter->registerRateLimitedAction($userKey); - $userKey = $user->username; - $rateLimiter = $this->login->getRateLimiter('pw_resets'); - $rateLimiter->registerRateLimitedAction($userKey); + if ($rateLimiter->isRateLimited($userKey)) { + $messages->add($language->translate(['PLUGIN_LOGIN.FORGOT_CANNOT_RESET_IT_IS_BLOCKED', $email, $rateLimiter->getInterval()]), 'error'); + $this->setRedirect($this->login->getRoute('login') ?? '/'); - if ($rateLimiter->isRateLimited($userKey)) { - $messages->add($language->translate(['PLUGIN_LOGIN.FORGOT_CANNOT_RESET_IT_IS_BLOCKED', $email, $rateLimiter->getInterval()]), 'error'); - $this->setRedirect($this->login->getRoute('login') ?? '/'); + return true; + } - return true; - } + $token = md5(uniqid((string)mt_rand(), true)); + $expire = time() + 604800; // next week - $token = md5(uniqid((string)mt_rand(), true)); - $expire = time() + 604800; // next week + $user->reset = $token . '::' . $expire; + $user->save(); - $user->reset = $token . '::' . $expire; - $user->save(); - - try { - Email::sendResetPasswordEmail($user); + try { + Email::sendResetPasswordEmail($user); + $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL'), 'info'); + } catch (\Exception $e) { + $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_FAILED_TO_EMAIL'), 'error'); + } + } else { $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL'), 'info'); - } catch (\Exception $e) { - $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_FAILED_TO_EMAIL'), 'error'); } + $this->setRedirect($this->login->getRoute('login') ?? '/'); return true; diff --git a/plugins/markdown-notices/CHANGELOG.md b/plugins/markdown-notices/CHANGELOG.md new file mode 100644 index 0000000..87e27b1 --- /dev/null +++ b/plugins/markdown-notices/CHANGELOG.md @@ -0,0 +1,38 @@ +# v1.1.0 +## 12/02/2020 + +1. [](#new) + * Support for indent-sensitive notices [#17](https://github.com/getgrav/grav-plugin-markdown-notices/pull/17) + * Pass phpstan level 1 tests + * Require Grav v1.6 + +# v1.0.4 +## 09/10/2019 + +1. [](#improved) + * Reverted PR#10 which was breaking multiline notices and also unintentionally marking up notices with `!` in paragraphs + +# v1.0.3 +## 08/16/2019 + +1. [](#improved) + * Fixed issue where PR#10 clobbered PR#9 + +# v1.0.2 +## 08/11/2019 + +1. [](#new) + * Ability to specify your own base classes [#9](https://github.com/getgrav/grav-plugin-markdown-notices/pull/9) + * Allow adding inline notices inside tables [#10](https://github.com/getgrav/grav-plugin-markdown-notices/pull/10) + +# v1.0.1 +## 03/09/2018 + +1. [](#improved) + * Updated blueprint file + +# v1.0.0 +## 12/22/2015 + +1. [](#new) + * ChangeLog started... diff --git a/plugins/markdown-notices/LICENSE b/plugins/markdown-notices/LICENSE new file mode 100644 index 0000000..4bb7092 --- /dev/null +++ b/plugins/markdown-notices/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Grav + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/markdown-notices/README.md b/plugins/markdown-notices/README.md new file mode 100644 index 0000000..00f9cb6 --- /dev/null +++ b/plugins/markdown-notices/README.md @@ -0,0 +1,62 @@ +# Grav Markdown Notices Plugin + +The **markdown-notices plugin** for [Grav](http://github.com/getgrav/grav) allows generation of notice blocks of text via markdown: + +![](assets/screenshot.png) + +# Installation + +This plugin is easy to install with GPM. + +``` +$ bin/gpm install markdown-notices +``` + +# Configuration + +Simply copy the `user/plugins/markdown-notices/markdown-notices.yaml` into `user/config/plugins/markdown-notices.yaml` and make your modifications. + +``` +enabled: true +built_in_css: true +base_classes: 'notices' +level_classes: [yellow, red, blue, green] +``` + +# Examples + +Using one level of `!` + +``` +! Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris feugiat quam erat, ut iaculis diam posuere nec. +! Vestibulum eu condimentum urna. Vestibulum feugiat odio ut sodales porta. Donec sit amet ante mi. Donec lobortis +! orci dolor. Donec tristique volutpat ultricies. Nullam tempus, enim sit amet fringilla facilisis, ipsum ex +! tincidunt ipsum, vel placerat sem sem vitae risus. Aenean posuere sed purus nec pretium. +``` + +You will output the following HTML + +``` +
+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris feugiat quam erat, ut iaculis diam posuere nec. + Vestibulum eu condimentum urna. Vestibulum feugiat odio ut sodales porta. Donec sit amet ante mi. Donec lobortis + orci dolor. Donec tristique volutpat ultricies. Nullam tempus, enim sit amet fringilla facilisis, ipsum ex + tincidunt ipsum, vel placerat sem sem vitae risus. Aenean posuere sed purus nec pretium. +

+
+``` + +The `notices` class determined by the `base_classes` and `yellow` class is determined by the `level_classes` in the configuration. You can customize this as you need. + +``` +!! Lorem ipsum dolor sit amet, **consectetur adipiscing** elit. Mauris feugiat quam erat, ut iaculis diam posuere nec. +!! +!! * List item a +!! * List item b +!! +!! orci dolor. Donec tristique volutpat ultricies. Nullam tempus, enim sit amet fringilla facilisis, ipsum ex +!! tincidunt ipsum, vel placerat sem sem vitae risus. Aenean posuere sed purus nec pretium. +``` + +Two levels of `!!` will use the second level class etc. You can also use complex markdown inside the notices. diff --git a/plugins/markdown-notices/assets/notices.css b/plugins/markdown-notices/assets/notices.css new file mode 100644 index 0000000..93c3a85 --- /dev/null +++ b/plugins/markdown-notices/assets/notices.css @@ -0,0 +1,32 @@ +.notices { + padding: 1px 1px 1px 30px; + margin: 15px 0; +} + +.notices p { + +} + +.notices.yellow { + border-left: 10px solid #f0ad4e; + background: #fcf8f2; + color: #df8a13; +} + +.notices.red { + border-left: 10px solid #d9534f; + background: #fdf7f7; + color: #b52b27; +} + +.notices.blue { + border-left: 10px solid #5bc0de; + background: #f4f8fa; + color: #28a1c5; +} + +.notices.green { + border-left: 10px solid #5cb85c; + background: #f1f9f1; + color: #3d8b3d; +} \ No newline at end of file diff --git a/plugins/markdown-notices/assets/screenshot.png b/plugins/markdown-notices/assets/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..cf27677a9736178e4945722a7f39a453b16cb558 GIT binary patch literal 86632 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 literal 0 HcmV?d00001 diff --git a/plugins/markdown-notices/blueprints.yaml b/plugins/markdown-notices/blueprints.yaml new file mode 100644 index 0000000..601b98a --- /dev/null +++ b/plugins/markdown-notices/blueprints.yaml @@ -0,0 +1,59 @@ +name: 'Markdown Notices' +type: plugin +slug: markdown-notices +version: 1.1.0 +description: 'Adds the ability to render notices blocks in Markdown' +icon: asterisk +author: + name: Team Grav + email: devs@getgrav.org + url: http://getgrav.org +homepage: https://github.com/getgrav/grav-plugin-markdown-notices +license: MIT +dependencies: + - { name: grav, version: '>=1.6.0' } + +form: + validation: strict + fields: + enabled: + type: toggle + label: PLUGIN_ADMIN.PLUGIN_STATUS + highlight: 1 + default: 0 + options: + 1: PLUGIN_ADMIN.ENABLED + 0: PLUGIN_ADMIN.DISABLED + validate: + type: bool + + built_in_css: + type: toggle + label: PLUGIN_MARKDOWN_NOTICES.USE_BUILT_IN_CSS + highlight: 1 + default: 1 + options: + 1: PLUGIN_ADMIN.ENABLED + 0: PLUGIN_ADMIN.DISABLED + validate: + type: bool + + base_classes: + type: selectize + label: PLUGIN_MARKDOWN_NOTICES.BASE_CLASSES + size: large + placeholder: PLUGIN_MARKDOWN_NOTICES.BASE_CLASSES_PLACEHOLDER + help: PLUGIN_MARKDOWN_NOTICES.BASE_CLASSES_HELP + classes: fancy + validate: + type: string + + level_classes: + type: selectize + label: PLUGIN_MARKDOWN_NOTICES.LEVEL_CLASSES + size: large + placeholder: PLUGIN_MARKDOWN_NOTICES.LEVEL_CLASSES_PLACEHOLDER + help: PLUGIN_MARKDOWN_NOTICES.LEVEL_CLASSES_HELP + classes: fancy + validate: + type: commalist diff --git a/plugins/markdown-notices/composer.json b/plugins/markdown-notices/composer.json new file mode 100644 index 0000000..b5f3540 --- /dev/null +++ b/plugins/markdown-notices/composer.json @@ -0,0 +1,27 @@ +{ + "name": "grav-plugin-markdown-notices", + "type": "grav-plugin", + "description": "Markdown notices plugin for Grav CMS", + "keywords": ["notices"], + "homepage": "https://github.com/getgrav/grav-plugin-markdown-notices/", + "license": "MIT", + "authors": [ + { + "name": "Team Grav", + "email": "devs@getgrav.org", + "homepage": "http://getgrav.org", + "role": "Developer" + } + ], + "require": { + "php": ">=7.1.3" + }, + "autoload": { + "classmap": ["markdown-notices.php"] + }, + "config": { + "platform": { + "php": "7.1.3" + } + } +} diff --git a/plugins/markdown-notices/composer.lock b/plugins/markdown-notices/composer.lock new file mode 100644 index 0000000..428bd2b --- /dev/null +++ b/plugins/markdown-notices/composer.lock @@ -0,0 +1,22 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "683006688355ff7a1f71b2726c2629b6", + "packages": [], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=7.1.3" + }, + "platform-dev": [], + "platform-overrides": { + "php": "7.1.3" + } +} diff --git a/plugins/markdown-notices/languages.yaml b/plugins/markdown-notices/languages.yaml new file mode 100644 index 0000000..dbee759 --- /dev/null +++ b/plugins/markdown-notices/languages.yaml @@ -0,0 +1,29 @@ +en: + PLUGIN_MARKDOWN_NOTICES: + USE_BUILT_IN_CSS: 'Use built-in CSS' + BASE_CLASSES: 'Base classes' + BASE_CLASSES_HELP: 'These classes will be added before the class level' + BASE_CLASSES_PLACEHOLDER: 'e.g. notices' + LEVEL_CLASSES: 'Level classes' + LEVEL_CLASSES_HELP: 'The classes to use for each level of notices depth' + LEVEL_CLASSES_PLACEHOLDER: 'e.g. yellow, red, blue, green' + +ru: + PLUGIN_MARKDOWN_NOTICES: + USE_BUILT_IN_CSS: 'Использовать встроенный CSS' + BASE_CLASSES: 'Базовые классы' + BASE_CLASSES_HELP: 'Эти классы будут добавлены до уровня класса' + BASE_CLASSES_PLACEHOLDER: 'например notices' + LEVEL_CLASSES: 'Классы уровней' + LEVEL_CLASSES_HELP: 'Эти классы используются на каждом уровне глубины уведомлений' + LEVEL_CLASSES_PLACEHOLDER: 'например yellow, red, blue, green' + +uk: + PLUGIN_MARKDOWN_NOTICES: + USE_BUILT_IN_CSS: 'Використовувати вбудований CSS' + BASE_CLASSES: 'Базові класи' + BASE_CLASSES_HELP: 'Ці класи будуть додані до рівня класу' + BASE_CLASSES_PLACEHOLDER: 'наприклад notices' + LEVEL_CLASSES: 'Класи рівнів' + LEVEL_CLASSES_HELP: 'Ці класи використовуються на кожному рівні глибини повідомлень' + LEVEL_CLASSES_PLACEHOLDER: 'наприклад yellow, red, blue, green' diff --git a/plugins/markdown-notices/markdown-notices.php b/plugins/markdown-notices/markdown-notices.php new file mode 100644 index 0000000..3829e2a --- /dev/null +++ b/plugins/markdown-notices/markdown-notices.php @@ -0,0 +1,92 @@ + [ + ['autoload', 100001], + ], + 'onMarkdownInitialized' => ['onMarkdownInitialized', 0], + 'onTwigSiteVariables' => ['onTwigSiteVariables', 0] + ]; + } + + /** + * [onPluginsInitialized:100000] Composer autoload. + * + * @return ClassLoader + */ + public function autoload() + { + return require __DIR__ . '/vendor/autoload.php'; + } + + public function onMarkdownInitialized(Event $event) + { + $markdown = $event['markdown']; + + $markdown->addBlockType('!', 'Notices', true, false); + + $markdown->blockNotices = function($Line) { + + $this->level_classes = $this->config->get('plugins.markdown-notices.level_classes'); + $this->base_classes = $this->config->get('plugins.markdown-notices.base_classes'); + + if (preg_match('/^(!{1,'.count($this->level_classes).'}) (.*)/', $Line['text'], $matches)) + { + $level = strlen($matches[1]) - 1; + + $text = $matches[2]; + $base_classes = (empty($this->base_classes)) ? '' : str_replace(',', ' ', $this->base_classes) . ' '; + + $Block = [ + 'element' => [ + 'name' => 'div', + 'handler' => 'lines', + 'attributes' => [ + 'class' => $base_classes . $this->level_classes[$level], + ], + 'text' => (array) $text, + ], + ]; + + return $Block; + } + }; + + $markdown->blockNoticesContinue = function($Line, array $Block) { + if (isset($Block['interrupted'])) + { + return; + } + + if (preg_match('/^(!{1,'.count($this->level_classes).'}) ?(.*)/', $Line['text'], $matches)) + { + $Block['element']['text'] []= $matches[2]; + + return $Block; + } + }; + } + + public function onTwigSiteVariables() + { + if ($this->config->get('plugins.markdown-notices.built_in_css')) { + $this->grav['assets'] + ->add('plugin://markdown-notices/assets/notices.css'); + } + } +} diff --git a/plugins/markdown-notices/markdown-notices.yaml b/plugins/markdown-notices/markdown-notices.yaml new file mode 100644 index 0000000..2e15749 --- /dev/null +++ b/plugins/markdown-notices/markdown-notices.yaml @@ -0,0 +1,4 @@ +enabled: true +built_in_css: true +base_classes: 'notices' +level_classes: [yellow, red, blue, green] diff --git a/plugins/markdown-notices/vendor/autoload.php b/plugins/markdown-notices/vendor/autoload.php new file mode 100644 index 0000000..e0aa508 --- /dev/null +++ b/plugins/markdown-notices/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath.'\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/plugins/markdown-notices/vendor/composer/LICENSE b/plugins/markdown-notices/vendor/composer/LICENSE new file mode 100644 index 0000000..f27399a --- /dev/null +++ b/plugins/markdown-notices/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/plugins/markdown-notices/vendor/composer/autoload_classmap.php b/plugins/markdown-notices/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..2c14f6c --- /dev/null +++ b/plugins/markdown-notices/vendor/composer/autoload_classmap.php @@ -0,0 +1,10 @@ + $baseDir . '/markdown-notices.php', +); diff --git a/plugins/markdown-notices/vendor/composer/autoload_namespaces.php b/plugins/markdown-notices/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..b7fc012 --- /dev/null +++ b/plugins/markdown-notices/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit83fb2a7c0fd89ecaed52b0401a5f24c0::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + return $loader; + } +} diff --git a/plugins/markdown-notices/vendor/composer/autoload_static.php b/plugins/markdown-notices/vendor/composer/autoload_static.php new file mode 100644 index 0000000..f5cb969 --- /dev/null +++ b/plugins/markdown-notices/vendor/composer/autoload_static.php @@ -0,0 +1,20 @@ + __DIR__ . '/../..' . '/markdown-notices.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->classMap = ComposerStaticInit83fb2a7c0fd89ecaed52b0401a5f24c0::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/plugins/markdown-notices/vendor/composer/installed.json b/plugins/markdown-notices/vendor/composer/installed.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/plugins/markdown-notices/vendor/composer/installed.json @@ -0,0 +1 @@ +[]