{"id":297204,"date":"2026-04-20T13:20:10","date_gmt":"2026-04-20T13:20:10","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/enterprise-api-importer\/"},"modified":"2026-04-30T16:22:17","modified_gmt":"2026-04-30T16:22:17","slug":"tporret-api-data-importer","status":"publish","type":"plugin","link":"https:\/\/en-au.wordpress.org\/plugins\/tporret-api-data-importer\/","author":23475994,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.3.0","stable_tag":"1.3.0","tested":"6.9.4","requires":"6.3","requires_php":"8.1","requires_plugins":null,"header_name":"tporret API Data Importer","header_author":"tporret","header_description":"Highly secure enterprise ETL importer for WordPress.","assets_banners_color":"303845","last_updated":"2026-04-30 16:22:17","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/porretto.com\/donate","header_plugin_uri":"https:\/\/github.com\/tporret\/enterprise-api-importer","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":183,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.2.5":{"tag":"1.2.5","author":"tporret","date":"2026-04-20 13:19:51"},"1.2.6":{"tag":"1.2.6","author":"tporret","date":"2026-04-24 16:38:04"},"1.3.0":{"tag":"1.3.0","author":"tporret","date":"2026-04-30 16:22:17"}},"upgrade_notice":{"1.2.5":"<p>Plugin name update for WordPress.org resubmission. No functional upgrade impact.<\/p>","1.2.4":"<p>Dry-run rendering now mirrors save-time template normalization, and mapping template HTML allowlist support has been expanded for card-style\/class-based templates while preserving centralized safety checks.<\/p>","1.2.3":"<p>Multisite release. Adds a Network Admin summary dashboard, preserves per-site dashboards, blocks unsupported network activation, and changes the default SSRF dashboard state on new installs from critical to warning.<\/p>","1.2.2":"<p>Security hardening release. Includes encrypted credential storage, masked REST credential responses, safer filter context handling, stronger content\/meta sanitization, and tighter admin capability checks.<\/p>","1.2.1":"<p>Maintenance release with cleaned repository history and packaging only. No functional upgrade steps required.<\/p>","1.2.0":"<p>Security and UX release: Includes the new React import workspace, expanded auth methods, API preview\/dry-run tools, optional templates on job creation, and per-import editing lock controls, plus enterprise hardening features (capabilities, Twig validation, audit logs, SSRF allowlisting).<\/p>","1.0.0":"<p>Initial stable release with enterprise ETL controls, Twig templating, dynamic post titles, and target post type support.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3510907,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3510907,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3510907,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3510907,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.2.5","1.2.6","1.3.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3510907,"resolution":"1","location":"assets","locale":"","width":2593,"height":1463},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3510907,"resolution":"2","location":"assets","locale":"","width":2624,"height":261},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3510907,"resolution":"3","location":"assets","locale":"","width":1998,"height":1226}},"screenshots":{"1":"The Twig Mapping Interface for transforming JSON data.","2":"API Connection and Data Filtering rules."}},"plugin_section":[],"plugin_tags":[1556,4567,260627,87,1118],"plugin_category":[59],"plugin_contributors":[260628],"plugin_business_model":[],"class_list":["post-297204","plugin","type-plugin","status-publish","hentry","plugin_tags-api","plugin_tags-cron","plugin_tags-etl","plugin_tags-import","plugin_tags-json","plugin_category-utilities-and-tools","plugin_contributors-tporret","plugin_committers-tporret"],"banners":{"banner":"https:\/\/ps.w.org\/tporret-api-data-importer\/assets\/banner-772x250.png?rev=3510907","banner_2x":"https:\/\/ps.w.org\/tporret-api-data-importer\/assets\/banner-1544x500.png?rev=3510907","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/tporret-api-data-importer\/assets\/icon-128x128.png?rev=3510907","icon_2x":"https:\/\/ps.w.org\/tporret-api-data-importer\/assets\/icon-256x256.png?rev=3510907","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/tporret-api-data-importer\/assets\/screenshot-1.png?rev=3510907","caption":"The Twig Mapping Interface for transforming JSON data."},{"src":"https:\/\/ps.w.org\/tporret-api-data-importer\/assets\/screenshot-2.png?rev=3510907","caption":"API Connection and Data Filtering rules."},{"src":"https:\/\/ps.w.org\/tporret-api-data-importer\/assets\/screenshot-3.png?rev=3510907","caption":""}],"raw_content":"<!--section=description-->\n<p>tporret API Data Importer gives WordPress teams an enterprise-grade ETL pipeline for importing external API data with confidence.<\/p>\n\n<p>The plugin ships readable source for its generated admin assets. JavaScript and CSS source files are included in the <code>src\/<\/code> directory, compiled assets are in <code>build\/<\/code>, and the maintained public source repository is available at https:\/\/github.com\/tporret\/enterprise-api-importer.<\/p>\n\n<p>This readme is written for WordPress administrators and site owners evaluating or using the plugin from the Plugins screen.<\/p>\n\n<p>Use tporret API Data Importer to run clean, repeatable import workflows without sacrificing flexibility:<\/p>\n\n<ul>\n<li>Multi-Connection Job Manager for organizing and scaling imports<\/li>\n<li>React Tabbed Import Job Workspace (Source\/Auth, Data Rules, Mapping\/Templating, Automation)<\/li>\n<li>Advanced JSON array traversal and pre-stage data filtering to remove noise before insertion<\/li>\n<li>Twig Templating Engine for complex logic, loops, and nested object mapping without drag-and-drop limitations<\/li>\n<li>Twig-powered Post Title Templates with safe sanitization and fallback handling<\/li>\n<li>Optional templates for new jobs (start with connection setup, add templates later)<\/li>\n<li>Multiple API auth modes: none, bearer token, custom API-key header, and basic auth<\/li>\n<li>Per-import Target Post Type selection (posts, pages, and public custom post types)<\/li>\n<li>Per-import Default Target Settings (post status, post author, comment status, pingback\/trackback status)<\/li>\n<li>Per-import editing lock toggle for imported posts (allow editing or enforce read-only)<\/li>\n<li>Time-aware batch processing via WP-Cron to reduce timeout and memory-risk scenarios<\/li>\n<li>Multisite support with per-site importer dashboards and an optional Network Admin summary dashboard when the plugin is also active on the primary site<\/li>\n<li><strong>[New v1.3] Deep Module Architecture (internal):<\/strong>\n\n<ul>\n<li><code>Tporapdi_Validator<\/code> \u2014 single validation seam for all import job fields<\/li>\n<li><code>Tporapdi_Import_Runner<\/code> \u2014 owns the 5-stage import lifecycle (Extract \u2192 Filter \u2192 Stage \u2192 Transform \u2192 Load)<\/li>\n<li><code>Tporapdi_Template_Engine<\/code> \u2014 unified Twig rendering seam for all template fields and dry-run previews<\/li>\n<li><code>Tporapdi_Security_Guard<\/code> \u2014 centralised SSRF, CIDR, and Twig security checks shared across save and run paths<\/li>\n<li><code>Tporapdi_Job_Repository<\/code>, <code>Tporapdi_Queue_Repository<\/code>, <code>Tporapdi_Log_Repository<\/code> \u2014 domain repositories hiding all SQL and cache management<\/li>\n<li><code>Tporapdi_Media_Ingestor<\/code> \u2014 isolated image sideload and HTML rewrite logic with idempotent deduplication<\/li>\n<li><code>Tporapdi_Cleanup_Service<\/code> \u2014 chunked garbage collection for staging queue and log tables<\/li>\n<li>Reporter self-registration via glob discovery \u2014 adding a new dashboard metric requires zero edits to existing files<\/li>\n<li><code>Tporapdi_Lock_Policy<\/code> \u2014 single edit-lock policy seam used by all admin UI affordances<\/li>\n<li><code>TPORAPDI_Defaults_Resolver::normalize()<\/code> \u2014 single normalization seam for post status defaults shared by REST save and import runtime<\/li>\n<\/ul><\/li>\n<li><strong>[New v1.2] Tableau-Style Reporting Dashboard:<\/strong> Real-time metrics on environment health, security posture, and API performance with interactive charts, status indicators, and audit activity feed<\/li>\n<li><strong>[New] Credential Encryption &amp; REST Masking:<\/strong>\n\n<ul>\n<li>AES-256-CBC encryption at rest for auth_token and auth_password fields<\/li>\n<li>REST GET responses mask credentials; boolean flags indicate stored state<\/li>\n<li>Blank credential fields on update preserve existing encrypted values<\/li>\n<li>React UI shows saved-credential indicators with placeholder text<\/li>\n<li>apply_filters no longer exposes raw tokens to third-party hooks<\/li>\n<\/ul><\/li>\n<li><strong>[New] Import Pipeline Sanitization:<\/strong>\n\n<ul>\n<li>Twig-rendered post content sanitized via wp_kses_post before wp_insert_post<\/li>\n<li>Custom meta values sanitized via sanitize_text_field before update_post_meta<\/li>\n<li>Admin menu pages restricted to manage_options capability (was read)<\/li>\n<\/ul><\/li>\n<li><strong>[New] Enterprise-Grade Security Hardening:<\/strong>\n\n<ul>\n<li>Dedicated template management capability with multisite support<\/li>\n<li>Twig template security validation (disallowed tags, size\/complexity limits, syntax checking)<\/li>\n<li>Template change audit logging with before\/after hashes and actor metadata<\/li>\n<li>SSRF prevention via hostname and CIDR allowlisting with DNS resolution<\/li>\n<li>Twig variable strictness is filterable, with permissive rendering used by default for resilient imports<\/li>\n<li>Imported items locked read-only (no editing, deletion, or quick-edit)<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<p>Whether you import catalogs, directory records, listings, events, or custom business data, tporret API Data Importer provides a scalable framework for structured API-to-WordPress ETL.<\/p>\n\n<p>Built for real-world production workflows:<\/p>\n\n<ul>\n<li>Title templates are rendered via Twig and sanitized before save<\/li>\n<li>Target post type safely falls back to post if invalid or unavailable<\/li>\n<li>Attachment is excluded by default from target post type selection<\/li>\n<li>Default target post settings are validated and applied at load time for consistent publishing\/discussion behavior<\/li>\n<li>Imports are staged and processed in queue batches for safer long-running jobs<\/li>\n<li>Imported items are cryptographically linked to their origin import (read-only)<\/li>\n<li>Template configuration changes are audit-logged with full actor context<\/li>\n<li>Endpoints validated against configurable SSRF allowlists and HTTPS enforcement<\/li>\n<li>Inline API connection testing, sample payload preview, and template dry-run rendering from the edit workspace<\/li>\n<\/ul>\n\n<h3>Development<\/h3>\n\n<p>To rebuild generated admin assets from source:<\/p>\n\n<ol>\n<li>Install Node.js dependencies: <code>npm install<\/code><\/li>\n<li>Build production assets: <code>npm run build<\/code> (uses <code>@wordpress\/scripts<\/code> \/ webpack)<\/li>\n<li>For a watch\/dev build: <code>npm start<\/code><\/li>\n<\/ol>\n\n<ul>\n<li>JavaScript\/CSS source lives in <code>src\/<\/code><\/li>\n<li>Production assets are generated into <code>build\/<\/code><\/li>\n<li>The public source repository is https:\/\/github.com\/tporret\/enterprise-api-importer<\/li>\n<\/ul>\n\n<h3>External services<\/h3>\n\n<p>This plugin connects to external APIs that you configure in each import job.<\/p>\n\n<p>The plugin does not hardcode any third-party API vendor. Data destination, terms, and privacy practices depend on the endpoint(s) you configure.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to the \/wp-content\/plugins\/ directory, or install it through the WordPress Plugins screen.<\/li>\n<li>Activate the plugin through the Plugins screen in WordPress.<\/li>\n<li>Go to tporret API Data Importer \u2192 Manage Imports to configure your API connections, filtering rules, target post type, and Twig templates.<\/li>\n<\/ol>\n\n<p>Multisite note: activate the plugin on each subsite that should run imports. If you also want the Network Admin summary dashboard, activate it on the primary site too. Do not use Network Activate; that mode is intentionally not supported.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20require%20wp-cli%3F\"><h3>Does this require WP-CLI?<\/h3><\/dt>\n<dd><p>No. It uses native WP-Cron scheduling, but supports CLI triggers.<\/p><\/dd>\n<dt id=\"can%20i%20parse%20nested%20json%20arrays%3F\"><h3>Can I parse nested JSON arrays?<\/h3><\/dt>\n<dd><p>Yes. Nested objects and arrays can be parsed and transformed through Twig templating.<\/p><\/dd>\n<dt id=\"does%20it%20handle%20api%20authentication%3F\"><h3>Does it handle API authentication?<\/h3><\/dt>\n<dd><p>Yes. It supports four modes per import job: none, bearer token, custom API-key header, and basic auth.<\/p><\/dd>\n<dt id=\"can%20i%20set%20dynamic%20titles%20for%20imported%20posts%3F\"><h3>Can I set dynamic titles for imported posts?<\/h3><\/dt>\n<dd><p>Yes. Use Post Title Template with Twig syntax. If left blank, the importer falls back to Imported Item {ID}.<\/p><\/dd>\n<dt id=\"can%20i%20import%20into%20custom%20post%20types%3F\"><h3>Can I import into custom post types?<\/h3><\/dt>\n<dd><p>Yes. Select any public post type from Target Post Type. If the selected post type becomes unavailable, imports safely fall back to post.<\/p><\/dd>\n<dt id=\"how%20does%20this%20work%20on%20multisite%3F\"><h3>How does this work on multisite?<\/h3><\/dt>\n<dd><p>Each subsite keeps its own import jobs, schedules, settings, and dashboard. A separate Network Admin dashboard can summarize active subsites when the plugin is also active on the primary site. Activate the plugin per site; Network Activate is intentionally blocked.<\/p><\/dd>\n<dt id=\"does%20this%20import%20media%20attachments%20automatically%20from%20url%20fields%3F\"><h3>Does this import media attachments automatically from URL fields?<\/h3><\/dt>\n<dd><p>The plugin includes a secure media sideload helper foundation with source URL deduplication. Full field-level media mapping workflows can be added on top of this helper.<\/p><\/dd>\n<dt id=\"who%20can%20edit%20imported%20items%20and%20templates%3F\"><h3>Who can edit imported items and templates?<\/h3><\/dt>\n<dd><p>Template configuration requires the <code>tporapdi_manage_templates<\/code> capability or <code>manage_options<\/code> role. Multisite super admins always have access. Imported item editing can now be controlled per import job with the \"Lock editing of imported posts\" setting.<\/p><\/dd>\n<dt id=\"what%20twig%20features%20are%20blocked%20for%20security%3F\"><h3>What Twig features are blocked for security?<\/h3><\/dt>\n<dd><p>The following Twig tags are disallowed to prevent file inclusion and code injection: <code>include<\/code>, <code>source<\/code>, <code>import<\/code>, <code>from<\/code>, <code>embed<\/code>, <code>extends<\/code>, <code>use<\/code>, <code>macro<\/code>.<\/p><\/dd>\n<dt id=\"can%20i%20allow%20imports%20from%20internal%2Fprivate%20networks%3F\"><h3>Can I allow imports from internal\/private networks?<\/h3><\/dt>\n<dd><p>Yes, but not recommended for production. Go to Settings \u2192 Allow Internal Endpoints to permit RFC1918 and loopback addresses. For whitelisting specific hosts\/CIDR blocks, use Settings \u2192 Allowed Endpoint Hosts and Settings \u2192 Allowed Endpoint CIDR Blocks.<\/p><\/dd>\n<dt id=\"why%20does%20the%20dashboard%20show%20a%20security%20warning%20on%20a%20new%20install%3F\"><h3>Why does the dashboard show a security warning on a new install?<\/h3><\/dt>\n<dd><p>The SSRF Hardening check starts in a warning state until you configure Allowed Endpoint Hosts or Allowed Endpoint CIDR Blocks. That warning is there to remind you that outbound API access is still open until you add an allowlist.<\/p><\/dd>\n<dt id=\"what%20should%20i%20configure%20in%20tporret%20api%20data%20importer%20%E2%86%92%20settings%20first%3F\"><h3>What should I configure in tporret API Data Importer \u2192 Settings first?<\/h3><\/dt>\n<dd><p>Start with Allowed Endpoint Hosts and list only trusted API domains. Leave Allow Internal Endpoints disabled unless you intentionally import from internal services. Add CIDR blocks only when you need additional IP-range restrictions.<\/p><\/dd>\n<dt id=\"where%20are%20template%20changes%20logged%3F\"><h3>Where are template changes logged?<\/h3><\/dt>\n<dd><p>All template configuration changes are logged to the wp_custom_import_logs database table with before\/after hashes, actor information, and precise timestamps. Review logs via tporret API Data Importer \u2192 Manage Imports \u2192 Import edit screen.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.3.0<\/h4>\n\n<ul>\n<li><strong>Architectural deepening release \u2014 no breaking changes to existing import jobs, REST API, or admin UI.<\/strong><\/li>\n<li>Extracted <code>Tporapdi_Validator<\/code> module: single entry point for all import job field validation (auth, recurrence, templates, post defaults, meta mappings) replacing scattered inline checks in rest.php.<\/li>\n<li>Extracted <code>Tporapdi_Import_Runner<\/code> module: owns the full 5-stage import lifecycle (Extract, Filter, Stage, Transform, Load) with state transitions and failure semantics in one place.<\/li>\n<li>Extracted <code>Tporapdi_Template_Engine<\/code> module: single <code>render()<\/code> seam used by both live import runs and dry-run previews, guaranteeing identical Twig security and output behaviour across all template fields.<\/li>\n<li>Extracted <code>Tporapdi_Security_Guard<\/code> module: centralises SSRF, CIDR, and Twig security validation \u2014 same rules enforced at save time and run time.<\/li>\n<li>Extracted three domain repositories (<code>Tporapdi_Job_Repository<\/code>, <code>Tporapdi_Queue_Repository<\/code>, <code>Tporapdi_Log_Repository<\/code>): all SQL and cache management moved out of db.php, which is now a thin backwards-compatible shim layer.<\/li>\n<li>Extracted <code>Tporapdi_Media_Ingestor<\/code> module: image sideload, deduplication, and HTML content rewriting isolated from lifecycle cleanup.<\/li>\n<li>Extracted <code>Tporapdi_Cleanup_Service<\/code> module: chunked garbage collection for staging queue and log tables, independent of media handling.<\/li>\n<li>Reporting Discovery Engine: reporters now self-register via <code>TPORAPDI_Reporting_Aggregator::register()<\/code>; <code>reporting.php<\/code> uses glob-based auto-discovery so new reporters require no edits to existing files.<\/li>\n<li>Extracted <code>Tporapdi_Lock_Policy<\/code> module: single <code>is_locked(int $post_id)<\/code> seam for all import-managed post edit-locking; all content.php hook callbacks route through this one policy.<\/li>\n<li>Deepened <code>TPORAPDI_Defaults_Resolver<\/code>: new <code>normalize(string $post_type, array $raw_input)<\/code> static method is the single seam for post status\/comment status\/ping status normalization \u2014 used identically by the REST save path and the import runtime.<\/li>\n<li>Updated the public plugin name to tporret API Data Importer for WordPress.org resubmission.<\/li>\n<\/ul>\n\n<h4>1.2.4<\/h4>\n\n<ul>\n<li>Aligned Twig dry-run template normalization with save-time normalization so preview output matches persisted output.<\/li>\n<\/ul>\n\n<h4>1.2.3<\/h4>\n\n<ul>\n<li>Added multisite Network Admin dashboard support while preserving per-site importer dashboards.<\/li>\n<li>Added multisite activation safeguards so unsupported Network Activate attempts are blocked and reverted.<\/li>\n<li>Added multisite admin guidance for primary-site activation requirements and network dashboard availability.<\/li>\n<li>Softened the SSRF Hardening reporter so fresh installs show a warning until an endpoint allowlist is configured.<\/li>\n<li>Tightened and de-duplicated release packaging workflows.<\/li>\n<\/ul>\n\n<h4>1.2.2<\/h4>\n\n<ul>\n<li>Security hardening release.<\/li>\n<li>Encrypted credential storage at rest for auth_token and auth_password.<\/li>\n<li>REST import-job GET now masks credentials and returns has_auth_token \/ has_auth_password flags.<\/li>\n<li>Update handlers preserve existing encrypted credentials when masked fields are submitted blank.<\/li>\n<li>Removed raw token exposure from tporapdi_remote_request_args filter context.<\/li>\n<li>Added post-content sanitization with wp_kses_post before post insert\/update.<\/li>\n<li>Added custom-meta sanitization with sanitize_text_field before update_post_meta.<\/li>\n<li>Tightened admin menu capability from read to manage_options.<\/li>\n<\/ul>\n\n<h4>1.2.1<\/h4>\n\n<ul>\n<li>Maintenance release from cleaned git history.<\/li>\n<li>Removed accidentally committed documentation\/test-data directories from repository history and release packaging.<\/li>\n<li>No runtime feature changes.<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li><strong>Updated: React Import Job Workspace<\/strong>\n\n<ul>\n<li>Replaced the legacy linear create\/edit form with a tabbed workspace in wp-admin.<\/li>\n<li>Added sticky footer actions for save, run now, and update existing item content.<\/li>\n<\/ul><\/li>\n<li><strong>Updated: REST Import Job CRUD + actions<\/strong>\n\n<ul>\n<li>Added REST routes for create\/read\/update import jobs and run\/template sync actions.<\/li>\n<li>Added centralized sanitization for import job payloads used by create\/update handlers.<\/li>\n<\/ul><\/li>\n<li><strong>Updated: API validation and preview tooling<\/strong>\n\n<ul>\n<li>Added in-workspace API test button with sample record preview support.<\/li>\n<li>Added Twig dry-run test support from the Mapping &amp; Templating tab.<\/li>\n<\/ul><\/li>\n<li><strong>Updated: Authentication model<\/strong>\n\n<ul>\n<li>Added four auth methods per import job: none, bearer, custom API-key header, and basic auth.<\/li>\n<\/ul><\/li>\n<li><strong>Updated: Optional templates for new imports<\/strong>\n\n<ul>\n<li>New imports can be created without title or mapping templates; templates can be added later.<\/li>\n<\/ul><\/li>\n<li><strong>Updated: Per-import editing lock control<\/strong>\n\n<ul>\n<li>Added \"Lock editing of imported posts\" toggle in Mapping &amp; Templating.<\/li>\n<li>Edit\/delete restrictions now apply by import configuration and can be disabled per job.<\/li>\n<\/ul><\/li>\n<li><strong>Updated: Default target post settings<\/strong>\n\n<ul>\n<li>Added per-import defaults for Post Status, Post Author, Comment Status, and Pingback\/Trackback Status in Mapping &amp; Templating.<\/li>\n<li>Added REST sanitization and persistence for these fields in import job create\/update handlers.<\/li>\n<li>Import load now applies these defaults during <code>wp_insert_post()<\/code> and sync updates discussion settings during <code>wp_update_post()<\/code>.<\/li>\n<\/ul><\/li>\n<li><strong>New: Enterprise Reporting Dashboard (Tableau-Style)<\/strong>\n\n<ul>\n<li>Real-time operations command center with global health status badge and force-refresh controls.<\/li>\n<li>Nine enterprise-grade metrics across three pillars:<\/li>\n<li><strong>Environment Health:<\/strong> Cron heartbeat, queue depth, daily success rate.<\/li>\n<li><strong>Security &amp; Compliance:<\/strong> SSRF hardening status, audit integrity tracking, protocol enforcement (HTTPS vs HTTP).<\/li>\n<li><strong>Connectivity &amp; Performance:<\/strong> API latency trends, active endpoint count, hourly throughput.<\/li>\n<li>High-performance React UI with Recharts data visualization and Lucide icons.<\/li>\n<li>Responsive grid layout with KPI stat cards (sparkline trends), status lists, donut charts, area charts, and system pulse marquee.<\/li>\n<li>REST API endpoints: <code>\/wp-json\/eapi\/v1\/dashboard<\/code> (metrics) and <code>\/wp-json\/eapi\/v1\/dashboard\/history<\/code> (time-series data).<\/li>\n<li>Transient-backed caching (600s TTL) with force-refresh capability.<\/li>\n<li>Shimmer loading states and dark\/light theme-aware styling via Tailwind CSS (namespaced to avoid wp-admin conflicts).<\/li>\n<li>Menu: EAPI \u2192 Dashboard (requires read capability).<\/li>\n<\/ul><\/li>\n<li><strong>Credential Encryption &amp; Data Sanitization<\/strong>\n\n<ul>\n<li>Credential fields (auth_token, auth_password) are now encrypted at rest with AES-256-CBC using a key derived from wp_salt('auth').<\/li>\n<li>REST GET responses mask credential values and expose boolean has_auth_token \/ has_auth_password flags.<\/li>\n<li>Credential preservation on update: blank credential fields retain existing encrypted values.<\/li>\n<li>React auth fields show \"Credential saved\" indicators with placeholder text for stored credentials.<\/li>\n<li>apply_filters('tporapdi_remote_request_args') no longer passes raw token \u2014 passes auth_method instead.<\/li>\n<li>Twig-rendered post content now passes through wp_kses_post() before wp_insert_post() (stored XSS prevention).<\/li>\n<li>Twig-compiled custom meta values now pass through sanitize_text_field() before update_post_meta().<\/li>\n<li>Admin menu pages capability changed from 'read' to 'manage_options' (subscriber access blocked).<\/li>\n<\/ul><\/li>\n<li><strong>Enhanced Security Hardening (Enterprise-Grade)<\/strong>\n\n<ul>\n<li>Added dedicated <code>tporapdi_manage_templates<\/code> capability for template configuration access (separate from <code>manage_options<\/code>).<\/li>\n<li>Implemented multisite-aware permission system: <code>tporapdi_manage_templates<\/code> OR <code>manage_options<\/code> OR <code>is_super_admin()<\/code>.<\/li>\n<li>Locked imported items as read-only (no editing, deletion, or quick-edit permissions via <code>map_meta_cap<\/code>).<\/li>\n<li>Added comprehensive Twig template security validator:<\/li>\n<li>Disallowed tags: include, source, import, from, embed, extends, use, macro (prevents SSTI and file inclusion).<\/li>\n<li>Size limits: 50 KB for mapping templates, 2 KB for title templates (filterable).<\/li>\n<li>Expression count limit: 250 default (filterable).<\/li>\n<li>Nesting depth limit: 12 levels default (filterable).<\/li>\n<li>Parse-time syntax validation via Twig tokenizer.<\/li>\n<li>Added template change audit logging:<\/li>\n<li>Logs to wp_custom_import_logs with before\/after SHA256 hashes.<\/li>\n<li>Captures actor metadata (user login, role, display name).<\/li>\n<li>Tracks template lengths and create vs. update distinction.<\/li>\n<li>Implemented SSRF prevention via allowlist system:<\/li>\n<li>Hostname allowlisting (exact + wildcard *.example.com support).<\/li>\n<li>CIDR allowlisting (IPv4 and IPv6 support).<\/li>\n<li>DNS resolution for hostname validation.<\/li>\n<li>Settings UI for managing allowed hosts and CIDR blocks.<\/li>\n<li>Twig variable strictness is filterable; permissive rendering now avoids row failures when a template references a missing key.<\/li>\n<li>Added Settings page (EAPI \u2192 Settings) for endpoint security configuration.<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial Release.<\/li>\n<li>Added dynamic Twig Post Title Template support with sanitization and fallback logic.<\/li>\n<li>Added Target Post Type selector for loading imports into posts, pages, or public custom post types.<\/li>\n<li>Added runtime fallback to post when target post type is invalid or missing.<\/li>\n<li>Added secure media sideload helper foundation with source URL deduplication metadata.<\/li>\n<\/ul>","raw_excerpt":"Enterprise ETL importer for WordPress that turns complex API payloads into reliable, automation-ready content workflows.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/en-au.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/297204","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/en-au.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/en-au.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/en-au.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=297204"}],"author":[{"embeddable":true,"href":"https:\/\/en-au.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/tporret"}],"wp:attachment":[{"href":"https:\/\/en-au.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=297204"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/en-au.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=297204"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/en-au.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=297204"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/en-au.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=297204"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/en-au.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=297204"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/en-au.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=297204"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}