NX::Site SEO Audit
NX::Site SEO Audit es un potente complemento SEO todo en uno diseñado para aumentar la visibilidad de su sitio web de WordPress en motores de búsqueda como Google, Bing y Yahoo. Realiza un análisis automático profundo de todas sus publicaciones y páginas (escaneando metaetiquetas, encabezados, imágenes, enlaces internos y externos, calidad del contenido y mucho más) y luego genera informes prácticos detallados para que pueda identificar y solucionar cada problema que frena su clasificación.
Descripción
Probado en Apache (usa .htaccess). Si tu hosting usa Nginx, puede que necesites configurar reglas de reescritura equivalentes manualmente.
Detalles técnicos
Licencia y categoría
Categoría: SEO
Slug: nx-site-seo-audit
Versión 5.1.8
- Requiere WordPress 5.9+
- Probado hasta WordPress 7.0.2
- Requiere PHP 7.4+
- Actualizado: 26/07/2026
Aviso: New versions of Site SEO Audit are available. Updating ensures better performance, security, and access to the latest features. Update Now.
Descarga gratuita
Este plugin es de acceso libre. Descarga el ZIP e instálalo directamente desde tu panel de WordPress.
Changelog — v5.1.8
v5.1.8 — NX::Site SEO Audit
- SECURITY — SMTP password now encrypted at rest: The SMTP password configured in Settings was previously stored in plain text in the WordPress database via update_option(). It is now encrypted using openssl_encrypt() with AES-128-CBC and WordPress-unique keys (wp_salt + AUTH_KEY) before being saved. The password is decrypted transparently when the mailer uses it. Falls back safely if OpenSSL is unavailable on the server.
- SECURITY — SSRF protection added to Minify Analyzer endpoints: The AJAX endpoints that fetch CSS/JS assets accepted a URL from $_POST without validating the resolved IP address, which could allow requests to private or loopback network ranges. A new is_private_ip() helper now blocks requests to 127.0.0.1, 192.168.x.x, 10.x.x.x, 172.16.x.x and all reserved ranges using PHP's FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE before any HTTP request is made.
- CODE QUALITY — Documented sslverify disabled across all audit classes: Ten instances of 'sslverify' => false across class-ajax-handler.php, class-sitemap-generator.php, class-core.php, class-links-auditor.php, class-page-speed-auditor.php, and class-ecommerce-auditor.php now include inline comments explaining that SSL verification is intentionally disabled to support auditing of sites running on self-signed or locally-issued certificates in staging and local development environments.
v5.1.7 — NX::Site SEO Audit
- BUG FIX — NX Meta Generator missing <title> tag on frontend: The SEO Title field was saved and visible in the NX Meta Generator preview, but the title tag was never injected into the actual page head. Added
pre_get_document_titlefilter to override the WordPress default title, and added explicit title output insideoutput_meta_tags()when NX Meta Generator is enabled for a post/page.
v5.1.6 — NX::Site SEO Audit
- BUG FIX — Dashboard "Recent Audits: section now correctly displays audit records after running "Run Full Audit". In sequential batch mode the issue counts were always saved as 0 because the final save step read from an empty in-memory array instead of the live database. Fixed: save_audit() now falls back to counting directly from the wpsap_issues table when no inline issue data is present. * BUG FIX — Reports & Export page "Total Audits" counter now registers correctly after every audit run (same root cause as above).
- NEW — Added "Help & Support": menu item to the plugin main menu (after License). Clicking it redirects directly to the developer documentation page at https://netsolex.com/wordpress/nx-site-seo-audit/.
v5.1.5 — NX::Site SEO Audit
- SECURITY — Rate Limiter: new class WPSAP_Rate_Limiter protects all 50 AJAX handlers grouped by risk (audit_heavy 5/2min, destructive 5/5min, write 20/min, export 10/min, light 30/min). Per-user via user ID or hashed IP. Cloudflare-aware. NEW — Export/Import Configuration: new section in Settings exports all plugin options to a dated .json file (browser download, SMTP password excluded). Import restores from file with full key whitelist and type-safe sanitization, auto-reloads page after success.
- NEW — Minify Analyzer: A new page (admin.php?page=wpsap-minify-analyzer) scans any URL on the site and lists all external CSS/JS files with their full path, minified status (green/red), size, and number of lines. Filters are available by file type and status. Clicking "View" opens a popup with the full file content (max. 500 KB) and a "Send to Minifier" button that sends the code directly to the built-in minification tool on the same page.
v5.1.4 — NX::Site SEO Audit
- NEW — Developer badge:small 32×32 px SVG icon injected in wp_footer (fixed, left:14px, bottom:14px) linking to netsolex.com/wordpress-plugins. Fully inline, zero external requests, smooth hover effect.
v5.1.3 — NX::Site SEO Audit
- NEW — Images Audit: Optimization detection (3 new checks)
File: includes/auditors/class-images-auditor.php
- Detects images not served in WebP format (checks src + srcset attributes). Issues logged as: image_no_web.
- Detects images missing lazy-load: checks loading="lazy", data-src, data-lazy-src, data-lazy (compatible with WP Rocket, Elementor, etc.). Issues logged as: image_no_lazy.
- Detects images missing width and/or height attributes (causes layout shift / bad CLS score). Issues logged as: image_no_dimensions.
- Inline base64 / data: images are excluded from optimization checks.
- DELETE query fixed to also clear the 3 new issue types on re-run.
- File: admin/views/images.php
- Added Optimization summary row with 3 new cards: No WebP / No Lazy-Load / No Dimensions.
- Added 3 new tabs: "No WebP", "No Lazy", "No Dimensions" with paginated tables and empty-state success messages.
- NEW — NX Meta Generator: 6 advanced meta tag fields
- Files: includes/class-nx-meta-generator.php admin/class-ajax-handler.php admin/views/meta-tags.php
- Schema.org Type:
- Outputs: meta itemscope itemtype=https://schema.org/Organization
- Presets: Organization, LocalBusiness, WebSite, WebPage, Article, Product, Person, Service, Event, FAQPage.
- Viewport:
- Outputs: meta name=viewport content=>
- Presets: standard with maximum-scale=5 with user-scalable=1.
- Default: width=device-width, initial-scale=1, maximum-scale=5
- Keywords:
- Outputs: meta name=keywords content=
- Language:
- Outputs: meta name=language content=es>
- Default: auto-detected from WordPress site locale.
- Presets: en, es, fr, de, it, pt, nl, ca, eu, gl.
v5.1.2 — NX::Site SEO Audit
- Update Badge Never Appears Without Manual "Delete All" Transients:
- wpsap_update_check_cache (our transient, TTL 12h) — stores the version info fetched from the Netsolex API.
- update_plugins (WordPress site transient, rebuilt by WP every 12h) — WordPress's own record of which plugins have updates available. This is what drives the red badge in the admin menu and the notice on the Plugins page.
- The admin notice in update_notice() reads our own transient directly to render the yellow banner.
- Fix: check_for_update() now checks whether our own transient exists. If it does not (i.e. it was just cleared), it calls get_remote_info(force=true) to fetch fresh data from the API immediately within the same WP update cycle.
- Fix: get_remote_info() now calls delete_site_transient('update_plugins') when it detects that the remote version is newer than the installed version. This forces WordPress to rebuild update_plugins on the next admin_init, which triggers check_for_update() and injects our update data immediately.
- Fix: after_install() now calls delete_site_transient('update_plugins') in addition to delete_transient(CACHE_KEY) after a successful install.
- Fix: The wpsap_auto_clean_transients cron action now also calls delete_site_transient('update_plugins'). Since the pre_set_site_transient_update_plugins filter runs whenever WP rebuilds update_plugins, deleting it forces an immediate rebuild on the next admin page load, which re-invokes check_for_update() and populates the update badge correctly.
v5.1.1 — NX::Site SEO Audit
- DASH-01 · Issues Distribution — Added "Passed" positive segment:
- File: admin/views/dashboard.php · assets/js/admin.js. The "Issues Distribution" donut chart only showed negative results (Critical, Warnings, Suggestions), making the visual appear completely red/yellow/blue even when most checks passed. Sites with only 1 Critical and 2 Warnings showed a chart that looked 100% problematic with no context of the overall health.
- Fix: A new green "Passed" segment is now always included in the donut chart, representing all issues with status = 'fixed'. The chart center label now reads "checks" instead of "issues" and reflects the total of all segments. The legend always shows the Passed row (green dot) so the distribution is honest and balanced. The PHP variable $passed_count is computed and passed to the JS chart data alongside critical, warning, and info. Clicking the Passed segment does not open a panel (no drill-down needed for resolved items).
- Image Converter — MIME Type Spoofing:
- The MIME type check relied exclusively on $_FILES['type'], which is the value reported by the browser/client. This field is never verified by PHP and can be trivially spoofed. An attacker could upload a PHP webshell with Content-Type: image/jpeg and bypass the check entirely.
- Fix: Replaced client-supplied MIME check with server-side mime_content_type() called on the actual temp file. Added an independent extension whitelist check (jpg, jpeg, png) as a second layer. The imagecreate function call now also uses the server-verified MIME type instead of $file['type']. The client-supplied type value is no longer used anywhere in the conversion flow.
- DB Optimizer — SQL Injection in add_index():
- Although $table was validated against a whitelist and $index_name was sanitized, the $column parameter was inserted directly into an ALTER TABLE query with no validation. Any attacker controlling this parameter could inject arbitrary SQL after the column position.
- Fix: Added an explicit whitelist of allowed column names: meta_key, meta_value, option_name, post_id, user_id, autoload, meta_key(191). The column value is also passed through sanitize_key() before the whitelist check. If the column is not in the whitelist the function returns an error immediately without executing any query.
- Backup Restore — Dangerous SQL Execution Without Filtering:
- The execute_sql_file() function executed every SQL statement in a backup file without filtering. A compromised or malicious .sql file could contain DROP DATABASE, CREATE USER, GRANT ALL PRIVILEGES, or SELECT INTO OUTFILE statements that would execute with full database privileges.
- Fix: Added a pre-execution blocklist check on each statement before it is sent to $wpdb->query(). The following command prefixes are blocked and skipped: DROP DATABASE, DROP SCHEMA, CREATE USER, RENAME USER, GRANT ALL, GRANT SUPER, INTO OUTFILE, INTO DUMPFILE, LOAD DATA INFILE. Blocked statements are logged to the PHP error log with a [NX Site Audit] SEC prefix and the error counter is incremented so the caller receives an appropriate warning about partial restore if needed.
- Backup — Missing Plugin Admin Session Check on Restore:
- The backup restore endpoints (ajax_restore and ajax_restore_upload) only verified a nonce and the manage_options capability. Unlike other destructive operations such as wp-config.php editing, they did not require a valid Plugin Admin session token. Any WordPress administrator could trigger a full database restore without the second authentication layer.
- Fix: Both ajax_restore() and ajax_restore_upload() now validate the Plugin Admin session token from $_POST['token'] using WPSAP_Admin_Auth::validate_session() before proceeding. If the session is missing or expired the endpoint returns an error with expired: true so the frontend can redirect to the Plugin Admin login screen, consistent with the rest of the plugin's security model.
- Admin Auth — PIN Brute-Force: No Attempt Limit:
- The PIN verification endpoint used during account activation had no attempt counter. Because the PIN is 6 numeric digits (000000–999999) an automated script could exhaust all 1,000,000 combinations without being blocked. The existing MAX_FAILURES brute-force protection only applied to the password login endpoint.
- Fix: Added pin_attempts TINYINT UNSIGNED NOT NULL DEFAULT 0 column to the admins table via CREATE TABLE schema update and a migration in maybe_install_table() that runs ALTER TABLE ADD COLUMN if the column does not exist (safe upgrade for existing installs).
- Fix: ajax_verify_pin() now reads pin_attempts before checking the PIN. If the count is >= MAX_FAILURES (5) the account is immediately locked and an error is returned without checking the PIN.
- Fix: On each wrong PIN the counter is incremented. When the counter reaches MAX_FAILURES after the increment the account is locked. Error messages include the number of remaining attempts for UX clarity.
v5.1.0 — NX::Site SEO Audit
- WooCommerce E-Commerce Auditor:
- Detects products missing offers.price in Schema.org Product markup.
- Checks product:price:amount + product:availability Open Graph tags.
- Audits BreadcrumbList structured data per product page.
- Tests category pagination pages for missing canonical / rel=prev/next.
- Live panel in Technical SEO → "Run E-Commerce Audit" button with summary cards + issues table.
- Cannibalization with Density:
- Expanded analysis now covers: title, meta description (NX SEO / Yoast / RankMath), H1, first 3 H2s, and first 100 words.
- Keyword density calculated per page — alerts at >3% (over-optimisation, shown in red).
- Canonical suggestion per group (oldest + most engaged page).
- CSV export button → downloads cannibalization-map.csv with URLs, keywords, densities, and canonical flag.
- Google Search Console Integration:
- Full OAuth2 flow (Client ID/Secret → Google authorisation → token storage).
- Fetches clicks, impressions, CTR, avg position per URL via GSC API.
- Detects low CTR pages (>100 impressions, CTR <1%) → snippet/title problem.
- Detects near-top-3 opportunities (ranked 4–20 with clicks).
- Dedicated Search Console menu item with live sync + data tables.
- Credentials panel in Settings page.
- Internal Links Anchor Text Analysis:
- Detects generic anchors ("click here", "leer más", "ver más", 20+ patterns in ES/EN).
- New Generic Anchor Issues section in Link Graph view showing each bad link + target.
- Anchor Quality column in the PageRank table (green ✓ or red badge).
- Summary card counts pages with generic anchor problems.
- Enhanced Sitemap:
- Image Sitemap with xmlns:image, image:loc, image:title, image:caption (featured images + content images).
- News Sitemap (nx-sitemap-news.xml) for posts published in last 48h with xmlns:news.
- Sitemap Index for sites >50,000 URLs — auto-splits into multiple files.
- Ping Google + Bing non-blocking on every regeneration (with last-pinged timestamp).
- Three toggle checkboxes in Sitemap settings with Save Options button.
v5.0.9 — NX::Site SEO Audit
- BUG #1: wpsap_deactivate() no longer deletes data (CRITICAL): core/SQL.php — The wpsap_deactivate() function now only clears cron jobs and calls flush_rewrite_rules(). DROP TABLE and all delete_option() functions have been removed. wpsap_uninstall() has been updated to respect the wpsap_delete_data_on_uninstall option (default: false), ensuring that data survives accidental uninstalls.
- BUG #3: SQL prepared in get_dashboard_data() (CRITICAL-SECURITY): admin/class-ajax-handler.php — The three count queries and the recent audits query now use $wpdb->prepare() with the placeholders %i (identifier) and %s, eliminating the direct interpolation pattern.
- BUG #8: rename_table_prefix() automatically updates wp-config.php (HIGH RISK): admin/class-ajax-handler.php — After renaming the tables, the code now attempts to automatically write the new $table_prefix to wp-config.php using is_writable() and preg_replace(). If the file lacks write permissions, it returns a clear warning with the exact command the admin should execute. The JSON response includes wpconfig_updated and wpconfig_warning.
- BUG #4: Hardcoded Spanish strings replaced with English (I18N): admin/class-ajax-handler.php — The 15+ Spanish strings in all dbopt_* methods were replaced with English equivalents within their existing __() wrappers. The nx-site-audit text domain was already consistent.
- BUG #5: export_csv() uses SQL_TBL_PREFIX: admin/class-ajax-handler.php — The three queries in export and clear_audit_data() no longer use {$wpdb->prefix}wpsap_* hardcoded. They now use {$wpdb->prefix} . SQL_TBL_PREFIX . "table", so they are resistant to prefix changes from the plugin's own security tool.
- BUG #6: Removed if (false) block (TECHNICAL DEBT): includes/auditors/class-content-auditor.php — Removed the 50 lines of dead code (comment + if (false) block). The active flow is not affected.
- set_time_limit / ini_set consolidated (PERFORMANCE): includes/class-core.php — Added static method WPSAP_Core::prepare_execution_environment() that centralises set_time_limit(300), ini_set('memory_limit', '512M') and output buffer configuration. Both WPSAP_Core::run_full_audit() and WPSAP_Ajax_Handler::run_full_audit() now call this single method instead of duplicating the block.
v5.0.8 — NX::Site SEO Audit
- DB Optimizer No Lock After Logout (Multi-Site Browser): localStorage tokens had no site prefix — multiple WordPress installs open in the same browser shared the same token keys, leaving protected pages unlocked after logout. Fixed by prefixing all token names with home_url(), making each installation's tokens unique in the browser.
- DB Optimizer / Sitemap Gate Conditional: render_gate() and close_gate() were inside if (admin_active) — JS-controlled divs were missing from the DOM when no admin was registered, bypassing the gate entirely. Fixed by calling both unconditionally.
- Admin Registration Failure: MySQL strict mode incompatible with DATETIME DEFAULT — fixed schema and added automatic migration.
- Meta Tags Duplicates: Missing UNIQUE KEY on wpsap_meta_data caused duplicate rows to be inserted on every analysis run.
- Settings HERO Invisible: render_gate() was called before div.wrap — the HERO section was hidden inside the gate wrapper.
- Page Lock Logout: clearGlobalSession() did not clear per-page tokens — protected pages remained accessible after logout.
- Security Tools Login Broken: Double esc_js() wrapping in render_js() call corrupted the AJAX URL and nonce.
- Settings / DB Optimizer Gate: Conditional render_gate() in PHP left the content-wrapper outside the gate — JS could not hide the protected content.
- Page Lock Toggle Ignored: render_js() did not receive the lock state — protected content was shown even when the toggle was OFF.
- DB Optimizer No Password Protection: Page had no password gate — added optional lock system matching the Settings page pattern.
- Dashboard Results Duplicating: DELETE in class-images-auditor used obsolete types (missing_alt, empty_alt) and class-links-auditor used redirect_chain instead of redirect_link — issues were never cleared and accumulated on every audit run.
v5.0.7 — NX::Site SEO Audit
- Bug Fix — admin/views/settings.php: The admin.php?page=wpsap-settings page wasn't locking correctly even though the Administrator plugin was active. The content was visible without authentication because the main div was structurally outside the gate wrapper, so the JavaScript hiding system never affected it.
- Bug Fix — includes/class-page-lock.php: Clicking the "Lock page" switch within Settings always opened a modal prompting for a username and password, even when the administrator already had a valid session in localStorage.
- New functionality — admin/views/db-optimizer.php: The admin.php?page=wpsap-db-optimizer page now locks automatically with a login form when the Plugin Administrator has status = active. The HERO is always visible. The full content is protected behind the gate. Same logic as settings.php.
- Security & SEO Tools + Backup & Restore — Always locked: Both pages refactored to use WPSAP_Page_Lock directly. No unlock option — they always require authentication regardless of whether an administrator is logged in or not (the gate displays a login link if no admin is present).
- Settings → Optional lock: Just below the title appears a card with a red/green toggle switch. Activating or deactivating it opens a modal window that prompts for the administrator password to confirm. The state is saved in the database (wpsap_page_lock_settings). When locked, the entire page is protected, including the toggle itself (to unlock it, you also need the password).
v5.0.6 — NX::Site SEO Audit
- Security & SEO Tools + Backup & Restore — Always locked: Both pages refactored to use WPSAP_Page_Lock directly. No unlock option — they always require authentication regardless of whether an administrator is logged in or not (the gate displays a login link if no admin is present).
- Settings → Optional lock: Just below the title appears a card with a red/green toggle switch. Activating or deactivating it opens a modal window that prompts for the administrator password to confirm. The state is saved in the database (wpsap_page_lock_settings). When locked, the entire page is protected, including the toggle itself (to unlock it, you also need the password).
v5.0.5 — NX::Site SEO Audit
- Onboarding banner in Dashboard: A striking visual banner with a dark purple gradient is added just after the HERO, featuring three clear steps and direct links: Configure SMTP → Register Administrator → All Features Unlocked. The banner disappears automatically when an administrator has active status. No action is required — it hides itself.
- Transients and automatic updates:
- Cron changed from weekly to hourly in SQL.php — new installations.
- Automatic migration in pluginloader.php — existing installations are migrated from weekly to hourly on the first admin_init without needing to deactivate/reactivate.
- delete_all_transients now also clears wpsap_update_check_cache — when the user manually deletes transients, the plugin's own cache is also cleared, and the next access to the dashboard forces a new query to the Updates API.
v5.0.4 — NX::Site SEO Audit
- Unified global session system: The root problem was that each protected page had its own independent session system in sessionStorage.
- A single global key: wpsap_global_token / wpsap_global_exp in localStorage.
- Log in to any protected page → all others are automatically unlocked.
- No session → displays "Login to Session" (purple button) which opens a login modal.
- With active session → displays "Session Active" (green badge) + "Close Session" (red button).
- Logging out also cleans all legacy v5.0.3 keys for upgrading installations.
- "Login" and "Close Session": A single global key, wpsap_global_session, is stored in localStorage. When a session is active, all protected pages are automatically unlocked. The button in admin-auth.php toggles between "Login" and "Close Session" depending on the current session status.
v5.0.3 — NX::Site SEO Audit
- Modal NX Meta Tag Editor Not Opening: admin/views/meta-tags.php — The div #wpsap-nxmeta-modal was nested inside the main .wrap. Although it has position fixed, in certain browser versions, a position fixed element loses its viewport reference if any ancestor has transform, filter, or will-change. The most reliable solution is to place it completely outside the .wrap. The modal now appears after the closing div tag of the wrapper, before the style and script tags. The JS remains unchanged.
- Analyzer Stuck at 88%: admin/views/meta-tags.php — The progress bar would reach 88% and get stuck if the server took longer than expected. Fix: AJAX call timeout increased from 120s to 180s; the set-to-100% block always executes upon receiving a response before checking r.success, so the progress bar reaches 100% in all cases before displaying the error or success message.
- Link Graph Analyzer collapse/expand not working: admin/views/link-graph.php — The explanation container div did not have the wpsap-desc-box class. The JS that triggers the toggle uses querySelectorAll('.wpsap-desc-box') — without that class, it never found the element. The class has been added to the container div.
- Duplicate Content Detector collapse/expand not working: admin/views/duplicate-content.php — The container had the class wpsap-desc-box and the button existed, but the collapsible content was never wrapped in div.wpsap-desc-more. The CSS .wpsap-desc-collapsed .wpsap-desc-more { display:none } had nothing to hide. The wpsap-desc-more wrapper was added around all the content after the first introductory paragraph.
- Security and SEO Tools password protection: admin/views/security-tools.php — The same pattern as backup-restore.php was applied: login gate #wpsap-st-auth-gate and protected container #wpsap-st-protected-content, using the same session system (sessionStorage + WPSAP_Admin_Auth). The session is shared per domain — if already authenticated in Backup & Restore, Security Tools is also accessible without logging in again.
- About Changelog section removed: admin/views/about.php — The block div.wpsap-changelog-box (versions v4.x, v4.8.9, etc.) and its collapse/expand animation JS have been completely removed. The rest of the page (hero, modules, plugin info, footer) remains intact.
- Registration Form — "Public Name" field (Security Fix):
- New required field "Public Name" added to the registration form, positioned between Username and Email.
- The Public Name (not the username) is displayed in the admin status card — username is never shown publicly.
- DB schema updated to v1.1 with public_name VARCHAR(100) column, with auto-migration for existing installs.
- Backend validation requires minimum 2 characters for Public Name.
- All registration form text translated to English (ready for i18n in 5 languages).
- "Manage Account" Button with Password-Protected Popup:
- New "Manage Account" button appears on the Plugin Administrator status card.
- Opens a modal popup requiring the current administrator password to confirm identity.
- Inside the popup: change Public Name and/or Email Address.
- Uses the wpsap_auth_update_account AJAX action with its own nonce (NONCE_ACCOUNT).
- Backup & Restore page — Password Protection:
- Entire page content is hidden behind a login gate on every page load.
- Uses sessionStorage (not localStorage) so the session clears when the browser tab closes.
- Same pattern as the wp-config.php editor: enter Username + Password → authenticated session.
- If no admin is registered yet, a link to the registration page is shown.
- Settings → SMTP Section — Password Protection:
- The "Email Server (SMTP)" section now shows a lock gate with "Password Protected" badge in the header.
- SMTP credentials are hidden until the admin logs in.
- Uses a separate sessionStorage key so SMTP and Backup sessions are independent.
- Session persists for the TTL duration (1 hour) within the same browser session.
v5.0.2 — NX::Site SEO Audit
- New DB table: wpsap_admin_auth: Created in core/SQL.php with dbDelta(). Fields: id, username, password_hash, email, status (pending/active/locked), pin_code, pin_expires, last_login, login_attempts, created_at, updated_at. This table is NEVER deleted on deactivation or uninstall — data always persists.
- Page "NX Admin Auth" — Administrator Registration: admin/views/admin-auth.php — Modern 3-step form: (1) Registration with username + email + password + confirm password, password viewer, strength meter; (2) 6-digit PIN verification sent by email; (3) success screen. If an admin is already registered, their info is shown (status, last login, etc.).
- Authentication system: includes/class-admin-auth.php — 7 AJAX handlers: register, login, verify_pin, resend_pin, logout, wpconfig_read, wpconfig_save. Sessions with random tokens (48 chars) stored in WP transients with 1-hour TTL. Passwords hashed with wp_hash_password(). Automatic lock after 5 failed attempts.
- wp-config.php Editor — Slide-out Popup: admin/views/security-tools.php — "Open wp-config.php Editor" button in the wp-config.php File Management section. Slide-in panel from the right with border-radius 12px 0 0 12px, black header with white text. No active session → login screen. After login → full text editor with: toolbar (Save / Reload / Logout), monospace dark-background textarea, footer with perms/size/date, Ctrl+S shortcut, automatic backup before saving, read-only warning if file is not writable.
v5.0.1 — NX::Site SEO Audit
- Bug Backup History — Root cause identified and resolved: jQuery uses . as a class selector. A file named backup-2024-06-17.sql.gz generated the ID bk-row-backup-2024-06-17.sql.gz, and $('#bk-row-backup-2024-06-17.sql.gz') failed silently because jQuery interpreted it as: id=bk-row-backup-2024-06-17, class=sql, class=gz.
- Fix PHP: str_replace('.', '_', sanitize_file_name(...)) on the <tr> and data-row-id attribute.
- Fix JS: uses data-row-id directly instead of recalculating the ID.
- Refresh button: New "↺ Refresh list" button next to the history title — reloads the list via AJAX without reloading the entire page. New ajax_list_refresh() in class-backup.php.
v5.0.0 — NX::Site SEO Audit
- class-keyword-cannibalization.php: TF-IDF + Jaccard, no HTTP, compatible with Elementor/YOOtheme.
- class-keyword-cannibalization.php: Iterative PageRank, orphan pages, link juice dilution.
- class-duplicate-content.php: k-shingle Jaccard on titles, meta, first 200 chars.
- class-image-converter.php: JPG/PNG→WebP, 200px gallery, pagination 10/20/30/50/100, Edit/Delete/Save/Export, resize 200/450/600/Full.
- class-robots-htaccess-auditor.php: Semantic analysis of robots.txt + .htaccess without HTTP.
- class-image-seo-optimizer.php: Filenames, CLS, non-modern formats, lazy load.
v4.9.0 — NX::Site SEO Audit
- Core Web Vitals Engine: includes/class-cwv-auditor.php — Calls the Google PageSpeed Insights v5 API, extracts LCP, CLS, INP, FCP, TTFB, TBT, Speed Index with official ratings (Good/Needs Improvement/Poor). Includes real Chrome UX Report data (p75). Automatic 6-hour cache.
- Full page with animated score ring: admin/views/home-dashboard.php — Animated ring, grid of 6 metrics with CrUX bars, opportunities sorted by ms saved, and internal SEO analysis (title, description, H1, canonical, HTTPS, robots, OG, schema JSON-LD, favicon, viewport, lang).
v4.8.9 — NX::Site SEO Audit
- WordPress footer appearing mid-page: Cause: #wpfooter { position: relative !important; } was overriding core. Fix: Override removed. WordPress now correctly manages the footer.
- HTTP loopback removed (get_page_html): Replaced wp_remote_get() with internal rendering using apply_filters('the_content', $post->post_content). Compatible with YOOtheme, Elementor, Divi, Gutenberg.
- All auditors pass $post->ID: Avoids url_to_postid() and ensures correct internal rendering.
- Content Auditor uses real HTML: Extracts text from rendered HTML with html_to_clean_text(). Fallback: clean_raw_post_content().
- Balanced HTML divs in 4 views: content.php, links.php, meta-tags.php had an extra div. db-optimizer.php had 2 missing divs. All corrected.
- Clear Audit Data — Available on All Pages:
- Section added in Dashboard, Meta Tags, Headings, Images, Links, Content, Keywords, DB Optimizer.
- Button with confirmation before deleting data.
- Automatic reload after clearing.
- Partial reusable: admin/views/partials/clear-audit-data.php.
- Sitemap Generator (New Page):
- New "Sitemap XML" menu item.
- Status cards, toggle enable/disable.
- Scan & Generate with animated progress bar.
- Modern post-generation modal.
- Full indexed table with filters.
- Download, copy URL and open sitemap in new tab.
- Generation history.
- Served virtually at /nx-sitemap.xml.
- Physical file generated in ABSPATH.
v4.8.8 — NX::Site SEO Audit
- NX Meta Generator: New class independent of external SEO plugins.
- Complete meta tag injection: description, robots, canonical, OG, Twitter, article, etc.
- NX Meta Editor modal: Per-page editing without leaving the auditor.
- Custom SEO Title: Real-time counter (50–60 chars).
- Meta Description: Counter (120–160 chars).
- ON/OFF toggle per page.
- OG Image selector with Media Library.
- Custom Robots meta.
- Twitter Card selector.
- Article Publisher URL field.
- Preview HTML.
- AJAX endpoints: wpsap_nxmeta_get and wpsap_nxmeta_save.
v4.8.7 — NX::Site SEO Audit
- Auto-refresh after DB actions.
- Modern modal instead of confirm().
- Protection of critical transients.
- WP-Cron weekly automatic cleanup.
- Change History log corrected.
v4.8.6 — NX::Site SEO Audit
- About page update.
- 5 languages updated.
- DB Optimizer in English.
- CSS/JS Minify & Unminify tool.
- Table prefix rename + persistent log.
v4.8.5 — NX::Site SEO Audit
- HERO header and global visual redesign.
v4.8.4 — NX::Site SEO Audit
- Email Notifications improvements.
- Complete translations in Settings and License.
v4.8.3 — NX::Site SEO Audit
- Fix Footer page.
v4.8.2 — NX::Site SEO Audit
- Broken link false positives eliminated.
- Link Allowlist added.
- About page updated.
v4.8.1 — NX::Site SEO Audit
- Link Allowlist + Donation section.
v4.8.0 — NX::Site SEO Audit
- Issues Distribution improved.
- Complete responsive CSS.
v4.7.4 — NX::Site SEO Audit
- Critical Fix Needs Improvement.
- Plugin footer redesigned.
- SEO Site Score modal improved.
v4.7.3 — NX::Site SEO Audit
- Pages Status block added.
v4.7.0 — NX::Site SEO Audit
- DB Optimizer PRO.
- Automatic update system.
v4.6.0 — NX::Site SEO Audit
- 5 languages implemented.
- Keywords + Technical SEO modules.
v4.5.0 — NX::Site SEO Audit
- Initial module version.
Otros plugins de SEO
NX::SEO Audit Pro
NX::SEO Audit Pro es un potente plugin SEO todo en uno diseñado para aumentar la visibilidad de tu sitio web de WordPress en buscadores como Google, Bing y Yahoo. Realiza un análisis automático exhaustivo de todas tus entradas y páginas (analizando metaetiquetas, encabezados, imágenes, enlaces internos y externos, calidad del contenido y mucho más) y genera informes detallados y prácticos para que puedas identificar y solucionar cualquier problema que esté afectando tu posicionamiento.