Merge pull request 'Worktree page links 1to1' (#214) from worktree-page-links-1to1 into main
Reviewed-on: CYL/wordpress-theme-aksrt#214
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* Header user-box density (check-in / wallet / payvip / signout modal).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
.aksrt-header-wallet {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
justify-content: space-between;
|
||||
padding: 8px 10px;
|
||||
border-radius: 8px;
|
||||
background: var(--surface-2, rgba(0, 0, 0, 0.04));
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.aksrt-header-wallet__item b {
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.aksrt-header-checkin {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
border-radius: 6px;
|
||||
padding: 8px 10px;
|
||||
cursor: pointer;
|
||||
background: rgba(255, 193, 7, 0.18);
|
||||
color: #b78103;
|
||||
}
|
||||
|
||||
.aksrt-header-checkin.is-done {
|
||||
opacity: 0.75;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.aksrt-header-payvip .payvip-icon,
|
||||
.aksrt-header-payvip .but {
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
padding: 8px 10px;
|
||||
border-radius: 6px;
|
||||
background: linear-gradient(90deg, #ff6b6b, #f04494);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.aksrt-header-badges {
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
#modal_signout.modal {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1100;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
#modal_signout.modal.is-open,
|
||||
#modal_signout.modal.show {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#modal_signout .modal-content {
|
||||
background: var(--main-bg-color, #fff);
|
||||
border-radius: 10px;
|
||||
min-width: 280px;
|
||||
max-width: 92vw;
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
|
||||
#modal_signout .but.c-red {
|
||||
background: #e74c3c;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
padding: 8px 14px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
#modal_signout .but {
|
||||
border: 0;
|
||||
background: var(--surface-2, #f0f0f0);
|
||||
padding: 8px 14px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-dropdown .social_loginbar {
|
||||
padding: 0 10px 12px;
|
||||
}
|
||||
@@ -0,0 +1,459 @@
|
||||
/**
|
||||
* AKSRT 网址导航 — zibll links page shell/styles.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
/* ---- cards ---- */
|
||||
.links-cat-header {
|
||||
padding: 0 15px 10px;
|
||||
}
|
||||
|
||||
.links-box:not(.zib-widget):not(.links-style-simple):not(.links-style-image) {
|
||||
margin: -5px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.links-box .links-card {
|
||||
padding: 10px 4px 10px 8px;
|
||||
min-width: 0;
|
||||
margin: 5px;
|
||||
width: calc(50% - 10px);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.links-style-bigcard {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.links-box .links-card.big-card {
|
||||
padding: 20px 10px 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.links-box:not(.zib-widget) .links-card {
|
||||
background: var(--main-bg-color, var(--surface-1, #fff));
|
||||
}
|
||||
|
||||
.author-minicard.links-card {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 4px var(--main-shadow, rgba(0, 0, 0, 0.06));
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.author-minicard.links-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 14px var(--main-shadow, rgba(0, 0, 0, 0.1));
|
||||
}
|
||||
|
||||
.links-card a {
|
||||
display: block;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.links-card .list-inline {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.links-card .list-inline > li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.link-img {
|
||||
--this-size: 42px;
|
||||
width: var(--this-size);
|
||||
height: var(--this-size);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.link-img img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 4px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.links-card.big-card .link-img {
|
||||
--this-size: 58px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.links-card.big-card .link-img img {
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
.links-style-image {
|
||||
--link-img-size: 60px;
|
||||
--this-margin: 10px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.links-style-image .link-img.link-only-img {
|
||||
margin: var(--this-margin);
|
||||
--this-size: var(--link-img-size);
|
||||
}
|
||||
|
||||
.links-style-image .link-img.link-only-img img {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
/* ---- fixed category nav ---- */
|
||||
.fixed-wrap .fixed-wrap-nav.zib-widget,
|
||||
.link-nav-box .zib-widget {
|
||||
padding: 8px 15px;
|
||||
}
|
||||
|
||||
.fixed-wrap-nav .tab-nav-theme {
|
||||
border-bottom: none;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.link-nav-box .nav > li > a {
|
||||
display: block;
|
||||
padding: 6px;
|
||||
color: var(--muted-2-color, #888);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.link-nav-box .nav > li > a:hover,
|
||||
.link-nav-box .nav > .active > a {
|
||||
color: var(--focus-color, var(--color-primary, #f04494));
|
||||
}
|
||||
|
||||
.link-nav-submit,
|
||||
.link-cat-submit {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.link-cat-submit {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.links-page-container .title-theme {
|
||||
font-weight: 600;
|
||||
font-size: 1.15em;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
/* ---- search cover ---- */
|
||||
.link-page-search-cover.page-cover {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
padding-bottom: calc(25% + 100px);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.link-page-search-cover .fit-cover {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.link-page-search-cover .header-slider-search {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: min(560px, 92%);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.link-page-search-cover .tab-nav-theme {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0 0 8px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.link-page-search-cover .tab-nav-theme li a {
|
||||
opacity: 0.7;
|
||||
padding: 0 10px;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.link-page-search-cover .tab-nav-theme li a:hover,
|
||||
.link-page-search-cover .tab-nav-theme li.active a {
|
||||
color: #fff;
|
||||
opacity: 1;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.link-page-search-cover .tab-pane {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.link-page-search-cover .tab-pane.active,
|
||||
.link-page-search-cover .tab-pane.in.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.link-page-search-cover .line-form {
|
||||
position: relative;
|
||||
background: rgba(255, 255, 255, 0.92);
|
||||
border-radius: 8px;
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.link-page-search-cover .line-form-input {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
outline: none;
|
||||
font-size: 15px;
|
||||
padding: 8px 36px 8px 4px;
|
||||
}
|
||||
|
||||
.link-page-search-cover .abs-right {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.link-page-search-cover .abs-right button {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
color: var(--muted-2-color, #666);
|
||||
}
|
||||
|
||||
.link-page-search-cover .header-slider-search-more {
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* ---- submit modal ---- */
|
||||
#submit-links-modal.modal {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1050;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
#submit-links-modal.modal.is-open,
|
||||
#submit-links-modal.modal.show {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#submit-links-modal .modal-dialog {
|
||||
width: min(520px, 100%);
|
||||
max-height: 90vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#submit-links-modal .modal-content {
|
||||
background: var(--main-bg-color, #fff);
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
|
||||
#submit-links-modal .modal-body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
#submit-links-modal .close {
|
||||
float: right;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
#submit-links-modal .preview-square {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border: 1px dashed var(--main-border-color, #ddd);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#submit-links-modal .preview-square img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
#submit-links-modal .hide {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#submit-links-modal .form-control {
|
||||
width: 100%;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid var(--main-border-color, #ddd);
|
||||
border-radius: 6px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#submit-links-modal .row.gutters-5 {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -5px;
|
||||
}
|
||||
|
||||
#submit-links-modal .col-sm-6,
|
||||
#submit-links-modal .col-sm-12 {
|
||||
padding: 0 5px;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
#submit-links-modal .col-sm-6 {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- responsive grid ---- */
|
||||
@media (min-width: 992px) {
|
||||
.links-box .links-card {
|
||||
width: calc(25% - 10px);
|
||||
}
|
||||
|
||||
.site-layout-1 .links-box .links-card,
|
||||
.fluid-widget-wrap .links-box .links-card {
|
||||
width: calc(20% - 10px);
|
||||
}
|
||||
|
||||
.fluid-widget-wrap .links-box.links-style-bigcard .links-card,
|
||||
.site-layout-1 .links-box.links-style-bigcard .links-card {
|
||||
width: calc(16.6665% - 10px);
|
||||
}
|
||||
|
||||
.sidebar .links-box .links-card {
|
||||
width: calc(50% - 10px);
|
||||
}
|
||||
|
||||
.fixed-wrap {
|
||||
position: relative;
|
||||
--fixed-width: 120px;
|
||||
}
|
||||
|
||||
.fixed-wrap > .fixed-wrap-nav {
|
||||
position: absolute;
|
||||
width: var(--fixed-width);
|
||||
}
|
||||
|
||||
.fixed-wrap > .fixed-wrap-nav + .fixed-wrap-content {
|
||||
margin-left: calc(var(--fixed-width) + 15px);
|
||||
}
|
||||
|
||||
.fixed-wrap-nav.affix {
|
||||
position: sticky;
|
||||
top: 80px;
|
||||
}
|
||||
|
||||
.fixed-wrap .tab-nav-theme.mini-scrollbar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
max-height: 70vh;
|
||||
text-align: center;
|
||||
border-bottom: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.fixed-wrap .tab-nav-theme.mini-scrollbar > li > a {
|
||||
padding: 6px;
|
||||
margin: 1px 0;
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
color: var(--muted-2-color, #888);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fixed-wrap .tab-nav-theme.mini-scrollbar > li > a:hover {
|
||||
color: var(--main-color, var(--color-primary));
|
||||
}
|
||||
|
||||
.fixed-wrap .tab-nav-theme.mini-scrollbar > li.active > a {
|
||||
color: var(--focus-color, var(--color-primary));
|
||||
font-weight: 500;
|
||||
background: color-mix(in srgb, var(--focus-color, var(--color-primary)) 12%, transparent);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.link-nav-submit {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
.link-nav-submit {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.link-cat-submit {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.link-nav-box > .zib-widget {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.link-nav-box .nav {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
overflow-x: auto;
|
||||
margin: 0 0 10px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.link-nav-box .nav > li {
|
||||
display: inline-block;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.link-nav-box .nav > li > a {
|
||||
padding: 2px 6px;
|
||||
font-size: 1.05em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.links-box .links-card {
|
||||
width: calc(50% - 10px);
|
||||
}
|
||||
|
||||
.link-page-search-cover .tab-nav-theme li a {
|
||||
padding: 0 3px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.links-page-container .fixed-wrap {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
/**
|
||||
* AKSRT 文章导航页 — zibll postsnavs shell + admin settings.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
/* header card */
|
||||
.page-template-posts-navs .content-wrap,
|
||||
main.page-template-posts-navs {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
main.page-template-posts-navs .content-wrap {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
main.page-template-posts-navs .sidebar {
|
||||
flex: 0 0 260px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.posts-navs .title-theme h2 {
|
||||
margin: 0;
|
||||
font-size: 1.15em;
|
||||
}
|
||||
|
||||
.posts-navs__list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.posts-navs__item {
|
||||
margin: 0 0 10px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.posts-navs__item .text-ellipsis {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.posts-navs__item .icon-circle {
|
||||
display: inline-block;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background: var(--muted-3-color, #ccc);
|
||||
margin: 0 0.55em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.posts-navs__item a {
|
||||
color: var(--color-ink, inherit);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.posts-navs__item a:hover {
|
||||
color: var(--focus-color, var(--color-primary));
|
||||
}
|
||||
|
||||
.posts-navs .theme-box {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.posts-navs .box-body.notop {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
/* TOC sidebar filled by section-navs.js */
|
||||
.posts-nav-box .posts-nav-lists,
|
||||
.posts-nav-box .aksrt-section-nav {
|
||||
max-height: 400px;
|
||||
padding-left: 10px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.posts-nav-box .zib-widget {
|
||||
background: var(--main-bg-color, var(--surface-1, #fff));
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 4px var(--main-shadow, rgba(0, 0, 0, 0.06));
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.posts-nav-lists .bl {
|
||||
border-left: 1px solid var(--main-border-color, #eee);
|
||||
padding: 12px 10px 12px 0;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.posts-nav-lists li {
|
||||
position: relative;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.posts-nav-lists li a {
|
||||
margin: 0 10px;
|
||||
display: block;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
margin-right: 20px;
|
||||
color: var(--muted-2-color, #666);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.posts-nav-lists li a:hover,
|
||||
.posts-nav-lists li.active a {
|
||||
background: var(--main-shadow, rgba(0, 0, 0, 0.04));
|
||||
color: var(--focus-color, var(--color-primary));
|
||||
}
|
||||
|
||||
.posts-nav-lists li.n-H1 a,
|
||||
.posts-nav-lists li.n-H2 a {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* settings modal */
|
||||
#post-navs-sz.modal {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1050;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
#post-navs-sz.modal.is-open,
|
||||
#post-navs-sz.modal.show {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#post-navs-sz .modal-dialog {
|
||||
width: min(640px, 100%);
|
||||
max-height: 90vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#post-navs-sz .modal-content {
|
||||
background: var(--main-bg-color, #fff);
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
|
||||
#post-navs-sz .modal-header,
|
||||
#post-navs-sz .modal-body,
|
||||
#post-navs-sz .modal-footer {
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
#post-navs-sz .modal-header {
|
||||
border-bottom: 1px solid var(--main-border-color, #eee);
|
||||
}
|
||||
|
||||
#post-navs-sz .modal-footer {
|
||||
border-top: 1px solid var(--main-border-color, #eee);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#post-navs-sz .close {
|
||||
float: right;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#post-navs-sz .form-control {
|
||||
width: 100%;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid var(--main-border-color, #ddd);
|
||||
border-radius: 6px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#post-navs-sz .form-group {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
#post-navs-sz .row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -8px;
|
||||
}
|
||||
|
||||
#post-navs-sz .col-xs-6,
|
||||
#post-navs-sz .col-sm-6 {
|
||||
width: 50%;
|
||||
padding: 0 8px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.cat-group {
|
||||
height: 200px;
|
||||
background: var(--body-bg-color, var(--surface-2, #f6f7f9));
|
||||
border: 1px solid var(--main-border-color, #ddd);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
padding: 5px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.sortable-cat-item {
|
||||
background: var(--main-border-color, #e8e8e8);
|
||||
padding: 4px 8px;
|
||||
transition: 0.2s;
|
||||
border-radius: 4px;
|
||||
margin: 2px;
|
||||
display: inline-block;
|
||||
cursor: grab;
|
||||
width: calc(100% - 15px);
|
||||
min-width: 100px;
|
||||
box-sizing: border-box;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.sortable-cat-item .badge {
|
||||
margin-left: 4px;
|
||||
background: rgba(0, 0, 0, 0.08);
|
||||
color: inherit;
|
||||
border-radius: 10px;
|
||||
padding: 0 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#cat-sortable-ok .sortable-cat-item {
|
||||
background: rgba(73, 214, 253, 0.12);
|
||||
color: #069cf3;
|
||||
}
|
||||
|
||||
.sortable-cat-item.is-dragging {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.sortable-cat-item.sortable-selected {
|
||||
background: rgba(251, 82, 82, 0.1) !important;
|
||||
color: #fb5454 !important;
|
||||
}
|
||||
|
||||
.cat-group.is-drop-target {
|
||||
outline: 2px dashed var(--focus-color, #f04494);
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
main.page-template-posts-navs .sidebar {
|
||||
flex: 1 1 100%;
|
||||
order: -1;
|
||||
}
|
||||
|
||||
#post-navs-sz .col-xs-6,
|
||||
#post-navs-sz .col-sm-6 {
|
||||
width: 100%;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* User identity auth page styles (zibll user-auth).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
.aksrt-user-auth-panel {
|
||||
overflow: hidden;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.aksrt-user-auth-panel .colorful-bg.c-blue {
|
||||
background: linear-gradient(135deg, #4e9bff 0%, #2f6df6 100%);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.aksrt-user-auth-panel .muted-2-color {
|
||||
color: var(--muted-2-color, #888);
|
||||
}
|
||||
|
||||
.aksrt-user-auth-panel .form-control {
|
||||
width: 100%;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid var(--main-border-color, #ddd);
|
||||
border-radius: 6px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.aksrt-user-auth-panel .mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.aksrt-user-auth-panel .mb6 {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.aksrt-user-auth-panel .but.c-blue,
|
||||
.aksrt-user-auth-panel button.but {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
background: var(--focus-color, #2f6df6);
|
||||
color: #fff;
|
||||
border: 0;
|
||||
border-radius: 6px;
|
||||
padding: 10px 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.aksrt-user-auth-panel .btn-block {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.aksrt-user-auth-panel__imgs {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.aksrt-user-auth-panel__imgs .preview-item {
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--main-border-color, #eee);
|
||||
}
|
||||
|
||||
.aksrt-user-auth-panel__imgs img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.aksrt-user-auth-panel .c-red {
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
.page-template-user-auth .content-wrap {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.page-template-user-auth .content-layout {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Header user-box: check-in REST + signout modal.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function restBase() {
|
||||
if (window.aksrtData && window.aksrtData.restUrl) return window.aksrtData.restUrl.replace(/\/?$/, '/');
|
||||
if (window.aksrtData && window.aksrtData.siteUrl) return String(window.aksrtData.siteUrl).replace(/\/?$/, '/') + 'wp-json/';
|
||||
return '/wp-json/';
|
||||
}
|
||||
|
||||
function restNonce() {
|
||||
return (window.aksrtData && window.aksrtData.restNonce) || '';
|
||||
}
|
||||
|
||||
function toast(msg, type) {
|
||||
if (window.aksrt && typeof window.aksrt.toast === 'function') {
|
||||
window.aksrt.toast(msg, type || 'info');
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line no-alert
|
||||
window.alert(msg);
|
||||
}
|
||||
|
||||
function openModal(id) {
|
||||
var modal = document.getElementById(id);
|
||||
if (!modal) return;
|
||||
modal.classList.add('is-open', 'show');
|
||||
modal.setAttribute('aria-hidden', 'false');
|
||||
}
|
||||
|
||||
function closeModal(id) {
|
||||
var modal = document.getElementById(id);
|
||||
if (!modal) return;
|
||||
modal.classList.remove('is-open', 'show');
|
||||
modal.setAttribute('aria-hidden', 'true');
|
||||
}
|
||||
|
||||
function initSignoutModal() {
|
||||
document.addEventListener('click', function (e) {
|
||||
var openBtn = e.target.closest('[data-target="#modal_signout"], [href="#modal_signout"]');
|
||||
if (openBtn) {
|
||||
e.preventDefault();
|
||||
openModal('modal_signout');
|
||||
return;
|
||||
}
|
||||
var dismiss = e.target.closest('#modal_signout [data-dismiss="modal"]');
|
||||
if (dismiss) {
|
||||
e.preventDefault();
|
||||
closeModal('modal_signout');
|
||||
return;
|
||||
}
|
||||
if (e.target && e.target.id === 'modal_signout') {
|
||||
closeModal('modal_signout');
|
||||
}
|
||||
});
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Escape') closeModal('modal_signout');
|
||||
});
|
||||
}
|
||||
|
||||
function initCheckin() {
|
||||
document.addEventListener('click', function (e) {
|
||||
var btn = e.target.closest('[data-aksrt-checkin="1"]');
|
||||
if (!btn || btn.disabled) return;
|
||||
e.preventDefault();
|
||||
btn.disabled = true;
|
||||
fetch(restBase() + 'aksrt/v1/signin', {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-WP-Nonce': restNonce(),
|
||||
},
|
||||
body: '{}',
|
||||
})
|
||||
.then(function (r) {
|
||||
return r.json().then(function (data) {
|
||||
return { ok: r.ok, data: data };
|
||||
});
|
||||
})
|
||||
.then(function (res) {
|
||||
if (!res.ok) {
|
||||
var msg = (res.data && (res.data.message || res.data.msg)) || '签到失败';
|
||||
toast(msg, 'danger');
|
||||
btn.disabled = false;
|
||||
return;
|
||||
}
|
||||
toast((res.data && res.data.message) || '签到成功', 'success');
|
||||
btn.classList.add('is-done');
|
||||
btn.innerHTML = '<i class="fa fa-calendar-check-o" aria-hidden="true"></i> 今日已签到';
|
||||
})
|
||||
.catch(function () {
|
||||
toast('网络错误', 'danger');
|
||||
btn.disabled = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
initSignoutModal();
|
||||
initCheckin();
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,221 @@
|
||||
/**
|
||||
* AKSRT 网址导航页 — search tabs, sticky cat nav, submit modal/AJAX.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function qs(sel, root) {
|
||||
return (root || document).querySelector(sel);
|
||||
}
|
||||
|
||||
function qsa(sel, root) {
|
||||
return Array.prototype.slice.call((root || document).querySelectorAll(sel));
|
||||
}
|
||||
|
||||
function ajaxUrl() {
|
||||
if (window.aksrtData && window.aksrtData.ajaxUrl) return window.aksrtData.ajaxUrl;
|
||||
if (window.ajaxurl) return window.ajaxurl;
|
||||
return '/wp-admin/admin-ajax.php';
|
||||
}
|
||||
|
||||
function toast(msg, type) {
|
||||
if (window.aksrt && typeof window.aksrt.toast === 'function') {
|
||||
window.aksrt.toast(msg, type || 'info');
|
||||
return;
|
||||
}
|
||||
if (window.notyf) {
|
||||
try {
|
||||
window.notyf(msg, type === 'danger' ? 'danger' : '');
|
||||
return;
|
||||
} catch (e) { /* ignore */ }
|
||||
}
|
||||
// eslint-disable-next-line no-alert
|
||||
window.alert(msg);
|
||||
}
|
||||
|
||||
/* ---------- search engine tabs ---------- */
|
||||
function initSearchTabs() {
|
||||
var cover = qs('.link-page-search-cover');
|
||||
if (!cover) return;
|
||||
|
||||
qsa('.tab-nav-theme a[data-aksrt-tab-target]', cover).forEach(function (a) {
|
||||
a.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
var target = a.getAttribute('data-aksrt-tab-target');
|
||||
if (!target) return;
|
||||
qsa('.tab-nav-theme li', cover).forEach(function (li) {
|
||||
li.classList.remove('active');
|
||||
});
|
||||
if (a.parentElement) a.parentElement.classList.add('active');
|
||||
qsa('.tab-pane', cover).forEach(function (pane) {
|
||||
pane.classList.remove('active', 'in');
|
||||
});
|
||||
var pane = qs(target, cover);
|
||||
if (pane) pane.classList.add('active', 'in');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* ---------- sticky category nav highlight ---------- */
|
||||
function initCatNav() {
|
||||
var wrap = qs('.links-page-container .fixed-wrap');
|
||||
if (!wrap) return;
|
||||
var nav = qs('.link-nav-box', wrap);
|
||||
var links = qsa('.link-nav-box a[href^="#"]', wrap);
|
||||
var sections = links
|
||||
.map(function (a) {
|
||||
var id = a.getAttribute('href');
|
||||
return id ? document.getElementById(id.replace(/^#/, '')) : null;
|
||||
})
|
||||
.filter(Boolean);
|
||||
if (!links.length || !sections.length) return;
|
||||
|
||||
links.forEach(function (a) {
|
||||
a.addEventListener('click', function (e) {
|
||||
var id = a.getAttribute('href');
|
||||
var el = id ? document.getElementById(id.replace(/^#/, '')) : null;
|
||||
if (!el) return;
|
||||
e.preventDefault();
|
||||
var top = el.getBoundingClientRect().top + window.pageYOffset - 90;
|
||||
window.scrollTo({ top: top, behavior: 'smooth' });
|
||||
});
|
||||
});
|
||||
|
||||
function updateActive() {
|
||||
var y = window.pageYOffset + 120;
|
||||
var current = sections[0];
|
||||
for (var i = 0; i < sections.length; i++) {
|
||||
if (sections[i].offsetTop <= y) current = sections[i];
|
||||
}
|
||||
if (!current) return;
|
||||
links.forEach(function (a) {
|
||||
var li = a.parentElement;
|
||||
if (!li) return;
|
||||
if (a.getAttribute('href') === '#' + current.id) {
|
||||
li.classList.add('active');
|
||||
} else {
|
||||
li.classList.remove('active');
|
||||
}
|
||||
});
|
||||
if (nav) nav.classList.add('affix');
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', updateActive, { passive: true });
|
||||
updateActive();
|
||||
}
|
||||
|
||||
/* ---------- submit modal ---------- */
|
||||
function initSubmitModal() {
|
||||
var modal = qs('#submit-links-modal');
|
||||
if (!modal) return;
|
||||
|
||||
function openModal(e) {
|
||||
if (e) e.preventDefault();
|
||||
modal.classList.add('is-open', 'show');
|
||||
modal.setAttribute('aria-hidden', 'false');
|
||||
document.documentElement.classList.add('aksrt-modal-open');
|
||||
}
|
||||
|
||||
function closeModal(e) {
|
||||
if (e) e.preventDefault();
|
||||
modal.classList.remove('is-open', 'show');
|
||||
modal.setAttribute('aria-hidden', 'true');
|
||||
document.documentElement.classList.remove('aksrt-modal-open');
|
||||
}
|
||||
|
||||
qsa('a[href="#submit-links-modal"], [data-toggle="modal"][href="#submit-links-modal"]').forEach(function (btn) {
|
||||
btn.addEventListener('click', openModal);
|
||||
});
|
||||
|
||||
qsa('[data-dismiss="modal"]', modal).forEach(function (btn) {
|
||||
btn.addEventListener('click', closeModal);
|
||||
});
|
||||
|
||||
modal.addEventListener('click', function (e) {
|
||||
if (e.target === modal) closeModal(e);
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Escape' && modal.classList.contains('is-open')) closeModal(e);
|
||||
});
|
||||
|
||||
var fileInput = qs('.aksrt-links-logo-input', modal);
|
||||
var preview = qs('.aksrt-links-logo-preview', modal);
|
||||
if (fileInput && preview) {
|
||||
fileInput.addEventListener('change', function () {
|
||||
var file = fileInput.files && fileInput.files[0];
|
||||
if (!file) return;
|
||||
var url = URL.createObjectURL(file);
|
||||
preview.src = url;
|
||||
});
|
||||
}
|
||||
|
||||
var form = qs('.aksrt-links-submit-form', modal);
|
||||
if (!form) return;
|
||||
|
||||
form.addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
var btn = qs('.aksrt-links-submit-btn', form);
|
||||
if (btn) {
|
||||
btn.disabled = true;
|
||||
btn.classList.add('loading');
|
||||
}
|
||||
|
||||
var fd = new FormData(form);
|
||||
if (!fd.get('action')) fd.set('action', 'aksrt_frontend_links_submit');
|
||||
|
||||
fetch(ajaxUrl(), {
|
||||
method: 'POST',
|
||||
body: fd,
|
||||
credentials: 'same-origin',
|
||||
})
|
||||
.then(function (r) {
|
||||
return r.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
if (!data || data.error) {
|
||||
toast((data && data.msg) || '提交失败', 'danger');
|
||||
return;
|
||||
}
|
||||
toast(data.msg || '提交成功', 'success');
|
||||
if (data.reload) {
|
||||
window.setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, 600);
|
||||
} else {
|
||||
closeModal();
|
||||
form.reset();
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
toast('网络错误,请稍后重试', 'danger');
|
||||
})
|
||||
.finally(function () {
|
||||
if (btn) {
|
||||
btn.disabled = false;
|
||||
btn.classList.remove('loading');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
if (!document.body.classList.contains('page-template-templates-pages-page-links-php')
|
||||
&& !qs('.page-template-links')
|
||||
&& !qs('.links-page-container')
|
||||
&& !qs('#submit-links-modal')) {
|
||||
// Still bind if modal exists alone.
|
||||
}
|
||||
initSearchTabs();
|
||||
initCatNav();
|
||||
initSubmitModal();
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,255 @@
|
||||
/**
|
||||
* AKSRT 文章导航页 — admin settings modal + HTML5 drag-sort (no SortableJS dependency).
|
||||
* TOC generation is handled by section-navs.js via [data-nav] + .posts-nav-box.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function qs(sel, root) {
|
||||
return (root || document).querySelector(sel);
|
||||
}
|
||||
|
||||
function qsa(sel, root) {
|
||||
return Array.prototype.slice.call((root || document).querySelectorAll(sel));
|
||||
}
|
||||
|
||||
function ajaxUrl() {
|
||||
if (window.aksrtData && window.aksrtData.ajaxUrl) return window.aksrtData.ajaxUrl;
|
||||
if (window.ajaxurl) return window.ajaxurl;
|
||||
return '/wp-admin/admin-ajax.php';
|
||||
}
|
||||
|
||||
function toast(msg, type) {
|
||||
if (window.aksrt && typeof window.aksrt.toast === 'function') {
|
||||
window.aksrt.toast(msg, type || 'info');
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line no-alert
|
||||
window.alert(msg);
|
||||
}
|
||||
|
||||
function initModal() {
|
||||
var modal = qs('#post-navs-sz');
|
||||
if (!modal) return;
|
||||
|
||||
function openModal(e) {
|
||||
if (e) e.preventDefault();
|
||||
modal.classList.add('is-open', 'show');
|
||||
modal.setAttribute('aria-hidden', 'false');
|
||||
}
|
||||
|
||||
function closeModal(e) {
|
||||
if (e) e.preventDefault();
|
||||
modal.classList.remove('is-open', 'show');
|
||||
modal.setAttribute('aria-hidden', 'true');
|
||||
}
|
||||
|
||||
qsa('[data-toggle="modal"][data-target="#post-navs-sz"], a[href="#post-navs-sz"]').forEach(function (el) {
|
||||
el.addEventListener('click', openModal);
|
||||
});
|
||||
// Title [设置] uses data-target.
|
||||
qsa('[data-target="#post-navs-sz"]').forEach(function (el) {
|
||||
el.addEventListener('click', openModal);
|
||||
});
|
||||
qsa('[data-dismiss="modal"]', modal).forEach(function (btn) {
|
||||
btn.addEventListener('click', closeModal);
|
||||
});
|
||||
modal.addEventListener('click', function (e) {
|
||||
if (e.target === modal) closeModal(e);
|
||||
});
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Escape' && modal.classList.contains('is-open')) closeModal(e);
|
||||
});
|
||||
}
|
||||
|
||||
function initDragSort() {
|
||||
var left = qs('#cat-sortable');
|
||||
var right = qs('#cat-sortable-ok');
|
||||
if (!left || !right) return;
|
||||
|
||||
var dragEl = null;
|
||||
|
||||
function onDragStart(e) {
|
||||
dragEl = e.currentTarget;
|
||||
dragEl.classList.add('is-dragging');
|
||||
try {
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
e.dataTransfer.setData('text/plain', dragEl.getAttribute('data-id') || '');
|
||||
} catch (err) { /* IE */ }
|
||||
}
|
||||
|
||||
function onDragEnd() {
|
||||
if (dragEl) dragEl.classList.remove('is-dragging');
|
||||
dragEl = null;
|
||||
qsa('.cat-group').forEach(function (g) {
|
||||
g.classList.remove('is-drop-target');
|
||||
});
|
||||
}
|
||||
|
||||
function bindItem(el) {
|
||||
el.setAttribute('draggable', 'true');
|
||||
el.addEventListener('dragstart', onDragStart);
|
||||
el.addEventListener('dragend', onDragEnd);
|
||||
}
|
||||
|
||||
qsa('.sortable-cat-item', left).forEach(bindItem);
|
||||
qsa('.sortable-cat-item', right).forEach(bindItem);
|
||||
|
||||
[left, right].forEach(function (group) {
|
||||
group.addEventListener('dragover', function (e) {
|
||||
e.preventDefault();
|
||||
group.classList.add('is-drop-target');
|
||||
if (!dragEl) return;
|
||||
var after = getDragAfterElement(group, e.clientY);
|
||||
if (after == null) {
|
||||
group.appendChild(dragEl);
|
||||
} else {
|
||||
group.insertBefore(dragEl, after);
|
||||
}
|
||||
});
|
||||
group.addEventListener('dragleave', function () {
|
||||
group.classList.remove('is-drop-target');
|
||||
});
|
||||
group.addEventListener('drop', function (e) {
|
||||
e.preventDefault();
|
||||
group.classList.remove('is-drop-target');
|
||||
});
|
||||
});
|
||||
|
||||
function getDragAfterElement(container, y) {
|
||||
var els = qsa('.sortable-cat-item:not(.is-dragging)', container);
|
||||
var closest = { offset: Number.NEGATIVE_INFINITY, element: null };
|
||||
els.forEach(function (child) {
|
||||
var box = child.getBoundingClientRect();
|
||||
var offset = y - box.top - box.height / 2;
|
||||
if (offset < 0 && offset > closest.offset) {
|
||||
closest = { offset: offset, element: child };
|
||||
}
|
||||
});
|
||||
return closest.element;
|
||||
}
|
||||
}
|
||||
|
||||
function initSave() {
|
||||
var form = qs('#aksrt-posts-navs-settings');
|
||||
if (!form) return;
|
||||
|
||||
form.addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
var ids = [];
|
||||
qsa('#cat-sortable-ok .sortable-cat-item').forEach(function (item) {
|
||||
var id = item.getAttribute('data-id');
|
||||
if (id) ids.push(id);
|
||||
});
|
||||
if (!ids.length) {
|
||||
toast('请选择需要显示的分类', 'danger');
|
||||
return;
|
||||
}
|
||||
|
||||
var fd = new FormData(form);
|
||||
fd.set('action', 'aksrt_post_navs_settings');
|
||||
// PHP accepts array; append each.
|
||||
fd.delete('navs_show_cat_id');
|
||||
ids.forEach(function (id) {
|
||||
fd.append('navs_show_cat_id[]', id);
|
||||
});
|
||||
|
||||
var btn = qs('button[type="submit"]', form);
|
||||
if (btn) btn.disabled = true;
|
||||
|
||||
fetch(ajaxUrl(), {
|
||||
method: 'POST',
|
||||
body: fd,
|
||||
credentials: 'same-origin',
|
||||
})
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (data) {
|
||||
if (!data || data.error) {
|
||||
toast((data && data.msg) || '保存失败', 'danger');
|
||||
return;
|
||||
}
|
||||
toast(data.msg || '保存成功', 'success');
|
||||
if (data.reload) {
|
||||
window.setTimeout(function () { window.location.reload(); }, 400);
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
toast('网络错误', 'danger');
|
||||
})
|
||||
.finally(function () {
|
||||
if (btn) btn.disabled = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Build simple TOC into .posts-nav-box if section-navs hasn't already.
|
||||
* Uses category h2 headings inside .posts-navs.
|
||||
*/
|
||||
function initFallbackToc() {
|
||||
var box = qs('.posts-nav-box');
|
||||
var root = qs('.posts-navs[data-nav]');
|
||||
if (!box || !root) return;
|
||||
if (box.querySelector('.posts-nav-lists, .aksrt-section-nav, .toc-list')) return;
|
||||
|
||||
var headings = qsa('.title-theme h2, h2', root);
|
||||
if (headings.length < 1) return;
|
||||
|
||||
var title = box.getAttribute('data-title') || '导航目录';
|
||||
var list = '';
|
||||
headings.forEach(function (h, i) {
|
||||
if (!h.id) h.id = 'navs-sec-' + i;
|
||||
list += '<li class="n-H2"><a class="text-ellipsis" href="#' + h.id + '">' + (h.textContent || '').trim() + '</a></li>';
|
||||
});
|
||||
|
||||
box.innerHTML =
|
||||
'<div class="box-body notop"><div class="title-theme">' + title + '</div></div>' +
|
||||
'<div class="zib-widget"><div class="posts-nav-lists scroll-y mini-scrollbar list-unstyled">' +
|
||||
'<ul class="bl relative nav">' + list + '</ul></div></div>';
|
||||
|
||||
qsa('a[href^="#"]', box).forEach(function (a) {
|
||||
a.addEventListener('click', function (e) {
|
||||
var id = a.getAttribute('href');
|
||||
var el = id ? document.getElementById(id.replace(/^#/, '')) : null;
|
||||
if (!el) return;
|
||||
e.preventDefault();
|
||||
var top = el.getBoundingClientRect().top + window.pageYOffset - 90;
|
||||
window.scrollTo({ top: top, behavior: 'smooth' });
|
||||
});
|
||||
});
|
||||
|
||||
function highlight() {
|
||||
var y = window.pageYOffset + 120;
|
||||
var current = headings[0];
|
||||
headings.forEach(function (h) {
|
||||
if (h.offsetTop <= y) current = h;
|
||||
});
|
||||
qsa('li', box).forEach(function (li) {
|
||||
var a = li.querySelector('a');
|
||||
if (a && current && a.getAttribute('href') === '#' + current.id) {
|
||||
li.classList.add('active');
|
||||
} else {
|
||||
li.classList.remove('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
window.addEventListener('scroll', highlight, { passive: true });
|
||||
highlight();
|
||||
}
|
||||
|
||||
function init() {
|
||||
initModal();
|
||||
initDragSort();
|
||||
initSave();
|
||||
// Defer so section-navs.js can own TOC first.
|
||||
window.setTimeout(initFallbackToc, 50);
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* User auth apply form AJAX.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function ajaxUrl() {
|
||||
if (window.aksrtData && window.aksrtData.ajaxUrl) return window.aksrtData.ajaxUrl;
|
||||
return '/wp-admin/admin-ajax.php';
|
||||
}
|
||||
|
||||
function toast(msg, type) {
|
||||
if (window.aksrt && typeof window.aksrt.toast === 'function') {
|
||||
window.aksrt.toast(msg, type || 'info');
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line no-alert
|
||||
window.alert(msg);
|
||||
}
|
||||
|
||||
function init() {
|
||||
var form = document.querySelector('.aksrt-user-auth-form');
|
||||
if (!form) return;
|
||||
|
||||
form.addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
var btn = form.querySelector('button[type="submit"]');
|
||||
if (btn) btn.disabled = true;
|
||||
var fd = new FormData(form);
|
||||
if (!fd.get('action')) fd.set('action', 'aksrt_user_auth_apply');
|
||||
|
||||
fetch(ajaxUrl(), {
|
||||
method: 'POST',
|
||||
body: fd,
|
||||
credentials: 'same-origin',
|
||||
})
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (data) {
|
||||
if (!data || data.error) {
|
||||
toast((data && data.msg) || '提交失败', 'danger');
|
||||
return;
|
||||
}
|
||||
toast(data.msg || '提交成功', 'success');
|
||||
if (data.reload) {
|
||||
window.setTimeout(function () { window.location.reload(); }, 500);
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
toast('网络错误', 'danger');
|
||||
})
|
||||
.finally(function () {
|
||||
if (btn) btn.disabled = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
@@ -249,6 +249,18 @@ if (class_exists('\AKSRT\Core\CommentActions')) {
|
||||
if (class_exists('\AKSRT\Core\GoRedirect')) {
|
||||
\AKSRT\Core\GoRedirect::get_instance()->init();
|
||||
}
|
||||
if (class_exists('\AKSRT\Core\LinksSubmit')) {
|
||||
\AKSRT\Core\LinksSubmit::get_instance()->init();
|
||||
}
|
||||
if (class_exists('\AKSRT\Core\LinksPageMeta')) {
|
||||
\AKSRT\Core\LinksPageMeta::get_instance()->init();
|
||||
}
|
||||
if (class_exists('\AKSRT\Core\PostsNavs')) {
|
||||
\AKSRT\Core\PostsNavs::get_instance()->init();
|
||||
}
|
||||
if (class_exists('\AKSRT\User\AuthApply')) {
|
||||
\AKSRT\User\AuthApply::get_instance()->init();
|
||||
}
|
||||
if (class_exists('\AKSRT\Messages\SiteNotice')) {
|
||||
\AKSRT\Messages\SiteNotice::get_instance()->init();
|
||||
}
|
||||
|
||||
+34
-1
@@ -303,11 +303,32 @@ if (!empty($aksrt_bg_styles)) {
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if (function_exists('aksrt_header_payvip_bar')) {
|
||||
echo aksrt_header_payvip_bar(get_current_user_id()); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
if (function_exists('aksrt_header_user_checkin_btn')) {
|
||||
$checkin = aksrt_header_user_checkin_btn(get_current_user_id());
|
||||
if ($checkin !== '') {
|
||||
echo '<div class="mt6 em09" style="padding:2px;">' . $checkin . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
}
|
||||
if (function_exists('aksrt_header_user_wallet_mini')) {
|
||||
echo '<div class="mt6" style="padding:2px;">' . aksrt_header_user_wallet_mini(get_current_user_id()) . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
} else {
|
||||
?>
|
||||
<div class="user-dropdown__credits">
|
||||
<i class="fas fa-coins" aria-hidden="true"></i>
|
||||
<span class="user-dropdown__credits-label"><?php echo esc_html($aksrt_currency_name); ?></span>
|
||||
<span class="user-dropdown__credits-value"><?php echo esc_html(number_format_i18n($aksrt_user_credit)); ?></span>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
if (function_exists('aksrt_header_user_badges_row')) {
|
||||
echo aksrt_header_user_badges_row(get_current_user_id()); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
<div class="user-dropdown__sep"></div>
|
||||
|
||||
@@ -326,7 +347,7 @@ if (!empty($aksrt_bg_styles)) {
|
||||
<span><?php esc_html_e('发布内容', 'aksrt'); ?></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<a class="user-dropdown__action is-danger" href="<?php echo esc_url(wp_logout_url(home_url('/'))); ?>">
|
||||
<a class="user-dropdown__action is-danger" href="javascript:;" data-toggle="modal" data-target="#modal_signout">
|
||||
<span class="user-dropdown__action-icon is-red"><i class="fas fa-sign-out-alt" aria-hidden="true"></i></span>
|
||||
<span><?php esc_html_e('退出登录', 'aksrt'); ?></span>
|
||||
</a>
|
||||
@@ -370,6 +391,16 @@ if (!empty($aksrt_bg_styles)) {
|
||||
<span><?php esc_html_e('找回密码', 'aksrt'); ?></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if (class_exists('\AKSRT\Auth\OAuth') && method_exists(\AKSRT\Auth\OAuth::get_instance(), 'render_social_buttons')) {
|
||||
$oauth_html = (string) \AKSRT\Auth\OAuth::get_instance()->render_social_buttons(__('快速登录', 'aksrt'));
|
||||
if ($oauth_html !== '') {
|
||||
echo '<div class="social_loginbar mt10">' . $oauth_html . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
@@ -385,6 +416,8 @@ if (!empty($aksrt_bg_styles)) {
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<?php if (function_exists('aksrt_render_signout_modal')) { aksrt_render_signout_modal(); } ?>
|
||||
|
||||
|
||||
<?php if (!empty($aksrt_header_settings['mobile_drawer'])) : ?>
|
||||
<div class="mobile-header nav-drawer-backdrop" id="nav-drawer-backdrop" aria-hidden="true"></div>
|
||||
|
||||
@@ -43,6 +43,8 @@ require_once AKSRT_DIR . '/inc/helpers/aksrt-coupon-order.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-credits.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-null.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-ajax-list.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-links.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-header-userbox.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-identity.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-rewards.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/menu-decoration.php';
|
||||
|
||||
@@ -7,12 +7,11 @@ defined('ABSPATH') || exit;
|
||||
add_filter('show_admin_bar', '__return_false');
|
||||
|
||||
// ============================================================
|
||||
// 隐藏不需要的默认菜单项
|
||||
// WordPress 链接管理(网址导航 / 书签)
|
||||
// zibll enables link_manager; AKSRT keeps it for page-links.
|
||||
// ============================================================
|
||||
|
||||
add_action('admin_menu', function () {
|
||||
remove_menu_page('link-manager.php');
|
||||
});
|
||||
add_filter('pre_option_link_manager_enabled', '__return_true');
|
||||
|
||||
// ============================================================
|
||||
// Gravatar 头像源替换(4层拦截:get_avatar_url / pre_get_avatar_data / avatar_defaults / ob_start 兜底)
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
/**
|
||||
* Header user-box density helpers (zibll zib_header_user_box subset).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
if (!function_exists('aksrt_header_user_checkin_btn')) :
|
||||
/**
|
||||
* Check-in CTA for header dropdown (uses REST /aksrt/v1/signin).
|
||||
*/
|
||||
function aksrt_header_user_checkin_btn(int $user_id = 0): string {
|
||||
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
|
||||
if ($user_id <= 0 || !class_exists('\AKSRT\Credits\Signin')) {
|
||||
return '';
|
||||
}
|
||||
$cfg = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_signin_reward_settings()
|
||||
: ['enabled' => false];
|
||||
if (empty($cfg['enabled'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Lightweight today status via private API if available.
|
||||
$signed = false;
|
||||
try {
|
||||
$signin = \AKSRT\Credits\Signin::get_instance();
|
||||
// Prefer public method if present.
|
||||
if (method_exists($signin, 'is_signed_today')) {
|
||||
$signed = (bool) $signin->is_signed_today($user_id);
|
||||
} else {
|
||||
// Fallback: direct meta/table probe via rest_today logic is heavy; use option day key.
|
||||
$day = wp_date('Y-m-d');
|
||||
$signed = (bool) get_user_meta($user_id, 'aksrt_signin_' . $day, true);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$signed = false;
|
||||
}
|
||||
|
||||
if ($signed) {
|
||||
return '<button type="button" class="but block c-yellow aksrt-header-checkin is-done" disabled>'
|
||||
. '<i class="fa fa-calendar-check-o" aria-hidden="true"></i> '
|
||||
. esc_html__('今日已签到', 'aksrt')
|
||||
. '</button>';
|
||||
}
|
||||
|
||||
return '<button type="button" class="but block c-yellow aksrt-header-checkin" data-aksrt-checkin="1">'
|
||||
. '<i class="fa fa-calendar-check-o" aria-hidden="true"></i> '
|
||||
. esc_html__('签到领取今日奖励', 'aksrt')
|
||||
. '</button>';
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_header_user_wallet_mini')) :
|
||||
/**
|
||||
* Mini wallet strip: credits + cash balance.
|
||||
*/
|
||||
function aksrt_header_user_wallet_mini(int $user_id = 0): string {
|
||||
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
|
||||
if ($user_id <= 0) {
|
||||
return '';
|
||||
}
|
||||
$credits = function_exists('aksrt_user_credits') ? (int) aksrt_user_credits($user_id) : 0;
|
||||
$currency = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_currency_name()
|
||||
: __('积分', 'aksrt');
|
||||
$wallet = 0.0;
|
||||
if (class_exists('\AKSRT\Credits\Balance')) {
|
||||
$wallet = (float) \AKSRT\Credits\Balance::balance($user_id);
|
||||
}
|
||||
$center = function_exists('aksrt_get_user_center_url') ? aksrt_get_user_center_url('assets') : '#';
|
||||
|
||||
$html = '<a class="aksrt-header-wallet flex ac jsb" href="' . esc_url($center) . '">';
|
||||
$html .= '<span class="aksrt-header-wallet__item"><i class="fas fa-coins" aria-hidden="true"></i> '
|
||||
. esc_html($currency) . ' <b>' . esc_html(number_format_i18n($credits)) . '</b></span>';
|
||||
$html .= '<span class="aksrt-header-wallet__item"><i class="fas fa-wallet" aria-hidden="true"></i> '
|
||||
. esc_html__('余额', 'aksrt') . ' <b>' . esc_html(number_format_i18n($wallet, 2)) . '</b></span>';
|
||||
$html .= '</a>';
|
||||
return $html;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_header_user_badges_row')) :
|
||||
/**
|
||||
* Identity / medal chips under profile.
|
||||
*/
|
||||
function aksrt_header_user_badges_row(int $user_id = 0): string {
|
||||
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
|
||||
if ($user_id <= 0 || !function_exists('aksrt_render_user_identity_chips')) {
|
||||
return '';
|
||||
}
|
||||
$chips = aksrt_render_user_identity_chips($user_id, 'card');
|
||||
if ($chips === '') {
|
||||
return '';
|
||||
}
|
||||
return '<div class="em09 author-tag mb10 mt6 flex jc aksrt-header-badges">' . $chips . '</div>';
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_header_payvip_bar')) :
|
||||
/**
|
||||
* VIP status / open CTA bar.
|
||||
*/
|
||||
function aksrt_header_payvip_bar(int $user_id = 0): string {
|
||||
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
|
||||
if ($user_id <= 0) {
|
||||
return '';
|
||||
}
|
||||
$badge = function_exists('aksrt_render_vip_badge') ? aksrt_render_vip_badge($user_id, 'md') : '';
|
||||
if ($badge !== '') {
|
||||
return '<div class="mt10 em09 aksrt-header-payvip">' . $badge . '</div>';
|
||||
}
|
||||
// Guest-style open VIP for non-members if VIP feature on.
|
||||
$vip_url = function_exists('aksrt_get_user_center_url') ? aksrt_get_user_center_url('vip') : '#';
|
||||
$enabled = true;
|
||||
if (class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'get_vip_settings')) {
|
||||
$vs = \AKSRT\Settings\Settings::get_vip_settings();
|
||||
$enabled = !empty($vs['enabled']) || !empty($vs['vip1_enabled']) || !empty($vs['vip2_enabled']);
|
||||
}
|
||||
if (!$enabled) {
|
||||
return '';
|
||||
}
|
||||
return '<div class="mt10 em09 aksrt-header-payvip">'
|
||||
. '<a class="but jb-red radius4 payvip-icon btn-block" href="' . esc_url($vip_url) . '">'
|
||||
. '<i class="fa fa-diamond mr6" aria-hidden="true"></i>'
|
||||
. esc_html__('开通会员 尊享会员权益', 'aksrt')
|
||||
. '</a></div>';
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_render_signout_modal')) :
|
||||
/**
|
||||
* Confirm logout modal markup (once per page).
|
||||
*/
|
||||
function aksrt_render_signout_modal(): void {
|
||||
static $done = false;
|
||||
if ($done || !is_user_logged_in()) {
|
||||
return;
|
||||
}
|
||||
$done = true;
|
||||
$logout = wp_logout_url(home_url('/'));
|
||||
?>
|
||||
<div class="modal fade" id="modal_signout" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-mini" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body text-center" style="padding:24px;">
|
||||
<div class="em2x mb10"><i class="fa fa-sign-out" aria-hidden="true"></i></div>
|
||||
<div class="mb15"><?php esc_html_e('确认退出当前账号?', 'aksrt'); ?></div>
|
||||
<div class="but-average flex jc" style="gap:10px;">
|
||||
<button type="button" class="but" data-dismiss="modal"><?php esc_html_e('取消', 'aksrt'); ?></button>
|
||||
<a class="but c-red" href="<?php echo esc_url($logout); ?>"><?php esc_html_e('确认退出', 'aksrt'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
endif;
|
||||
@@ -0,0 +1,486 @@
|
||||
<?php
|
||||
/**
|
||||
* 网址导航 / 书签链接渲染(zibll pages/links.php + zib_links_box parity).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
if (!function_exists('aksrt_go_link')) :
|
||||
/**
|
||||
* Wrap external URL with /go/ intermediate page when enabled.
|
||||
*/
|
||||
function aksrt_go_link(string $url, bool $force = false): string {
|
||||
$url = esc_url_raw($url);
|
||||
if ($url === '') {
|
||||
return '';
|
||||
}
|
||||
if (!$force && class_exists('\AKSRT\Settings\Settings') && empty(\AKSRT\Settings\Settings::get_value('seo_go_link', true))) {
|
||||
return $url;
|
||||
}
|
||||
if (class_exists('\AKSRT\Core\GoRedirect')) {
|
||||
return \AKSRT\Core\GoRedirect::get_instance()->create_go_link($url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_page_links_settings')) :
|
||||
/**
|
||||
* Read page_links_* meta for a page.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
function aksrt_get_page_links_settings(int $post_id = 0): array {
|
||||
if ($post_id <= 0) {
|
||||
$post_id = (int) get_queried_object_id();
|
||||
}
|
||||
$cats = get_post_meta($post_id, 'page_links_category', true);
|
||||
if (!is_array($cats)) {
|
||||
$cats = $cats !== '' && $cats !== null ? array_filter(array_map('intval', (array) $cats)) : [];
|
||||
} else {
|
||||
$cats = array_values(array_filter(array_map('intval', $cats)));
|
||||
}
|
||||
$search_types = get_post_meta($post_id, 'page_links_search_types', true);
|
||||
if (!is_array($search_types)) {
|
||||
$search_types = $search_types ? array_values(array_filter(array_map('sanitize_key', (array) $search_types))) : [];
|
||||
} else {
|
||||
$search_types = array_values(array_filter(array_map('sanitize_key', $search_types)));
|
||||
}
|
||||
$submit_cats = get_post_meta($post_id, 'page_links_submit_cats', true);
|
||||
if (!is_array($submit_cats)) {
|
||||
$submit_cats = $submit_cats !== '' && $submit_cats !== null ? array_filter(array_map('intval', (array) $submit_cats)) : [];
|
||||
} else {
|
||||
$submit_cats = array_values(array_filter(array_map('intval', $submit_cats)));
|
||||
}
|
||||
|
||||
$style = sanitize_key((string) get_post_meta($post_id, 'page_links_style', true));
|
||||
if (!in_array($style, ['card', 'bigcard', 'image', 'simple'], true)) {
|
||||
$style = 'card';
|
||||
}
|
||||
$orderby = sanitize_key((string) get_post_meta($post_id, 'page_links_orderby', true));
|
||||
if (!in_array($orderby, ['name', 'updated', 'rating', 'rand', 'id', 'length'], true)) {
|
||||
$orderby = 'name';
|
||||
}
|
||||
$order = strtoupper((string) get_post_meta($post_id, 'page_links_order', true));
|
||||
if (!in_array($order, ['ASC', 'DESC'], true)) {
|
||||
$order = 'ASC';
|
||||
}
|
||||
$position = sanitize_key((string) get_post_meta($post_id, 'page_links_content_position', true));
|
||||
if (!in_array($position, ['top', 'bottom'], true)) {
|
||||
$position = 'top';
|
||||
}
|
||||
|
||||
return [
|
||||
'content_s' => (bool) get_post_meta($post_id, 'page_links_content_s', true),
|
||||
'content_position' => $position,
|
||||
'search_s' => (bool) get_post_meta($post_id, 'page_links_search_s', true),
|
||||
'search_types' => $search_types,
|
||||
'category' => $cats,
|
||||
'style' => $style,
|
||||
'limit' => max(0, (int) get_post_meta($post_id, 'page_links_limit', true)),
|
||||
'orderby' => $orderby,
|
||||
'order' => $order,
|
||||
'go_s' => (bool) get_post_meta($post_id, 'page_links_go_s', true),
|
||||
'blank_s' => (bool) get_post_meta($post_id, 'page_links_blank_s', true),
|
||||
// Default nofollow ON (zibll default true).
|
||||
'nofollow_s' => get_post_meta($post_id, 'page_links_nofollow_s', true) === ''
|
||||
? true
|
||||
: (bool) get_post_meta($post_id, 'page_links_nofollow_s', true),
|
||||
'submit_s' => (bool) get_post_meta($post_id, 'page_links_submit_s', true),
|
||||
'submit_sign_s' => get_post_meta($post_id, 'page_links_submit_sign_s', true) === ''
|
||||
? true
|
||||
: (bool) get_post_meta($post_id, 'page_links_submit_sign_s', true),
|
||||
'submit_cats' => $submit_cats,
|
||||
'submit_title' => (string) (get_post_meta($post_id, 'page_links_submit_title', true) ?: __('申请入驻', 'aksrt')),
|
||||
'submit_dec' => (string) get_post_meta($post_id, 'page_links_submit_dec', true),
|
||||
];
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_links_box')) :
|
||||
/**
|
||||
* Render bookmark cards (zibll zib_links_box).
|
||||
*
|
||||
* @param array<int,object|array> $links Bookmark rows from get_bookmarks().
|
||||
*/
|
||||
function aksrt_links_box($links = [], string $type = 'card', bool $nofollow = true, bool $go_link = false, bool $blank_s = false): string {
|
||||
if (empty($links) || !is_array($links)) {
|
||||
return '';
|
||||
}
|
||||
$type = in_array($type, ['card', 'bigcard', 'image', 'simple'], true) ? $type : 'card';
|
||||
$placeholder = get_template_directory_uri() . '/assets/img/placeholder.svg';
|
||||
$html = '';
|
||||
$i = 0;
|
||||
|
||||
foreach ($links as $raw) {
|
||||
$link = (array) $raw;
|
||||
if (empty($link['href']) && !empty($link['link_url'])) {
|
||||
$link['href'] = $link['link_url'];
|
||||
}
|
||||
if (empty($link['title']) && !empty($link['link_name'])) {
|
||||
$link['title'] = $link['link_name'];
|
||||
}
|
||||
if (empty($link['src']) && !empty($link['link_image'])) {
|
||||
$link['src'] = $link['link_image'];
|
||||
}
|
||||
if (empty($link['desc']) && !empty($link['link_description'])) {
|
||||
$link['desc'] = $link['link_description'];
|
||||
}
|
||||
if ($blank_s) {
|
||||
$link['blank'] = true;
|
||||
}
|
||||
if (empty($link['blank']) && !empty($link['link_target'])) {
|
||||
$link['blank'] = true;
|
||||
}
|
||||
|
||||
$href = !empty($link['href']) ? (string) $link['href'] : '';
|
||||
$title = !empty($link['title']) ? (string) $link['title'] : '';
|
||||
if ($href === '' || $title === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($go_link || !empty($link['go_link'])) {
|
||||
$href = aksrt_go_link($href, true);
|
||||
} else {
|
||||
$href = esc_url($href);
|
||||
}
|
||||
|
||||
$src = !empty($link['src']) ? esc_url((string) $link['src']) : '';
|
||||
$blank = !empty($link['blank']) ? ' target="_blank"' : '';
|
||||
$dec = !empty($link['desc']) ? (string) $link['desc'] : '';
|
||||
$rel = $nofollow ? ' rel="nofollow noopener noreferrer"' : ' rel="noopener noreferrer"';
|
||||
$img_src = $src !== '' ? $src : $placeholder;
|
||||
$img = '<img class="lazyload avatar" src="' . esc_url($placeholder) . '" data-src="' . esc_url($img_src) . '" alt="" loading="lazy">';
|
||||
$data_dec = $dec !== ''
|
||||
? ' title="' . esc_attr($title) . '" data-content="' . esc_attr($dec) . '"'
|
||||
: ' data-content="' . esc_attr($title) . '"';
|
||||
|
||||
if ($type === 'bigcard') {
|
||||
$html .= '<div class="author-minicard links-card radius8 big-card">';
|
||||
$html .= '<a' . $blank . ' href="' . esc_url($href) . '" title="' . esc_attr($dec) . '"' . $rel . '>';
|
||||
$html .= '<div class="avatar-img link-img">' . $img . '</div>';
|
||||
$html .= '<div class="text-ellipsis mt20 font-bold">' . esc_html($title) . '</div>';
|
||||
if ($dec !== '') {
|
||||
$html .= '<dd class="mt6 avatar-dest em09 muted-3-color text-ellipsis">' . esc_html($dec) . '</dd>';
|
||||
}
|
||||
$html .= '</a></div>';
|
||||
} elseif ($type === 'image') {
|
||||
$html .= '<a' . $blank . ' class="avatar-img link-img link-only-img" data-trigger="hover" data-toggle="popover" data-placement="top"'
|
||||
. $data_dec . ' href="' . esc_url($href) . '"' . $rel . '>' . $img . '</a>';
|
||||
} elseif ($type === 'simple') {
|
||||
$sc = $i === 0 ? '' : 'icon-spot';
|
||||
$html .= '<a' . $blank . ' class="' . esc_attr($sc) . '" data-trigger="hover" data-toggle="popover" data-placement="top"'
|
||||
. $data_dec . ' href="' . esc_url($href) . '"' . $rel . '>' . esc_html($title) . '</a>';
|
||||
} else {
|
||||
$html .= '<div class="author-minicard links-card radius8"><a' . $blank . ' href="' . esc_url($href) . '" title="' . esc_attr($dec) . '"' . $rel . '>';
|
||||
$html .= '<ul class="list-inline">';
|
||||
$html .= '<li><div class="avatar-img link-img">' . $img . '</div></li>';
|
||||
$html .= '<li><dl><dt class="text-ellipsis">' . esc_html($title) . '</dt>';
|
||||
if ($dec !== '') {
|
||||
$html .= '<dd class="mt3 avatar-dest em09 muted-3-color text-ellipsis">' . esc_html($dec) . '</dd>';
|
||||
}
|
||||
$html .= '</dl></li></ul></a></div>';
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_page_links_html')) :
|
||||
/**
|
||||
* Build the multi/single category links block for a page.
|
||||
*/
|
||||
function aksrt_page_links_html(int $post_id = 0): string {
|
||||
$post_id = $post_id > 0 ? $post_id : (int) get_queried_object_id();
|
||||
$s = aksrt_get_page_links_settings($post_id);
|
||||
$cats = $s['category'];
|
||||
if (empty($cats)) {
|
||||
if (current_user_can('manage_links')) {
|
||||
return '<div class="mb20"><a class="author-minicard links-card radius8" href="' . esc_url(admin_url('link-manager.php')) . '" target="_blank" rel="noopener">'
|
||||
. esc_html__('添加链接', 'aksrt') . '</a></div>';
|
||||
}
|
||||
return '<div class="author-minicard links-card radius8 mb20">' . esc_html__('暂无链接', 'aksrt') . '</div>';
|
||||
}
|
||||
|
||||
$limit = (int) $s['limit'];
|
||||
$orderby = (string) $s['orderby'];
|
||||
$order = (string) $s['order'];
|
||||
$style = (string) $s['style'];
|
||||
$nofollow = (bool) $s['nofollow_s'];
|
||||
$go_s = (bool) $s['go_s'];
|
||||
$blank_s = (bool) $s['blank_s'];
|
||||
$submit_s = (bool) $s['submit_s'];
|
||||
$submit_title = (string) $s['submit_title'];
|
||||
$is_mobile = wp_is_mobile();
|
||||
$links_con = '';
|
||||
|
||||
if (count($cats) > 1) {
|
||||
$link_cat_con = '';
|
||||
$link_cat_nav = '';
|
||||
foreach ($cats as $cat_id) {
|
||||
$args = [
|
||||
'orderby' => $orderby,
|
||||
'order' => $order,
|
||||
'limit' => $limit > 0 ? $limit : -1,
|
||||
'category' => (int) $cat_id,
|
||||
];
|
||||
$_link = aksrt_links_box(get_bookmarks($args), $style, $nofollow, $go_s, $blank_s);
|
||||
if (!$_link) {
|
||||
continue;
|
||||
}
|
||||
$term = get_term((int) $cat_id, 'link_category');
|
||||
if (!$term || is_wp_error($term)) {
|
||||
continue;
|
||||
}
|
||||
$_id = 'links-' . (int) $cat_id;
|
||||
$link_cat_con .= '<div class="mb20 links-cat-box"><div class="links-cat-header"><div class="title-theme"><div id="' . esc_attr($_id) . '">'
|
||||
. esc_html($term->name) . '</div></div></div><div class="links-box links-style-' . esc_attr($style) . '">' . $_link . '</div></div>';
|
||||
$link_cat_nav .= '<li class="n-H2"><a class="text-ellipsis" href="#' . esc_attr($_id) . '">' . esc_html($term->name) . '</a></li>';
|
||||
}
|
||||
|
||||
if ($link_cat_con === '') {
|
||||
$links_con = '';
|
||||
} else {
|
||||
$submit_nav = $submit_s
|
||||
? '<div class="link-nav-submit"><a class="padding-h10 hollow but c-theme btn-block text-ellipsis" href="#submit-links-modal" data-toggle="modal">'
|
||||
. esc_html($submit_title) . '</a></div>'
|
||||
: '';
|
||||
$submit_con = $submit_s
|
||||
? '<div class="link-cat-submit"><a class="padding-h10 hollow but c-theme btn-block text-ellipsis" href="#submit-links-modal" data-toggle="modal">'
|
||||
. esc_html($submit_title) . '</a></div>'
|
||||
: '';
|
||||
$offset_top = $is_mobile ? '-8' : '';
|
||||
$offset_bottom = $is_mobile ? '20' : '-30';
|
||||
$links_con = '<div class="fixed-wrap">'
|
||||
. '<div class="fixed-wrap-nav affix-header-sm affix link-nav-box tab-auto-center-sm" data-offset-top="' . esc_attr((string) $offset_top) . '" data-offset-bottom="' . esc_attr((string) $offset_bottom) . '">'
|
||||
. '<div class="zib-widget"><ul class="nav list-inline scroll-x mini-scrollbar tab-nav-theme">' . $link_cat_nav . '</ul></div>'
|
||||
. $submit_nav
|
||||
. '</div><div class="fixed-wrap-content">' . $link_cat_con . $submit_con . '</div></div>';
|
||||
}
|
||||
} else {
|
||||
$cat_id = (int) $cats[0];
|
||||
$args = [
|
||||
'orderby' => $orderby,
|
||||
'order' => $order,
|
||||
'limit' => $limit > 0 ? $limit : -1,
|
||||
'category' => $cat_id,
|
||||
];
|
||||
$submit_con = $submit_s
|
||||
? '<div class="mt20"><a class="padding-h10 hollow but c-theme btn-block text-ellipsis" href="#submit-links-modal" data-toggle="modal">'
|
||||
. esc_html($submit_title) . '</a></div>'
|
||||
: '';
|
||||
$links_con = '<div class="links-box links-style-' . esc_attr($style) . '">'
|
||||
. aksrt_links_box(get_bookmarks($args), $style, $nofollow, $go_s, $blank_s)
|
||||
. '</div>' . $submit_con;
|
||||
}
|
||||
|
||||
if ($links_con === '') {
|
||||
if (current_user_can('manage_links')) {
|
||||
return '<div class="mb20"><a class="author-minicard links-card radius8" href="' . esc_url(admin_url('link-manager.php')) . '" target="_blank" rel="noopener">'
|
||||
. esc_html__('添加链接', 'aksrt') . '</a></div>';
|
||||
}
|
||||
return '<div class="author-minicard links-card radius8 mb20">' . esc_html__('暂无链接', 'aksrt') . '</div>';
|
||||
}
|
||||
|
||||
return '<div class="links-page-container mb20">' . $links_con . '</div>';
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_link_get_search_cover')) :
|
||||
/**
|
||||
* Search cover with multi-engine tabs (zibll zib_link_get_search_cover).
|
||||
*/
|
||||
function aksrt_link_get_search_cover(int $post_id = 0): string {
|
||||
$post_id = $post_id > 0 ? $post_id : (int) get_queried_object_id();
|
||||
$s = aksrt_get_page_links_settings($post_id);
|
||||
if (empty($s['search_s']) || empty($s['search_types'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$search_types_args = [
|
||||
'self' => [
|
||||
'name' => __('站内', 'aksrt'),
|
||||
'input_name' => 's',
|
||||
'url' => home_url('/'),
|
||||
],
|
||||
'baidu' => [
|
||||
'name' => __('百度', 'aksrt'),
|
||||
'input_name' => 'wd',
|
||||
'url' => 'https://www.baidu.com/s',
|
||||
],
|
||||
'google' => [
|
||||
'name' => __('谷歌', 'aksrt'),
|
||||
'input_name' => 'q',
|
||||
'url' => 'https://www.google.com/search',
|
||||
],
|
||||
'bing' => [
|
||||
'name' => __('必应', 'aksrt'),
|
||||
'input_name' => 'q',
|
||||
'url' => 'https://cn.bing.com/search',
|
||||
],
|
||||
'sogou' => [
|
||||
'name' => __('搜狗', 'aksrt'),
|
||||
'input_name' => 'query',
|
||||
'url' => 'https://www.sogou.com/web',
|
||||
],
|
||||
'360' => [
|
||||
'name' => '360',
|
||||
'input_name' => 'q',
|
||||
'url' => 'https://www.so.com/s',
|
||||
],
|
||||
];
|
||||
|
||||
$type_nav = '';
|
||||
$type_con = '';
|
||||
$i = 0;
|
||||
foreach ($s['search_types'] as $k) {
|
||||
if (!isset($search_types_args[$k])) {
|
||||
continue;
|
||||
}
|
||||
$cfg = $search_types_args[$k];
|
||||
$active = $i === 0 ? ' active' : '';
|
||||
$pane_id = 'link-page-' . $post_id . '-' . $k;
|
||||
$type_nav .= '<li class="' . esc_attr(trim($active)) . '"><a href="javascript:;" data-aksrt-tab-target="#' . esc_attr($pane_id) . '">'
|
||||
. esc_html($cfg['name']) . '</a></li>';
|
||||
$type_con .= '<div class="tab-pane' . ($i === 0 ? ' in active' : '') . '" id="' . esc_attr($pane_id) . '">'
|
||||
. '<form method="get" target="_blank" class="padding-10 search-form" action="' . esc_url($cfg['url']) . '">'
|
||||
. '<div class="line-form blur-bg"><div class="search-input-text">'
|
||||
. '<input type="text" name="' . esc_attr($cfg['input_name']) . '" class="line-form-input" tabindex="1" value="" autocomplete="off">'
|
||||
. '<i class="line-form-line"></i>'
|
||||
. '<div class="scale-placeholder">' . esc_html(sprintf(__('%s搜索', 'aksrt'), $cfg['name'])) . '</div>'
|
||||
. '<div class="abs-right muted-color"><button type="submit" tabindex="2" class="null" aria-label="' . esc_attr__('搜索', 'aksrt') . '">'
|
||||
. '<i class="fa fa-search" aria-hidden="true"></i></button></div>'
|
||||
. '</div></div></form></div>';
|
||||
$i++;
|
||||
}
|
||||
if ($type_nav === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$title = get_the_title($post_id);
|
||||
$img = '';
|
||||
$thumb_id = get_post_thumbnail_id($post_id);
|
||||
if ($thumb_id) {
|
||||
$image = wp_get_attachment_image_src($thumb_id, 'full');
|
||||
$img = !empty($image[0]) ? (string) $image[0] : '';
|
||||
}
|
||||
if ($img === '') {
|
||||
$img = (string) get_post_meta($post_id, 'page_header_cover_img', true);
|
||||
}
|
||||
if ($img === '' && class_exists('\AKSRT\Settings\Settings')) {
|
||||
$img = (string) \AKSRT\Settings\Settings::get_value('page_header_cover_img', '');
|
||||
}
|
||||
if ($img === '') {
|
||||
$img = get_template_directory_uri() . '/assets/img/placeholder.svg';
|
||||
}
|
||||
$src = get_template_directory_uri() . '/assets/img/placeholder.svg';
|
||||
|
||||
$search = '<div class="header-slider-search abs-center"><div class="header-slider-search-more text-center before">'
|
||||
. '<div class="em14 font-bold mb10">' . esc_html($title) . '</div></div>'
|
||||
. '<div class="search-input"><div class="flex jc"><ul class="list-inline scroll-x mini-scrollbar tab-nav-theme">' . $type_nav . '</ul></div>'
|
||||
. '<div class="tab-content">' . $type_con . '</div></div></div>';
|
||||
|
||||
return '<div class="page-cover theme-box radius8 main-shadow link-page-search-cover">'
|
||||
. '<img class="fit-cover no-scale lazyload" src="' . esc_url($src) . '" data-src="' . esc_url($img) . '" alt="">'
|
||||
. $search . '</div>';
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_submit_links_modal')) :
|
||||
/**
|
||||
* Frontend submit modal markup (zibll zib_submit_links_modal).
|
||||
*
|
||||
* @param array{title?:string,dec?:string,sign?:bool,cats?:int[]} $args
|
||||
*/
|
||||
function aksrt_submit_links_modal(array $args = []): string {
|
||||
$defaults = [
|
||||
'title' => __('申请入驻', 'aksrt'),
|
||||
'dec' => '',
|
||||
'sign' => true,
|
||||
'cats' => [],
|
||||
];
|
||||
$args = array_merge($defaults, $args);
|
||||
$title = (string) $args['title'];
|
||||
$header = $title !== ''
|
||||
? '<div class="mb20"><button type="button" class="close" data-dismiss="modal" aria-label="' . esc_attr__('关闭', 'aksrt') . '">'
|
||||
. '<i class="fa fa-times" aria-hidden="true"></i></button>'
|
||||
. '<b class="modal-title flex ac"><span class="toggle-radius mr10 b-theme"><i class="fa fa-pencil-square-o" aria-hidden="true"></i></span>'
|
||||
. esc_html($title) . '</b></div>'
|
||||
: '';
|
||||
|
||||
$body = '';
|
||||
if (!empty($args['dec'])) {
|
||||
$body .= '<div class="muted-box em09">' . wp_kses_post((string) $args['dec']) . '</div>';
|
||||
}
|
||||
|
||||
$need_login = !empty($args['sign']) && !is_user_logged_in();
|
||||
if ($need_login) {
|
||||
$sign_url = function_exists('aksrt_get_login_url')
|
||||
? aksrt_get_login_url()
|
||||
: (function_exists('aksrt_get_sign_page_url') ? aksrt_get_sign_page_url('login') : wp_login_url());
|
||||
$body .= '<div class="muted-box text-center">';
|
||||
$body .= '<div class="mb20 muted-3-color">' . esc_html__('请先登录', 'aksrt') . '</div>';
|
||||
$body .= '<p><a href="' . esc_url($sign_url) . '" class="signin-loader but c-blue padding-lg">'
|
||||
. '<i class="fa fa-fw fa-sign-in mr10" aria-hidden="true"></i>' . esc_html__('登录', 'aksrt') . '</a></p>';
|
||||
if (class_exists('\AKSRT\Auth\OAuth') && method_exists(\AKSRT\Auth\OAuth::get_instance(), 'render_social_buttons')) {
|
||||
$social = (string) \AKSRT\Auth\OAuth::get_instance()->render_social_buttons(__('使用以下方式快速登录', 'aksrt'));
|
||||
if ($social !== '') {
|
||||
$body .= '<div class="social_loginbar">' . $social . '</div>';
|
||||
}
|
||||
}
|
||||
$body .= '</div>';
|
||||
} else {
|
||||
$term_args = [
|
||||
'taxonomy' => 'link_category',
|
||||
'hide_empty' => false,
|
||||
];
|
||||
if (!empty($args['cats']) && is_array($args['cats'])) {
|
||||
$term_args['include'] = array_map('intval', $args['cats']);
|
||||
$term_args['orderby'] = 'include';
|
||||
}
|
||||
$terms = get_terms($term_args);
|
||||
$cats_options = '';
|
||||
if (!is_wp_error($terms) && !empty($terms)) {
|
||||
foreach ($terms as $item) {
|
||||
$cats_options .= '<option value="' . (int) $item->term_id . '">' . esc_html($item->name) . '</option>';
|
||||
}
|
||||
}
|
||||
$cats_field = $cats_options !== ''
|
||||
? '<div class="col-sm-12 mb10"><div class="em09 muted-2-color mb6">' . esc_html__('网站类别', 'aksrt') . '</div>'
|
||||
. '<div class="form-select"><select name="link_category" class="form-control">' . $cats_options . '</select></div></div>'
|
||||
: '';
|
||||
|
||||
$placeholder_upload = get_template_directory_uri() . '/assets/img/placeholder.svg';
|
||||
$body .= '<form class="form-horizontal mt10 form-upload aksrt-links-submit-form" enctype="multipart/form-data">';
|
||||
$body .= '<div class="row gutters-5">';
|
||||
$body .= '<div class="col-sm-6 mb10"><div class="em09 muted-2-color mb6">' . esc_html__('网站名称(必填)', 'aksrt') . '</div>'
|
||||
. '<input type="text" class="form-control" name="link_name" required placeholder="' . esc_attr__('请输入网站名称', 'aksrt') . '"></div>';
|
||||
$body .= '<div class="col-sm-6 mb10"><div class="em09 muted-2-color mb6">' . esc_html__('网站地址(必填)', 'aksrt') . '</div>'
|
||||
. '<input type="url" class="form-control" name="link_url" required placeholder="https://..."></div>';
|
||||
$body .= '<div class="col-sm-12 mb10"><div class="em09 muted-2-color mb6">' . esc_html__('网站简介', 'aksrt') . '</div>'
|
||||
. '<input type="text" class="form-control" name="link_description" placeholder="' . esc_attr__('一句话介绍网站', 'aksrt') . '"></div>';
|
||||
$body .= $cats_field;
|
||||
$body .= '<div class="col-sm-12 mb10"><div class="em09 muted-2-color mb6">' . esc_html__('LOGO图像', 'aksrt') . '</div>'
|
||||
. '<label class="pointer"><div class="preview preview-square"><img class="fit-cover aksrt-links-logo-preview" src="'
|
||||
. esc_url($placeholder_upload) . '" alt=""></div>'
|
||||
. '<input class="hide aksrt-links-logo-input" type="file" accept="image/gif,image/jpeg,image/jpg,image/png" name="image"></label>'
|
||||
. '<div class="px12 muted-2-color mb6">' . esc_html__('请选择正方形 LOGO,支持 jpg/png/gif', 'aksrt') . '</div></div>';
|
||||
$body .= '</div>';
|
||||
$body .= '<div class="text-right edit-footer">'
|
||||
. '<button type="submit" class="but c-blue padding-lg aksrt-links-submit-btn"><i class="fa fa-check" aria-hidden="true"></i>'
|
||||
. esc_html__('确认提交', 'aksrt') . '</button></div>';
|
||||
$body .= wp_nonce_field('aksrt_frontend_links_submit', '_wpnonce', false, false);
|
||||
$body .= '<input type="hidden" name="action" value="aksrt_frontend_links_submit">';
|
||||
$body .= '</form>';
|
||||
}
|
||||
|
||||
return '<div class="modal fade" id="submit-links-modal" tabindex="-1" role="dialog" aria-hidden="true">'
|
||||
. '<div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-body">'
|
||||
. $header . $body
|
||||
. '</div></div></div></div>';
|
||||
}
|
||||
endif;
|
||||
@@ -550,6 +550,18 @@ class UsersMenus {
|
||||
} elseif ($status === 'verified') {
|
||||
delete_user_meta($user_id, 'aksrt_user_verify_reason');
|
||||
}
|
||||
// Promote apply payload to public auth info when approved.
|
||||
if ($status === 'verified') {
|
||||
$apply = get_user_meta($user_id, 'aksrt_user_verify_apply', true);
|
||||
if (is_array($apply)) {
|
||||
update_user_meta($user_id, 'aksrt_user_verify_info', [
|
||||
'name' => (string) ($apply['name'] ?? ''),
|
||||
'desc' => (string) ($apply['desc'] ?? ''),
|
||||
'type' => (string) ($apply['type'] ?? ''),
|
||||
'time' => current_time('Y-m-d H:i'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
$log = get_option('aksrt_verify_review_log', []);
|
||||
$log = is_array($log) ? $log : [];
|
||||
$log[] = [
|
||||
|
||||
@@ -0,0 +1,302 @@
|
||||
<?php
|
||||
/**
|
||||
* Page meta for 网址导航 template (page_links_* keys, zibll metabox parity).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
namespace AKSRT\Core;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class LinksPageMeta {
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
public static function get_instance(): self {
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function init(): void {
|
||||
add_action('add_meta_boxes', [$this, 'register_meta_box']);
|
||||
add_action('save_post_page', [$this, 'save_meta_box']);
|
||||
}
|
||||
|
||||
public function register_meta_box(): void {
|
||||
add_meta_box(
|
||||
'aksrt_page_links_meta',
|
||||
__('网址导航设置', 'aksrt'),
|
||||
[$this, 'render_meta_box'],
|
||||
'page',
|
||||
'normal',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether current page uses the links template.
|
||||
*/
|
||||
private function is_links_template(int $post_id): bool {
|
||||
$tpl = (string) get_post_meta($post_id, '_wp_page_template', true);
|
||||
return $tpl === 'templates/pages/page-links.php';
|
||||
}
|
||||
|
||||
public function render_meta_box(\WP_Post $post): void {
|
||||
$post_id = (int) $post->ID;
|
||||
if (!$this->is_links_template($post_id)) {
|
||||
echo '<p class="description">' . esc_html__('将页面模板设为「AKSRT - 网址导航」后在此配置分类、样式与提交模块。', 'aksrt') . '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
$s = function_exists('aksrt_get_page_links_settings')
|
||||
? aksrt_get_page_links_settings($post_id)
|
||||
: [];
|
||||
|
||||
wp_nonce_field('aksrt_page_links_meta', 'aksrt_page_links_meta_nonce');
|
||||
|
||||
$terms = get_terms([
|
||||
'taxonomy' => 'link_category',
|
||||
'hide_empty' => false,
|
||||
]);
|
||||
if (is_wp_error($terms)) {
|
||||
$terms = [];
|
||||
}
|
||||
|
||||
$selected_cats = array_map('intval', (array) ($s['category'] ?? []));
|
||||
$submit_cats = array_map('intval', (array) ($s['submit_cats'] ?? []));
|
||||
$search_types = (array) ($s['search_types'] ?? []);
|
||||
$engine_options = [
|
||||
'self' => __('站内', 'aksrt'),
|
||||
'baidu' => __('百度', 'aksrt'),
|
||||
'google' => __('谷歌', 'aksrt'),
|
||||
'bing' => __('必应', 'aksrt'),
|
||||
'sogou' => __('搜狗', 'aksrt'),
|
||||
'360' => '360',
|
||||
];
|
||||
?>
|
||||
<table class="form-table aksrt-page-links-meta" role="presentation">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('显示页面内容', 'aksrt'); ?></th>
|
||||
<td>
|
||||
<label>
|
||||
<input type="checkbox" name="page_links_content_s" value="1" <?php checked(!empty($s['content_s'])); ?>>
|
||||
<?php esc_html_e('在链接列表上下方展示页面正文', 'aksrt'); ?>
|
||||
</label>
|
||||
<p>
|
||||
<label>
|
||||
<input type="radio" name="page_links_content_position" value="top" <?php checked(($s['content_position'] ?? 'top'), 'top'); ?>>
|
||||
<?php esc_html_e('链接列表上面', 'aksrt'); ?>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<input type="radio" name="page_links_content_position" value="bottom" <?php checked(($s['content_position'] ?? ''), 'bottom'); ?>>
|
||||
<?php esc_html_e('链接列表下面', 'aksrt'); ?>
|
||||
</label>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('搜索引擎模块', 'aksrt'); ?></th>
|
||||
<td>
|
||||
<label>
|
||||
<input type="checkbox" name="page_links_search_s" value="1" <?php checked(!empty($s['search_s'])); ?>>
|
||||
<?php esc_html_e('显示搜索封面(使用特色图作背景)', 'aksrt'); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e('选择引擎(可多选,按住 Ctrl)', 'aksrt'); ?></p>
|
||||
<select name="page_links_search_types[]" multiple class="widefat" size="6">
|
||||
<?php foreach ($engine_options as $key => $label) : ?>
|
||||
<option value="<?php echo esc_attr($key); ?>" <?php selected(in_array($key, $search_types, true)); ?>>
|
||||
<?php echo esc_html($label); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('链接分类(必选)', 'aksrt'); ?></th>
|
||||
<td>
|
||||
<?php if (empty($terms)) : ?>
|
||||
<p class="description">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: link manager URL */
|
||||
wp_kses_post(__('暂无链接分类。请先在 <a href="%s">链接管理</a> 中创建分类与链接。', 'aksrt')),
|
||||
esc_url(admin_url('link-manager.php'))
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<?php else : ?>
|
||||
<select name="page_links_category[]" multiple class="widefat" size="8">
|
||||
<?php foreach ($terms as $term) : ?>
|
||||
<option value="<?php echo (int) $term->term_id; ?>" <?php selected(in_array((int) $term->term_id, $selected_cats, true)); ?>>
|
||||
<?php echo esc_html($term->name . ' (' . (int) $term->count . ')'); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<p class="description"><?php esc_html_e('多选时按导航目录展示;一个都不选则不显示链接。', 'aksrt'); ?></p>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('显示样式', 'aksrt'); ?></th>
|
||||
<td>
|
||||
<?php
|
||||
$style = (string) ($s['style'] ?? 'card');
|
||||
$styles = [
|
||||
'card' => __('图文列表', 'aksrt'),
|
||||
'bigcard' => __('大卡片', 'aksrt'),
|
||||
'image' => __('纯图片', 'aksrt'),
|
||||
];
|
||||
foreach ($styles as $key => $label) :
|
||||
?>
|
||||
<label style="margin-right:12px;">
|
||||
<input type="radio" name="page_links_style" value="<?php echo esc_attr($key); ?>" <?php checked($style, $key); ?>>
|
||||
<?php echo esc_html($label); ?>
|
||||
</label>
|
||||
<?php endforeach; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('数量与排序', 'aksrt'); ?></th>
|
||||
<td>
|
||||
<label>
|
||||
<?php esc_html_e('每类最多', 'aksrt'); ?>
|
||||
<input type="number" name="page_links_limit" value="<?php echo esc_attr((string) (int) ($s['limit'] ?? 0)); ?>" min="0" step="1" class="small-text">
|
||||
<?php esc_html_e('个(0=不限)', 'aksrt'); ?>
|
||||
</label>
|
||||
<p>
|
||||
<select name="page_links_orderby">
|
||||
<?php
|
||||
$orderbys = [
|
||||
'name' => __('名称', 'aksrt'),
|
||||
'updated' => __('更新时间', 'aksrt'),
|
||||
'rating' => __('评分', 'aksrt'),
|
||||
'rand' => __('随机', 'aksrt'),
|
||||
];
|
||||
$orderby = (string) ($s['orderby'] ?? 'name');
|
||||
foreach ($orderbys as $key => $label) :
|
||||
?>
|
||||
<option value="<?php echo esc_attr($key); ?>" <?php selected($orderby, $key); ?>><?php echo esc_html($label); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<select name="page_links_order">
|
||||
<option value="ASC" <?php selected(($s['order'] ?? 'ASC'), 'ASC'); ?>><?php esc_html_e('升序', 'aksrt'); ?></option>
|
||||
<option value="DESC" <?php selected(($s['order'] ?? ''), 'DESC'); ?>><?php esc_html_e('降序', 'aksrt'); ?></option>
|
||||
</select>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('链接行为', 'aksrt'); ?></th>
|
||||
<td>
|
||||
<label><input type="checkbox" name="page_links_go_s" value="1" <?php checked(!empty($s['go_s'])); ?>> <?php esc_html_e('外链重定向 /go/', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="page_links_blank_s" value="1" <?php checked(!empty($s['blank_s'])); ?>> <?php esc_html_e('新标签打开', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="page_links_nofollow_s" value="1" <?php checked(!empty($s['nofollow_s'])); ?>> <?php esc_html_e('添加 nofollow', 'aksrt'); ?></label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('提交链接', 'aksrt'); ?></th>
|
||||
<td>
|
||||
<label><input type="checkbox" name="page_links_submit_s" value="1" <?php checked(!empty($s['submit_s'])); ?>> <?php esc_html_e('显示申请入驻', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="page_links_submit_sign_s" value="1" <?php checked(!empty($s['submit_sign_s'])); ?>> <?php esc_html_e('登录后才能提交', 'aksrt'); ?></label>
|
||||
<p>
|
||||
<label><?php esc_html_e('按钮标题', 'aksrt'); ?>
|
||||
<input type="text" class="regular-text" name="page_links_submit_title" value="<?php echo esc_attr((string) ($s['submit_title'] ?? '')); ?>">
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label for="page_links_submit_dec"><?php esc_html_e('提交说明(HTML)', 'aksrt'); ?></label><br>
|
||||
<textarea class="large-text" rows="5" id="page_links_submit_dec" name="page_links_submit_dec"><?php echo esc_textarea((string) ($s['submit_dec'] ?? '')); ?></textarea>
|
||||
</p>
|
||||
<?php if (!empty($terms)) : ?>
|
||||
<p class="description"><?php esc_html_e('提交时可选分类(空=全部分类)', 'aksrt'); ?></p>
|
||||
<select name="page_links_submit_cats[]" multiple class="widefat" size="6">
|
||||
<?php foreach ($terms as $term) : ?>
|
||||
<option value="<?php echo (int) $term->term_id; ?>" <?php selected(in_array((int) $term->term_id, $submit_cats, true)); ?>>
|
||||
<?php echo esc_html($term->name); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function save_meta_box(int $post_id): void {
|
||||
if (!isset($_POST['aksrt_page_links_meta_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash((string) $_POST['aksrt_page_links_meta_nonce'])), 'aksrt_page_links_meta')) {
|
||||
return;
|
||||
}
|
||||
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
||||
return;
|
||||
}
|
||||
if (!current_user_can('edit_post', $post_id)) {
|
||||
return;
|
||||
}
|
||||
if (!$this->is_links_template($post_id) && empty($_POST['page_links_category']) && empty($_POST['page_links_submit_s'])) {
|
||||
// Still allow save if user just switched template in same request.
|
||||
$tpl = isset($_POST['page_template']) ? (string) wp_unslash($_POST['page_template']) : '';
|
||||
if ($tpl !== 'templates/pages/page-links.php') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$bool_keys = [
|
||||
'page_links_content_s',
|
||||
'page_links_search_s',
|
||||
'page_links_go_s',
|
||||
'page_links_blank_s',
|
||||
'page_links_nofollow_s',
|
||||
'page_links_submit_s',
|
||||
'page_links_submit_sign_s',
|
||||
];
|
||||
foreach ($bool_keys as $key) {
|
||||
update_post_meta($post_id, $key, isset($_POST[$key]) ? 1 : 0);
|
||||
}
|
||||
|
||||
$position = isset($_POST['page_links_content_position']) ? sanitize_key((string) wp_unslash($_POST['page_links_content_position'])) : 'top';
|
||||
if (!in_array($position, ['top', 'bottom'], true)) {
|
||||
$position = 'top';
|
||||
}
|
||||
update_post_meta($post_id, 'page_links_content_position', $position);
|
||||
|
||||
$style = isset($_POST['page_links_style']) ? sanitize_key((string) wp_unslash($_POST['page_links_style'])) : 'card';
|
||||
if (!in_array($style, ['card', 'bigcard', 'image', 'simple'], true)) {
|
||||
$style = 'card';
|
||||
}
|
||||
update_post_meta($post_id, 'page_links_style', $style);
|
||||
|
||||
$orderby = isset($_POST['page_links_orderby']) ? sanitize_key((string) wp_unslash($_POST['page_links_orderby'])) : 'name';
|
||||
if (!in_array($orderby, ['name', 'updated', 'rating', 'rand', 'id', 'length'], true)) {
|
||||
$orderby = 'name';
|
||||
}
|
||||
update_post_meta($post_id, 'page_links_orderby', $orderby);
|
||||
|
||||
$order = isset($_POST['page_links_order']) ? strtoupper(sanitize_text_field(wp_unslash((string) $_POST['page_links_order']))) : 'ASC';
|
||||
update_post_meta($post_id, 'page_links_order', $order === 'DESC' ? 'DESC' : 'ASC');
|
||||
|
||||
$limit = isset($_POST['page_links_limit']) ? max(0, (int) $_POST['page_links_limit']) : 0;
|
||||
update_post_meta($post_id, 'page_links_limit', $limit);
|
||||
|
||||
$cats = isset($_POST['page_links_category']) ? array_values(array_filter(array_map('intval', (array) wp_unslash($_POST['page_links_category'])))) : [];
|
||||
update_post_meta($post_id, 'page_links_category', $cats);
|
||||
|
||||
$submit_cats = isset($_POST['page_links_submit_cats']) ? array_values(array_filter(array_map('intval', (array) wp_unslash($_POST['page_links_submit_cats'])))) : [];
|
||||
update_post_meta($post_id, 'page_links_submit_cats', $submit_cats);
|
||||
|
||||
$engines = isset($_POST['page_links_search_types']) ? array_values(array_filter(array_map('sanitize_key', (array) wp_unslash($_POST['page_links_search_types'])))) : [];
|
||||
$allowed = ['self', 'baidu', 'google', 'bing', 'sogou', '360'];
|
||||
$engines = array_values(array_intersect($engines, $allowed));
|
||||
update_post_meta($post_id, 'page_links_search_types', $engines);
|
||||
|
||||
$title = isset($_POST['page_links_submit_title']) ? sanitize_text_field(wp_unslash((string) $_POST['page_links_submit_title'])) : '';
|
||||
update_post_meta($post_id, 'page_links_submit_title', $title);
|
||||
|
||||
$dec = isset($_POST['page_links_submit_dec']) ? wp_kses_post(wp_unslash((string) $_POST['page_links_submit_dec'])) : '';
|
||||
update_post_meta($post_id, 'page_links_submit_dec', $dec);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/**
|
||||
* Frontend links (bookmarks) submit — zibll frontend_links_submit parity.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
namespace AKSRT\Core;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class LinksSubmit {
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
public static function get_instance(): self {
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function init(): void {
|
||||
add_action('wp_ajax_aksrt_frontend_links_submit', [$this, 'ajax_submit']);
|
||||
add_action('wp_ajax_nopriv_aksrt_frontend_links_submit', [$this, 'ajax_submit']);
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX: create a pending WordPress bookmark (link).
|
||||
*/
|
||||
public function ajax_submit(): void {
|
||||
if (!check_ajax_referer('aksrt_frontend_links_submit', '_wpnonce', false)) {
|
||||
wp_send_json(['error' => 1, 'ys' => 'danger', 'msg' => __('安全校验失败,请刷新后重试', 'aksrt')]);
|
||||
}
|
||||
|
||||
if (isset($_COOKIE['aksrt_links_submit_time'])) {
|
||||
wp_send_json(['error' => 1, 'ys' => 'danger', 'msg' => __('操作过于频繁,请稍候再试', 'aksrt')]);
|
||||
}
|
||||
|
||||
$link_name = isset($_POST['link_name']) ? sanitize_text_field(wp_unslash((string) $_POST['link_name'])) : '';
|
||||
$link_url = isset($_POST['link_url']) ? esc_url_raw(wp_unslash((string) $_POST['link_url'])) : '';
|
||||
$link_desc = isset($_POST['link_description']) ? sanitize_text_field(wp_unslash((string) $_POST['link_description'])) : '';
|
||||
$cat_raw = isset($_POST['link_category']) ? wp_unslash($_POST['link_category']) : [];
|
||||
|
||||
if ($link_name === '') {
|
||||
wp_send_json(['error' => 1, 'ys' => 'danger', 'msg' => __('请填写网站名称', 'aksrt')]);
|
||||
}
|
||||
if ($link_url === '' || !wp_http_validate_url($link_url)) {
|
||||
wp_send_json(['error' => 1, 'ys' => 'danger', 'msg' => __('网站地址格式错误', 'aksrt')]);
|
||||
}
|
||||
|
||||
// Optional logo upload.
|
||||
$logo_url = '';
|
||||
if (!empty($_FILES['image']['name'])) {
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/media.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
$attachment_id = media_handle_upload('image', 0);
|
||||
if (is_wp_error($attachment_id)) {
|
||||
wp_send_json(['error' => 1, 'ys' => 'danger', 'msg' => $attachment_id->get_error_message()]);
|
||||
}
|
||||
$src = wp_get_attachment_image_src((int) $attachment_id, 'medium');
|
||||
$logo_url = !empty($src[0]) ? (string) $src[0] : (string) wp_get_attachment_url((int) $attachment_id);
|
||||
}
|
||||
|
||||
$categories = [];
|
||||
if (is_array($cat_raw)) {
|
||||
$categories = array_values(array_filter(array_map('intval', $cat_raw)));
|
||||
} elseif ($cat_raw !== '' && $cat_raw !== null) {
|
||||
$categories = [absint($cat_raw)];
|
||||
}
|
||||
|
||||
// Duplicate URL guard.
|
||||
global $wpdb;
|
||||
$exists = (int) $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(1) FROM {$wpdb->links} WHERE link_url = %s",
|
||||
$link_url
|
||||
)
|
||||
);
|
||||
if ($exists > 0) {
|
||||
wp_send_json(['error' => 1, 'ys' => 'danger', 'msg' => __('您的链接已提交,请勿重复提交', 'aksrt')]);
|
||||
}
|
||||
|
||||
if (!function_exists('wp_insert_link')) {
|
||||
require_once ABSPATH . 'wp-admin/includes/bookmark.php';
|
||||
}
|
||||
|
||||
$linkdata = [
|
||||
'link_name' => $link_name,
|
||||
'link_url' => $link_url,
|
||||
'link_description' => $link_desc,
|
||||
'link_image' => $logo_url,
|
||||
// Non-admins create invisible links pending review (zibll parity).
|
||||
'link_visible' => current_user_can('manage_links') ? 'Y' : 'N',
|
||||
'link_category' => $categories,
|
||||
];
|
||||
|
||||
$links_id = wp_insert_link($linkdata, true);
|
||||
if (is_wp_error($links_id)) {
|
||||
wp_send_json(['error' => 1, 'ys' => 'danger', 'msg' => $links_id->get_error_message()]);
|
||||
}
|
||||
|
||||
// 30s client throttle cookie.
|
||||
if (!headers_sent()) {
|
||||
setcookie('aksrt_links_submit_time', (string) time(), time() + 30, COOKIEPATH ?: '/', COOKIE_DOMAIN, is_ssl(), true);
|
||||
}
|
||||
|
||||
$msg = $linkdata['link_visible'] === 'Y'
|
||||
? __('提交成功', 'aksrt')
|
||||
: __('提交成功,等待管理员处理', 'aksrt');
|
||||
|
||||
/**
|
||||
* Fires after a frontend link submission is stored.
|
||||
*
|
||||
* @param array $linkdata Sanitized bookmark data.
|
||||
* @param int $links_id New link ID.
|
||||
*/
|
||||
do_action('aksrt_frontend_links_submit_success', $linkdata, (int) $links_id);
|
||||
|
||||
wp_send_json(['error' => 0, 'msg' => $msg, 'reload' => true]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* 文章导航页设置 AJAX(zibll action/post_navs.php parity).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
namespace AKSRT\Core;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class PostsNavs {
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
public static function get_instance(): self {
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function init(): void {
|
||||
add_action('wp_ajax_aksrt_post_navs_settings', [$this, 'ajax_save_settings']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Super-admin only: save navs_page_name / desc / ordered cat IDs.
|
||||
*/
|
||||
public function ajax_save_settings(): void {
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json(['error' => 1, 'ys' => 'danger', 'msg' => __('权限不足', 'aksrt')]);
|
||||
}
|
||||
if (!check_ajax_referer('aksrt_post_navs_settings', '_wpnonce', false)) {
|
||||
wp_send_json(['error' => 1, 'ys' => 'danger', 'msg' => __('安全校验失败', 'aksrt')]);
|
||||
}
|
||||
|
||||
$page_id = isset($_POST['page_id']) ? absint($_POST['page_id']) : 0;
|
||||
if ($page_id <= 0 || get_post_type($page_id) !== 'page') {
|
||||
wp_send_json(['error' => 1, 'ys' => 'danger', 'msg' => __('无效页面', 'aksrt')]);
|
||||
}
|
||||
|
||||
$cat_ids = [];
|
||||
if (isset($_POST['navs_show_cat_id'])) {
|
||||
$raw = wp_unslash($_POST['navs_show_cat_id']);
|
||||
if (is_array($raw)) {
|
||||
$cat_ids = array_values(array_filter(array_map('intval', $raw)));
|
||||
} elseif (is_string($raw) && $raw !== '') {
|
||||
$decoded = json_decode($raw, true);
|
||||
if (is_array($decoded)) {
|
||||
$cat_ids = array_values(array_filter(array_map('intval', $decoded)));
|
||||
} else {
|
||||
$cat_ids = array_values(array_filter(array_map('intval', explode(',', $raw))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($cat_ids)) {
|
||||
wp_send_json(['error' => 1, 'ys' => 'danger', 'msg' => __('请选择需要显示的分类', 'aksrt')]);
|
||||
}
|
||||
|
||||
if (isset($_POST['navs_page_name'])) {
|
||||
update_post_meta($page_id, 'navs_page_name', sanitize_text_field(wp_unslash((string) $_POST['navs_page_name'])));
|
||||
}
|
||||
if (isset($_POST['navs_page_desc'])) {
|
||||
update_post_meta($page_id, 'navs_page_desc', sanitize_text_field(wp_unslash((string) $_POST['navs_page_desc'])));
|
||||
}
|
||||
update_post_meta($page_id, 'navs_show_cat_id', $cat_ids);
|
||||
|
||||
wp_send_json([
|
||||
'error' => 0,
|
||||
'msg' => __('保存成功', 'aksrt'),
|
||||
'reload'=> true,
|
||||
'ids' => $cat_ids,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -129,6 +129,27 @@ trait ScriptsPart1b {
|
||||
}
|
||||
}
|
||||
|
||||
// Header user-box density (check-in / wallet / signout modal)
|
||||
$hub_css = get_template_directory() . '/assets/css/frontend/nav/header-userbox.css';
|
||||
if (file_exists($hub_css)) {
|
||||
wp_enqueue_style(
|
||||
'aksrt-header-userbox',
|
||||
$base_uri . '/assets/css/frontend/nav/header-userbox.css',
|
||||
[$core_dep],
|
||||
(string) filemtime($hub_css)
|
||||
);
|
||||
}
|
||||
$hub_js = get_template_directory() . '/assets/js/header-userbox.js';
|
||||
if (file_exists($hub_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-header-userbox',
|
||||
$base_uri . '/assets/js/header-userbox.js',
|
||||
[],
|
||||
(string) filemtime($hub_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// Print stylesheet — only load on singular pages
|
||||
if (is_singular()) {
|
||||
wp_enqueue_style(
|
||||
@@ -381,6 +402,85 @@ trait ScriptsPart1b {
|
||||
);
|
||||
}
|
||||
|
||||
// 网址导航页(zibll links.php)
|
||||
if (is_page_template('templates/pages/page-links.php')) {
|
||||
$links_css = get_template_directory() . '/assets/css/routes/links.css';
|
||||
if (file_exists($links_css)) {
|
||||
wp_enqueue_style(
|
||||
'aksrt-route-links',
|
||||
$base_uri . '/assets/css/routes/links.css',
|
||||
['aksrt-tokens'],
|
||||
(string) filemtime($links_css)
|
||||
);
|
||||
}
|
||||
$links_js = get_template_directory() . '/assets/js/links-page.js';
|
||||
if (file_exists($links_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-links-page',
|
||||
$base_uri . '/assets/js/links-page.js',
|
||||
['jquery'],
|
||||
(string) filemtime($links_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 文章导航页(zibll postsnavs.php)
|
||||
if (is_page_template('templates/pages/page-posts-navs.php')) {
|
||||
$pn_css = get_template_directory() . '/assets/css/routes/posts-navs.css';
|
||||
if (file_exists($pn_css)) {
|
||||
wp_enqueue_style(
|
||||
'aksrt-route-posts-navs',
|
||||
$base_uri . '/assets/css/routes/posts-navs.css',
|
||||
['aksrt-tokens'],
|
||||
(string) filemtime($pn_css)
|
||||
);
|
||||
}
|
||||
$section_navs = get_template_directory() . '/assets/js/section-navs.js';
|
||||
if (file_exists($section_navs)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-section-navs',
|
||||
$base_uri . '/assets/js/section-navs.js',
|
||||
['jquery'],
|
||||
(string) filemtime($section_navs),
|
||||
true
|
||||
);
|
||||
}
|
||||
$pn_js = get_template_directory() . '/assets/js/posts-navs-page.js';
|
||||
if (file_exists($pn_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-posts-navs-page',
|
||||
$base_uri . '/assets/js/posts-navs-page.js',
|
||||
['jquery'],
|
||||
(string) filemtime($pn_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 用户身份认证页(zibll user-auth.php)
|
||||
if (is_page_template('templates/pages/page-user-auth.php')) {
|
||||
$ua_css = get_template_directory() . '/assets/css/routes/user-auth.css';
|
||||
if (file_exists($ua_css)) {
|
||||
wp_enqueue_style(
|
||||
'aksrt-route-user-auth',
|
||||
$base_uri . '/assets/css/routes/user-auth.css',
|
||||
['aksrt-tokens'],
|
||||
(string) filemtime($ua_css)
|
||||
);
|
||||
}
|
||||
$ua_js = get_template_directory() . '/assets/js/user-auth-page.js';
|
||||
if (file_exists($ua_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-user-auth-page',
|
||||
$base_uri . '/assets/js/user-auth-page.js',
|
||||
[],
|
||||
(string) filemtime($ua_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 交易中心共享壳层(购物车 / 订单 / 收益)
|
||||
$is_commerce_center = is_page_template('templates/pages/page-orders.php')
|
||||
|| is_page_template('templates/pages/page-cart.php')
|
||||
|
||||
@@ -46,6 +46,8 @@ class Templates {
|
||||
'templates/pages/page-submit.php' => __('AKSRT - 写文章/投稿', 'aksrt'),
|
||||
'templates/pages/page-posts-navs.php' => __('AKSRT - 文章导航', 'aksrt'),
|
||||
'templates/pages/page-friends.php' => __('AKSRT - 友情链接', 'aksrt'),
|
||||
'templates/pages/page-links.php' => __('AKSRT - 网址导航', 'aksrt'),
|
||||
'templates/pages/page-user-auth.php' => __('AKSRT - 用户身份认证', 'aksrt'),
|
||||
'templates/pages/page-orders.php' => __('AKSRT - 订单中心', 'aksrt'),
|
||||
'templates/pages/page-revenue.php' => __('AKSRT - 收益中心', 'aksrt'),
|
||||
'templates/pages/page-cart.php' => __('AKSRT - 购物车', 'aksrt'),
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
/**
|
||||
* Frontend identity verification apply (zibll user-auth page parity on aksrt_user_verify_* meta).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
namespace AKSRT\User;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class AuthApply {
|
||||
|
||||
public const STATUS_META = 'aksrt_user_verify_status';
|
||||
public const REASON_META = 'aksrt_user_verify_reason';
|
||||
public const APPLY_META = 'aksrt_user_verify_apply';
|
||||
public const INFO_META = 'aksrt_user_verify_info';
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
public static function get_instance(): self {
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function init(): void {
|
||||
add_action('wp_ajax_aksrt_user_auth_apply', [$this, 'ajax_apply']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* enabled:bool,allow_apply:bool,public_display:bool,badge_text:string,
|
||||
* limit_level:int,desc:string,disable_desc:string,
|
||||
* types:array<int,array{slug:string,label:string}>
|
||||
* }
|
||||
*/
|
||||
public static function settings(): array {
|
||||
$all = class_exists('\AKSRT\Settings\Settings')
|
||||
? (array) \AKSRT\Settings\Settings::get_all()
|
||||
: [];
|
||||
$enabled = !isset($all['user_verify_enabled']) || !empty($all['user_verify_enabled']);
|
||||
$types_raw = (string) ($all['user_verify_apply_option'] ?? "real_name|实名认证\norganization|企业认证");
|
||||
$types = [];
|
||||
foreach (preg_split('/\r\n|\r|\n/', $types_raw) as $line) {
|
||||
$line = trim($line);
|
||||
if ($line === '') {
|
||||
continue;
|
||||
}
|
||||
$parts = array_map('trim', explode('|', $line, 2));
|
||||
$slug = sanitize_key($parts[0] ?? '');
|
||||
$label = $parts[1] ?? $parts[0];
|
||||
if ($slug === '') {
|
||||
continue;
|
||||
}
|
||||
$types[] = ['slug' => $slug, 'label' => (string) $label];
|
||||
}
|
||||
return [
|
||||
'enabled' => $enabled,
|
||||
'allow_apply' => !isset($all['user_verify_allow_apply']) || !empty($all['user_verify_allow_apply']),
|
||||
'public_display' => !isset($all['user_verify_public_display']) || !empty($all['user_verify_public_display']),
|
||||
'badge_text' => (string) ($all['user_verify_badge_text'] ?? __('已认证', 'aksrt')),
|
||||
'limit_level' => max(0, (int) ($all['user_verify_limit_level'] ?? 0)),
|
||||
'desc' => (string) ($all['user_verify_desc'] ?? ''),
|
||||
'disable_desc' => (string) ($all['user_verify_disable_desc'] ?? ''),
|
||||
'types' => $types,
|
||||
];
|
||||
}
|
||||
|
||||
public static function get_status(int $user_id): string {
|
||||
if ($user_id <= 0) {
|
||||
return '';
|
||||
}
|
||||
return sanitize_key((string) get_user_meta($user_id, self::STATUS_META, true));
|
||||
}
|
||||
|
||||
public static function is_verified(int $user_id): bool {
|
||||
return self::get_status($user_id) === 'verified';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public static function get_auth_info(int $user_id): array {
|
||||
$info = get_user_meta($user_id, self::INFO_META, true);
|
||||
return is_array($info) ? $info : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public static function get_apply_payload(int $user_id): array {
|
||||
$apply = get_user_meta($user_id, self::APPLY_META, true);
|
||||
return is_array($apply) ? $apply : [];
|
||||
}
|
||||
|
||||
public function ajax_apply(): void {
|
||||
if (!is_user_logged_in()) {
|
||||
wp_send_json(['error' => 1, 'msg' => __('请先登录', 'aksrt')]);
|
||||
}
|
||||
if (!check_ajax_referer('aksrt_user_auth_apply', '_wpnonce', false)) {
|
||||
wp_send_json(['error' => 1, 'msg' => __('安全校验失败', 'aksrt')]);
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$s = self::settings();
|
||||
if (!$s['enabled'] || !$s['allow_apply']) {
|
||||
wp_send_json(['error' => 1, 'msg' => __('暂不能申请身份认证', 'aksrt')]);
|
||||
}
|
||||
if (self::is_verified($user_id)) {
|
||||
wp_send_json(['error' => 1, 'msg' => __('您已是认证用户', 'aksrt')]);
|
||||
}
|
||||
if (self::get_status($user_id) === 'pending') {
|
||||
wp_send_json(['error' => 1, 'msg' => __('您的申请正在审核中', 'aksrt')]);
|
||||
}
|
||||
if ($s['limit_level'] > 0 && class_exists('\AKSRT\User\Level')) {
|
||||
$lv = (int) Level::get_level($user_id);
|
||||
if ($lv < $s['limit_level']) {
|
||||
wp_send_json([
|
||||
'error' => 1,
|
||||
'msg' => sprintf(
|
||||
/* translators: %d: required level */
|
||||
__('等级不足,需达到 LV.%d 后申请', 'aksrt'),
|
||||
$s['limit_level']
|
||||
),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$name = isset($_POST['name']) ? sanitize_text_field(wp_unslash((string) $_POST['name'])) : '';
|
||||
$desc = isset($_POST['desc']) ? sanitize_textarea_field(wp_unslash((string) $_POST['desc'])) : '';
|
||||
$msg = isset($_POST['msg']) ? sanitize_textarea_field(wp_unslash((string) $_POST['msg'])) : '';
|
||||
$type = isset($_POST['type']) ? sanitize_key((string) wp_unslash($_POST['type'])) : '';
|
||||
if ($name === '') {
|
||||
wp_send_json(['error' => 1, 'msg' => __('请填写认证身份名称', 'aksrt')]);
|
||||
}
|
||||
|
||||
$images = [];
|
||||
if (!empty($_FILES['image']['name'])) {
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/media.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
|
||||
$files = $_FILES['image'];
|
||||
// Normalize multi-file upload.
|
||||
$names = $files['name'];
|
||||
if (!is_array($names)) {
|
||||
$names = [$names];
|
||||
$tmp = [
|
||||
'name' => $names,
|
||||
'type' => [$files['type']],
|
||||
'tmp_name' => [$files['tmp_name']],
|
||||
'error' => [$files['error']],
|
||||
'size' => [$files['size']],
|
||||
];
|
||||
$files = $tmp;
|
||||
}
|
||||
$count = min(3, count($files['name']));
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
if (empty($files['name'][$i]) || (int) $files['error'][$i] !== UPLOAD_ERR_OK) {
|
||||
continue;
|
||||
}
|
||||
$file = [
|
||||
'name' => $files['name'][$i],
|
||||
'type' => $files['type'][$i],
|
||||
'tmp_name' => $files['tmp_name'][$i],
|
||||
'error' => $files['error'][$i],
|
||||
'size' => $files['size'][$i],
|
||||
];
|
||||
$_FILES['aksrt_auth_img'] = $file;
|
||||
$aid = media_handle_upload('aksrt_auth_img', 0);
|
||||
if (!is_wp_error($aid)) {
|
||||
$url = wp_get_attachment_url((int) $aid);
|
||||
if ($url) {
|
||||
$images[] = $url;
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($_FILES['aksrt_auth_img']);
|
||||
}
|
||||
|
||||
$payload = [
|
||||
'name' => $name,
|
||||
'desc' => $desc,
|
||||
'msg' => $msg,
|
||||
'type' => $type,
|
||||
'img' => $images,
|
||||
'time' => current_time('Y-m-d H:i'),
|
||||
];
|
||||
update_user_meta($user_id, self::APPLY_META, $payload);
|
||||
update_user_meta($user_id, self::STATUS_META, 'pending');
|
||||
delete_user_meta($user_id, self::REASON_META);
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
* @param array $payload
|
||||
*/
|
||||
do_action('aksrt_user_auth_apply_submitted', $user_id, $payload);
|
||||
|
||||
wp_send_json([
|
||||
'error' => 0,
|
||||
'msg' => __('提交成功,请等待管理员审核', 'aksrt'),
|
||||
'reload' => true,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - 网址导航
|
||||
* Template Post Type: page
|
||||
*
|
||||
* Zibll pages/links.php 1:1 — multi-category bookmarks, search cover, submit modal.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$post_id = (int) get_queried_object_id();
|
||||
$s = function_exists('aksrt_get_page_links_settings')
|
||||
? aksrt_get_page_links_settings($post_id)
|
||||
: [];
|
||||
|
||||
get_header();
|
||||
?>
|
||||
<main class="container page-content-default page-template-links">
|
||||
<div class="content-wrap">
|
||||
<div class="content-layout">
|
||||
<?php
|
||||
while (have_posts()) :
|
||||
the_post();
|
||||
|
||||
// Optional page header (style 1 / 2 / 3 via existing page meta).
|
||||
if (function_exists('aksrt_get_page_header_html')) {
|
||||
echo aksrt_get_page_header_html($post_id); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
} else {
|
||||
$header_style = (string) get_post_meta($post_id, 'page_header_style', true);
|
||||
if ($header_style !== 'not') {
|
||||
echo '<div class="theme-box radius8 main-bg main-shadow box-body mb20"><h1 class="article-title">' . esc_html(get_the_title()) . '</h1></div>';
|
||||
}
|
||||
}
|
||||
|
||||
if (function_exists('aksrt_link_get_search_cover')) {
|
||||
echo aksrt_link_get_search_cover($post_id); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
|
||||
$links_html = function_exists('aksrt_page_links_html') ? aksrt_page_links_html($post_id) : '';
|
||||
$content_s = !empty($s['content_s']);
|
||||
$position = (string) ($s['content_position'] ?? 'top');
|
||||
|
||||
if ($position !== 'top') {
|
||||
echo $links_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
|
||||
if ($content_s) {
|
||||
echo '<div class="zib-widget"><article class="article wp-posts-content">';
|
||||
the_content();
|
||||
wp_link_pages([
|
||||
'before' => '<p class="text-center post-nav-links radius8 padding-6">',
|
||||
'after' => '</p>',
|
||||
]);
|
||||
echo '</article></div>';
|
||||
}
|
||||
|
||||
if ($position === 'top') {
|
||||
echo $links_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
endwhile;
|
||||
|
||||
if (comments_open() || get_comments_number()) {
|
||||
comments_template();
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php get_sidebar(); ?>
|
||||
</main>
|
||||
<?php
|
||||
if (!empty($s['submit_s']) && function_exists('aksrt_submit_links_modal')) {
|
||||
echo aksrt_submit_links_modal([ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
'title' => (string) ($s['submit_title'] ?? __('申请入驻', 'aksrt')),
|
||||
'dec' => (string) ($s['submit_dec'] ?? ''),
|
||||
'sign' => !empty($s['submit_sign_s']),
|
||||
'cats' => (array) ($s['submit_cats'] ?? []),
|
||||
]);
|
||||
}
|
||||
|
||||
get_footer();
|
||||
@@ -1,65 +1,228 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Posts Navigation
|
||||
* Template Name: AKSRT - 文章导航
|
||||
* Template Post Type: page
|
||||
*
|
||||
* 文章导航页:分类+标签的导航聚合页。
|
||||
* Zibll pages/postsnavs.php 1:1 — selected categories with full post lists,
|
||||
* affix TOC sidebar, admin drag-sort settings modal.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
$post = get_queried_object();
|
||||
$post_id = $post instanceof WP_Post ? (int) $post->ID : (int) get_queried_object_id();
|
||||
|
||||
$categories = get_categories(['hide_empty' => true, 'orderby' => 'count', 'order' => 'DESC', 'number' => 20]);
|
||||
$tags = get_tags(['hide_empty' => true, 'orderby' => 'count', 'order' => 'DESC', 'number' => 40]);
|
||||
|
||||
if (function_exists('aksrt_archive_open_shell')) {
|
||||
aksrt_archive_open_shell([
|
||||
'main_class' => 'site-main container content-shell content-shell--page page-content-default',
|
||||
'has_sidebar' => false,
|
||||
'page_kind' => 'posts-navs',
|
||||
]);
|
||||
$show_cat_id = get_post_meta($post_id, 'navs_show_cat_id', true);
|
||||
if (!is_array($show_cat_id)) {
|
||||
$show_cat_id = $show_cat_id !== '' && $show_cat_id !== null
|
||||
? array_values(array_filter(array_map('intval', (array) $show_cat_id)))
|
||||
: [];
|
||||
} else {
|
||||
$show_cat_id = array_values(array_filter(array_map('intval', $show_cat_id)));
|
||||
}
|
||||
|
||||
$page_desc = (string) get_post_meta($post_id, 'navs_page_desc', true);
|
||||
$page_name = (string) get_post_meta($post_id, 'navs_page_name', true);
|
||||
$title = get_the_title($post_id);
|
||||
$page_name = $page_name !== '' ? $page_name : $title;
|
||||
|
||||
$all_cats = get_categories([
|
||||
'orderby' => 'term_group',
|
||||
'order' => 'ASC',
|
||||
'hide_empty' => false,
|
||||
]);
|
||||
|
||||
$can_admin = is_user_logged_in() && current_user_can('manage_options');
|
||||
|
||||
get_header();
|
||||
?>
|
||||
<div class="content-main content-main--page content-main--posts-navs">
|
||||
<?php
|
||||
get_template_part('templates/parts/page-header', null, [
|
||||
'title' => esc_html(get_the_title() ?: __('文章导航', 'aksrt')),
|
||||
<style>
|
||||
.page-share a { margin-right: 10px; }
|
||||
.page-share a > text { display: none; }
|
||||
</style>
|
||||
|
||||
<div class="container">
|
||||
<div class="main-bg theme-box radius8 main-shadow box-body">
|
||||
<div class="box-body">
|
||||
<h2 class="theme-box">
|
||||
<?php echo esc_html($page_name); ?>
|
||||
<?php if ($can_admin) : ?>
|
||||
<small>
|
||||
<a style="cursor:pointer" href="javascript:;" data-toggle="modal" data-target="#post-navs-sz">
|
||||
[<?php esc_html_e('设置', 'aksrt'); ?>]
|
||||
</a>
|
||||
</small>
|
||||
<?php endif; ?>
|
||||
</h2>
|
||||
<div class="flex ab jsb hh">
|
||||
<div class="muted-color mr20">
|
||||
<?php echo esc_html($page_desc !== '' ? $page_desc : __('暂无简介内容,请设置', 'aksrt')); ?>
|
||||
</div>
|
||||
<div class="pull-right page-share mt20">
|
||||
<?php
|
||||
if (function_exists('aksrt_render_share_buttons')) {
|
||||
aksrt_render_share_buttons(['compact' => true]);
|
||||
} elseif (function_exists('aksrt_get_share_html')) {
|
||||
echo aksrt_get_share_html(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main class="container page-template-posts-navs">
|
||||
<div class="content-wrap">
|
||||
<div class="content-layout">
|
||||
<div class="posts-navs" data-nav="posts">
|
||||
<?php
|
||||
if (!empty($show_cat_id)) {
|
||||
foreach ($show_cat_id as $c_id) {
|
||||
$the_cat = get_category((int) $c_id);
|
||||
if (!$the_cat || is_wp_error($the_cat)) {
|
||||
continue;
|
||||
}
|
||||
$posts = get_posts([
|
||||
'category' => (int) $c_id,
|
||||
'numberposts' => -1,
|
||||
'post_status' => 'publish',
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'suppress_filters' => false,
|
||||
]);
|
||||
?>
|
||||
if (empty($posts)) {
|
||||
continue;
|
||||
}
|
||||
$section_id = 'navs-cat-' . (int) $c_id;
|
||||
echo '<div class="theme-box">';
|
||||
echo '<div class="box-body notop"><div class="title-theme"><h2 id="' . esc_attr($section_id) . '">' . esc_html($the_cat->name) . '</h2></div></div>';
|
||||
echo '<div class="main-bg radius8 main-shadow box-body"><ul class="posts-navs__list">';
|
||||
foreach ($posts as $p) {
|
||||
$time_tip = get_the_time('Y年m月d日 H:i', $p);
|
||||
$time_ago = human_time_diff(get_the_time('U', $p), current_time('timestamp')) . __('前', 'aksrt');
|
||||
$views = function_exists('aksrt_get_post_views') ? (int) aksrt_get_post_views($p->ID) : 0;
|
||||
$likes = (int) get_post_meta($p->ID, 'like', true);
|
||||
if ($likes <= 0) {
|
||||
$likes = (int) get_post_meta($p->ID, 'aksrt_like', true);
|
||||
}
|
||||
$post_tip = sprintf(
|
||||
/* translators: 1: views 2: likes */
|
||||
__('阅读(%1$s) 点赞(%2$s)', 'aksrt'),
|
||||
(string) $views,
|
||||
(string) $likes
|
||||
);
|
||||
$subtitle = (string) get_post_meta($p->ID, 'subtitle', true);
|
||||
if ($subtitle === '') {
|
||||
$subtitle = (string) get_post_meta($p->ID, 'aksrt_subtitle', true);
|
||||
}
|
||||
echo '<li class="posts-navs__item">';
|
||||
echo '<div class="text-ellipsis">';
|
||||
echo '<span title="' . esc_attr($time_tip) . '" class="muted-2-color">' . esc_html($time_ago) . '</span>';
|
||||
echo '<span class="icon-circle"></span>';
|
||||
echo '<a title="' . esc_attr($post_tip) . '" href="' . esc_url(get_permalink($p->ID)) . '">';
|
||||
echo esc_html(get_the_title($p->ID));
|
||||
if ($subtitle !== '') {
|
||||
echo ' <span class="muted-2-color">' . esc_html($subtitle) . '</span>';
|
||||
}
|
||||
echo '</a></div></li>';
|
||||
}
|
||||
echo '</ul></div></div>';
|
||||
}
|
||||
} elseif ($can_admin) {
|
||||
echo '<div class="theme-box main-bg radius8 main-shadow box-body">';
|
||||
echo '<p class="muted-2-color">' . esc_html__('尚未选择分类,请点击标题旁「设置」配置要展示的分类。', 'aksrt') . '</p>';
|
||||
echo '</div>';
|
||||
} else {
|
||||
echo '<div class="theme-box main-bg radius8 main-shadow box-body">';
|
||||
echo '<p class="muted-2-color">' . esc_html__('暂无导航内容', 'aksrt') . '</p>';
|
||||
echo '</div>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar">
|
||||
<div class="posts-nav-box" data-affix="true" data-title="<?php esc_attr_e('导航目录', 'aksrt'); ?>"></div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="aksrt-posts-navs">
|
||||
<?php if (!empty($categories)) : ?>
|
||||
<section class="aksrt-posts-navs__section">
|
||||
<h2 class="aksrt-posts-navs__heading"><?php esc_html_e('热门分类', 'aksrt'); ?></h2>
|
||||
<div class="aksrt-posts-navs__cats">
|
||||
<?php foreach ($categories as $cat) : ?>
|
||||
<a href="<?php echo esc_url(get_category_link($cat->term_id)); ?>" class="aksrt-posts-navs__cat-chip">
|
||||
<span class="aksrt-posts-navs__cat-name"><?php echo esc_html($cat->name); ?></span>
|
||||
<span class="aksrt-posts-navs__cat-count"><?php echo esc_html((string) $cat->count); ?></span>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
<?php if ($can_admin) : ?>
|
||||
<div class="modal fade" id="post-navs-sz" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<form id="aksrt-posts-navs-settings" class="aksrt-posts-navs-settings">
|
||||
<div class="modal-header">
|
||||
<p class="modal-title">
|
||||
<?php esc_html_e('当前页面设置', 'aksrt'); ?>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="<?php esc_attr_e('关闭', 'aksrt'); ?>">
|
||||
<i class="fa fa-times" aria-hidden="true"></i>
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="navs_page_name"><?php esc_html_e('标题', 'aksrt'); ?></label>
|
||||
<input type="text" class="form-control" id="navs_page_name" name="navs_page_name" placeholder="<?php esc_attr_e('自定义标题', 'aksrt'); ?>" value="<?php echo esc_attr($page_name); ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="navs_page_desc"><?php esc_html_e('简介', 'aksrt'); ?></label>
|
||||
<input type="text" class="form-control" id="navs_page_desc" name="navs_page_desc" placeholder="<?php esc_attr_e('自定义简介', 'aksrt'); ?>" value="<?php echo esc_attr($page_desc); ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><?php esc_html_e('请将需要显示的分类拖动到选区并排序', 'aksrt'); ?></label>
|
||||
<div class="row text-center">
|
||||
<div class="col-xs-6 col-sm-6">
|
||||
<p class="text-muted"><?php esc_html_e('未选择的分类', 'aksrt'); ?></p>
|
||||
<div class="cat-group mini-scrollbar" id="cat-sortable">
|
||||
<?php
|
||||
foreach ($all_cats as $the_cat) {
|
||||
$c_id = (int) $the_cat->term_id;
|
||||
if (in_array($c_id, $show_cat_id, true)) {
|
||||
continue;
|
||||
}
|
||||
$c_name = rtrim((string) get_category_parents($c_id, false, '>'), '>');
|
||||
echo '<span class="sortable-cat-item" draggable="true" data-id="' . esc_attr((string) $c_id) . '">'
|
||||
. esc_html($c_name)
|
||||
. '<span class="badge">' . (int) $the_cat->count . '</span></span>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($tags)) : ?>
|
||||
<section class="aksrt-posts-navs__section">
|
||||
<h2 class="aksrt-posts-navs__heading"><?php esc_html_e('热门标签', 'aksrt'); ?></h2>
|
||||
<div class="aksrt-posts-navs__tags">
|
||||
<?php foreach ($tags as $tag) : ?>
|
||||
<a href="<?php echo esc_url(get_tag_link($tag->term_id)); ?>" class="aksrt-posts-navs__tag"><?php echo esc_html($tag->name); ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6">
|
||||
<p class="text-muted"><?php esc_html_e('已选择的分类', 'aksrt'); ?></p>
|
||||
<div class="cat-group mini-scrollbar" id="cat-sortable-ok">
|
||||
<?php
|
||||
foreach ($show_cat_id as $c_id) {
|
||||
$the_cat = get_category((int) $c_id);
|
||||
if (!$the_cat || is_wp_error($the_cat)) {
|
||||
continue;
|
||||
}
|
||||
$c_name = rtrim((string) get_category_parents((int) $c_id, false, '>'), '>');
|
||||
echo '<span class="sortable-cat-item" draggable="true" data-id="' . esc_attr((string) $c_id) . '">'
|
||||
. esc_html($c_name)
|
||||
. '<span class="badge">' . (int) $the_cat->count . '</span></span>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<input type="hidden" name="action" value="aksrt_post_navs_settings">
|
||||
<input type="hidden" name="page_id" value="<?php echo (int) $post_id; ?>">
|
||||
<?php wp_nonce_field('aksrt_post_navs_settings', '_wpnonce', false); ?>
|
||||
<button type="submit" class="btn btn-primary" evt="action"><?php esc_html_e('确认修改', 'aksrt'); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="navs-bj"></div>
|
||||
<?php
|
||||
if (function_exists('aksrt_archive_close_shell')) {
|
||||
aksrt_archive_close_shell(['has_sidebar' => false]);
|
||||
}
|
||||
endif;
|
||||
|
||||
get_footer();
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - 用户身份认证
|
||||
* Template Post Type: page
|
||||
*
|
||||
* Zibll pages/user-auth.php 1:1 shell on aksrt_user_verify_* storage.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
use AKSRT\User\AuthApply;
|
||||
|
||||
$settings = class_exists(AuthApply::class) ? AuthApply::settings() : ['enabled' => true, 'allow_apply' => true];
|
||||
$user_id = get_current_user_id();
|
||||
$status = $user_id && class_exists(AuthApply::class) ? AuthApply::get_status($user_id) : '';
|
||||
$info = $user_id && class_exists(AuthApply::class) ? AuthApply::get_auth_info($user_id) : [];
|
||||
$apply = $user_id && class_exists(AuthApply::class) ? AuthApply::get_apply_payload($user_id) : [];
|
||||
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url(get_permalink()) : wp_login_url(get_permalink());
|
||||
|
||||
get_header();
|
||||
?>
|
||||
<main class="container page-template-user-auth">
|
||||
<div class="content-wrap">
|
||||
<div class="content-layout">
|
||||
<?php while (have_posts()) : the_post(); ?>
|
||||
<div class="nopw-sm box-body theme-box radius8 main-bg main-shadow">
|
||||
<article class="article wp-posts-content">
|
||||
<?php
|
||||
the_content();
|
||||
wp_link_pages([
|
||||
'before' => '<p class="text-center post-nav-links radius8 padding-6">',
|
||||
'after' => '</p>',
|
||||
]);
|
||||
?>
|
||||
</article>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
|
||||
<div class="theme-box radius8 main-bg main-shadow relative-h aksrt-user-auth-panel">
|
||||
<?php if (empty($settings['enabled'])) : ?>
|
||||
<div class="colorful-bg c-blue flex jc" style="min-height:120px;align-items:center;justify-content:center;">
|
||||
<div class="text-center">
|
||||
<div class="em2x"><i class="fa fa-id-badge" aria-hidden="true"></i></div>
|
||||
<div class="mt10 em12"><?php esc_html_e('身份认证功能未启用', 'aksrt'); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php elseif ($status === 'verified') : ?>
|
||||
<?php
|
||||
$name = (string) ($info['name'] ?? ($apply['name'] ?? __('官方认证', 'aksrt')));
|
||||
$desc = (string) ($info['desc'] ?? ($apply['desc'] ?? ''));
|
||||
$time = (string) ($info['time'] ?? get_user_meta($user_id, 'aksrt_user_verify_reviewed_at', true));
|
||||
?>
|
||||
<div class="colorful-bg c-blue flex ac jse aksrt-user-auth-panel__verified" style="padding:30px 16px;gap:20px;flex-wrap:wrap;">
|
||||
<div class="text-center flex0">
|
||||
<div class="em3x"><i class="fa fa-id-badge" aria-hidden="true"></i></div>
|
||||
<div class="mt10 padding-w10"><?php esc_html_e('我的认证信息', 'aksrt'); ?></div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div><i class="fa fa-check-circle" aria-hidden="true"></i> <b class="ml3"><?php echo esc_html($name); ?></b></div>
|
||||
<?php if ($desc !== '') : ?>
|
||||
<div class="muted-2-color mt10"><?php echo esc_html($desc); ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($time !== '') : ?>
|
||||
<div class="muted-2-color mt10"><?php echo esc_html(sprintf(__('认证时间:%s', 'aksrt'), $time)); ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php elseif (!$user_id) : ?>
|
||||
<div class="colorful-bg c-blue flex jc" style="min-height:120px;align-items:center;justify-content:center;padding:24px;">
|
||||
<div class="text-center">
|
||||
<div class="em2x"><i class="fa fa-id-badge" aria-hidden="true"></i></div>
|
||||
<div class="em12 padding-w10 mt10"><?php esc_html_e('申请身份认证', 'aksrt'); ?></div>
|
||||
<p class="mt20">
|
||||
<a class="but c-blue padding-lg signin-loader" href="<?php echo esc_url($login_url); ?>">
|
||||
<i class="fa fa-sign-in mr6" aria-hidden="true"></i><?php esc_html_e('登录后申请', 'aksrt'); ?>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php elseif ($status === 'pending') : ?>
|
||||
<div class="box-body" style="padding:24px;">
|
||||
<div class="c-red mb10"><?php esc_html_e('您的申请正在审核中,请耐心等待', 'aksrt'); ?></div>
|
||||
<div><i class="fa fa-id-badge" aria-hidden="true"></i> <b class="ml3"><?php echo esc_html((string) ($apply['name'] ?? '')); ?></b></div>
|
||||
<?php if (!empty($apply['desc'])) : ?>
|
||||
<div class="muted-2-color mt10"><?php echo esc_html((string) $apply['desc']); ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($apply['msg'])) : ?>
|
||||
<div class="muted-2-color mt10"><?php echo esc_html(sprintf(__('申请说明:%s', 'aksrt'), (string) $apply['msg'])); ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($apply['time'])) : ?>
|
||||
<div class="muted-2-color mt10"><?php echo esc_html(sprintf(__('申请时间:%s', 'aksrt'), (string) $apply['time'])); ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($apply['img']) && is_array($apply['img'])) : ?>
|
||||
<div class="mt20 aksrt-user-auth-panel__imgs">
|
||||
<?php foreach ($apply['img'] as $img_url) : ?>
|
||||
<div class="preview-item"><img src="<?php echo esc_url((string) $img_url); ?>" alt=""></div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php elseif (empty($settings['allow_apply'])) : ?>
|
||||
<div class="box-body" style="padding:24px;">
|
||||
<div class="c-red"><i class="fa mr6 fa-info-circle" aria-hidden="true"></i><?php esc_html_e('抱歉!暂时不能申请身份认证', 'aksrt'); ?></div>
|
||||
<?php if (!empty($settings['disable_desc'])) : ?>
|
||||
<div class="muted-color mt20"><?php echo wp_kses_post(nl2br(esc_html((string) $settings['disable_desc']))); ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<?php
|
||||
$blocked_level = false;
|
||||
$limit = (int) ($settings['limit_level'] ?? 0);
|
||||
if ($limit > 0 && class_exists('\AKSRT\User\Level')) {
|
||||
$lv = (int) \AKSRT\User\Level::get_level($user_id);
|
||||
if ($lv < $limit) {
|
||||
$blocked_level = true;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?php if ($blocked_level) : ?>
|
||||
<div class="box-body" style="padding:24px;">
|
||||
<div class="c-red"><i class="fa mr6 fa-info-circle" aria-hidden="true"></i><?php esc_html_e('抱歉!您暂时不能申请身份认证', 'aksrt'); ?></div>
|
||||
<div class="muted-color mt20">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d level */
|
||||
esc_html__('由于您的等级过低,请升级到 LV.%d 后再来申请', 'aksrt'),
|
||||
$limit
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="colorful-bg c-blue flex ac" style="height:100px;justify-content:center;gap:10px;">
|
||||
<div class="em2x"><i class="fa fa-id-badge" aria-hidden="true"></i></div>
|
||||
<div class="em12 padding-w10"><?php esc_html_e('申请身份认证', 'aksrt'); ?></div>
|
||||
</div>
|
||||
<div class="box-body" style="padding:20px;">
|
||||
<?php if ($status === 'rejected') : ?>
|
||||
<div class="c-red mb15">
|
||||
<?php esc_html_e('上次申请未通过,可修改资料后重新提交。', 'aksrt'); ?>
|
||||
<?php
|
||||
$reason = (string) get_user_meta($user_id, AuthApply::REASON_META, true);
|
||||
if ($reason !== '') {
|
||||
echo '<div class="muted-2-color mt6">' . esc_html(sprintf(__('原因:%s', 'aksrt'), $reason)) . '</div>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($settings['desc'])) : ?>
|
||||
<div class="muted-color mb20"><?php echo wp_kses_post(nl2br(esc_html((string) $settings['desc']))); ?></div>
|
||||
<?php endif; ?>
|
||||
<form class="aksrt-user-auth-form form-upload" enctype="multipart/form-data">
|
||||
<?php if (!empty($settings['types'])) : ?>
|
||||
<div class="mb20">
|
||||
<div class="em09 muted-2-color mb6"><?php esc_html_e('认证类型', 'aksrt'); ?></div>
|
||||
<select class="form-control" name="type">
|
||||
<?php foreach ($settings['types'] as $t) : ?>
|
||||
<option value="<?php echo esc_attr($t['slug']); ?>"><?php echo esc_html($t['label']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="mb20">
|
||||
<div class="em09 muted-2-color mb6"><?php esc_html_e('认证身份', 'aksrt'); ?></div>
|
||||
<input type="text" class="form-control" name="name" required placeholder="<?php esc_attr_e('请输入身份名称', 'aksrt'); ?>" value="<?php echo esc_attr((string) ($apply['name'] ?? '')); ?>">
|
||||
</div>
|
||||
<div class="mb20">
|
||||
<div class="em09 muted-2-color mb6"><?php esc_html_e('身份简介', 'aksrt'); ?></div>
|
||||
<textarea class="form-control" name="desc" rows="2" placeholder="<?php esc_attr_e('请输入申请的身份简介', 'aksrt'); ?>"><?php echo esc_textarea((string) ($apply['desc'] ?? '')); ?></textarea>
|
||||
</div>
|
||||
<div class="mb20">
|
||||
<div class="em09 muted-2-color mb6"><?php esc_html_e('申请说明', 'aksrt'); ?></div>
|
||||
<textarea class="form-control" name="msg" rows="2" placeholder="<?php esc_attr_e('请输入申请缘由及说明', 'aksrt'); ?>"><?php echo esc_textarea((string) ($apply['msg'] ?? '')); ?></textarea>
|
||||
</div>
|
||||
<div class="mb20">
|
||||
<div class="em09 muted-2-color mb6"><?php esc_html_e('证明材料', 'aksrt'); ?></div>
|
||||
<input type="file" name="image[]" accept="image/gif,image/jpeg,image/jpg,image/png" multiple>
|
||||
<div class="px12 muted-2-color mt6"><?php esc_html_e('最多 3 张图片', 'aksrt'); ?></div>
|
||||
</div>
|
||||
<?php wp_nonce_field('aksrt_user_auth_apply', '_wpnonce', false); ?>
|
||||
<input type="hidden" name="action" value="aksrt_user_auth_apply">
|
||||
<button type="submit" class="but c-blue padding-lg btn-block">
|
||||
<i class="fa fa-check" aria-hidden="true"></i> <?php esc_html_e('确认提交', 'aksrt'); ?>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if (comments_open() || get_comments_number()) {
|
||||
comments_template();
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php get_sidebar(); ?>
|
||||
</main>
|
||||
<?php
|
||||
get_footer();
|
||||
Reference in New Issue
Block a user