๐ฅ
๐
๐ป
Z
U
๐f
(โฆ)
๐n
(โฆ)
โฐ
๐พS
๐ฅ
๐C
๐
๐
ฦ
yE
Fn
St
Fi
Hd
<?php /** * ํ์ผ: yyy_find.php * ๋ฒ์ : /var/www/html/y/yyy_find.php */ define("_CMD_", true); error_reporting(E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_PARSE | E_USER_ERROR); include_once __DIR__ . "/yyy_config_host.php"; include_once "yyy_func.php"; include_once('yyy_host_link.php'); # ๋งํฌ๊ด๋ จํจ์ include_once('yyy_url_fav.php'); //include_once('yyy_ip_auth.php'); /* =============================== ๊ธฐ์กด POST / GET ์ฒ๋ฆฌ (์๋ณธ ์ ์ง) =============================== */ if (isset($_REQUEST['save_file']) && $_REQUEST['save_file'] == '1') { $file_path = $_REQUEST['file_path'] ?? ''; $content = $_REQUEST['content'] ?? ''; $no_bak = $_REQUEST['no_bak'] ?? false; if (!$file_path) die("โ ํ์ผ ๊ฒฝ๋ก๊ฐ ์์ต๋๋ค."); $dir = dirname($file_path); if (!is_dir($dir)) { if (!mkdir($dir, 0755, true)) { die("โ ๋๋ ํ ๋ฆฌ ์์ฑ ์คํจ: " . htmlspecialchars($dir)); } } if (file_exists($file_path)) { if (!createBackup($file_path, $no_bak)) { $err = getBackupLastError(); if ($err) { var_dump($err); echo ("yy71:[{$err['code']}] {$err['message']}\n"); } else { echo ("[UNKNOWN] ์ ์ ์๋ ์ค๋ฅ\n"); } exit; } } $result = file_put_contents($file_path, $content); if ($result === false) die("โ ํ์ผ ์ ์ฅ์ ์คํจํ์ต๋๋ค."); echo "โ ์ ์ฅ ์ฑ๊ณต: " . htmlspecialchars($file_path) . " (" . number_format($result) . " bytes)"; exit; } $action = $_REQUEST['action'] ?? ''; yyy_urlfav_handle_ajax(); /* ---- ๊ฐ๋ณ์์ (AJAX) ---- */ if ($_SERVER['REQUEST_METHOD'] === 'POST' && $action === 'single_replace') { $file = $_POST['target_file'] ?? ''; $line = (int)($_POST['target_line'] ?? 0); $content = $_POST['new_content'] ?? ''; $no_bak = $_POST['no_bak'] ?? 0; if ($file && $line && is_writable($file)) { $lines = file($file); if (isset($lines[$line - 1])) { $lines[$line - 1] = $content . "\n"; if (!$no_bak) createBackup($file); if (file_put_contents($file, implode('', $lines)) !== false) { echo "โ " . basename($file) . " {$line}๋ผ์ธ ์์ ์๋ฃ!"; exit; } } } echo "โ ์์ ์คํจ (ํ์ผ ๊ถํ์ด๋ ๋ผ์ธ ํ์ธ ํ์)"; exit; } $R = $_REQUEST; $req_bool = function($k){ return isset($_REQUEST[$k]) && $_REQUEST[$k] == '1'; }; ?> <!DOCTYPE html> <html lang="ko" data-bs-theme="<?= htmlspecialchars($_COOKIE['theme'] ?? 'light', ENT_QUOTES) ?>"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes"> <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='0.9em' font-size='90'>๐ฅ</text></svg>"> <title>y</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/theme/dracula.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/xml/xml.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/javascript/javascript.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/css/css.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/htmlmixed/htmlmixed.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/clike/clike.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/php/php.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/sql/sql.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/python/python.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/shell/shell.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/properties/properties.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/yaml/yaml.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/markdown/markdown.min.js"></script> <script src="/y/_docs/yy_alarm_ds2gt_final_full.js.php?v=1.19"></script> <script src="yyy_batch_files.js?v=1.2"></script> <script src="yyy_toggle_panel.js?v=1.0.3"></script> <link href="yyy__theme_style.css?v=2.2a" rel="stylesheet"> <link href="yyy_cmd_css.css?v=1.5" rel="stylesheet"> <script src="yy_zip_drop_to_apply.js?v=1.10"></script> </head> <body> <div class="container main-wrapper" > <div id="yy-toast-wrap"></div> <div id="yyyFindUrlFavWrap" data-yy-toggle-target="1" data-yy-toggle-scope="find" data-yy-toggle-key="urlfav" data-yy-toggle-label="์ฆ๊ฒจ์ฐพ๊ธฐ" data-yy-toggle-order="20"> <?php yyy_urlfav_render_top_menu(); ?> </div> <?php $req_bool = function($key) use ($R) { if (!isset($R[$key])) return false; $v = $R[$key]; return $v === '1' || $v === 1 || $v === 'on' || $v === 'true' || $v === 'checked'; }; $file_path = $R['file_path'] ?? ''; $view = $R['view'] ?? ''; $line = isset($R['line']) ? (int)$R['line'] : 0; $auto_edit = $R['auto_edit'] ?? ''; $ckAddFiles= $R['ckAddFiles']?? ''; $find = isset($R['seed']) ? $R['seed'] : ($R['find'] ?? ''); $replace_text = $R['replace_text'] ?? ''; $path_filter = $R['path'] ?? ''; $ext_filter = $R['ext'] ?? 'php'; $fileLike = $R['fileLike'] ?? ''; $eXn = $R['eXn'] ?? ''; $eXt = $R['eXt'] ?? ''; $arrHomeFiles = []; $word_mode = $R['w'] ?? ''; $Caps = $_REQUEST['caps'] ?? ''; $R['caps'] = $Caps; $ed = $R['ed'] ?? ''; $ed2 = $R['ed2'] ?? ''; $no_bak = $R['no_bak'] ?? ''; $rolback = $R['rolback'] ?? ''; $Diff = $R['Diff'] ?? ''; $debug = $_REQUEST['debug'] ?? ''; $dev = $R['dev'] ?? ''; $find2File = $R['find2File'] ?? ''; $mLen = isset($R['mLen']) ? (int)$R['mLen'] : 10; $cmd_mode = $R['cmd'] ?? ''; $is_multiline = (int)($R['is_multiline'] ?? 1); if ($is_multiline < 1) $is_multiline = 1; $exdir_raw = $R['exdir'] ?? ''; $exclude_dirs = array_values(array_filter(array_map('trim', explode(',', $exdir_raw)))); ?> <!-- script src="_docs/jcs/highlight.min.js?ver=v11.8.0"></script --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github-dark.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script> <script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script> <?php if (!isset($_REQUEST['mode'])) { ?> <style> a, a:hover, a:focus, a:visited { text-decoration:none; } .btn_edt{ .background:#28a745; padding:3px 8px; font-size:11px; white-space:nowrap; } .form-check-label { vertical-align:middle; padding-top:10px; } textarea.cmd-textarea{ resize:vertical; min-height:72px; font-family:Consolas, Monaco, 'Courier New', monospace; line-height:1.45; } #find{ min-height:96px; } #replace_text{ min-height:96px; width:100%; } .find-form .position-relative{ min-width:0; } .find-form .CodeMirror{ width:100% !important; min-width:0 !important; border:1px solid var(--bs-border-color, #ced4da); border-radius:.375rem; font-family:Consolas, Monaco, 'Courier New', monospace; font-size:13px; line-height:1.45; } .find-form .CodeMirror-focused{ outline:0; box-shadow:0 0 0 .2rem rgba(13,110,253,.15); } .find-form .CodeMirror-gutters{ border-right:1px solid rgba(128,128,128,.18); background:rgba(128,128,128,.06); } .find-form .CodeMirror-linenumber{ padding:0 8px 0 6px; } .find-form .CodeMirror-scroll{ min-height:96px; } .bulk-form textarea.form-control{ width:100%; } .match-line{ display:flex; align-items:center; gap:8px; flex-wrap:nowrap; } .match-line > a{ flex:0 0 auto; min-width:56px; } .match-line .edit-unit{ flex:1 1 auto; min-width:0; display:flex !important; align-items:center; gap:6px; margin-top:0 !important; } .match-line .edit-input{ flex:1 1 auto; min-width:0 !important; width:100%; } .match-line .btn{ flex:0 0 auto; } </style> <?php } ?> <?php if ($_SERVER['REQUEST_METHOD'] === 'POST' && $action) { if ($action === 'bulk_replace' && !empty($_POST['replace_text']) && !empty($_POST['search_term'])) { $find = isset($_POST['search_term']) ? $_POST['search_term'] : ''; $replace_text = isset($_POST['replace_text']) ? $_POST['replace_text'] : ''; $path_filter = isset($_POST['path_filter']) ? $_POST['path_filter'] : ''; $ext_filter = isset($_POST['ext_filter']) ? $_POST['ext_filter'] : 'php'; $no_bak = isset($_POST['no_bak']) ? $_POST['no_bak'] : 0; $eXn = isset($R['eXn']) ? $R['eXn'] : ''; $eXt = isset($R['eXt']) ? $R['eXt'] : ''; $is_multiline_post = (int)($_POST['is_multiline'] ?? 1); if ($is_multiline_post < 1) $is_multiline_post = 1; list($cmd, $file_list) = find_build_and_run(); if (!empty($debug)) { echo '<h3>' . htmlspecialchars($cmd) . '</h3>'; echo '<div style="color:#666">is_multiline=' . (int)$is_multiline_post . '</div>'; } $use_regex = false; $word_mode = !empty($word_mode); $max_bytes = 8 * 1024 * 1024; $success_count = 0; $backup_count = 0; $changed_files = 0; $pattern = null; $Capsi = $Caps ? "" : "i"; if ($is_multiline_post <= 1) { if ($use_regex) { $pattern = (preg_match('#^/.+/[imsxuADSUXJ]*$#', $find)) ? $find : '/' . str_replace('/', '\/', $find) . '/' . $Capsi; } else { if ($word_mode) { $pattern = $Caps ? '/\b' . preg_quote($find, '/') . '\b/' : '/\b' . preg_quote($find, '/') . '\b/i'; $use_regex = true; } } if ($debug) echo "pattern============$pattern<br>"; } if (!empty($file_list)) { foreach ($file_list as $file) { if (!$file || !is_file($file) || !is_readable($file) || !is_writable($file)) { continue; } $sz = @filesize($file); if ($max_bytes > 0 && $sz !== false && $sz > $max_bytes) { continue; } $content = @file_get_contents($file); if ($content === false || strpos($content, "\0") !== false) { continue; } $new_content = $content; $file_changes = 0; if ($is_multiline_post > 1) { $ret_m = yyy_bulk_replace_exact_multiline_content($content, $find, $replace_text, $Caps); $new_content = isset($ret_m['content']) ? $ret_m['content'] : $content; $file_changes = isset($ret_m['count']) ? (int)$ret_m['count'] : 0; if ($debug && $file_changes > 0) { echo '<div style="color:#0d6efd">MULTI HIT: ' . htmlspecialchars($file) . ' / ' . $file_changes . '๊ฑด</div>'; } } else { if ($use_regex && $pattern) { if (preg_match($pattern, $content)) { $new_content = preg_replace($pattern, $replace_text, $content, -1, $file_changes); } } else { if ($Caps) { if (strpos($content, $find) !== false) { $new_content = str_replace($find, $replace_text, $content, $file_changes); } } else { if (stripos($content, $find) !== false) { $new_content = str_ireplace($find, $replace_text, $content, $file_changes); } } } } if ($file_changes > 0 && $new_content !== $content) { if (empty($no_bak) && createBackup($file)) { $backup_count++; } if (@file_put_contents($file, $new_content) !== false) { $success_count += $file_changes; $changed_files++; } } } } echo '<div style="background:#d4edda; color:#155724; padding:10px; margin:10px 0; border-radius:5px;">'; echo 'โ ' . number_format($changed_files) . '๊ฐ ํ์ผ ์์ , ์ด ' . number_format($success_count) . '๊ฑด ์นํ ์๋ฃ' . ' (๋ฐฑ์ : ' . number_format($backup_count) . '๊ฐ)</div>'; } } ?> <!-- div class="container main-wrapper" ์์๋ก ์ด๋ --> <div id="yyyFindHeader" class="header-panel mb-3 d-flex flex-wrap align-items-center justify-content-between" data-yy-toggle-target="1" data-yy-toggle-scope="find" data-yy-toggle-key="header" data-yy-toggle-label="์๋จ" data-yy-toggle-order="10"> <div class="d-flex align-items-center gap-2 mb-2 mb-md-0"> <a href="<?= $_SERVER['PHP_SELF']; ?>" class="fw-bold text-decoration-none fs-5">๐ฅ ํ์ผ๊ฒ์</a> <span class="text-secondary small"> (<?= BASE_ROOT ?> ์ ์ฒด) </span> </div> <div class="icon-group d-flex align-items-center gap-2 flex-wrap"> <div class="btn btn-sm btn-outline-secondary" id="yy-alarm-icon-here">โฐ</div> <!-- // yyy-used-files-exclude:start --> <a href="yyy_view.php?view=<?= yyy_get_url_fav_json_path($host);?>" target="icon" class="btn btn-sm btn-outline-secondary" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-title="json์์ ">๐ ๏ธ</a> <a href="yyy_view.php?view=yyy_find.php" target="icon" class="btn btn-sm btn-outline-secondary" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-title="yyy์์ ">๐</a> <a href="yyy_cmd.php" class="btn btn-sm btn-outline-secondary" target="icon" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-title="๋ช ๋ น์คํ">๐ป </a> <a class="btn btn-sm btn-outline-secondary" href="yyy_zip_apply.php" target="yyy_zip_apply" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-title="ZIP ์์ถํ๊ธฐ <?=dirname(__FILE__);?>">Z</a> <button id="themeToggle" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-title="๋คํฌ๋ชจ๋ ํ ๊ธ" class="btn btn-sm btn-outline-secondary">๐</button> <a href="_docs/yyy_test_bs5_icon_view.php" target="icon" class="btn btn-sm btn-outline-secondary"> <i class="bi bi-grid-fill"></i> </a> <a href="_docs/deep_seek.php" target="icon" class="btn btn-sm btn-outline-secondary">๐</a> <a href="_docs/deep_seek_auto_fit_auto_fill.html" target="icon" class="btn btn-sm btn-outline-secondary"> <i class="bi bi-gear-fill"></i> </a> <!-- // yyy-used-files-exclude:end --> </div> </div> <div id="yy-alarm-timer-here" data-yy-toggle-target="1" data-yy-toggle-scope="find" data-yy-toggle-key="alarm" data-yy-toggle-label="์๋" data-yy-toggle-order="30" data-yy-toggle-default-hidden="1"></div> <div id="yyyFindTogglePanel" data-yy-toggle-panel="1" data-yy-toggle-scope="find" data-yy-toggle-storage="yyy_find_panes" data-yy-toggle-title="find ํ์:" data-yy-toggle-mini="1" data-yy-toggle-mini-default="1" data-yy-toggle-mini-storage="yyy_find_panes_panel_mini" data-yy-toggle-mini-title="find ํ์ ํจ๋ ์ด๊ธฐ"></div> <div class="find-form"> <form method="GET" class="find-form m-0"> <div id="yyyFindSearchRow" class="row g-2 mb-3 align-items-stretch" data-yy-toggle-target="1" data-yy-toggle-scope="find" data-yy-toggle-key="search" data-yy-toggle-label="๊ฒ์" data-yy-toggle-order="40"> <div class="col"> <div class="position-relative"> <i class="bi bi-search position-absolute top-50 start-0 translate-middle-y ms-3 text-secondary"></i> <textarea id="find" name="find" class="form-control ps-5 cmd-textarea w-100" placeholder="๊ฒ์ํ ๋ด์ฉ์ ์ ๋ ฅํ์ธ์ (์ฌ๋ฌ ์ค ๊ฐ๋ฅ)" onkeydown="handleEnter(event)"><?= htmlspecialchars($find) ?></textarea> </div> </div> <div class="col-auto d-flex align-items-stretch"> <input id="is_multiline" name="is_multiline" size="3" class="form-control form-control-sm text-center" style="width:56px;" value="<?= (int)max(1, (int)$is_multiline) ?>"> </div> <div class="col-6 col-lg-2"> <select name="ext" id="extSelect" class="form-select"> <option value="php" <?= $ext_filter=='php'?'selected':'' ?>>php</option> <option value="bak" <?= $ext_filter=='bak'?'selected':'' ?>>bak</option> <option value="py" <?= $ext_filter=='py'?'selected':'' ?>>py</option> <option value="js" <?= $ext_filter=='js'?'selected':'' ?>>js</option> <option value="ts" <?= $ext_filter=='ts'?'selected':'' ?>>ts</option> <option value="css" <?= $ext_filter=='css'?'selected':'' ?>>css</option> <option value="csv" <?= $ext_filter=='csv'?'selected':'' ?>>csv</option> <option value="html"<?= $ext_filter=='html'?'selected':'' ?>>html</option> <option value="conf"<?= $ext_filter=='conf'?'selected':'' ?>>conf</option> <option value="log" <?= $ext_filter=='log'?'selected':'' ?>>log</option> <option value="all" <?= $ext_filter=='all'?'selected':'' ?>>ALL</option> </select> </div> <div class="col-6 col-lg-2"> <button type="submit" class="btn btn-primary w-100"> ๊ฒ์ </button> </div> </div> <div id="yyyFindFilterRow" class="row g-2 mb-3" data-yy-toggle-target="1" data-yy-toggle-scope="find" data-yy-toggle-key="filter" data-yy-toggle-label="ํํฐ" data-yy-toggle-order="50"> <div class="col-12 col-md-4"> <input type="text" name="path" id="path_filter" value="<?= htmlspecialchars($path_filter) ?>" class="form-control" placeholder="path_filter"> </div> <div class="col-12 col-md-4"> <input type="text" name="fileLike" value="<?= htmlspecialchars($fileLike) ?>" class="form-control" placeholder="fileLike"> </div> <div class="col-12 col-md-4"> <input type="text" name="eXt" id="eXtInput" value="<?= htmlspecialchars($eXt) ?>" class="form-control" placeholder="์ ์ธ ํ์ฅ์ (bak,tmp)"> </div> </div> <div id="yyyFindExcludeRow" class="row g-2 mb-3" data-yy-toggle-target="1" data-yy-toggle-scope="find" data-yy-toggle-key="exclude" data-yy-toggle-label="์ ์ธ" data-yy-toggle-order="60"> <div class="col-12 col-md-6"> <input type="text" name="eXn" value="<?= htmlspecialchars($eXn) ?>" class="form-control" placeholder="์ ์ธ ํ์ผ๋ช (*.log)"> </div> <div class="col-12 col-md-6"> <input type="text" name="exdir" value="<?= htmlspecialchars($exdir_raw) ?>" class="form-control" placeholder="์ ์ธํด๋ (_trasy,node_modules,.git,_bak)"> </div> </div> <div id="yyyFindOptionRow" class="row g-3 align-items-center small" data-yy-toggle-target="1" data-yy-toggle-scope="find" data-yy-toggle-key="options" data-yy-toggle-label="์ต์ " data-yy-toggle-order="70"> <div class="col-auto form-check"> <label class="form-check-label"><input class="form-check-input" type="checkbox" name="Diff" value="checked" <?= $Diff ?>> Diff๋น๊ต</label> </div> <div class="col-auto form-check"> <label class="form-check-label text-primary"><input class="form-check-input" type="checkbox" name="dev" value="checked" <?= $dev ?>> dev๋น๊ต</label> </div> <div class="col-auto form-check"> <label class="form-check-label"><input class="form-check-input" type="checkbox" name="w" value="checked" <?= $word_mode ?>> ์๋ ๋จ์</label> </div> <div class="col-auto form-check"> <label class="form-check-label"><input class="form-check-input" type="checkbox" name="caps" value="checked" <?= $Caps; ?>> ๋์๋ฌธ์</label> </div> <div class="col-auto form-check"> <label class="form-check-label"><input class="form-check-input form-check-input is-invalid" type="checkbox" name="ed" value="checked" <?= $ed ?>> ์ผ๊ด์์ </label> </div> <div class="col-auto form-check"> <label class="form-check-label"><input class="form-check-input" type="checkbox" name="ed2" value="checked" <?= $ed2 ?>> ๊ฐ๋ณ์์ </label> </div> <div class="col-auto form-check"> <label class="form-check-label"><input class="form-check-input" type="checkbox" name="rolback" value="checked" <?= $rolback ?>> rolback</label> </div> <div class="col-auto form-check"> <label class="form-check-label"><input class="form-check-input" type="checkbox" name="no_bak" value="checked" <?= $no_bak ?>> ๋ฐฑ์ ์ํจ</label> </div> <div class="col-auto form-check"> <label class="form-check-label"><input class="form-check-input" type="checkbox" name="debug" value="1" <?= $debug?'checked':'' ?>> debug</label> </div> <div class="col-auto"> <input type="text" name="mLen" value="<?= $mLen ?>" size="3" class="form-control form-control-sm" placeholder="mLen"> </div> <div class="col-auto form-check"> <label class="form-check-label"><input class="form-check-input" type="checkbox" name="find2File" value="checked" <?= $find2File ?>> find2File</label> </div> </div> </form> </div> <div id="yyyFindResultArea" class="result-area mt-3" data-yy-toggle-target="1" data-yy-toggle-scope="find" data-yy-toggle-key="result" data-yy-toggle-label="๊ฒฐ๊ณผ" data-yy-toggle-order="100"> <?php include_once "yyy_rolback.php"; if ($find) { if ($debug) echo '<h2>๊ฒ์: ' . htmlspecialchars($find) . '</h2>'; if (!$find2File) list($cmd, $file_list) = find_build_and_run(); if ($debug) echo '<h3 style="word-break:break-all">'.htmlspecialchars($cmd).'</h3>'; $results_count = 0; $total_matches = 0; echo '<div id="sch_rst"></div>'; if ($ed) { echo '<div id="yyyFindBulkForm" class="bulk-form mt-3" data-yy-toggle-target="1" data-yy-toggle-scope="find" data-yy-toggle-key="bulk" data-yy-toggle-label="์ผ๊ด" data-yy-toggle-order="80">'; echo '<h4>๐ ์ผ๊ด์์ ๋ชจ๋</h4>'; echo '<form method="POST" class="d-flex align-items-stretch gap-2">'; echo '<input type="hidden" name="action" value="bulk_replace">'; echo '<input type="hidden" name="search_term" value="' . htmlspecialchars($find) . '">'; echo '<textarea name="search_term" style="display:none">' . htmlspecialchars($find) . '</textarea>'; echo '<input type="hidden" name="is_muxXltiline" value="' . (!empty($R['is_multiline']) ? '1' : '0') . '">'; echo '<input type="hidden" name="path_filter" value="' . htmlspecialchars($path_filter) . '">'; echo '<input type="hidden" name="ckAddFiles" value="' . ($ckAddFiles) . '">'; echo '<input type="hidden" name="ext_filter" value="' . htmlspecialchars($ext_filter) . '">'; echo '<input type="hidden" name="no_bak" value="' . $no_bak . '">'; echo '<input type="text" id="is_multiline_post" size="1" name="is_multiline" value="' . (int)max(1, (int)$is_multiline) . '" class="form-control form-control-sm flex-shrink-0 text-center" style="width:56px;">'; echo '<textarea name="replace_text" id="replace_text" placeholder="๋ฐ๊ฟ ๋ด์ฉ" class="form-control ps-3 cmd-textarea flex-grow-1" style="flex:1 1 auto; min-width:0; height:80px;" onkeydown="handleEnter(event)">' . htmlspecialchars($replace_text) . '</textarea>'; echo '<button type="submit" class="btn fw-bold flex-shrink-0" style="background:#ffc107; color:#000; width: 150px; border: none;"> ์ ์ฒด XX๊ฐ<br>์์ ์ ์ฉ </button>'; echo '</form>'; echo '</div>'; } $Caps = !empty($_REQUEST['caps']); $Capsi = $Caps ? "" : "i"; $file_list_cnt = 0; $file_list_cnt2 = 0; if (!empty($file_list)) { $file_list_cnt = count($file_list); $file_list_cnt2 = 0; foreach ($file_list as $file) { $file_list_cnt2++; $file = trim($file); if (!$file || !is_file($file) || !is_readable($file)) continue; if ($debug) echo "file=" . htmlspecialchars($file) . "<br>"; $is_multiline = (int)($_REQUEST['is_multiline'] ?? 1); if ($is_multiline < 1) $is_multiline = 1; if ($is_multiline > 1) { $ret = yyy_find_in_file_multiline($file, $find, $Caps, $word_mode); } else { $ret = yyy_find_in_file_singleline($file, $find, $Caps, $word_mode); } $lines = $ret['lines']; $found_lines = $ret['found_lines']; $pattern_regex1 = $ret['pattern_regex']; $tmp_found = []; foreach ($found_lines as $one_found) { $k1 = isset($one_found['num']) ? (int)$one_found['num'] : 0; $k2 = isset($one_found['num_end']) ? (int)$one_found['num_end'] : $k1; $tmp_found[$k1 . ':' . $k2] = $one_found; } $found_lines = array_values($tmp_found); $total_line_count = count($lines); if (empty($lines) && !is_file($file)) continue; if ($debug && $word_mode) { $pattern_regex1 = '/\b' . preg_quote($find, '/') . '\b/' . $Capsi . "<br>"; } if ($debug && $pattern_regex1) echo "pattern_regex1=$pattern_regex1"; $iSfOUfILE = !empty($found_lines); if ($iSfOUfILE && !$dev) { $results_count++; $total_matches += count($found_lines); $is_writable = is_writable($file); $permission_class = $is_writable ? 'editable-success' : 'editable-danger'; $permission_text = $is_writable ? 'โ ์์ ๊ฐ๋ฅ' : 'โ ์ฝ๊ธฐ์ ์ฉ'; echo '<div class="file-result">'; $first_line_num = $found_lines[0]['num'] ?? 1; $asFile = addslashes($file); echo '<label class="me-1" style="cursor:pointer;">'; echo '<input type="checkbox" class="cmp-file" value="' . htmlspecialchars($file, ENT_QUOTES) . '"> '; echo '</label>'; echo '<span class="file-path" onclick="copyToClipboard(\'' . $asFile . '\')">' . htmlspecialchars($file) . '</span>'; echo '<span class="badge bg-primary pointer" onclick="copyToClipboard(\'' . $asFile . '\')">๋ณต์ฌ</span>'; echo get_down_link($file); $web_url = get_web_url($file); $web_icon = $web_url ? ' <a href="'.$web_url.'" target="_blank" class="selct-none" title="์น์ผ๋ก ์ด๊ธฐ">๐</a> ' : ''; echo $web_icon; // yyy-used-files-exclude:start $A_href_yyy = '<a " target="_blank" href="yyy_view.php?view=' . $file; echo $A_href_yyy . '&line=' . $first_line_num . '" class="badge bg-danger">ํธ์ง</a>'; // yyy-used-files-exclude:end echo '<span style="margin-left:10px;font-size:12px;color:' . ($is_writable ? '#28a745' : '#dc3545') . '">' . $permission_text . '</span>'; $pattern_regex1 = ""; foreach (array_slice($found_lines, 0, 5) as $found_line) { $line_num = (int)$found_line['num']; $start = max(1, $line_num - $mLen); $end = min(count($lines), $line_num + $mLen); for ($i = $start; $i <= $end; $i++) { $line_content = $lines[$i - 1]; echo '<div class="match-line ' . $permission_class . '">'; echo $A_href_yyy . '&line=' . $i . '> <span class="line-num">' . $i . '</span></a> '; if ($i == $line_num) { if ($ed2 && $is_writable) { echo '<div class="edit-unit d-inline-flex gap-1 align-items-center mt-1" style="width:calc(100% - 0px);max-width:100%;vertical-align:middle">'; echo '<textarea type="text" name="new_content" style="flex:1 1 auto;min-width:240px" class="form-control form-control-sm edit-input ' . $permission_class . '">' . htmlspecialchars($line_content) . '</textarea>'; echo '<button type="button" class="btn text-nowrap btn-sm btn-success" onclick="ajaxSaveLine(this)" data-file="' . htmlspecialchars($file) . '" data-line="' . $found_line['num'] . '"> ๐พ ์์ </button></div>'; } else { if ($word_mode) { $pattern_highlight = '/\b(' . preg_quote($find, '/') . ')\b/' . $Capsi; $safe = htmlspecialchars($line_content); $highlighted = preg_replace($pattern_highlight, "<mark class='yy-hit'>$1</mark>", $safe); } else { $safe = htmlspecialchars($line_content); $pattern_highlight = '/' . preg_quote($find, '/') . '/' . $Capsi; $highlighted = preg_replace($pattern_highlight, "<mark class='yy-hit'>$0</mark>", $safe); } echo $highlighted; } } else { echo htmlspecialchars($line_content); } echo '</div>'; } } if ($debug && $pattern_regex1) echo "pattern_regex2=$pattern_regex1<br>"; if (count($found_lines) > 5) { echo '<div style="color:#666">... ' . (count($found_lines) - 5) . '๊ฐ ๋</div>'; } echo '</div>'; } else { if ($iSfOUfILE && $dev) $arrHomeFiles[] = $file; } } if ($results_count) { echo '<script>document.getElementById("sch_rst").innerHTML = "๊ฒฐ๊ณผ ' . $results_count . '๊ฐ '.$total_matches.' ๊ณณ์์ ๋ฐ๊ฒฌ '.$file_list_cnt2.' :Fc";</script>'; } else { echo '<script>document.getElementById("sch_rst").innerHTML = "๊ฒฐ๊ณผ ' . $results_count . '๊ฐ '.$file_list_cnt.' ๊ณณ์ ์์'.$file_list_cnt2.' :Fc";</script>'; } echo '<p style="color:#28a745"><strong>' . $results_count . '๊ฐ ํ์ผ ๋ฐ๊ฒฌ</strong></p>'; if ($dev) print_arrHomeFiles($arrHomeFiles, $mLen); if ($ed) { echo '<script>document.querySelector(".bulk-form button").innerHTML = "์ ์ฒด ' . $total_matches . '๊ฐ<br> ์์ ์ ์ฉ";</script>'; } } else { if (!$find2File) echo '<p style="color:#dc3545"><strong>๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์์ต๋๋ค.</strong></p>'; } } else { echo '<p style="color:#28a745"><strong>find ๊ฒ์์ด๋ฅผ ์ ๋ ฅํ์ธ์!</strong></p>'; } if ($find2File) require_once 'yyy_find2file.php'; ?> <script> let yyFindCM = null; function yyIsDarkTheme() { return document.documentElement.getAttribute('data-bs-theme') === 'dark'; } function yyCountLines(text) { const v = String(text == null ? '' : text).replace(/\r\n/g, '\n').replace(/\r/g, '\n'); if (v === '') return 1; return (v.match(/\n/g) || []).length + 1; } function yyGetFindText() { if (yyFindCM) return yyFindCM.getValue(); const el = document.getElementById('find'); return el ? el.value : ''; } function yyGetReplaceText() { const el = document.getElementById('replace_text'); return el ? el.value : ''; } function yyUpdateMultiLineFlag() { const inputs = document.querySelectorAll('input[name="is_multiline"]'); if (!inputs.length) return; const findLines = yyCountLines(yyGetFindText()); const maxLines = Math.max(findLines, 1); inputs.forEach(function(el) { el.value = maxLines; }); } function yyAutoResizePlainTextarea(el, minPx, maxPx) { if (!el) return; el.style.height = 'auto'; const nextH = Math.max(minPx, Math.min(el.scrollHeight + 2, maxPx)); el.style.height = nextH + 'px'; } function yyFitFindEditorHeight() { if (!yyFindCM) return; const lineCount = Math.max(1, yyFindCM.lineCount()); const lineHeight = (typeof yyFindCM.defaultTextHeight === 'function') ? yyFindCM.defaultTextHeight() : 20; let h = (lineCount * lineHeight) + 12; const minPx = 96; const maxPx = Math.max(220, Math.floor(window.innerHeight * 0.42)); if (h < minPx) h = minPx; if (h > maxPx) h = maxPx; yyFindCM.setSize('100%', h + 'px'); } function yySubmitClosestForm(textarea) { const form = textarea ? textarea.closest('form') : null; if (form) form.submit(); } function yyCmModeByExt(ext) { ext = String(ext || '').toLowerCase(); if (ext === 'php' || ext === 'bak') return 'application/x-httpd-php'; if (ext === 'html' || ext === 'htm') return 'htmlmixed'; if (ext === 'xml') return 'xml'; if (ext === 'js') return 'javascript'; if (ext === 'ts') return 'text/typescript'; if (ext === 'css') return 'css'; if (ext === 'sql') return 'sql'; if (ext === 'py') return 'python'; if (ext === 'conf') return 'shell'; if (ext === 'csv') return 'shell'; if (ext === 'json') return 'application/json'; if (ext === 'yaml' || ext === 'yml') return 'yaml'; if (ext === 'md') return 'markdown'; if (ext === 'ini' || ext === 'properties') return 'properties'; return 'text/plain'; } function yyApplyFindTheme() { if (!yyFindCM) return; yyFindCM.setOption('theme', yyIsDarkTheme() ? 'dracula' : 'default'); yyFindCM.refresh(); } function yyApplyFindMode() { if (!yyFindCM) return; const extEl = document.getElementById('extSelect'); yyFindCM.setOption('mode', yyCmModeByExt(extEl ? extEl.value : '')); yyFindCM.refresh(); } function yyInitFindCodeMirror() { const ta = document.getElementById('find'); if (!ta || typeof CodeMirror === 'undefined') return null; yyFindCM = CodeMirror.fromTextArea(ta, { lineNumbers: true, mode: yyCmModeByExt(document.getElementById('extSelect') ? document.getElementById('extSelect').value : ''), theme: yyIsDarkTheme() ? 'dracula' : 'default', indentUnit: 4, indentWithTabs: false, lineWrapping: false, matchBrackets: true, autoCloseBrackets: true, viewportMargin: Infinity, extraKeys: { "Enter": function() { yySubmitClosestForm(ta); }, "Shift-Enter": function(cm) { cm.replaceSelection("\n", "end"); }, "Ctrl-Enter": function() { yySubmitClosestForm(ta); }, "Cmd-Enter": function() { yySubmitClosestForm(ta); } } }); const wrap = yyFindCM.getWrapperElement(); wrap.style.width = '100%'; wrap.style.minWidth = '0'; wrap.style.flex = '1 1 auto'; yyFindCM.on('change', function() { ta.value = yyFindCM.getValue(); yyUpdateMultiLineFlag(); yyFitFindEditorHeight(); }); setTimeout(function() { yyApplyFindTheme(); yyApplyFindMode(); yyFitFindEditorHeight(); yyUpdateMultiLineFlag(); }, 0); return yyFindCM; } (function yyBindThemeHook(){ try { const moBody = new MutationObserver(function() { yyApplyFindTheme(); }); moBody.observe(document.body, { attributes:true, attributeFilter:['class'] }); const moHtml = new MutationObserver(function() { yyApplyFindTheme(); }); moHtml.observe(document.documentElement, { attributes:true, attributeFilter:['data-bs-theme'] }); } catch(e) {} })(); document.addEventListener('DOMContentLoaded', function() { const findElement = document.getElementById('find'); const replaceElement = document.getElementById('replace_text'); const extSelect = document.getElementById('extSelect'); const pathInput = document.getElementById('path_filter'); yyInitFindCodeMirror(); if (findElement && !yyFindCM) { findElement.addEventListener('input', function() { yyUpdateMultiLineFlag(); yyAutoResizePlainTextarea(this, 96, Math.max(220, Math.floor(window.innerHeight * 0.42))); }); yyAutoResizePlainTextarea(findElement, 96, Math.max(220, Math.floor(window.innerHeight * 0.42))); } if (replaceElement) { replaceElement.addEventListener('input', function() { yyUpdateMultiLineFlag(); yyAutoResizePlainTextarea(this, 96, Math.max(220, Math.floor(window.innerHeight * 0.38))); }); yyAutoResizePlainTextarea(replaceElement, 96, Math.max(220, Math.floor(window.innerHeight * 0.38))); } yyUpdateMultiLineFlag(); function updatePath() { if (extSelect && pathInput && extSelect.value === "bak") { pathInput.value = "<?=BACKUP_ROOT?>"; } } updatePath(); if (extSelect) { extSelect.addEventListener("change", function() { updatePath(); yyApplyFindMode(); }); } }); window.addEventListener('resize', function() { if (yyFindCM) yyFitFindEditorHeight(); }); document.addEventListener('submit', function() { if (yyFindCM) { const taFind = document.getElementById('find'); if (taFind) taFind.value = yyFindCM.getValue(); } yyUpdateMultiLineFlag(); }); function handleEnter(e) { const id = e.target && e.target.id ? e.target.id : ''; if (id === 'find' && e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); const form = e.target.closest('form'); if (form) form.submit(); } } // hljs ์ด๊ธฐํ hljs.highlightAll(); // ALL ์ ํ์ ์๋ ์ ๋ ฅ ๊ธฐ๋ฅ document.addEventListener("DOMContentLoaded", function() { const extSelect = document.getElementById("extSelect"); const eXtInput = document.getElementById("eXtInput"); if (extSelect && eXtInput) { if (extSelect.options[extSelect.selectedIndex].value === "all") { if (!eXtInput.value) eXtInput.value = "zip,jpg,png,gif,pdf,mp4,avi,exe,dll,xlsx,xls"; } extSelect.addEventListener("change", function() { if (this.value === "all") { if (!eXtInput.value) eXtInput.value = "zip,jpg,png,gif,pdf,mp4,avi,exe,dll,xlsx,xls"; } }); } }); document.addEventListener("DOMContentLoaded", function() { if (typeof PR !== "undefined") { PR.prettyPrint(); } }); function ajaxSaveLine(btn) { console.log("--- [1] ajaxSaveLine ํธ์ถ๋จ ---"); console.log("ํด๋ฆญ๋ ๋ฒํผ ๊ฐ์ฒด:", btn); const unit = btn.closest('.edit-unit'); if (!unit) { console.error("โ ์๋ฌ: '.edit-unit' ๋ถ๋ชจ ์์๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค. HTML ๊ตฌ์กฐ๋ฅผ ํ์ธํ์ธ์."); return; } const input = unit.querySelector('.edit-input'); const targetFile = btn.getAttribute('data-file'); const targetLine = btn.getAttribute('data-line'); const newContent = input ? input.value : null; console.log("--- [2] ์ถ์ถ๋ ๋ฐ์ดํฐ ---"); console.log("- ํ์ผ:", targetFile); console.log("- ๋ผ์ธ:", targetLine); console.log("- ๋ด์ฉ:", newContent); if (!targetFile || !targetLine) { console.error("โ ์๋ฌ: data-file ๋๋ data-line ์์ฑ์ด ๋น์ด์์ต๋๋ค."); return; } const fd = new FormData(); fd.append('action', 'single_replace'); fd.append('target_file', targetFile); fd.append('target_line', targetLine); fd.append('new_content', newContent); const noBak = document.querySelector('input[name="no_bak"]')?.checked ? '1' : '0'; fd.append('no_bak', noBak); console.log("- ๋ฐฑ์ ์ํจ(no_bak) ์ฌ๋ถ:", noBak); console.log("--- [3] ์๋ฒ๋ก ์ ์ก ์์ (fetch) ---"); fetch(window.location.href, { method: 'POST', body: fd }) .then(res => { console.log("- ์๋ต ์ํ(HTTP Status):", res.status); return res.text(); }) .then(data => { console.log("--- [4] ์๋ฒ ์๋ต ๋ณธ๋ฌธ ---"); console.log(data); const msg = (data || '').trim(); if (msg.includes("โ ")) { console.log("โ ๊ฒฐ๊ณผ: ์ฑ๊ณต!"); if (typeof showToast === 'function') showToast(msg, "success"); else alert(msg); if (input) { input.style.transition = 'background-color .25s ease'; input.style.backgroundColor = "#1e3a2f"; setTimeout(() => { input.style.backgroundColor = ""; }, 1000); } } else { console.warn("โ ๏ธ ๊ฒฐ๊ณผ: ์คํจ ํน์ ํ์ ๋ถ์ผ์น"); if (typeof showToast === 'function') showToast(msg || "์ ์ฅ ์คํจ", "error"); else alert(msg || "์ ์ฅ ์คํจ"); } }) .catch(err => { console.error("โ [5] ํต์ ์์ฒด ์คํจ:", err); if (typeof showToast === 'function') showToast("ํต์ ์ค๋ฅ ๋ฐ์", "error"); else alert("ํต์ ์ค๋ฅ ๋ฐ์"); }); } </script> <?php // Display current time (unchanged) echo '<span class="badge badge-outline secondary"> ์๊ฐ: ' . date("Y-m-d H:i:s") . '</span>'; // Display label for allowed IPs echo ' <span class="badge badge-soft secondary">์ ๊ทผ๊ฐ๋ฅ IP:</span> '; // Loop through allowed IPs and apply conditional border foreach ($allowed_ips as $ip) { $border_class = ($ip === $_SERVER['REMOTE_ADDR']) ? 'primary' : 'secondary'; echo '<span class="badge badge-outline ' . $border_class . '">' . $ip . '</span> '; } ?> <script> // GET ๊ฒ์ํผ์ด ๋๋ฌด ๊ธธ๋ฉด ์๋์ผ๋ก POST๋ก ์ ํ document.addEventListener('submit', function(e){ var form = e.target; if (!form || !form.tagName || form.tagName.toUpperCase() !== 'FORM') return; var method = (form.getAttribute('method') || 'GET').toUpperCase(); if (method !== 'GET') return; if (!form.querySelector('[name="find"]')) return; var actionEl = form.querySelector('input[name="action"]'); var actionVal = actionEl ? actionEl.value : ''; if (actionVal === 'single_replace' || actionVal === 'single_replace_block') return; var fd = new FormData(form); var qs = new URLSearchParams(fd).toString(); var MAX_GET_LEN = 1800; if (qs.length <= MAX_GET_LEN) return; e.preventDefault(); e.stopImmediatePropagation(); var postForm = document.createElement('form'); postForm.method = 'POST'; postForm.action = form.getAttribute('action') || window.location.pathname; postForm.style.display = 'none'; var target = form.getAttribute('target'); if (target) postForm.setAttribute('target', target); fd.forEach(function(value, key){ var input = document.createElement('input'); input.type = 'hidden'; input.name = key; input.value = value; postForm.appendChild(input); }); var autoPost = document.createElement('input'); autoPost.type = 'hidden'; autoPost.name = 'auto_post'; autoPost.value = '1'; postForm.appendChild(autoPost); document.body.appendChild(postForm); console.log('๐ฎ GET ๊ธธ์ด ์ด๊ณผ โ POST๋ก ์๋ ์ ํ', qs.length); postForm.submit(); }, true); </script> <?php include "yyy_foot.php"; ?> <script src="yy__theme.js?v=1.3"></script> <script src="_docs/yy_alarm_ds2gt_final_fulld.js.php?v=1.22"></script> <script src="yy_drag_resize.js?v=1.5"></script> </div> </body> </html>
โจyyy_find.php
45,922 bytes
::
php
Y:0px 0%
X:0px 0%
Split:--
Line:1
A0
Aโ
A+
Lh0
Lhโ
Lh+
pre+
ฦ ํจ์ / ํด๋์ค ๋ชฉ๋ก
โ
๐พ
Aa
.*
bF
1
๐
๐
๊ฒ์์ด๋ฅผ ๋จผ์ ์ ๋ ฅํ์ธ์.
1
At
์ ์ฒด์ ์ฉ
๋ค์์ฐพ๊ธฐ
1๊ฐ์ ์ฉ
-----------