Browse Source

1.2.3

main 1.2.3
xiaoz 3 days ago
parent
commit
9c97579843
  1. 3
      .gitignore
  2. 44
      AGENTS.md
  3. 26
      class/Api.php
  4. 6
      controller/api.php
  5. 4
      data/update.log
  6. 5
      templates/admin/index.php
  7. 7
      templates/admin/setting/subscribe.php
  8. 2
      templates/admin/static/embed.js
  9. 2
      version.txt

3
.gitignore vendored

@ -0,0 +1,3 @@
class/cache
data/config.php
data/onenav.db3

44
AGENTS.md

@ -0,0 +1,44 @@
# AGENTS
- 全程使用中文输出,包括分析、进度说明、变更说明、提交信息建议;不要默认切回英文。
## 入口与分发
- 真实入口是根目录 `index.php`,不要从 README 猜流程。
- `index.php` 启动顺序固定:先检查 `data/config.php`,不存在就进入 `controller/init.php`;再检查 `data/onenav.db3`,不存在时从 `db/onenav.simple.db3` 复制;然后 `require ./data/config.php`;最后按 `?c=` 分发到 `controller/*.php`
- 未传 `c` 时进入 `controller/index.php`;`?c=api`、`?c=admin`、`?c=login`、`?c=mobile` 等都直接映射到 `controller/<name>.php`
- `index.php` 会拒绝包含 `./` 的控制器参数;改路由时不要破坏这层基于文件名的动态分发。
- `.htaccess` 只做两条重要伪静态:`/click/<id>` -> `index.php?c=click&id=<id>`,`/api/<method>` -> `index.php?c=api&method=<method>`
## 关键目录
- `controller/` 放页面/入口控制器,真正的 API 业务主要在 `class/Api.php`,不要只改 `controller/api.php` 的参数转发层。
- `functions/helper.php` 放登录态、主题枚举、移动端跳转等共享函数;前台首页和后台都依赖它。
- 后台管理的大部分前端交互、表格渲染和 API 调用集中在 `templates/admin/static/embed.js`;改后台管理行为时要同时检查这个文件。
- 内置主题在 `templates/`,用户自定义主题走 `data/templates/`;代码里默认先找内置目录,再回退到 `data/templates/`
- `db/onenav.simple.db3` 是初始化种子库,`data/onenav.db3` 是运行中的真实数据。
## 运行与状态文件
- `data/config.php``data/onenav.db3` 是本地实例状态文件,且被 `.gitignore` 忽略;除非用户明确要求,不要覆盖、删除、重建这两个文件。
- 安装流程依赖 `config.simple.php` 模板生成 `data/config.php`;涉及初始化逻辑时,同时检查 `controller/init.php``config.simple.php`
- `controller/init.php` 的可执行约束比 README 更可信:初始化会检查 `pdo_sqlite`、`openssl`、`zlib`、`curl`,并拒绝二级目录安装。
## 前台与主题流程
- `controller/index.php` 会先查 `on_options.s_site` 和分类/链接,再决定主题;不要只看模板目录名判断首页行为。
- 未配置主题时默认 `default2`;已配置时按 UA 在 `s_themes` 中区分 `pc_theme``mobile_theme`
- `?theme=` 只允许切到 `get_all_themes()` 返回的主题;这个函数会排除 `admin`、`mobile`、`universal`。
- 主题配置文件兼容两套命名:优先 `config.json`,其次 `info.json`;内置主题和 `data/templates/` 都要一起兼容。
## 认证与 API 约束
- 登录态不是 PHP session,而是 `key` cookie;`functions/helper.php::is_login()` 会把它和 `USER + ENCRYPTED_PASSWORD + onenav + User-Agent` 的 MD5 比较。
- `class/Api.php::auth()` 允许两种 API 鉴权:`token=md5(USER + SecretKey)` 或请求头 `X-Token`;没传 token 时会退回 cookie 登录态。
- 后台和移动后台都依赖同一套 cookie 登录判断;改鉴权时要一起看 `controller/admin.php`、`controller/mobile.php`、`controller/login.php`。
## 验证方式
- 仓库里没有可验证的 `composer.json`、`package.json`、CI workflow、lint/test 配置;不要臆造 `composer test`、`npm run build` 之类命令。
- 对 PHP 改动,最小可执行验证是对改过的文件运行 `php -l <file>`
- 对路由或接口改动,优先按真实入口验证:`/index.php?c=...` 或重写后的 `/api/...`、`/click/...`。

26
class/Api.php

@ -753,10 +753,12 @@ class Api {
*/ */
public function export_link(){ public function export_link(){
//鉴权 //鉴权
$this->auth($token); $this->auth('');
// 一次性获取所有分类与链接,减少查询次数 // 一次性获取所有分类与链接,减少查询次数
$categories = $this->db->select("on_categorys", [ $categories = $this->db->select("on_categorys", [
"id","name","fid","weight","add_time" "id","name","fid","weight","add_time"
],[
"ORDER" => ["fid" => "ASC", "weight" => "DESC", "id" => "DESC"]
]); ]);
$links = $this->db->select("on_links", [ $links = $this->db->select("on_links", [
"id","fid","title","url","add_time","weight" "id","fid","title","url","add_time","weight"
@ -777,6 +779,8 @@ class Api {
'id' => $c['id'], 'id' => $c['id'],
'name' => $c['name'], 'name' => $c['name'],
'fid' => $c['fid'], 'fid' => $c['fid'],
'weight' => isset($c['weight']) ? intval($c['weight']) : 0,
'add_time' => isset($c['add_time']) ? $c['add_time'] : '',
'links' => isset($linksByCat[$c['id']]) ? $linksByCat[$c['id']] : [], 'links' => isset($linksByCat[$c['id']]) ? $linksByCat[$c['id']] : [],
'children' => [] 'children' => []
]; ];
@ -797,6 +801,25 @@ class Api {
} }
} }
unset($node); unset($node);
$sortCategoryTree = function (&$nodes) use (&$sortCategoryTree) {
usort($nodes, function ($a, $b) {
$weightDiff = intval($b['weight']) - intval($a['weight']);
if ($weightDiff !== 0) {
return $weightDiff;
}
return intval($b['id']) - intval($a['id']);
});
foreach ($nodes as &$item) {
if (!empty($item['children'])) {
$sortCategoryTree($item['children']);
}
}
unset($item);
};
$sortCategoryTree($tree);
return $tree; return $tree;
} }
/** /**
@ -3367,4 +3390,3 @@ class Api {
} }

6
controller/api.php

@ -584,10 +584,10 @@ function export_link($api) {
HTML; HTML;
// 构造根目录“书签栏”包裹所有顶级分类 // 构造浏览器兼容的根目录,名称使用 Bookmarks 以兼容导入器忽略系统根目录的逻辑
$rootAdd = $now; $rootAdd = $now;
$rootMod = $now; $rootMod = $now;
echo " <DT><H3 ADD_DATE=\"{$rootAdd}\" LAST_MODIFIED=\"{$rootMod}\" PERSONAL_TOOLBAR_FOLDER=\"true\">OneNav</H3>\n"; echo " <DT><H3 ADD_DATE=\"{$rootAdd}\" LAST_MODIFIED=\"{$rootMod}\" PERSONAL_TOOLBAR_FOLDER=\"true\">Bookmarks</H3>\n";
echo " <DL><p>\n"; echo " <DL><p>\n";
foreach ($tree as $topCat) { foreach ($tree as $topCat) {
@ -771,4 +771,4 @@ function get_subscribe(){
function get_subscribe_status(){ function get_subscribe_status(){
global $api; global $api;
$api->get_subscribe_status(); $api->get_subscribe_status();
} }

4
data/update.log

@ -1,3 +1,7 @@
2026.04.27
1. 【后台 - 链接管理 - 我的链接】,导出所有链接支持保留二级分类。
2. 后台首页和订阅页面,新增ZMark发布提示。
2025.09.01 2025.09.01
1. 导出所有链接支持二级分类 1. 导出所有链接支持二级分类
2. 删除空白的default3主题 2. 删除空白的default3主题

5
templates/admin/index.php

@ -5,6 +5,11 @@
<div class="layui-body place-holder"> <div class="layui-body place-holder">
<!-- 内容主体区域 --> <!-- 内容主体区域 -->
<div style="padding: 15px;"> <div style="padding: 15px;">
<div class="layui-container" style="margin-top: 2em; margin-bottom: 1em;">
<blockquote class="layui-elem-quote" style="border-left-color: #ff5722; background-color: #fff4e8; color: #8a4b08; font-size: 15px; line-height: 1.8;">
<strong>OneNav重构版ZMark现已发布,</strong><a href="https://dwz.ovh/amr6" target="_blank" rel="noopener noreferrer" style="color: #ff5722; font-weight: bold; text-decoration: underline;">点此了解如何升级</a>
</blockquote>
</div>
<div class="layui-container" style = "margin-top:2em;"> <div class="layui-container" style = "margin-top:2em;">
<div class="layui-row layui-col-space18"> <div class="layui-row layui-col-space18">

7
templates/admin/setting/subscribe.php

@ -5,6 +5,11 @@
<div class="layui-body"> <div class="layui-body">
<!-- 内容主体区域 --> <!-- 内容主体区域 -->
<div class="layui-row content-body place-holder" style="padding-bottom: 3em;"> <div class="layui-row content-body place-holder" style="padding-bottom: 3em;">
<div class="layui-col-lg12">
<blockquote class="layui-elem-quote" style="border-left-color: #ff5722; background-color: #fff4e8; color: #8a4b08; font-size: 15px; line-height: 1.8; margin-bottom: 15px;">
<strong>OneNav重构版ZMark现已发布,</strong><a href="https://dwz.ovh/amr6" target="_blank" rel="noopener noreferrer" style="color: #ff5722; font-weight: bold; text-decoration: underline;">点此了解如何升级</a>
</blockquote>
</div>
<!-- 说明提示框 --> <!-- 说明提示框 -->
<div class="layui-col-lg12"> <div class="layui-col-lg12">
<div class="setting-msg"> <div class="setting-msg">
@ -270,4 +275,4 @@
$("#btn_update").show(); $("#btn_update").show();
$("#btn_updating").hide(); $("#btn_updating").hide();
} }
</script> </script>

2
templates/admin/static/embed.js

@ -1166,7 +1166,7 @@ function set_link_attribute(ids,property) {
//导出所有链接 //导出所有链接
function export_link(url, fileName) { function export_link(url, fileName) {
layer.confirm('导出的链接可以导入到浏览器也可以再次导入到OneNav!', {icon: 3, title:'确定导出所有链接?'}, function(index){ layer.confirm('导出的链接可以导入到浏览器也可以再次导入到OneNav/ZMark!', {icon: 3, title:'确定导出所有链接?'}, function(index){
var date = new Date(); var date = new Date();
var current_time = date.toLocaleDateString(); var current_time = date.toLocaleDateString();
current_time = current_time.replaceAll("/","."); current_time = current_time.replaceAll("/",".");

2
version.txt

@ -1 +1 @@
v1.2.2-20250901 v1.2.3-20260427
Loading…
Cancel
Save