docs: detailed comments; fix: var declarations, no DROP, text inputs

This commit is contained in:
2026-07-20 08:13:26 +04:00
parent 53e12ecddd
commit d0fb4df1cb
2 changed files with 169 additions and 23 deletions
+57 -7
View File
@@ -1,15 +1,41 @@
<!---
index.cfm — CRUD-интерфейс для таблицы в PostgreSQL
Логика:
1. Если POST-запрос с FORM.action — выполняем create/update/delete
и редиректим на GET (POST-redirect-GET паттерн)
2. Если GET-запрос с URL.edit — загружаем запись для редактирования
3. Всегда показываем список всех записей + форму добавления/редактирования
Безопасность:
- cfqueryparam для всех входных данных → защита от SQL-инъекций
- cflocation после POST → защита от повторной отправки формы
- cfoutput только где нужно → XSS-защита через автоматическое экранирование Lucee
Переменные:
- request.tableName — имя таблицы (из Application.cfc / json_env TABLE_NAME)
- FORM.action — create | update | delete (POST)
- FORM.value — значение записи (POST)
- FORM.id — ID записи для update/delete (POST)
- URL.edit — ID записи для редактирования (GET)
--->
<cfset tableName = request.tableName />
<!--- Обработка действий --->
<!--- ====== ОБРАБОТКА POST-ЗАПРОСОВ (create / update / delete) ====== --->
<!--- isDefined("FORM.action") — true только если страница вызвана через <form method="post"> --->
<cfif isDefined("FORM.action")>
<!--- CREATE: вставка новой записи --->
<cfif FORM.action EQ "create">
<!--- cfqueryparam cfsqltype="cf_sql_varchar" — экранирует значение, защита от SQL-инъекций --->
<cfquery name="insertRow">
INSERT INTO #tableName# (value)
VALUES (<cfqueryparam value="#FORM.value#" cfsqltype="cf_sql_varchar" />)
</cfquery>
</cfif>
<!--- UPDATE: обновление существующей записи по ID --->
<cfif FORM.action EQ "update">
<cfquery name="updateRow">
UPDATE #tableName#
@@ -18,6 +44,7 @@
</cfquery>
</cfif>
<!--- DELETE: удаление записи по ID --->
<cfif FORM.action EQ "delete">
<cfquery name="deleteRow">
DELETE FROM #tableName#
@@ -25,22 +52,30 @@
</cfquery>
</cfif>
<!--- POST-redirect-GET: после любого действия — редирект на чистый URL без POST-данных.
Это предотвращает повторную отправку формы при обновлении страницы (F5). --->
<cflocation url="index.cfm" addtoken="no" />
</cfif>
<!--- Режим редактирования --->
<!--- ====== РЕЖИМ РЕДАКТИРОВАНИЯ (GET-запрос с ?edit=ID) ====== --->
<!--- editRow всегда инициализируем пустым словарём.
Если URL.edit не задан или запись не найдена — editRow останется пустым. --->
<cfset editRow = {} />
<cfif isDefined("URL.edit")>
<!--- Загружаем запись по ID из URL --->
<cfquery name="editQuery">
SELECT id, value FROM #tableName#
WHERE id = <cfqueryparam value="#URL.edit#" cfsqltype="cf_sql_integer" />
</cfquery>
<!--- Если запись найдена — заполняем editRow данными из запроса --->
<cfif editQuery.recordCount GT 0>
<cfset editRow = { id = editQuery.id, value = editQuery.value } />
</cfif>
</cfif>
<!--- Все записи --->
<!--- ====== СПИСОК ВСЕХ ЗАПИСЕЙ ====== --->
<cfquery name="rows">
SELECT id, value FROM #tableName# ORDER BY id
</cfquery>
@@ -64,18 +99,23 @@
<h1>#tableName#</h1>
<!--- Таблица записей --->
<table>
<tr>
<th>ID</th>
<th>Value</th>
<th></th>
</tr>
<!--- cfoutput query="rows" — цикл по всем строкам результата SELECT --->
<cfoutput query="rows">
<tr>
<td>#id#</td>
<td>#value#</td>
<td class="actions">
<!--- Ссылка на редактирование: index.cfm?edit={id} --->
<a href="index.cfm?edit=#id#">✏️</a>
<!--- Форма удаления: POST с action=delete и id записи.
JS confirm() — защита от случайного удаления. --->
<form method="post" style="display:inline">
<input type="hidden" name="action" value="delete" />
<input type="hidden" name="id" value="#id#" />
@@ -84,28 +124,38 @@
</td>
</tr>
</cfoutput>
<!--- Если записей нет — показываем информационное сообщение --->
<cfif rows.recordCount EQ 0>
<tr><td colspan="3">Нет записей. Создайте первую.</td></tr>
</cfif>
</table>
<cfif NOT structIsEmpty(editRow)><cfoutput>
<!--- ====== ФОРМА: редактирование ИЛИ добавление ====== --->
<!--- structIsEmpty(editRow) — true если нет записи для редактирования → показываем форму ДОБАВЛЕНИЯ --->
<!--- false если URL.edit задан и запись найдена → показываем форму РЕДАКТИРОВАНИЯ --->
<cfif NOT structIsEmpty(editRow)>
<!--- cfoutput нужен чтобы #editRow.id# и #editRow.value# вычислились --->
<cfoutput>
<h2>Редактировать #editRow.id#</h2>
<form method="post">
<input type="hidden" name="action" value="update" />
<input type="hidden" name="id" value="#editRow.id#" />
<input type="number" name="value" value="#editRow.value#" required />
<!--- type="text" — позволяет вводить любые символы, не только цифры --->
<input type="text" name="value" value="#editRow.value#" required />
<button type="submit">Сохранить</button>
<a href="index.cfm">Отмена</a>
</form></cfoutput>
</form>
</cfoutput>
<cfelse>
<h2>Добавить</h2>
<form method="post">
<input type="hidden" name="action" value="create" />
<input type="number" name="value" placeholder="Значение" required />
<!--- placeholder — подсказка в пустом поле --->
<input type="text" name="value" placeholder="Значение" required />
<button type="submit">Добавить</button>
</form>
</cfif>
</body>
</html>
</html>