Files
nexusphp/app/Repositories/ToolRepository.php

238 lines
9.1 KiB
PHP
Raw Normal View History

2021-05-02 17:24:05 +08:00
<?php
namespace App\Repositories;
2022-03-31 16:28:08 +08:00
use App\Models\Message;
use App\Models\News;
use App\Models\Poll;
use App\Models\PollAnswer;
2021-05-15 01:24:44 +08:00
use App\Models\Setting;
2022-03-31 16:28:08 +08:00
use App\Models\User;
2022-03-31 22:22:04 +08:00
use Carbon\Carbon;
use Symfony\Component\Mailer\Transport\Dsn;
use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransportFactory;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
2021-05-02 17:24:05 +08:00
class ToolRepository extends BaseRepository
{
2021-05-15 01:24:44 +08:00
public function backupWeb(): array
2021-05-02 17:24:05 +08:00
{
$webRoot = base_path();
$dirName = basename($webRoot);
2021-05-13 21:31:09 +08:00
$filename = sprintf('%s/%s.web.%s.tar.gz', sys_get_temp_dir(), $dirName, date('Ymd.His'));
2021-05-02 17:24:05 +08:00
$command = sprintf(
'tar --exclude=vendor --exclude=.git -czf %s -C %s %s',
$filename, dirname($webRoot), $dirName
);
2021-05-05 22:28:19 +08:00
$result = exec($command, $output, $result_code);
2021-05-02 17:24:05 +08:00
do_log(sprintf(
2021-05-05 22:28:19 +08:00
"command: %s, output: %s, result_code: %s, result: %s, filename: %s",
$command, json_encode($output), $result_code, $result, $filename
2021-05-02 17:24:05 +08:00
));
2021-05-05 22:28:19 +08:00
return compact('result_code', 'filename');
2021-05-02 17:24:05 +08:00
}
public function backupDatabase()
{
$connectionName = config('database.default');
$config = config("database.connections.$connectionName");
$filename = sprintf('%s/%s.database.%s.sql', sys_get_temp_dir(), basename(base_path()), date('Ymd.His'));
$command = sprintf(
'mysqldump --user=%s --password=%s --port=%s --single-transaction --databases %s >> %s',
$config['username'], $config['password'], $config['port'], $config['database'], $filename,
);
2021-05-05 22:28:19 +08:00
$result = exec($command, $output, $result_code);
2021-05-02 17:24:05 +08:00
do_log(sprintf(
2021-05-05 22:28:19 +08:00
"command: %s, output: %s, result_code: %s, result: %s, filename: %s",
$command, json_encode($output), $result_code, $result, $filename
2021-05-02 17:24:05 +08:00
));
2021-05-05 22:28:19 +08:00
return compact('result_code', 'filename');
2021-05-02 17:24:05 +08:00
}
2021-05-15 01:24:44 +08:00
public function backupAll(): array
2021-05-02 17:24:05 +08:00
{
2021-05-13 21:31:09 +08:00
$backupWeb = $this->backupWeb();
2021-05-05 22:28:19 +08:00
if ($backupWeb['result_code'] != 0) {
2021-05-02 17:24:05 +08:00
throw new \RuntimeException("backup web fail: " . json_encode($backupWeb));
}
$backupDatabase = $this->backupDatabase();
2021-05-05 22:28:19 +08:00
if ($backupDatabase['result_code'] != 0) {
2021-05-02 17:24:05 +08:00
throw new \RuntimeException("backup database fail: " . json_encode($backupDatabase));
}
$filename = sprintf('%s/%s.%s.tar.gz', sys_get_temp_dir(), basename(base_path()), date('Ymd.His'));
$command = sprintf(
'tar -czf %s -C %s %s -C %s %s',
$filename,
dirname($backupWeb['filename']), basename($backupWeb['filename']),
dirname($backupDatabase['filename']), basename($backupDatabase['filename'])
);
2021-05-05 22:28:19 +08:00
$result = exec($command, $output, $result_code);
2021-05-02 17:24:05 +08:00
do_log(sprintf(
2021-05-05 22:28:19 +08:00
"command: %s, output: %s, result_code: %s, result: %s, filename: %s",
$command, json_encode($output), $result_code, $result, $filename
2021-05-02 17:24:05 +08:00
));
2021-05-15 01:24:44 +08:00
return compact('result_code', 'filename');
}
/**
* do backup cronjob
*
* @return array|false
*/
2022-04-04 17:26:26 +08:00
public function cronjobBackup($force = false): bool|array
2021-05-15 01:24:44 +08:00
{
$setting = Setting::get('backup');
2022-04-04 17:26:26 +08:00
if ($setting['enabled'] != 'yes' && !$force) {
2021-05-15 01:24:44 +08:00
do_log("Backup not enabled.");
return false;
}
$now = now();
$frequency = $setting['frequency'];
$settingHour = (int)$setting['hour'];
$settingMinute = (int)$setting['minute'];
$nowHour = (int)$now->format('H');
2021-05-15 01:45:15 +08:00
$nowMinute = (int)$now->format('i');
2022-04-04 17:26:26 +08:00
do_log("Backup frequency: $frequency, force: " . strval($force));
if (!$force) {
if ($frequency == 'daily') {
if ($settingHour != $nowHour) {
do_log(sprintf('Backup setting hour: %s != now hour: %s', $settingHour, $nowHour));
return false;
}
if ($settingMinute != $nowMinute) {
do_log(sprintf('Backup setting minute: %s != now minute: %s', $settingMinute, $nowMinute));
return false;
}
} elseif ($frequency == 'hourly') {
if ($settingMinute != $nowMinute) {
do_log(sprintf('Backup setting minute: %s != now minute: %s', $settingMinute, $nowMinute));
return false;
}
} else {
throw new \RuntimeException("Unknown backup frequency: $frequency");
2021-05-15 01:24:44 +08:00
}
}
$backupResult = $this->backupAll();
do_log("Backup all result: " . json_encode($backupResult));
if ($backupResult['result_code'] != 0) {
throw new \RuntimeException("Backup all fail.");
}
2021-05-15 01:24:44 +08:00
$clientId = $setting['google_drive_client_id'] ?? '';
$clientSecret = $setting['google_drive_client_secret'] ?? '';
$refreshToken = $setting['google_drive_refresh_token'] ?? '';
$folderId = $setting['google_drive_folder_id'] ?? '';
if (empty($clientId)) {
do_log("No google_drive_client_id, won't do upload.");
return false;
}
if (empty($clientSecret)) {
do_log("No google_drive_client_secret, won't do upload.");
return false;
}
if (empty($refreshToken)) {
do_log("No google_drive_refresh_token, won't do upload.");
return false;
}
do_log("Google drive info: clientId: $clientId, clientSecret: $clientSecret, refreshToken: $refreshToken, folderId: $folderId");
2022-03-31 22:22:04 +08:00
$client = new \Google\Client();
2021-05-15 01:24:44 +08:00
$client->setClientId($clientId);
$client->setClientSecret($clientSecret);
$client->refreshToken($refreshToken);
2022-03-31 22:22:04 +08:00
$service = new \Google\Service\Drive($client);
$adapter = new \Masbug\Flysystem\GoogleDriveAdapter($service, $folderId);
2022-04-04 17:26:26 +08:00
$filesystem = new \League\Flysystem\Filesystem($adapter);
2022-03-31 22:22:04 +08:00
$localAdapter = new \League\Flysystem\Local\LocalFilesystemAdapter('/');
2022-04-04 17:26:26 +08:00
$localFilesystem = new \League\Flysystem\Filesystem($localAdapter);
2021-05-15 01:24:44 +08:00
$filename = $backupResult['filename'];
2022-04-04 17:26:26 +08:00
$start = Carbon::now();
2022-03-31 22:22:04 +08:00
try {
2022-04-04 17:26:26 +08:00
$filesystem->writeStream(basename($filename), $localFilesystem->readStream($filename));
$speed = !(float)$start->diffInSeconds() ? 0 :filesize($filename) / (float)$start->diffInSeconds();
$log = 'Elapsed time: '.$start->diffForHumans(null, true);
2022-03-31 22:22:04 +08:00
$log .= ', Speed: '. number_format($speed/1024,2) . ' KB/s';
do_log($log);
$backupResult['upload_result'] = 'success: ' .$log;
} catch (\Throwable $exception) {
$backupResult['upload_result'] = 'fail: ' . $exception->getMessage();
}
2021-05-15 01:24:44 +08:00
return $backupResult;
2021-05-02 17:24:05 +08:00
}
2021-06-01 23:33:28 +08:00
2022-03-26 04:27:04 +08:00
/**
* @param $to
* @param $subject
* @param $body
* @return bool
*/
public function sendMail($to, $subject, $body): bool
{
2022-03-31 22:22:04 +08:00
$log = "[SEND_MAIL]";
do_log("$log, to: $to, subject: $subject, body: $body");
$factory = new EsmtpTransportFactory();
2022-04-04 17:26:26 +08:00
$smtp = Setting::getFromDb('smtp');
2022-03-26 04:27:04 +08:00
$encryption = null;
if (isset($smtp['encryption']) && in_array($smtp['encryption'], ['ssl', 'tls'])) {
$encryption = $smtp['encryption'];
}
2022-03-31 22:22:04 +08:00
// Create the Transport
$transport = $factory->create(new Dsn(
$encryption === 'tls' ? (($smtp['smtpport'] == 465) ? 'smtps' : 'smtp') : '',
$smtp['smtpaddress'],
$smtp['accountname'] ?? null,
$smtp['accountpassword'] ?? null,
$smtp['smtpport'] ?? null
));
2022-03-26 04:27:04 +08:00
// Create the Mailer using your created Transport
2022-03-31 22:22:04 +08:00
$mailer = new Mailer($transport);
2022-03-26 04:27:04 +08:00
// Create a message
2022-03-31 22:22:04 +08:00
$message = (new Email())
->from(new Address($smtp['accountname'], Setting::get('basic.SITENAME')))
->to($to)
->subject($subject)
->html($body)
2022-03-26 04:27:04 +08:00
;
// Send the message
try {
2022-03-31 22:22:04 +08:00
$mailer->send($message);
2022-03-26 04:27:04 +08:00
return true;
2022-03-31 22:22:04 +08:00
} catch (\Throwable $e) {
do_log("$log, fail: " . $e->getMessage() . "\n" . $e->getTraceAsString(), 'error');
2022-03-26 04:27:04 +08:00
return false;
}
}
2022-03-31 16:28:08 +08:00
public function getNotificationCount(User $user): array
{
$result = [];
//attend or not
$attendRep = new AttendanceRepository();
$attendance = $attendRep->getAttendance($user->id, date('Ymd'));
$result['attendance'] = $attendance ? 0 : 1;
//unread news
$count = News::query()->where('added', '>', $user->last_home)->count();
$result['news'] = $count;
//unread messages
$count = Message::query()->where('receiver', $user->id)->where('unread', 'yes')->count();
$result['message'] = $count;
//un-vote poll
$total = Poll::query()->count();
$userVoteCount = PollAnswer::query()->where('userid', $user->id)->selectRaw('count(distinct(pollid)) as counts')->first()->counts;
$result['poll'] = $total - $userVoteCount;
return $result;
}
2021-05-02 17:24:05 +08:00
}