리빌더 부분 추가

This commit is contained in:
2025-07-02 14:13:16 +09:00
parent b491c16b5e
commit 68797db562
1200 changed files with 264947 additions and 0 deletions

View File

@ -0,0 +1,2 @@
<?php
include_once("../../../../common.php");

View File

@ -0,0 +1,33 @@
<?php
include_once("./_common.php");
// 삭제 요청된 파일 URL 가져오기
$file_url = isset($_POST['file']) ? $_POST['file'] : '';
if (!$file_url) {
echo json_encode(["error" => "파일 경로가 제공되지 않았습니다."]);
exit;
}
// 업로드된 파일 경로에서 /data/editor/YYYY/MM/ 추출
$pattern = "#/data/editor/(\d{4})/([\w\d_-]+\.\w+)$#"; // 2502/파일명.확장자 패턴
if (!preg_match($pattern, $file_url, $matches)) {
echo json_encode(["error" => "잘못된 파일 경로 형식입니다."]);
exit;
}
$ym = $matches[1]; // 2502 (연월)
$file_name = $matches[2]; // 1738844872_c13aee53489a52b7_...png
// 업로드된 디렉토리 경로
$data_dir = G5_DATA_PATH . "/editor/" . $ym . "/";
$file_path = $data_dir . $file_name;
// 파일 존재 여부 확인 후 삭제
if (file_exists($file_path)) {
unlink($file_path);
echo json_encode(["success" => "파일이 삭제되었습니다.", "file" => $file_name]);
} else {
echo json_encode(["error" => "파일을 찾을 수 없습니다."]);
}
?>

View File

@ -0,0 +1,18 @@
<?php
include_once("./_common.php");
$g5_editor = isset( $_GET['editor']) ? $_GET['editor'] : 'rb.editor';
$editor_url = G5_PATH.'/plugin/editor/'.$g5_editor;
header('Content-Type: application/json');
// 대상 폴더 (fonts 경로)
$folderPath = $editor_url.'/fonts';
if (is_dir($folderPath)) {
$folders = array_filter(scandir($folderPath), function($item) use ($folderPath) {
return $item !== '.' && $item !== '..' && is_dir($folderPath . DIRECTORY_SEPARATOR . $item);
});
echo json_encode(["folders" => array_values($folders)]);
} else {
echo json_encode(["error" => "폰트없음"]);
}

View File

@ -0,0 +1,50 @@
<?php
// image_proxy.php
if(isset($_GET['url'])) {
$url = $_GET['url'];
// URL 유효성 검사
if (!filter_var($url, FILTER_VALIDATE_URL)) {
http_response_code(400);
exit('Invalid URL');
}
// cURL 설정 및 실행
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 리디렉션 허용
curl_setopt($ch, CURLOPT_MAXREDIRS, 5); // 최대 5번 리디렉션 허용
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36');
curl_setopt($ch, CURLOPT_REFERER, $url); // 원본 URL을 Referer로 설정
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Accept: image/*', // 이미지 전용 Accept 헤더 추가
'Cache-Control: no-cache', // 캐시 우회
'Pragma: no-cache'
]);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // SSL 검증 비활성화
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$data = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
$contentLength = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
curl_close($ch);
// **HTTP 응답이 200이 아닌 경우에도 강제 출력**
if ($httpCode === 200 && $data) {
header("Content-Type: $contentType");
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Pragma: no-cache");
echo $data;
} else {
// **cURL이 실패하면 URL 직접 반환**
header("Content-Type: text/plain");
echo $url;
}
} else {
http_response_code(400);
exit('URL parameter is required');
}
?>

View File

@ -0,0 +1,143 @@
<?php
header("Access-Control-Allow-Origin: *");
header('Content-Type: application/json; charset=UTF-8');
header('Access-Control-Allow-Credentials: true');
header('Set-Cookie: my_cookie=value; SameSite=None; Secure');
function isFunctionAvailable($function) {
return function_exists($function);
}
function curl_get_contents($url) {
if (!isFunctionAvailable('curl_init')) {
return ['error' => 'CURL 기능이 서버에서 지원되지 않습니다.'];
}
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Referer: https://www.google.com/',
'Upgrade-Insecure-Requests: 1'
]);
$data = curl_exec($ch);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
curl_close($ch);
return ['error' => 'CURL 에러: ' . $error_msg];
}
curl_close($ch);
return ['html' => $data, 'content_type' => $contentType];
}
if (isset($_GET['url'])) {
$url = $_GET['url'];
if (preg_match('/\.(jpg|jpeg|png|gif|webp|svg)$/i', $url)) {
echo json_encode(['title' => 'Image', 'meta' => ['og:image' => $url]], JSON_UNESCAPED_UNICODE);
exit;
}
$result = curl_get_contents($url);
if (isset($result['error'])) {
echo json_encode(['error' => $result['error']], JSON_UNESCAPED_UNICODE);
exit;
}
$html = $result['html'];
$contentType = $result['content_type'];
if (!$html) {
echo json_encode(['error' => '데이터를 가져오지 못했습니다.'], JSON_UNESCAPED_UNICODE);
exit;
}
preg_match('/<meta.*?charset=["\']?([^"\'>]+)/i', $html, $matches);
$htmlCharset = isset($matches[1]) ? strtolower($matches[1]) : 'utf-8';
if (isFunctionAvailable('mb_detect_encoding')) {
$detectedEncoding = mb_detect_encoding($html, ['UTF-8', 'EUC-KR', 'SJIS', 'ISO-8859-1', 'CP949'], true);
} else {
$detectedEncoding = false;
}
if (isFunctionAvailable('mb_convert_encoding')) {
if ($detectedEncoding && $detectedEncoding !== 'UTF-8') {
$html = mb_convert_encoding($html, 'UTF-8', $detectedEncoding);
} elseif ($htmlCharset !== 'utf-8' && $htmlCharset !== '') {
$html = mb_convert_encoding($html, 'UTF-8', strtoupper($htmlCharset));
}
}
if (!class_exists('DOMDocument')) {
echo json_encode(['error' => 'DOMDocument 확장이 필요합니다.'], JSON_UNESCAPED_UNICODE);
exit;
}
$dom = new DOMDocument();
@$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
$metas = $dom->getElementsByTagName('meta');
$metaData = [];
foreach ($metas as $meta) {
$name = $meta->getAttribute('name');
if (!$name) {
$name = $meta->getAttribute('property');
}
$content = $meta->getAttribute('content');
if ($name && $content) {
$metaData[$name] = $content;
}
}
// ✅ og:image가 없으면 첫 번째 <img> 태그의 src를 가져옴
if (!isset($metaData['og:image'])) {
$imgTags = $dom->getElementsByTagName('img');
$firstImage = null;
foreach ($imgTags as $img) {
$src = $img->getAttribute('src');
if (!$src) continue;
if (!preg_match('/^https?:\/\//', $src)) {
$parsedUrl = parse_url($url);
$base = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];
if (isset($parsedUrl['port'])) {
$base .= ':' . $parsedUrl['port'];
}
$src = $base . (substr($src, 0, 1) === '/' ? '' : '/') . $src;
}
$firstImage = $src;
break;
}
if ($firstImage) {
$metaData['og:image'] = $firstImage;
}
}
// ✅ <title> 태그 가져오기
$titleElement = $dom->getElementsByTagName('title')->item(0);
$title = $titleElement ? trim($titleElement->nodeValue) : '';
$response = [
'title' => $title,
'meta' => $metaData
];
echo json_encode($response, JSON_UNESCAPED_UNICODE);
} else {
echo json_encode(['error' => 'URL 파라미터가 필요합니다.'], JSON_UNESCAPED_UNICODE);
}
?>

View File

@ -0,0 +1,20 @@
<?php
include_once("./_common.php");
header('Content-Type: application/json');
$data = json_decode(file_get_contents('php://input'), true);
$url = $data['url'];
if (!$url) {
echo json_encode(['error' => 'Invalid URL']);
exit;
}
$editor_url = G5_EDITOR_URL.'/'.$config['cf_editor'];
// 🛠️ 실제 메타데이터 스크래핑을 수행하는 파일 호출
$metadata_url = $editor_url.'/php/rb.metadata.php?url=' . urlencode($url);
$response = file_get_contents($metadata_url);
echo $response;
?>

View File

@ -0,0 +1,54 @@
<?php
// CORS 허용
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET");
header("Access-Control-Allow-Headers: Content-Type");
// 요청된 이미지 URL 가져오기
if (!isset($_GET['url'])) {
http_response_code(400);
echo "URL이 잘못 되었습니다.";
exit;
}
$image_url = filter_var($_GET['url'], FILTER_SANITIZE_URL);
// URL 유효성 검사
if (!filter_var($image_url, FILTER_VALIDATE_URL)) {
http_response_code(400);
echo "URL이 잘못 되었습니다.";
exit;
}
// CURL을 사용하여 이미지 다운로드
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $image_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$image_data = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$mime_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
curl_close($ch);
if ($http_code !== 200 || !$image_data) {
http_response_code(500);
echo "이미지 파일 저장에 실패 하였습니다.";
exit;
}
// 이미지 타입 허용 (JPG, PNG, WEBP, GIF만 허용)
$allowed_types = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
if (!in_array($mime_type, $allowed_types)) {
http_response_code(400);
echo "이미지 파일만 가능합니다.";
exit;
}
// 올바른 Content-Type 설정 후 출력
header("Content-Type: " . $mime_type);
echo $image_data;
?>

View File

@ -0,0 +1,30 @@
<?php
include_once("./_common.php");
$g5_editor = isset( $_GET['editor']) ? $_GET['editor'] : 'rb.editor';
$baseDir = G5_PATH.'/plugin/editor/'.$g5_editor.'/image/sticker/';
header('Content-Type: application/json');
if (isset($_GET['folder'])) {
// 폴더의 파일 조회 (이미지 파일만)
$folder = preg_replace('/[^a-zA-Z0-9-_ ]/', '', $_GET['folder']); // 보안 필터링
$path = $baseDir . $folder;
if (is_dir($path)) {
$files = array_values(array_filter(scandir($path), function ($file) use ($path) {
return preg_match('/\.(png|jpe?g|gif|svg|webp)$/i', $file) && is_file("$path/$file");
}));
echo json_encode(["files" => $files]);
} else {
echo json_encode(["error" => "폴더가 존재하지 않습니다."]);
}
} else {
// 전체 폴더 목록 조회
$folders = array_filter(glob($baseDir . '*'), 'is_dir');
$folderNames = array_map('basename', $folders);
echo json_encode(["folders" => $folderNames]);
}
?>

View File

@ -0,0 +1,83 @@
<?php
include_once("./_common.php");
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// Nonce 관련 상수 정의 추가
if (!defined('FT_NONCE_UNIQUE_KEY'))
define('FT_NONCE_UNIQUE_KEY', sha1($_SERVER['SERVER_SOFTWARE'] . G5_MYSQL_USER . session_id() . G5_TABLE_PREFIX));
if (!defined('FT_NONCE_SESSION_KEY'))
define('FT_NONCE_SESSION_KEY', substr(md5(FT_NONCE_UNIQUE_KEY), 5));
if (!defined('FT_NONCE_DURATION'))
define('FT_NONCE_DURATION', 60 * 60); // 1시간 유효
if (!defined('FT_NONCE_KEY'))
define('FT_NONCE_KEY', '_nonce');
// 세션에서 Nonce 값을 가져옴
$session_nonce = isset($_SESSION['token_' . FT_NONCE_SESSION_KEY]) ? $_SESSION['token_' . FT_NONCE_SESSION_KEY] : '';
// 업로드 시 전달된 Nonce 값
$posted_nonce = isset($_POST['editor_nonce']) ? $_POST['editor_nonce'] : '';
// Nonce 검증 로그 추가
error_log("업로드 요청 Nonce 값: " . $posted_nonce);
error_log("서버 세션 Nonce 값: " . $session_nonce);
if (!$session_nonce || $posted_nonce !== $session_nonce) {
error_log("Nonce 불일치: 업로드된 nonce = " . $posted_nonce . " | 세션 nonce = " . $session_nonce);
echo json_encode(array("files" => array(array("error" => "잘못된 접근입니다. (Nonce 불일치)"))));
exit;
}
// 업로드 디렉토리 설정
$ym = date('ym', G5_SERVER_TIME);
$data_dir = G5_DATA_PATH . '/editor/' . $ym . '/';
$data_url = G5_DATA_URL . '/editor/' . $ym . '/';
// 디렉토리가 없으면 생성
if (!is_dir($data_dir)) {
if (!@mkdir($data_dir, G5_DIR_PERMISSION, true)) {
error_log("업로드 디렉토리 생성 실패: " . $data_dir);
echo json_encode(array("files" => array(array("error" => "업로드 디렉토리 생성에 실패했습니다."))));
exit;
}
@chmod($data_dir, G5_DIR_PERMISSION);
}
// 파일 업로드 검증
if (!isset($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
error_log("파일 업로드 실패 (파일 정보 없음 또는 오류 코드 존재)");
echo json_encode(array("files" => array(array("error" => "파일 업로드에 실패했습니다."))));
exit;
}
// 파일 저장 처리
$tempfile = $_FILES['file']['tmp_name'];
$filename = time() . '_' . bin2hex(random_bytes(8)) . '_' . $_FILES['file']['name'];
$savefile = $data_dir . $filename;
if (!file_exists($tempfile)) {
error_log("임시 파일이 존재하지 않음: " . $tempfile);
echo json_encode(array("files" => array(array("error" => "임시 파일이 존재하지 않습니다."))));
exit;
}
if (!move_uploaded_file($tempfile, $savefile)) {
error_log("파일 저장 실패: " . $savefile);
echo json_encode(array("files" => array(array("error" => "파일 저장에 실패했습니다."))));
exit;
}
// 파일 권한 설정
@chmod($savefile, G5_FILE_PERMISSION);
// 업로드 성공 응답
$file_url = $data_url . $filename;
echo json_encode(array('files' => array(array('name' => $filename, 'url' => $file_url))));
?>