| 开发者 | brokensmile.2103 |
|---|---|
| 更新时间 | 2026年10月4日 01:16 |
| PHP版本: | 7.4 及以上 |
| WordPress版本: | 7.1 |
| 版权: | GPLv2 or later |
| 版权网址: | 版权信息 |
/wp-content/plugins/init-user-engine[init_user_engine] in any page/post/template= How do I customize the UI? =\ The frontend is written in modular Vanilla JS with minimal HTML structure.\ Override styles via your theme or inject custom JS as needed.
user_meta: EXP, level, Coin, Cash, VIP, referralwp_init_user_engine_inbox: inbox messages (custom DB table)
= Can I extend or integrate it? =\
Yes. The plugin is built around WordPress hooks and REST API. You can inject logic via add_action, add_filter, or build your own UI on top of the endpoints.UPDATE … WHERE user_id = … AND status = 'unread') taking 2.5 seconds on a 1.2M-message Inboxuser_status (user_id, status): the unread badge count, "Mark All as Read" and the Unread tab now read the index only instead of loading every message row of the user (about 181 → 3 pages read per unread count in our 1.25M-row benchmark)user_pinned_created (user_id, pinned, created_at): the Inbox list (ORDER BY pinned DESC, created_at DESC) is read straight from the index, no more filesortuser_id indexes on the Inbox, Transaction log and EXP log tables. They were fully covered by composite indexes that start with user_id, so they only cost extra writes and disk space (every Coin/EXP change writes to these tables)ALGORITHM=INPLACE, LOCK=NONE), so reads and writes keep working while indexes are built; it gives up after 3 seconds if it has to wait for a table lock, instead of making other queries queue behind it, then retries an hour later (up to 24 times); and a lock option makes sure only one process ever runs it. If WP-Cron is not running, the upgrade runs on the next admin page load after the event is more than an hour latewp_ with your table prefix); the plugin detects the new indexes and marks the upgrade as done: ALTER TABLE wp_init_user_engine_inbox ADD KEY user_status (user_id, status), ADD KEY user_pinned_created (user_id, pinned, created_at), DROP KEY user_id, ALGORITHM=INPLACE, LOCK=NONE; then ALTER TABLE wp_init_user_engine_transaction_log DROP KEY user_id; and ALTER TABLE wp_init_user_engine_exp_log DROP KEY user_id;DELETE … LEFT JOIN over the whole Inbox table. That statement scanned and locked every row (even when nothing needed deleting), blocking every member's Inbox actions while it ran; in our benchmark a member's "Mark All as Read" waited 7.9 seconds. It now walks the distinct user IDs through the index, checks them against the users table in batches of 500 and deletes only orphaned messages, at most 1,000 rows per statement (0.45 s and no table-wide locks when there is nothing to delete)DELETE … WHERE type = …, which locked the whole table until done (members' Inbox actions waited 7 seconds while 200k messages were deleted in our benchmark; now under 0.1 second)$wpdb->prefix . 'users' as the users table, which does not exist on Multisite sub-sites (the users table is shared network-wide). It now uses $wpdb->userswp-login.phpwp-login.php?action=lostpassword page as beforewp-login.php?action=lostpassword, so the reset email, lostpassword_form / lostpassword_post hooks and the Turnstile "Lost Password Form" protection all keep workingwp-login.php behaviour so its exact message is still shownlostpassword-form.php can be overridden from your-theme/init-user-engine/; any element can also open it with data-iue="lostpassword"init_plugin_suite_user_engine_lostpassword_modal_enabledMutationObserver on the whole <body> (it fired on every DOM change of the page just to attach the password toggle to the registration form, which is already in the page)get_avatar_url filter no longer re-runs every plugin's pre_get_avatar_data callbacks for each avatar; it only applies Init User Engine's own avatar logic (the result is the same)pagehide instead of beforeunload, so browsers can keep the page in the back/forward cacheincludes/core.php instead of the main plugin file, so it never ran and the plugin's cron events stayed scheduled after deactivation. All three recurring events are now cleared on deactivation (they are scheduled again automatically on reactivation)?rest_route=/inituser/v1), requests that add their own query string were malformed: the registration math captcha never loaded, and Inbox, Transaction History and Experience Log pagination failed. Query strings are now appended with & when the REST URL already has one.pot/.po/.mo translation files with the new strings introduced above (Vietnamese translation included), regenerated with WP-CLI0 = feature off) and Coin Cost per Missed Day (0 = free). Off by default, so nothing changes on existing sites until an admin turns it onPOST /checkin gained three optional JSON fields: prompt_restore (answer with status restore_available instead of checking in when the streak can be kept — nothing is changed), restore_streak and restore_cost. Clients that don't send them behave exactly as beforeinit_plugin_suite_user_engine_streak_restore_max_days and init_plugin_suite_user_engine_streak_restore_cost, and action init_plugin_suite_user_engine_streak_restoredincludes/streak-restore.phpPOST /checkin had no protection against overlapping requests, so two requests fired at the same moment could both pass the "already checked in today" test and reward the same day twice. Check-ins are now serialized per user with the same short-lived mutex pattern used by the exchange endpoints; a request that arrives while another is running gets a 409 busy responsefadeIn/slideDown keyframes referenced by #iue-modal only existed in style-guest.css, which is not loaded for logged-in users. Added namespaced iue-fade-in/iue-slide-down keyframes to style-user.css (so a theme's own fadeIn/slideDown can no longer interfere) plus a prefers-reduced-motion opt-outinit_plugin_suite_user_engine_get_coin_label() / ..._get_cash_label() helpersincludes/init.php instead of the main plugin file, so it never ran and the database tables were only created later, on the first admin_init. It now runs on activation as intended (the admin_init version check stays as the upgrade path).pot/.po/.mo translation files with the new strings introduced above (Vietnamese translation included), regenerated with WP-CLIdeleted_user action (fires for both single-site wp_delete_user() and multisite wpmu_delete_user(), so one hook covers both): as soon as a user is permanently deleted, their EXP log rows and all Inbox messages are deleted right along with itiue_* user meta (check-in streak, login bonus flags, profile bonus flag...) needed no extra handling — WordPress core already wipes all usermeta for the user before deleted_user firesinit_plugin_suite_user_engine_user_data_purged (fires with the deleted user's ID right after cleanup) so other plugins/add-ons can hook in and clean up their own related data too.pot/.po files are unchanged/register) immediately signs the new user in (wp_set_auth_cookie() + wp_set_current_user(), followed by the standard wp_login action for compatibility with other plugins/themes) instead of leaving them on the Login formwp_login_form()) used to fall back to WordPress's default behavior and redirect the visitor to wp-login.php, which felt out of place on sites that never expose that page. Failed logins now redirect back to the exact page the visitor was on, with the login modal automatically reopened and an inline error message (wrong username, wrong password, or missing fields)wp_login_failed action combined with wp_get_referer(); only intervenes when the login attempt came from a normal frontend page, so logins made directly on wp-login.php or inside wp-admin keep WordPress's native behavior untouchediue_login_failed, iue_login_code) that assets/js/guest.js reads once to open the modal and show the right message, then immediately strips from the URL via history.replaceState() so refreshing or sharing the link never re-shows the noticereadme.txt — the Features section was rewritten from scratch to match the plugin's actual current feature set (Turnstile/captcha, Require Login gate, Redeem/VIP Codes with CSV export, Inbox Statistics, admin user metabox, and more), several of which had been implemented in past releases but never documented here.pot/.po translation files with the new strings introduced above (Vietnamese translation included)pinned back to 0 in the exact same UPDATE query that already sets a message to read (init_plugin_suite_user_engine_mark_inbox_read() and the "mark all as read" REST endpoint) — no extra query, no change to the Inbox SELECT/ORDER BY, and no new database index neededpinned for any pre-existing message that was already pinned and read before this update.pot/.po translation files (no new strings were needed for this change; existing ones were already sufficient).csv file=, +, -, @, or a tab are safely prefixed)manage_options capability plus a dedicated nonce per screen (iue_redeem_code_export_csv / iue_vip_code_export_csv).pot/.po translation files with the new strings introduced above (Vietnamese translation included); .mo not rebuilt as part of this changetemplate_redirect, so wp_head()/wp_footer() still run in full — the plugin's own login modal, and every other theme/plugin hook attached to those actions, keeps working normallyinit_plugin_suite_user_engine_require_login_bypass so other plugins/themes can exclude specific requests (e.g. a payment callback URL) from the gateassets/css/require-login.css and assets/js/require-login.js files render the gate's background and auto-open the login modal, kept separate from PHP output for coding-standards complianceguest.js) only exposed window.openLoginModal (and wired up Escape-to-close, Alt+L, and hash-triggered opening) when an avatar element was present on the page. Pages without the avatar shortcode/widget — including the new Require Login gate — could not open the login modal at all. The avatar element is now optional; the modal and its triggers work on any page as long as the modal itself is rendered (always the case via wp_footer).pot/.po translation files with the new strings introduced above (Vietnamese translation included); .mo not rebuilt as part of this change
View full changelog (all versions): Init User Engine – Changelog