262 lines
7.7 KiB
PHP
262 lines
7.7 KiB
PHP
<?php
|
|
/**
|
|
* 招新“学期”数据层:把原本单一的 itstudio_join_settings 配置扩展为可存档的多学期集合。
|
|
*
|
|
* 存储:
|
|
* option itstudio_join_terms —— array,键为学期 id,值为 { id, academic_year, season, label, created, settings }
|
|
* option itstudio_join_active_term_id —— string,当前生效学期的 id
|
|
* option itstudio_join_terms_migrated —— 迁移完成标记
|
|
*
|
|
* 兼容:旧的 itstudio_join_settings 选项保留,作为迁移来源与兜底。
|
|
* 迁移铁律沿用:各字段/选项标识不变,老数据不丢。
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* 可选的季节及其中文名。
|
|
*/
|
|
function itstudio_join_get_seasons() {
|
|
return array(
|
|
'fall' => '秋季',
|
|
'spring' => '春季',
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 读取全部学期(id => term 的关联数组)。
|
|
*/
|
|
function itstudio_join_get_terms() {
|
|
$terms = get_option('itstudio_join_terms', array());
|
|
return is_array($terms) ? $terms : array();
|
|
}
|
|
|
|
/**
|
|
* 当前生效学期 id。
|
|
*/
|
|
function itstudio_join_get_active_term_id() {
|
|
$id = (string) get_option('itstudio_join_active_term_id', '');
|
|
if ($id !== '') {
|
|
$terms = itstudio_join_get_terms();
|
|
if (isset($terms[$id])) {
|
|
return $id;
|
|
}
|
|
}
|
|
|
|
// 生效指针失效时,回退到第一个存在的学期。
|
|
$terms = itstudio_join_get_terms();
|
|
if (!empty($terms)) {
|
|
return (string) array_key_first($terms);
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* 取单个学期结构(不存在返回 null)。
|
|
*/
|
|
function itstudio_join_get_term($term_id) {
|
|
$term_id = (string) $term_id;
|
|
$terms = itstudio_join_get_terms();
|
|
return isset($terms[$term_id]) ? $terms[$term_id] : null;
|
|
}
|
|
|
|
/**
|
|
* 学期的展示名:优先自定义 label,否则“学年 + 季节招新”。
|
|
*/
|
|
function itstudio_join_term_label($term) {
|
|
if (!is_array($term)) {
|
|
return '';
|
|
}
|
|
|
|
$custom = trim((string) ($term['label'] ?? ''));
|
|
if ($custom !== '') {
|
|
return $custom;
|
|
}
|
|
|
|
$seasons = itstudio_join_get_seasons();
|
|
$season_cn = $seasons[$term['season'] ?? ''] ?? '';
|
|
$year = trim((string) ($term['academic_year'] ?? ''));
|
|
$label = trim($year . ' ' . $season_cn . '招新');
|
|
return $label !== '招新' ? $label : '未命名招新期';
|
|
}
|
|
|
|
/**
|
|
* 由学年 + 季节生成稳定且唯一的学期 id(冲突时追加 -2、-3…)。
|
|
*/
|
|
function itstudio_join_make_term_id($academic_year, $season, array $existing = array()) {
|
|
$base = sanitize_title($academic_year . '-' . $season);
|
|
if ($base === '') {
|
|
$base = 'term';
|
|
}
|
|
|
|
$id = $base;
|
|
$suffix = 2;
|
|
while (isset($existing[$id])) {
|
|
$id = $base . '-' . $suffix;
|
|
$suffix++;
|
|
}
|
|
|
|
return $id;
|
|
}
|
|
|
|
/**
|
|
* 新建学期。$settings 省略时用默认空配置。返回新学期 id。
|
|
*/
|
|
function itstudio_join_create_term($academic_year, $season, $label = '', $settings = null) {
|
|
$terms = itstudio_join_get_terms();
|
|
|
|
$season = array_key_exists($season, itstudio_join_get_seasons()) ? $season : 'fall';
|
|
$academic_year = itstudio_join_sanitize_shortcode_value($academic_year);
|
|
$label = itstudio_join_sanitize_shortcode_value($label);
|
|
|
|
$id = itstudio_join_make_term_id($academic_year, $season, $terms);
|
|
|
|
$terms[$id] = array(
|
|
'id' => $id,
|
|
'academic_year' => $academic_year,
|
|
'season' => $season,
|
|
'label' => $label,
|
|
'created' => current_time('mysql'),
|
|
'settings' => is_array($settings)
|
|
? itstudio_join_sanitize_settings($settings)
|
|
: itstudio_join_get_default_settings(),
|
|
);
|
|
|
|
update_option('itstudio_join_terms', $terms);
|
|
|
|
// 若尚无“显式”生效学期(读原始选项,不走会兜底的 getter),新建的即为生效。
|
|
$active_raw = (string) get_option('itstudio_join_active_term_id', '');
|
|
if ($active_raw === '' || !isset($terms[$active_raw])) {
|
|
itstudio_join_set_active_term($id);
|
|
}
|
|
|
|
return $id;
|
|
}
|
|
|
|
/**
|
|
* 更新某学期的元信息(学年/季节/自定义名)。
|
|
*/
|
|
function itstudio_join_update_term_meta($term_id, $academic_year, $season, $label = '') {
|
|
$terms = itstudio_join_get_terms();
|
|
$term_id = (string) $term_id;
|
|
if (!isset($terms[$term_id])) {
|
|
return false;
|
|
}
|
|
|
|
$terms[$term_id]['academic_year'] = itstudio_join_sanitize_shortcode_value($academic_year);
|
|
$terms[$term_id]['season'] = array_key_exists($season, itstudio_join_get_seasons()) ? $season : 'fall';
|
|
$terms[$term_id]['label'] = itstudio_join_sanitize_shortcode_value($label);
|
|
|
|
update_option('itstudio_join_terms', $terms);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 把一份配置写入指定学期。
|
|
*/
|
|
function itstudio_join_save_term_settings($term_id, $raw_settings) {
|
|
$terms = itstudio_join_get_terms();
|
|
$term_id = (string) $term_id;
|
|
if (!isset($terms[$term_id])) {
|
|
return false;
|
|
}
|
|
|
|
$terms[$term_id]['settings'] = itstudio_join_sanitize_settings($raw_settings);
|
|
update_option('itstudio_join_terms', $terms);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 设为当前生效学期。
|
|
*/
|
|
function itstudio_join_set_active_term($term_id) {
|
|
$term_id = (string) $term_id;
|
|
$terms = itstudio_join_get_terms();
|
|
if (!isset($terms[$term_id])) {
|
|
return false;
|
|
}
|
|
|
|
update_option('itstudio_join_active_term_id', $term_id);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 删除学期。不允许删“当前生效”或最后一个。
|
|
*/
|
|
function itstudio_join_delete_term($term_id) {
|
|
$term_id = (string) $term_id;
|
|
$terms = itstudio_join_get_terms();
|
|
|
|
if (!isset($terms[$term_id])) {
|
|
return false;
|
|
}
|
|
if (count($terms) <= 1) {
|
|
return false;
|
|
}
|
|
if (itstudio_join_get_active_term_id() === $term_id) {
|
|
return false;
|
|
}
|
|
|
|
unset($terms[$term_id]);
|
|
update_option('itstudio_join_terms', $terms);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 由旧的单一配置推断学年与季节(报名开始月份 >= 7 视为秋季)。
|
|
*/
|
|
function itstudio_join_guess_term_from_settings($settings) {
|
|
$settings = is_array($settings) ? $settings : array();
|
|
$anchor = '';
|
|
foreach (array('registration_start', 'notice_start_date', 'first_interview_date') as $key) {
|
|
if (!empty($settings[$key])) {
|
|
$anchor = (string) $settings[$key];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($anchor === '' || !preg_match('/(\d{4})-(\d{2})/', $anchor, $m)) {
|
|
return array('academic_year' => '', 'season' => 'fall');
|
|
}
|
|
|
|
$year = (int) $m[1];
|
|
$month = (int) $m[2];
|
|
if ($month >= 7) {
|
|
return array('academic_year' => $year . '-' . ($year + 1), 'season' => 'fall');
|
|
}
|
|
|
|
return array('academic_year' => ($year - 1) . '-' . $year, 'season' => 'spring');
|
|
}
|
|
|
|
/**
|
|
* 一次性迁移:把旧的单一 itstudio_join_settings 归入首个学期并设为生效。
|
|
* 前后台每个请求都会触发,但有标记,已迁移则立即返回。
|
|
*/
|
|
function itstudio_join_maybe_migrate_terms() {
|
|
if (get_option('itstudio_join_terms_migrated')) {
|
|
return;
|
|
}
|
|
|
|
$terms = itstudio_join_get_terms();
|
|
if (empty($terms)) {
|
|
$legacy = get_option('itstudio_join_settings', array());
|
|
$legacy = is_array($legacy) ? $legacy : array();
|
|
|
|
if (!empty($legacy)) {
|
|
$guess = itstudio_join_guess_term_from_settings($legacy);
|
|
$label = $guess['academic_year'] === '' ? '初始招新期' : '';
|
|
itstudio_join_create_term($guess['academic_year'], $guess['season'], $label, $legacy);
|
|
} else {
|
|
// 全新安装:建一个空的当前学期占位。
|
|
$now_year = (int) current_time('Y');
|
|
itstudio_join_create_term($now_year . '-' . ($now_year + 1), 'fall', '', null);
|
|
}
|
|
}
|
|
|
|
update_option('itstudio_join_terms_migrated', 1);
|
|
}
|
|
add_action('init', 'itstudio_join_maybe_migrate_terms', 1);
|