Twilio & PHP Mailer

main
Robert 4 months ago
parent bf0d9ebebd
commit 2b30d7d91d
  1. 4
      docs/TODO.md
  2. 4
      src/bootstrap/main.php
  3. 21
      src/classes/app.php
  4. 11
      src/classes/misc.php
  5. 239
      src/classes/services/emailer.php

@ -45,9 +45,9 @@
[ ] → Rate Limiting [ ] → Rate Limiting
[ ] → PHP Mailer / Access Token [?] → PHP Mailer / Access Token
[ ] → Twilio Support [x] → Twilio Support
[x] → Logger [x] → Logger

@ -17,10 +17,6 @@ if (!function_exists('str_contains')) {
} }
} }
unset($_REQUEST); // Request is dangerious as order of Vars is not Known
unset($_GET); // Super Globals are not Filtered, so unset them
unset($_POST);
$mem_baseline = memory_get_usage(); $mem_baseline = memory_get_usage();
require_once CodeHydrater_FRAMEWORK . 'bootstrap/errors.php'; require_once CodeHydrater_FRAMEWORK . 'bootstrap/errors.php';

@ -26,6 +26,19 @@ class app {
private $method; private $method;
private $params; private $params;
private function get_without_file_extension(string $route): string {
$dot_position = strpos($route, '.');
if ($dot_position !== false) {
$offset = strlen($route) - $dot_position;
$ext = \CodeHydrater\bootstrap\common::get_string_right($route, $offset);
if ($ext === ".php") {
$this->local404();
}
return substr($route, 0, $dot_position);
}
return $route; // No dot found, return full string
}
private function get_first_chunks(string $input): string { private function get_first_chunks(string $input): string {
$parts = explode('/', $input); $parts = explode('/', $input);
$last = array_pop($parts); $last = array_pop($parts);
@ -43,13 +56,13 @@ class app {
*/ */
public function __construct() { public function __construct() {
$full_route = bootstrap\site_helper::get_route(); $full_route = bootstrap\site_helper::get_route();
$no_hmtl = str_replace(".html", "", $full_route); $no_file_ext = $this->get_without_file_extension($full_route);
// Find the Route // Find the Route
$route = $this->get_first_chunks($no_hmtl); $route = $this->get_first_chunks($no_file_ext);
// Find the Method // Find the Method
$the_method = $this->get_last_part($no_hmtl); $the_method = $this->get_last_part($no_file_ext);
$params = bootstrap\site_helper::get_params(); $params = bootstrap\site_helper::get_params();
@ -168,7 +181,7 @@ class app {
if ($method === "error" && str_contains($class, "app") && if ($method === "error" && str_contains($class, "app") &&
method_exists($controller, $method) === false method_exists($controller, $method) === false
) { ) {
CodeHydrater_broken_error(); \CodeHydrater\bootstrap\broken_error();
return false; return false;
} }

@ -281,9 +281,18 @@ final class misc {
$vars = self::safe_url($vars); $vars = self::safe_url($vars);
} }
$dot_position = strpos($method, '.');
if ($dot_position !== false) {
$offset = strlen($method) - $dot_position;
$ext = \CodeHydrater\bootstrap\common::get_string_right($method, $offset);
$method = \CodeHydrater\bootstrap\common::get_string_left($method, $dot_position);
} else {
$ext = ".html";
}
if (bootstrap\configure::get('CodeHydrater', 'short_url') === true) { if (bootstrap\configure::get('CodeHydrater', 'short_url') === true) {
$vars = (!empty($vars)) ? "?{$vars}" : ''; $vars = (!empty($vars)) ? "?{$vars}" : '';
return rtrim(PROJECT_BASE_REF, "/") . "/{$route}/{$method}.html{$vars}"; return rtrim(PROJECT_BASE_REF, "/") . "/{$route}/{$method}{$ext}{$vars}";
} else { } else {
$vars = (!empty($vars)) ? "&{$vars}" : ''; $vars = (!empty($vars)) ? "&{$vars}" : '';
return rtrim(PROJECT_BASE_REF, "/") . "?route={$route}&m={$method}{$vars}"; return rtrim(PROJECT_BASE_REF, "/") . "?route={$route}&m={$method}{$vars}";

@ -0,0 +1,239 @@
<?php
declare(strict_types=1);
/**
* @author Robert Strutts
* @copyright Copyright (c) 2022, Robert Strutts.
* @license MIT
*/
namespace CodeHydrater\services;
use CodeHydrater\bootstrap\registry as Reg;
class emailer {
/**
* Send an Email.
* to=>array(addresses, address, name)
* @param array $options (to, cc, bcc, from, subject, email, type['html', or 'text'])
* @return bool
*/
function send_email(array $options): bool {
if (!is_array($options)) {
return false;
}
if (! Reg::get('loader')->is_loaded('PHPMailer\PHPMailer')) {
Reg::get('loader')->add_namespace('PHPMailer\PHPMailer', CodeHydrater_PROJECT . 'vendor/phpmailer/phpmailer/src');
}
$mail = new \PHPMailer\PHPMailer\PHPMailer();
$message = '';
$subject = '';
$to = '';
$from = '';
$from_name = '';
$reply = '';
$reply_name = '';
$content_type = '';
$cc = '';
$cc_name = '';
$bcc = '';
$bcc_name = '';
foreach ($options as $key => $value) {
$default = (isset($value[0])) ? $value[0] : null;
switch (\CodeHydrater\bootstrap\common::string_to_lowercase($key)) {
case 'to':
if (is_array($value)) {
$mto = (isset($value['addresses']) && is_array($value['addresses'])) ? $value['addresses'] : false;
$to = (isset($value['address'])) ? $value['address'] : $default;
$to_name = (isset($value['name'])) ? $value['name'] : false;
if ($mto !== false) {
foreach ($mto as $name => $address) {
$mail->addAddress($address, $name);
$to .= $address . "({$name});";
}
} elseif ($to_name === false) {
$mail->addAddress($to);
} else {
$mail->addAddress($to, $to_name);
}
} else {
$to = $value;
$mail->addAddress($to); // Add a recipient
}
break;
case 'cc':
if (is_array($value)) {
$mcc = (isset($value['addresses']) && is_array($value['addresses'])) ? $value['addresses'] : false;
$cc = (isset($value['address'])) ? $value['address'] : $default;
$cc_name = (isset($value['name'])) ? $value['name'] : false;
if ($mcc !== false) {
foreach ($mcc as $name => $address) {
$mail->addCC($address, $name);
}
} elseif ($cc_name === false) {
$mail->addCC($cc);
} else {
$mail->addCC($cc, $cc_name);
}
} else {
$mail->addCC($value);
}
break;
case 'bcc':
if (is_array($value)) {
$mbcc = (isset($value['addresses']) && is_array($value['addresses'])) ? $value['addresses'] : false;
$bcc = (isset($value['address'])) ? $value['address'] : $default;
$bcc_name = (isset($value['name'])) ? $value['name'] : false;
if ($mbcc !== false) {
foreach ($mbcc as $name => $address) {
$mail->addBBC($address, $name);
}
} elseif ($bbc_name === false) {
$mail->addBCC($bcc);
} else {
$mail->addBCC($bcc, $bcc_name);
}
} else {
$mail->addBCC($value);
}
break;
case 'from':
if (is_array($value)) {
$from = (isset($value['address'])) ? $value['address'] : $default;
$from_name = (isset($value['name'])) ? $value['name'] : false;
if ($from_name === false) {
$mail->setFrom($from);
} else {
$mail->setFrom($from, $from_name);
}
} else {
$from = $value;
$mail->setFrom($from);
}
break;
case 'subject':
$subject = $value;
$mail->Subject = $subject;
break;
case 'email':
case 'message':
$message = $value;
$mail->Body = $message;
$mail->AltBody = strip_tags($message);
break;
case 'reply to':
case 'reply':
if (is_array($value)) {
$mreply = (isset($value['addresses']) && is_array($value['addresses'])) ? $value['addresses'] : false;
$reply = (isset($value['address'])) ? $value['address'] : $default;
$reply_name = (isset($value['name'])) ? $value['name'] : false;
if ($mreply !== false) {
foreach ($mreply as $name => $address) {
$mail->addReplyTo($address, $name);
}
} elseif ($reply_name === false) {
$mail->addReplyTo($reply);
} else {
$mail->addReplyTo($reply, $reply_name);
}
} else {
$mail->addReplyTo($value);
}
break;
case 'bounce':
case 'bounce address':
case 'bounce backs':
$bounce = $value;
break;
case 'attachment':
case 'attach':
if (is_array($value)) {
$attachment = (isset($value['file'])) ? $value['file'] : $default;
$file_name = (isset($value['name'])) ? $value['name'] : false;
if ($file_name === false) {
$mail->addAttachment($attachment);
} else {
$mail->addAttachment($attachment, $file_name);
}
} else {
$mail->addAttachment($value);
}
break;
case 'type':
case 'content type':
$content_type = $value;
break;
}
}
if (empty($to) || empty($from) || empty($subject) || empty($message)) {
return false;
}
switch ($content_type) {
case 'html':
$mail->isHTML(true); // Set email format to HTML
break;
case 'text':
default:
$mail->isHTML(false); // Set email format to Plain Text
break;
}
$settings = Reg::get('email');
if (isset($settings['send_emails']) && $settings['send_emails'] === false) {
try {
$log = Regy::get('di')->get_service('log', ['emails']);
$log->write("To: {$to} Subject: {$subject} Message: {$message}");
} catch (Exception $e) {
}
return false;
}
if (isset($settings['host']) && !empty($settings['host'])) {
if (isset($settings['smtp_debug'])) {
$mail->SMTPDebug = $settings['smtp_debug']; // Enable verbose debug output
}
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = $settings['host']; // Specify main and backup SMTP servers
$auth = ( isset($settings['username']) && !empty($settings['username']) &&
isset($settings['password']) && !empty($settings['password']) &&
(!isset($settings['auth']) || $settings['auth'] === true)
) ? true : false; // Enable SMTP authentication
if ($auth === true) {
$mail->SMTPAuth = true;
$mail->Username = $settings['username']; // SMTP username
$mail->Password = $settings['password']; // SMTP password
$mail->SMTPSecure = (isset($settings['secure'])) ? $settings['secure'] : 'tls'; // Enable TLS encryption, `ssl` also accepted
}
$mail->Port = (isset($settings['port'])) ? $settings['port'] : 587; // TCP port to connect to
} else {
$mail->isMail(); // Use SendMail
}
if ($mail->send()) {
return true; // Yes, it worked!
} else {
try {
$log = Reg::get('di')->get_service('log', ['failed_emails']);
$log->write('Mailer Error: ' . $mail->ErrorInfo);
} catch (Exception $e) {
}
error_log('Mailer Error: ' . $mail->ErrorInfo);
return false;
}
}
}
Loading…
Cancel
Save