cfmgrv4 init...2
This commit is contained in:
parent
d19eefa4fb
commit
ac2a677e81
@ -12,6 +12,9 @@ $routes->addPlaceholder('uuid', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}
|
||||
//1. app/Filters/AuthFilter.php
|
||||
//2. Config/Filters.php -> $aliases = ['authFilter' => AuthFilter::class]
|
||||
$routes->get('/', 'Home::index');
|
||||
$routes->group('/RSSFeed', function ($routes) {
|
||||
$routes->get('getITWorld', 'RSSFeedController::getITWorld');
|
||||
});
|
||||
$routes->group('/user', function ($routes) {
|
||||
$routes->get('login', 'UserController::login_form');
|
||||
$routes->post('login', 'UserController::login');
|
||||
|
||||
@ -2,12 +2,27 @@
|
||||
|
||||
namespace App\Controllers\Admin;
|
||||
|
||||
use App\Controllers\CommonController;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use CodeIgniter\HTTP\RequestInterface;
|
||||
use App\Helpers\CommonHelper;
|
||||
use App\Controllers\Admin\AdminController;
|
||||
|
||||
class Home extends CommonController
|
||||
class Home extends AdminController
|
||||
{
|
||||
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
|
||||
{
|
||||
parent::initController($request, $response, $logger);
|
||||
$this->title = "Main";
|
||||
$this->helper = new CommonHelper();
|
||||
}
|
||||
protected function getModel(): mixed
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public function index(): string
|
||||
{
|
||||
return view('welcome_message');
|
||||
helper(['form']);
|
||||
return view('admin/welcome_message', ['viewDatas' => $this->getViewDatas()]);
|
||||
}
|
||||
}
|
||||
|
||||
26
app/Controllers/RSSFeedController.php
Normal file
26
app/Controllers/RSSFeedController.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use CodeIgniter\Controller;
|
||||
|
||||
class RSSFeedController extends Controller
|
||||
{
|
||||
public function getITWorld()
|
||||
{
|
||||
$url = 'https://www.itworld.co.kr/rss/feed/index.php';
|
||||
$rss = simplexml_load_file($url);
|
||||
|
||||
$items = [];
|
||||
foreach ($rss->channel->item as $item) {
|
||||
$items[] = [
|
||||
'title' => (string) $item->title,
|
||||
'link' => (string) $item->link,
|
||||
'description' => (string) $item->description,
|
||||
'pubDate' => (string) $item->pubDate
|
||||
];
|
||||
}
|
||||
|
||||
return $this->response->setJSON($items);
|
||||
}
|
||||
}
|
||||
@ -2,9 +2,11 @@
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
abstract class CommonHelper
|
||||
class CommonHelper
|
||||
{
|
||||
protected function __construct() {}
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
final public function getRandomString($length = 10, $characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||
{
|
||||
return substr(str_shuffle($characters), 0, $length);
|
||||
|
||||
@ -1,5 +1,134 @@
|
||||
<?= $this->extend('layouts/admin') ?>
|
||||
<?= $this->extend(LAYOUTS[$viewDatas['layout']]['path']) ?>
|
||||
<?= $this->section('content') ?>
|
||||
<?= $this->include('templates/admin/header'); ?>
|
||||
<?= $this->include('templates/admin/footer'); ?>
|
||||
<div class="layout_top"><?= $this->include(LAYOUTS[$viewDatas['layout']]['path'] . '/top'); ?></div>
|
||||
<div class="layout_middle">
|
||||
<div class="layout_left"><?= $this->include(LAYOUTS[$viewDatas['layout']]['path'] . '/left_menu'); ?></div>
|
||||
<div class="layout_right">
|
||||
<?= $this->include("templates/{$viewDatas['layout']}/index_header"); ?>
|
||||
<div id="container" class="layout_content">
|
||||
<style>
|
||||
.news-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.news-item {
|
||||
width: 48%;
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid #ddd;
|
||||
padding: 10px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.news-item h3 {
|
||||
font-size: 18px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.news-item p {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
<div
|
||||
style="display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 20px; border-bottom: 2px solid #007bff; padding-bottom: 10px;">
|
||||
<h2 style="color: #007bff; font-size: 24px; margin: 0;">ITWorld의 최신 뉴스</h2>
|
||||
<small style="color: #6c757d; font-size: 14px;">최근 업데이트: <span id="lastUpdate"></span></small>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function updateLastUpdateTime() {
|
||||
const now = new Date();
|
||||
const options = {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
hour12: false
|
||||
};
|
||||
document.getElementById('lastUpdate').textContent = now.toLocaleString('ko-KR', options);
|
||||
}
|
||||
|
||||
// 페이지 로드 시 초기 시간 설정
|
||||
updateLastUpdateTime();
|
||||
|
||||
// RSS 피드를 가져올 때마다 시간 업데이트
|
||||
const originalFetchRSS = fetchRSS;
|
||||
fetchRSS = function () {
|
||||
originalFetchRSS();
|
||||
updateLastUpdateTime();
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="news-container" id="newsContainer">
|
||||
<!-- RSS 피드 항목들이 여기에 동적으로 추가됩니다 -->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function fetchRSS() {
|
||||
fetch('/RSSFeed/getITWorld')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const newsContainer = document.getElementById('newsContainer');
|
||||
newsContainer.innerHTML = '';
|
||||
data.forEach(item => {
|
||||
console.log('RSS 항목:', item); // 디버깅을 위한 로그
|
||||
const pubDate = new Date(item.pubDate);
|
||||
const newsItem = document.createElement('div');
|
||||
newsItem.className = 'news-item';
|
||||
|
||||
// 이미지 URL 추출 및 변환
|
||||
let imageUrl = item.imageUrl || extractImageFromContent(item.content);
|
||||
imageUrl = convertToAbsoluteUrl(imageUrl, item.link);
|
||||
|
||||
newsItem.innerHTML = `
|
||||
<img src="${imageUrl || '/path/to/default-image.jpg'}" alt="${item.title}" onerror="this.onerror=null; this.src='/path/to/default-image.jpg';">
|
||||
<h3><a href="${item.link}" target="_blank">${item.title}</a></h3>
|
||||
<p>${item.description}</p>
|
||||
<small>게시일: ${pubDate.toLocaleString()}</small>
|
||||
`;
|
||||
newsContainer.appendChild(newsItem);
|
||||
});
|
||||
})
|
||||
.catch(error => console.error('RSS 피드를 가져오는 중 오류 발생:', error));
|
||||
}
|
||||
|
||||
// RSS 내용에서 이미지 URL 추출
|
||||
function extractImageFromContent(content) {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(content, 'text/html');
|
||||
const img = doc.querySelector('img');
|
||||
return img ? img.src : null;
|
||||
}
|
||||
|
||||
// 상대 URL을 절대 URL로 변환
|
||||
function convertToAbsoluteUrl(url, baseUrl) {
|
||||
if (!url) return null;
|
||||
if (url.startsWith('http://') || url.startsWith('https://')) {
|
||||
return url; // 이미 절대 URL인 경우
|
||||
}
|
||||
const base = new URL(baseUrl);
|
||||
if (url.startsWith('/')) {
|
||||
return `${base.protocol}//${base.hostname}${url}`;
|
||||
}
|
||||
return `${base.protocol}//${base.hostname}${base.pathname.substring(0, base.pathname.lastIndexOf('/') + 1)}${url}`;
|
||||
}
|
||||
|
||||
// 페이지 로드 시 RSS 피드 가져오기
|
||||
fetchRSS();
|
||||
|
||||
// 1시간마다 RSS 피드 업데이트
|
||||
setInterval(fetchRSS, 3600000);
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layout_footer"><?= $this->include("templates/{$viewDatas['layout']}/index_footer"); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layout_bottom">
|
||||
<?= $this->include(LAYOUTS[$viewDatas['layout']]['path'] . '/bottom'); ?>
|
||||
</div>
|
||||
<?= $this->endSection() ?>
|
||||
@ -4,7 +4,7 @@
|
||||
<div id="left_menu" onMouseOver="sideMenuToggle(this);" onMouseOut="sideMenuToggle(this);">
|
||||
<div id="accordion" class="accordion accordion-flush">
|
||||
<div class="main">
|
||||
<a href="/admin/user"><?= ICONS["HOME"] ?> Main</a>
|
||||
<a href="/admin"><?= ICONS["HOME"] ?> Main</a>
|
||||
</div>
|
||||
<?= $this->include(LAYOUTS[$viewDatas['layout']]['path'] . '/left_menu/base'); ?>
|
||||
<?= $this->include(LAYOUTS[$viewDatas['layout']]['path'] . '/left_menu/cloudflare'); ?>
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
<nav class="navbar navbar-expand-lg">
|
||||
<div class="container-fluid">
|
||||
<nav class="nav"><a class="navbar-brand" href="#">관리페이지</a></nav>
|
||||
<nav class="nav"><a class="navbar-brand" href="#">CFMGR 관리</a></nav>
|
||||
<ul class="nav justify-content-center">
|
||||
<li class="nav-item">
|
||||
<?= ICONS['LOCK'] ?>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<input type="text" class="form-control" value="<?= $viewDatas['helper']->getPasswordString() ?>" id="makePassword">
|
||||
<input type="text" class="form-control" value="<?= $viewDatas['helper']->getPasswordString() ?>"
|
||||
id="makePassword">
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="btn btn-default border border-dark" type="button" id="totSearchBtn"
|
||||
@ -23,27 +24,29 @@
|
||||
<li class="nav-item">
|
||||
<?php if ($viewDatas['myauth']->isLoggedIn()): ?>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-outline-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<button type="button" class="btn btn-outline-primary dropdown-toggle" data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
<b><?= ICONS['LOGIN'] . $viewDatas['myauth']->getAuthInfo('name') ?></b>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li><?= form_label(
|
||||
ICONS['SETUP'] . "정보수정",
|
||||
"modify",
|
||||
[
|
||||
"class" => "dropdown-item",
|
||||
"data-src" => "/admin/user/modify/" . $viewDatas['myauth']->getAuthInfo('uid'),
|
||||
"data-bs-toggle" => "modal",
|
||||
"data-bs-target" => "#index_action_form"
|
||||
]
|
||||
) ?></li>
|
||||
ICONS['SETUP'] . "정보수정",
|
||||
"modify",
|
||||
[
|
||||
"class" => "dropdown-item",
|
||||
"data-src" => "/admin/user/modify/" . $viewDatas['myauth']->getAuthInfo('uid'),
|
||||
"data-bs-toggle" => "modal",
|
||||
"data-bs-target" => "#index_action_form"
|
||||
]
|
||||
) ?></li>
|
||||
<li>
|
||||
<hr class="dropdown-divider">
|
||||
</li>
|
||||
<li><a class="dropdown-item" href="<?= URLS['LOGOUT'] ?>"><?= ICONS['LOGOUT'] ?>Logout</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<?php else: ?><a class="nav-link dropdown-toggle" href="<?= URLS['LOGIN'] ?>" role="button"><?= ICONS['LOGIN'] ?>Login</a><?php endif ?>
|
||||
<?php else: ?><a class="nav-link dropdown-toggle" href="<?= URLS['LOGIN'] ?>"
|
||||
role="button"><?= ICONS['LOGIN'] ?>Login</a><?php endif ?>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user