Files
FamilyBook/templates/tasks/_edit_form.php
T

130 lines
6.3 KiB
PHP
Raw Normal View History

<?php
/**
* 🔴 v43(用户 2026-10-11 第 6 条)—— 任务的「编辑」表单,**独立一份**。
*
* 为什么要独立出来:
* 原来它内联在 `tasks/show.php` 的 `<details>` 里。而条目详情浮层点「编辑」时,
* 需要**单独取这份表单**(`tasks/edit?embed=1`)—— 不可能去详情页里抠。
* 抽成一份后,详情页与浮层用的是**同一张表单**,不会出现"两处字段不一致"。
*
* ⚠️ 字段名 / 服务端契约与原来**一字未改**(tasks/update 收的就是这些)。
* ⚠️ 「状态」不在这里改:状态由专门的 `tasks/status` 路由管(它还要处理循环任务),
* 文案里也说明了这一点(与 v24 第 14 批的口径一致)。
*
* 🔴🔴 **本片段一律用带前缀的局部变量(`$tk*`),绝不碰入参的名字。**
* 第一版写的是 `$t = is_array($t ?? null) ? $t : [];` —— 看似无害,其实是在
* **覆盖宿主模板的 `$t`**(那是"这条任务"本身)。只读一次没问题,
* 但下一个人只要把某个 `$tk*` 改回 `$t`(很自然)就会让详情页后半段的
* `$t['children']` / 评论区全是 null —— **而且是静默的**。
* 项目的"片段体检"(`_fb_frag_guard`)当场抓到了这处裸赋值,是对的。
* ⇒ 入参先**收进 `$tkT`**,后面全用它。
*
* 用法(include 前设好):
* $t 任务(Task::find 的形状)
* $people 名册
* $parents 可选父任务候选
* $categories / $boards 分类与看板
* $tkEditEmbed 是否"浮层形态"(true = 不输出自己的「保存」,由浮层底栏给)
*/
$tkT = is_array($t ?? null) ? $t : [];
$tkPeople = (array)($people ?? []);
$tkParents = (array)($parents ?? []);
$tkCats = (array)($categories ?? []);
$tkBoards = (array)($boards ?? []);
$tkEmbed = !empty($tkEditEmbed);
?>
<form method="post" action="<?= e(url('tasks/update')) ?>" class="node-form" id="tkEditForm">
<?= csrf_field() ?>
<input type="hidden" name="id" value="<?= (int)($tkT['id'] ?? 0) ?>">
<div class="nf-grid">
<div class="field full">
<label for="tk-title">标题</label>
<input class="input" id="tk-title" name="title" required value="<?= e((string)($tkT['title'] ?? '')) ?>">
</div>
<div class="field">
<label>截止时间(留空=不上日历)</label>
<?php $dtName = 'due_at'; $dtValue = $tkT['due_at'] ?? null;
$dtRequired = false;
require __DIR__ . '/../_datetime.php'; ?>
</div>
<div class="field">
<label>负责人</label>
<?php /* 第 8 条同一诉求:负责人也是「选人」,人多时用弹窗 + 首字母更快。
保留原下拉的「不指定」(pp-item-none + value=0)。 */ ?>
<?php
$ppName = 'assignee_id';
$ppPeople = $tkPeople;
$ppSelected = [(int)($tkT['assignee_id'] ?? 0)];
$ppMode = 'single';
$ppOpenBtn = '更换负责人';
$ppTitle = '谁负责这件事';
$ppEmptyText = '不指定';
$ppAllowEmpty = true;
require __DIR__ . '/../_person_picker.php';
?>
</div>
<div class="field">
<label>循环</label>
<select class="select" name="repeat_rule">
<?php foreach (\App\Task::REPEAT as $rk => $rv): ?>
<option value="<?= e($rk) ?>"<?= (string)($tkT['repeat_rule'] ?? '') === (string)$rk ? ' selected' : '' ?>>
<?= e($rv) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="field">
<label>挂到哪个父任务下</label>
<select class="select" name="parent_id">
<option value="0">(这是一项独立的任务)</option>
<?php foreach ($tkParents as $p): ?>
<option value="<?= (int)$p['id'] ?>"<?= (int)($tkT['parent_id'] ?? 0) === (int)$p['id'] ? ' selected' : '' ?>>
<?= e((string)$p['title']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<?php /* v24 第 9、10 条:分类与看板(看板把任务放到哪一块,分类是标签) */ ?>
<div class="field">
<label>分类</label>
<select class="select" name="category_id">
<option value="0">未分类</option>
<?php foreach ($tkCats as $c): ?>
<option value="<?= (int)$c['id'] ?>"<?= (int)($tkT['category_id'] ?? 0) === (int)$c['id'] ? ' selected' : '' ?>>
<?= e((string)$c['name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="field">
<label>看板</label>
<select class="select" name="board_id">
<?php foreach ($tkBoards as $b): ?>
<option value="<?= (int)$b['id'] ?>"<?= (int)($tkT['board_id'] ?? 0) === (int)$b['id'] ? ' selected' : '' ?>>
<?= e((string)$b['name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="field full">
<label for="tk-note">备注</label>
<textarea class="input" id="tk-note" name="note" rows="3"><?= e((string)($tkT['note'] ?? '')) ?></textarea>
</div>
</div>
<?php /* ⚠️ 「状态」不在这里改(由 tasks/status 路由管,它还要处理循环任务)。
浮层形态下由它的底栏给「保存」;整页详情页里带自己的按钮。 */ ?>
<?php if (!$tkEmbed): ?>
<div class="btn-row"><button class="btn btn-sm" type="submit">保存</button></div>
<?php endif; ?>
</form>
<?php /* 🔴🔴 —— **千万不要 unset 入参变量**!
这几种是宿主模板的"大局变量"(`$t` = 这条任务、`$people` = 名册…),
include 之后宿主还要继续用它们(`$t['children']`、评论、子任务…)。
我第一版照抄了 `_datetime.php` 那种"用完即清"的写法,把 `$t` 一并 unset ——
结果 `tasks/show.php` 后半段全部拿不到 `$t`,**子任务列表与评论区静默消失**
(e2e 当场抓到 2 条:子任务没了、@高亮没了)。
⇒ 这里只清**本片段自己造的**临时变量(`$tk*` 与 `$dt*` / `$pp*` 那几组)。 */
unset($tkT, $tkPeople, $tkParents, $tkCats, $tkBoards, $tkEmbed,
$dtName, $dtValue, $dtRequired,
$ppName, $ppPeople, $ppSelected, $ppMode, $ppOpenBtn, $ppTitle,
$ppEmptyText, $ppAllowEmpty); ?>