Merge branch 'rhymix:develop' into develop

This commit is contained in:
Lastorder 2024-07-22 11:29:41 +09:00 committed by GitHub
commit c572d34465
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 452 additions and 12 deletions

View file

@ -13,7 +13,7 @@ class MailFunction extends Base implements \Rhymix\Framework\Drivers\MailInterfa
protected function __construct()
{
include_once \RX_BASEDIR . 'common/libraries/swift_mail.php';
$this->mailer = new \Swift_Mailer(new \Swift_MailTransport);
$this->_mailer = new \Swift_Mailer(new \Swift_MailTransport);
}
/**
@ -23,7 +23,7 @@ class MailFunction extends Base implements \Rhymix\Framework\Drivers\MailInterfa
*/
public static function getName()
{
return 'mail() Function';
return 'PHP mail() Function';
}
/**
@ -60,7 +60,8 @@ class MailFunction extends Base implements \Rhymix\Framework\Drivers\MailInterfa
{
try
{
$result = $this->mailer->send($message->message, $errors);
$errors = [];
$result = $this->_mailer->send($message->message, $errors);
}
catch(\Exception $e)
{

View file

@ -0,0 +1,184 @@
<?php
namespace Rhymix\Framework\Drivers\Mail;
/**
* The NAVER Cloud Outbound Mailer mail driver.
*/
class Ncloud_Mailer extends Base implements \Rhymix\Framework\Drivers\MailInterface
{
/**
* The API URL.
*/
protected static $_url = 'https://mail.apigw.ntruss.com/api/v1/mails';
protected static $_timeout = 10;
/**
* Get the human-readable name of this mail driver.
*
* @return string
*/
public static function getName()
{
return 'NAVER Cloud Outbound Mailer';
}
/**
* Get the list of configuration fields required by this mail driver.
*
* @return array
*/
public static function getRequiredConfig()
{
return array('api_key', 'api_secret');
}
/**
* Get the SPF hint.
*
* @return string
*/
public static function getSPFHint()
{
return 'include:email.ncloud.com';
}
/**
* Get the DKIM hint.
*
* @return string
*/
public static function getDKIMHint()
{
return 'mailer._domainkey';
}
/**
* Check if the current mail driver is supported on this server.
*
* This method returns true on success and false on failure.
*
* @return bool
*/
public static function isSupported()
{
return function_exists('hash_hmac');
}
/**
* Create signature for NAVER Cloud gateway server
*
* @param string $timestamp
* @param string $access_key
* @param string $secret_key
* @return string
*/
protected static function _makeSignature($timestamp, $access_key, $secret_key): string
{
$method = 'POST';
$uri = '/api/v1/mails';
$content = "$method $uri\n$timestamp\n$access_key";
return base64_encode(hash_hmac('sha256', $content, $secret_key, true));
}
/**
* Send a message.
*
* This method returns true on success and false on failure.
*
* @param object $message
* @return bool
*/
public function send(\Rhymix\Framework\Mail $message)
{
// Prepare data for Requests.
$data = array(
'title' => $message->getSubject(),
'body' => $message->getBody(),
'senderAddress' => '',
'senderName' => '',
'recipients' => array(),
);
// Fill the sender info.
$from = $message->message->getFrom();
foreach($from as $email => $name)
{
$data['senderAddress'] = $email;
$data['senderName'] = trim($name) ?: substr($email, 0, strpos($email, '@'));
break;
}
// Fill the recipient info.
if ($to = $message->message->getTo())
{
foreach($to as $email => $name)
{
$receiver = array();
$receiver['address'] = $email;
$receiver['name'] = str_replace(',', '', trim($name) ?: substr($email, 0, strpos($email, '@')));
$receiver['type'] = "R";
$data['recipients'][] = $receiver;
}
}
if ($cc = $message->message->getCc())
{
foreach($cc as $email => $name)
{
$receiver = array();
$receiver['address'] = $email;
$receiver['name'] = str_replace(',', '', trim($name) ?: substr($email, 0, strpos($email, '@')));
$receiver['type'] = "C";
$data['recipients'][] = $receiver;
}
}
if ($bcc = $message->message->getBcc())
{
foreach($bcc as $email => $name)
{
$receiver = array();
$receiver['address'] = $email;
$receiver['name'] = str_replace(',', '', trim($name) ?: substr($email, 0, strpos($email, '@')));
$receiver['type'] = "B";
$data['recipients'][] = $receiver;
}
}
// Generate the NAVER cloud gateway signature.
$timestamp = floor(microtime(true) * 1000);
$signature = self::_makeSignature($timestamp, $this->_config['api_key'], $this->_config['api_secret']);
$headers = array(
'x-ncp-apigw-timestamp' => $timestamp,
'x-ncp-iam-access-key' => $this->_config['api_key'],
'x-ncp-apigw-signature-v2' => $signature,
);
// Send the API request.
try
{
$request = \Rhymix\Framework\HTTP::post(self::$_url, [], $headers, [], [
'timeout' => self::$_timeout,
'json' => $data,
]);
$result = @json_decode($request->getBody()->getContents());
}
catch (\Exception $e)
{
$message->errors[] = 'NAVER Cloud Outbound Mailer: ' . $e->getMessage();
return false;
}
if (isset($result->error))
{
$message->errors[] = 'NAVER Cloud Outbound Mailer: ' . $result->error->message . PHP_EOL . $result->error->details;
return false;
}
else
{
return true;
}
}
}

View file

@ -179,7 +179,7 @@ class Woorimail extends Base implements \Rhymix\Framework\Drivers\MailInterface
$request = \Rhymix\Framework\HTTP::post(self::$_url, $data, $headers, [], ['timeout' => self::$_timeout]);
$result = @json_decode($request->getBody()->getContents());
}
catch (\Requests_Exception $e)
catch (\Exception $e)
{
$message->errors[] = 'Woorimail: ' . $e->getMessage();
return false;

View file

@ -116,7 +116,7 @@ class CoolSMS extends Base implements \Rhymix\Framework\Drivers\SMSInterface
}
catch (\Nurigo\Exceptions\CoolsmsException $e)
{
$message->errors[] = class_basename($e) . ': ' . $e->getMessage();
$original->addError(class_basename($e) . ': ' . $e->getMessage());
return false;
}
}

View file

@ -0,0 +1,244 @@
<?php
namespace Rhymix\Framework\Drivers\SMS;
use Rhymix\Framework\Storage;
/**
* The NAVER Cloud SENS SMS driver.
*/
class Ncloud_Sens extends Base implements \Rhymix\Framework\Drivers\SMSInterface
{
/**
* API endpoint URL
*/
const API_HOST = 'https://sens.apigw.ntruss.com';
const API_PATH = '/sms/v2/services/%s/%s';
const TIMEOUT = 10;
/**
* API specifications.
*/
protected static $_spec = array(
'max_recipients' => 100,
'sms_max_length' => 90,
'sms_max_length_in_charset' => 'CP949',
'lms_supported' => true,
'lms_supported_country_codes' => array(82),
'lms_max_length' => 2000,
'lms_max_length_in_charset' => 'CP949',
'lms_subject_supported' => true,
'lms_subject_max_length' => 40,
'mms_supported' => true,
'mms_supported_country_codes' => array(82),
'mms_max_length' => 2000,
'mms_max_length_in_charset' => 'CP949',
'mms_subject_supported' => true,
'mms_subject_max_length' => 40,
'image_allowed_types' => array('jpg'),
'image_max_dimensions' => array(1500, 1440),
'image_max_filesize' => 300000,
'delay_supported' => true,
);
/**
* Config keys used by this driver are stored here.
*/
protected static $_required_config = array('service_id', 'api_key', 'api_secret');
protected static $_optional_config = array();
/**
* Get the human-readable name of this SMS driver.
*
* @return string
*/
public static function getName()
{
return 'NAVER Cloud SENS';
}
/**
* Check if the current SMS driver is supported on this server.
*
* This method returns true on success and false on failure.
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Create a signature for NAVER Cloud gateway server.
*
* @param string $method
* @param string $uri
* @param string $timestamp
* @param string $access_key
* @param string $secret_key
* @return string
*/
protected static function _makeSignature($method, $uri, $timestamp, $access_key, $secret_key): string
{
$content = "$method $uri\n$timestamp\n$access_key";
return base64_encode(hash_hmac('sha256', $content, $secret_key, true));
}
/**
* Upload an attachment and get the file ID.
*
* @param string $filename
* @param string $path
* @return ?string
*/
protected function _uploadFile(string $filename, string $path): ?string
{
// Return null if the file cannot be read.
if (!Storage::exists($path) || !Storage::isReadable($path) || !Storage::isFile($path))
{
return null;
}
// Generate the NAVER cloud gateway signature.
$timestamp = floor(microtime(true) * 1000);
$uri = sprintf(self::API_PATH, $this->_config['service_id'], 'files');
$signature = self::_makeSignature('POST', $uri, $timestamp, $this->_config['api_key'], $this->_config['api_secret']);
$headers = array(
'x-ncp-apigw-timestamp' => $timestamp,
'x-ncp-iam-access-key' => $this->_config['api_key'],
'x-ncp-apigw-signature-v2' => $signature,
);
// Send the API request.
try
{
$url = self::API_HOST . sprintf(self::API_PATH, $this->_config['service_id'], 'files');
$request = \Rhymix\Framework\HTTP::post($url, [], $headers, [], [
'timeout' => self::TIMEOUT,
'json' => [
'fileName' => $filename,
'fileBody' => base64_encode(file_get_contents($path)),
],
]);
$result = @json_decode($request->getBody()->getContents());
if (!empty($result->fileId))
{
return $result->fileId;
}
else
{
return null;
}
}
catch (\Exception $e)
{
return null;
}
}
/**
* Send a message.
*
* This method returns true on success and false on failure.
*
* @param array $messages
* @param object $original
* @return bool
*/
public function send(array $messages, \Rhymix\Framework\SMS $original)
{
$status = true;
$file_ids = [];
foreach ($messages as $i => $message)
{
// Basic information
$data = array();
$data['type'] = $message->type;
$data['from'] = str_replace('-', '', \Rhymix\Framework\Korea::formatPhoneNumber($message->from));
if ($message->country && $message->country != 82)
{
$data['countryCode'] = $message->country;
}
// Subject and content
if ($message->type !== 'SMS' && $message->subject)
{
$data['subject'] = $message->subject;
}
$data['content'] = $message->content;
// Recipients
foreach ($message->to as $num)
{
$data['messages'][] = [
'to' => str_replace('-', '', \Rhymix\Framework\Korea::formatPhoneNumber($num)),
];
}
// Image attachment
if (!empty($message->image))
{
$path = realpath($message->image);
if (!isset($file_ids[$path]))
{
$file_ids[$path] = $this->_uploadFile('image.jpg', $path);
}
if (isset($file_ids[$path]))
{
$data['files'][] = ['fileId' => $file_ids[$path]];
}
}
// Set delay
if ($message->delay && $message->delay > time() + 900)
{
$data['reserveTime'] = gmdate('Y-m-d H:i', $message->delay + (3600 * 9));
}
// Generate the NAVER cloud gateway signature.
$timestamp = floor(microtime(true) * 1000);
$uri = sprintf(self::API_PATH, $this->_config['service_id'], 'messages');
$signature = self::_makeSignature('POST', $uri, $timestamp, $this->_config['api_key'], $this->_config['api_secret']);
$headers = array(
'x-ncp-apigw-timestamp' => $timestamp,
'x-ncp-iam-access-key' => $this->_config['api_key'],
'x-ncp-apigw-signature-v2' => $signature,
);
// Send the API request.
try
{
$url = self::API_HOST . sprintf(self::API_PATH, $this->_config['service_id'], 'messages');
$request = \Rhymix\Framework\HTTP::post($url, [], $headers, [], [
'timeout' => self::TIMEOUT,
'json' => $data,
]);
$status_code = $request->getStatusCode();
$response = $request->getBody()->getContents();
$result = $response ? @json_decode($response) : null;
if (isset($result->statusName))
{
if ($result->statusName != 'success')
{
$original->addError(trim('NAVER Cloud SENS: ' . $result->statusCode . ' ' . $result->statusName));
$status = false;
}
}
else
{
$original->addError(trim('NAVER Cloud SENS: ' . $status_code . ' ' . ($result->errorMessage ?? $response)));
$status = false;
}
}
catch (\Exception $e)
{
$original->addError('NAVER Cloud SENS: ' . $e->getMessage());
$status = false;
}
}
return $status;
}
}

View file

@ -398,10 +398,10 @@ class addonAdminModel extends addon
}
$obj->options = array();
for($i = 0, $c = count($val->options); $i < $c; $i++)
foreach ($val->options ?? [] as $i => $option)
{
$obj->options[$i]->title = $val->options[$i]->title->body;
$obj->options[$i]->value = $val->options[$i]->value->body;
$obj->options[$i]->title = $option->title->body;
$obj->options[$i]->value = $option->value->body;
}
$addon_info->extra_vars[] = $obj;
}

View file

@ -100,16 +100,16 @@
<label class="x_control-label">{$lang->target}</label>
<div class="x_controls">
<label for="check_all"><input type="checkbox" id="check_all" /> Check all</label>
<block loop="$mid_list => $module_category_srl, $modules">
<!--@if(count($mid_list) > 1)-->
<block loop="$mid_list => $module_category_srl, $modules">
<!--@if(is_array($mid_list) && count($mid_list) > 1)-->
<fieldset>
<legend><!--@if($modules->title)-->{$modules->title}<!--@else-->{$lang->none_category}<!--@end--></legend>
<!--@end-->
<label loop="$modules->list => $key, $val">
<input type="checkbox" value="{$key}" name="mid_list[]" id="chk_mid_list_{$key}" checked="checked"|cond="in_array($key, $addon_info->mid_list)"/>
<input type="checkbox" value="{$key}" name="mid_list[]" id="chk_mid_list_{$key}" checked="checked"|cond="in_array($key, $addon_info->mid_list ?? [])"/>
{$key} ({$val->browser_title})
</label>
<!--@if(count($mid_list) > 1)-->
<!--@if(is_array($mid_list) && count($mid_list) > 1)-->
</fieldset>
<!--@end-->
</block>

View file

@ -245,6 +245,15 @@
{@ $conf_value = escape(config("sms.$driver_name.$conf_name"))}
<!--@if($conf_name === 'service_id')-->
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
<label class="x_control-label" for="sms_{$driver_name}_service_id">{$lang->cmd_advanced_mailer_service_id}</label>
<div class="x_controls">
<input type="text" name="sms_{$driver_name}_service_id" id="sms_{$driver_name}_service_id" value="{$conf_value}" />
</div>
</div>
<!--@end-->
<!--@if($conf_name === 'api_url')-->
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
<label class="x_control-label" for="sms_{$driver_name}_api_key">{$lang->cmd_advanced_mailer_api_url}</label>

View file

@ -28,6 +28,7 @@ $lang->cmd_advanced_mailer_smtp_security_tls = 'TLS (STARTTLS)';
$lang->cmd_advanced_mailer_smtp_security_none = 'None';
$lang->cmd_advanced_mailer_smtp_user = 'Username';
$lang->cmd_advanced_mailer_smtp_pass = 'Password';
$lang->cmd_advanced_mailer_service_id = 'Service ID';
$lang->cmd_advanced_mailer_api_url = 'API URL';
$lang->cmd_advanced_mailer_api_key = 'API key';
$lang->cmd_advanced_mailer_api_secret = 'API secret';

View file

@ -28,6 +28,7 @@ $lang->cmd_advanced_mailer_smtp_security_tls = 'TLS (STARTTLS)';
$lang->cmd_advanced_mailer_smtp_security_none = '사용하지 않음';
$lang->cmd_advanced_mailer_smtp_user = '아이디';
$lang->cmd_advanced_mailer_smtp_pass = '비밀번호';
$lang->cmd_advanced_mailer_service_id = '서비스 ID';
$lang->cmd_advanced_mailer_api_url = 'API URL';
$lang->cmd_advanced_mailer_api_key = 'API 키';
$lang->cmd_advanced_mailer_api_secret = 'API 비밀';