Changeset 3453209
- Timestamp:
- 02/03/2026 07:16:39 PM (3 weeks ago)
- Location:
- pluxo-blueprint
- Files:
-
- 59 added
- 4 deleted
- 9 edited
-
assets/banner-1544x500.png (modified) (previous)
-
assets/screenshot-1.png (modified) (previous)
-
assets/screenshot-2.png (modified) (previous)
-
trunk/README.md (modified) (1 diff)
-
trunk/assets/css/admin.css (modified) (1 diff)
-
trunk/assets/js/admin-copy-markdown.js (added)
-
trunk/composer.json (deleted)
-
trunk/composer.lock (deleted)
-
trunk/includes/Admin (added)
-
trunk/includes/Admin/class-pluxo-blueprint-admin-page.php (added)
-
trunk/includes/Admin/class-pluxo-blueprint-overview.php (added)
-
trunk/includes/Helpers (added)
-
trunk/includes/Helpers/class-pluxo-blueprint-markdown-helper.php (added)
-
trunk/includes/Modules (added)
-
trunk/includes/Modules/Builders (added)
-
trunk/includes/Modules/Builders/Theme_Builder_Elementor (added)
-
trunk/includes/Modules/Builders/Theme_Builder_Elementor/class-pluxo-blueprint-module-theme-builder-elementor.php (added)
-
trunk/includes/Modules/Builders/Theme_Builder_Elementor/class-pluxo-blueprint-theme-builder-elementor-renderer.php (added)
-
trunk/includes/Modules/Builders/Theme_Builder_Elementor/class-pluxo-blueprint-theme-builder-elementor-repository.php (added)
-
trunk/includes/Modules/Builders/class-pluxo-blueprint-builders-renderer.php (added)
-
trunk/includes/Modules/Builders/class-pluxo-blueprint-builders-repository.php (added)
-
trunk/includes/Modules/Builders/class-pluxo-blueprint-module-builders.php (added)
-
trunk/includes/Modules/Content_Types (added)
-
trunk/includes/Modules/Content_Types/class-pluxo-blueprint-content-types-repository.php (added)
-
trunk/includes/Modules/Content_Types/class-pluxo-blueprint-module-content-types.php (added)
-
trunk/includes/Modules/Cookies_Consent (added)
-
trunk/includes/Modules/Cookies_Consent/class-pluxo-blueprint-cookies-consent-registry.php (added)
-
trunk/includes/Modules/Cookies_Consent/class-pluxo-blueprint-cookies-consent-scan.php (added)
-
trunk/includes/Modules/Cookies_Consent/class-pluxo-blueprint-module-cookies-consent.php (added)
-
trunk/includes/Modules/Header_Footer (added)
-
trunk/includes/Modules/Header_Footer/class-pluxo-blueprint-header-footer-renderer.php (added)
-
trunk/includes/Modules/Header_Footer/class-pluxo-blueprint-header-footer-repository.php (added)
-
trunk/includes/Modules/Header_Footer/class-pluxo-blueprint-header-footer-scan.php (added)
-
trunk/includes/Modules/Header_Footer/class-pluxo-blueprint-module-header-footer.php (added)
-
trunk/includes/Modules/Menus (added)
-
trunk/includes/Modules/Menus/class-pluxo-blueprint-menus-renderer.php (added)
-
trunk/includes/Modules/Menus/class-pluxo-blueprint-menus-repository.php (added)
-
trunk/includes/Modules/Menus/class-pluxo-blueprint-module-menus.php (added)
-
trunk/includes/Modules/Plugins (added)
-
trunk/includes/Modules/Plugins/class-pluxo-blueprint-module-plugins.php (added)
-
trunk/includes/Modules/Plugins/class-pluxo-blueprint-plugins-inventory.php (added)
-
trunk/includes/Modules/Plugins/class-pluxo-blueprint-plugins-renderer.php (added)
-
trunk/includes/Modules/Plugins/class-pluxo-blueprint-plugins-repository.php (added)
-
trunk/includes/Modules/Site_Info (added)
-
trunk/includes/Modules/Site_Info/class-pluxo-blueprint-module-site-info.php (added)
-
trunk/includes/Modules/Site_Info/class-pluxo-blueprint-site-info-renderer.php (added)
-
trunk/includes/Modules/Site_Info/class-pluxo-blueprint-site-info-repository.php (added)
-
trunk/includes/Modules/Themes (added)
-
trunk/includes/Modules/Themes/class-pluxo-blueprint-module-themes.php (added)
-
trunk/includes/Modules/Themes/class-pluxo-blueprint-themes-repository.php (added)
-
trunk/includes/Modules/Tracking (added)
-
trunk/includes/Modules/Tracking/Data (added)
-
trunk/includes/Modules/Tracking/Data/class-pluxo-blueprint-tracking-registry.php (added)
-
trunk/includes/Modules/Tracking/Services (added)
-
trunk/includes/Modules/Tracking/Services/class-pluxo-blueprint-tracking-scanner.php (added)
-
trunk/includes/Modules/Tracking/class-pluxo-blueprint-module-tracking.php (added)
-
trunk/includes/Modules/Tracking/class-pluxo-blueprint-tracking-renderer.php (added)
-
trunk/includes/Modules/Tracking/class-pluxo-blueprint-tracking-repository.php (added)
-
trunk/includes/Modules/Translators (added)
-
trunk/includes/Modules/Translators/class-pluxo-blueprint-module-translators.php (added)
-
trunk/includes/Modules/Translators/class-pluxo-blueprint-translators-renderer.php (added)
-
trunk/includes/Modules/Translators/class-pluxo-blueprint-translators-repository.php (added)
-
trunk/includes/Modules/Users (added)
-
trunk/includes/Modules/Users/class-pluxo-blueprint-module-users.php (added)
-
trunk/includes/Modules/Users/class-pluxo-blueprint-users-repository.php (added)
-
trunk/includes/PDF/class-pluxo-blueprint-pdf-generator.php (modified) (3 diffs)
-
trunk/includes/PDF/templates/overview-print.php (added)
-
trunk/includes/PDF/templates/site-doc.php (deleted)
-
trunk/includes/class-pluxo-blueprint.php (modified) (6 diffs)
-
trunk/pluxo-blueprint.php (modified) (2 diffs)
-
trunk/readme.txt (modified) (3 diffs)
-
trunk/vendor (deleted)
Legend:
- Unmodified
- Added
- Removed
-
pluxo-blueprint/trunk/README.md
r3444357 r3453209 1 1 # Pluxo Blueprint 2 2 3 Pluxo Blueprint is a WordPress plugin that helps you generate a clear PDF snapshot of your site documentation, including installed plugins, themes, users and roles, detected page builders, and high-level tracking signals.3 Pluxo Blueprint is a WordPress plugin that helps you generate a clear and structured documentation snapshot of your website. 4 4 5 It also helps you document your installed plugins by displaying detailed information and exporting the plugin list to CSV, JSON, or Markdown, so you can easily use it for documentation in tools like Confluence, Notion, or OneNote. 5 Inside the WordPress admin, it provides an Overview dashboard organised into expandable modules, covering key areas such as site information, themes, plugins, content types, users and roles, page builders, tracking sources, cookies & consent, and translation tools. 6 7 Each module can be copied individually as Markdown, making it easy to reuse the documentation in tools like Confluence, Notion, or OneNote. You can also generate a one-click PDF export based on the full Overview, ideal for sharing a complete technical snapshot of the website. 8 9 Pluxo Blueprint runs entirely inside your WordPress installation, uses no external services, and does not send or track any data. -
pluxo-blueprint/trunk/assets/css/admin.css
r3444357 r3453209 139 139 margin-right: 16px; 140 140 } 141 142 .pluxo-blueprint-tabs { 143 margin-top: 12px; 144 } 145 146 .pluxo-blueprint-grid { 147 display: grid; 148 grid-template-columns: 1fr; 149 gap: 16px; 150 margin-top: 16px; 151 } 152 153 @media (min-width: 1100px) { 154 .pluxo-blueprint-grid { 155 grid-template-columns: 2fr 1fr; 156 align-items: start; 157 } 158 } 159 160 .pluxo-blueprint-muted { 161 opacity: 0.85; 162 } 163 164 .pluxo-blueprint-accordion { 165 border: 1px solid rgba(0, 0, 0, 0.08); 166 border-radius: 10px; 167 padding: 10px 12px; 168 margin-top: 10px; 169 background: #fff; 170 } 171 172 .pluxo-blueprint-accordion summary { 173 cursor: pointer; 174 display: flex; 175 align-items: center; 176 justify-content: space-between; 177 gap: 12px; 178 font-weight: 600; 179 } 180 181 .pluxo-blueprint-accordion summary::-webkit-details-marker { 182 display: none; 183 } 184 185 .pluxo-blueprint-accordion-body { 186 margin-top: 10px; 187 } 188 189 .pluxo-blueprint-pill { 190 display: inline-flex; 191 align-items: center; 192 padding: 2px 8px; 193 border-radius: 999px; 194 font-size: 12px; 195 font-weight: 600; 196 background: rgba(0, 0, 0, 0.06); 197 } 198 199 .pluxo-blueprint-list { 200 margin: 10px 0 0 18px; 201 } 202 203 .pluxo-blueprint-accordion-table { 204 margin-top: 12px; 205 overflow-x: auto; 206 } 207 208 .pluxo-blueprint-accordion-table table { 209 margin-top: 0; 210 } 211 212 .pluxo-blueprint-pill--danger strong, 213 .pluxo-blueprint-pill--warning strong, 214 .pluxo-blueprint-pill--good strong { 215 font-weight: 700; 216 } 217 218 .pluxo-blueprint-pill--good { 219 background: #edf7ed; 220 border-color: #46b450; 221 } 222 223 .pluxo-blueprint-pill--warning { 224 background: #fcf9e8; 225 border-color: #dba617; 226 } 227 228 .pluxo-blueprint-pill--danger { 229 background: #fcf0f1; 230 border-color: #d63638; 231 } 232 233 .pluxo-blueprint-divider { 234 border: 0; 235 border-top: 1px solid #e5e7eb; 236 margin: 24px 0; 237 } 238 239 .pluxo-blueprint-summary-actions { 240 display: inline-flex; 241 align-items: center; 242 gap: 8px; 243 margin-left: auto; 244 } 245 246 .pluxo-blueprint-copy-md-btn { 247 border: 1px solid #c3c4c7; 248 background: #fff; 249 color: #1d2327; 250 border-radius: 6px; 251 padding: 4px 10px; 252 font-size: 12px; 253 line-height: 1.6; 254 cursor: pointer; 255 } 256 257 .pluxo-blueprint-copy-md-btn:hover { 258 background: #f6f7f7; 259 } 260 261 .pluxo-blueprint-copy-md-btn.is-copied { 262 border-color: #00a32a; 263 } 264 265 .pluxo-blueprint-copy-md-btn.is-error { 266 border-color: #d63638; 267 } 268 269 .pluxo-blueprint-accordion > summary { 270 display: flex; 271 align-items: center; 272 justify-content: space-between; 273 gap: 12px; 274 cursor: pointer; 275 } -
pluxo-blueprint/trunk/includes/PDF/class-pluxo-blueprint-pdf-generator.php
r3444357 r3453209 1 1 <?php 2 2 /** 3 * P DF generator for Pluxo Blueprint.3 * Print export generator for Pluxo Blueprint (browser print to PDF). 4 4 * 5 5 * @package Pluxo_Blueprint … … 25 25 */ 26 26 public function __construct( $plugin_path ) { 27 if ( ! is_string( $plugin_path ) || '' === $plugin_path ) { 28 $this->plugin_path = ''; 29 return; 30 } 31 27 32 $real = realpath( $plugin_path ); 28 33 … … 36 41 37 42 /** 38 * Render HTML for the PDF.43 * Render an Overview print page (browser print to PDF). 39 44 * 40 * @return string 41 */ 42 private function render_html() { 43 $template = $this->plugin_path . '/includes/PDF/templates/site-doc.php'; 44 45 if ( ! file_exists( $template ) ) { 46 return ''; 47 } 48 49 $real_template = realpath( $template ); 50 51 // Ensure the template is inside the plugin path. 52 if ( false === $real_template || 0 !== strpos( $real_template, $this->plugin_path ) ) { 53 return ''; 54 } 55 56 ob_start(); 57 require $real_template; 58 $html = ob_get_clean(); 59 60 return is_string( $html ) ? $html : ''; 61 } 62 63 /** 64 * Stream the PDF as a download. 65 * 45 * @param string $modules_html Modules HTML. 66 46 * @return void 67 47 */ 68 public function stream_pdf() { 69 48 public function render_overview_print_page( $modules_html ) { 70 49 if ( ! current_user_can( 'manage_options' ) ) { 71 wp_die( esc_html__( 'You do not have permission to export PDFs.', 'pluxo-blueprint' ) );50 wp_die( esc_html__( 'You do not have permission to access this export.', 'pluxo-blueprint' ) ); 72 51 } 73 52 74 53 if ( '' === $this->plugin_path ) { 75 wp_die( esc_html__( 'Invalid plugin path for PDF generation.', 'pluxo-blueprint' ) );54 wp_die( esc_html__( 'Invalid plugin path for export rendering.', 'pluxo-blueprint' ) ); 76 55 } 77 56 78 // EN-UK: Load Composer autoloader only if Dompdf is not already loaded. 79 if ( ! class_exists( '\Dompdf\Dompdf' ) ) { 80 $autoload = trailingslashit( $this->plugin_path ) . 'vendor/autoload.php'; 57 $modules_html = (string) $modules_html; 81 58 82 if ( file_exists( $autoload ) ) { 83 require_once $autoload; 84 } 59 $template = $this->plugin_path . '/includes/PDF/templates/overview-print.php'; 60 61 if ( ! file_exists( $template ) ) { 62 wp_die( esc_html__( 'Export template is missing. Please reinstall the plugin.', 'pluxo-blueprint' ) ); 85 63 } 86 64 87 if ( ! class_exists( '\Dompdf\Dompdf' ) || ! class_exists( '\Dompdf\Options' ) ) { 88 wp_die( esc_html__( 'PDF library is missing. Please reinstall the plugin.', 'pluxo-blueprint' ) ); 89 } 90 91 $html = $this->render_html(); 92 if ( '' === $html ) { 93 wp_die( esc_html__( 'Failed to render PDF template.', 'pluxo-blueprint' ) ); 94 } 95 96 // Dompdf hardening options: 97 // - Disable remote assets by default (safer). 98 // - Restrict file access to within plugin directory via chroot. 99 $options = new \Dompdf\Options(); 100 $options->set( 'isRemoteEnabled', false ); 101 $options->set( 'chroot', $this->plugin_path ); 102 $options->set( 'defaultFont', 'DejaVu Sans' ); 103 104 $dompdf = new \Dompdf\Dompdf( $options ); 105 106 $dompdf->loadHtml( $html, 'UTF-8' ); 107 $dompdf->setPaper( 'A4', 'portrait' ); 108 $dompdf->render(); 109 110 $timestamp = gmdate( 'Ymd-His' ); 111 $filename = 'pluxo-blueprint-site-docs-' . $timestamp . '.pdf'; 112 113 // Prevent caching and avoid output compression issues. 114 nocache_headers(); 115 116 if ( function_exists( 'ini_set' ) ) { 117 // Best-effort: avoid corrupted binary output on hosts with output compression enabled. 118 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged 119 @ini_set( 'zlib.output_compression', 'Off' ); 120 } 121 122 // Prevent any accidental output from corrupting the PDF. 123 while ( ob_get_level() > 0 ) { 124 // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged 125 @ob_end_clean(); 126 } 127 128 // Stream as attachment (download). 129 $dompdf->stream( 130 $filename, 131 array( 132 'Attachment' => true, 133 ) 134 ); 135 65 require $template; 136 66 exit; 137 67 } -
pluxo-blueprint/trunk/includes/class-pluxo-blueprint.php
r3444357 r3453209 10 10 } 11 11 12 require_once __DIR__ . '/Admin/class-pluxo-blueprint-overview.php'; 13 require_once __DIR__ . '/Admin/class-pluxo-blueprint-admin-page.php'; 14 15 require_once __DIR__ . '/Modules/Site_Info/class-pluxo-blueprint-site-info-repository.php'; 16 require_once __DIR__ . '/Modules/Site_Info/class-pluxo-blueprint-site-info-renderer.php'; 17 require_once __DIR__ . '/Modules/Site_Info/class-pluxo-blueprint-module-site-info.php'; 18 19 require_once __DIR__ . '/Modules/Themes/class-pluxo-blueprint-themes-repository.php'; 20 require_once __DIR__ . '/Modules/Themes/class-pluxo-blueprint-module-themes.php'; 21 22 require_once __DIR__ . '/Modules/Content_Types/class-pluxo-blueprint-content-types-repository.php'; 23 require_once __DIR__ . '/Modules/Content_Types/class-pluxo-blueprint-module-content-types.php'; 24 25 require_once __DIR__ . '/Modules/Plugins/class-pluxo-blueprint-plugins-repository.php'; 26 require_once __DIR__ . '/Modules/Plugins/class-pluxo-blueprint-plugins-renderer.php'; 27 require_once __DIR__ . '/Modules/Plugins/class-pluxo-blueprint-plugins-inventory.php'; 28 require_once __DIR__ . '/Modules/Plugins/class-pluxo-blueprint-module-plugins.php'; 29 30 require_once __DIR__ . '/Modules/Builders/class-pluxo-blueprint-builders-repository.php'; 31 require_once __DIR__ . '/Modules/Builders/class-pluxo-blueprint-builders-renderer.php'; 32 require_once __DIR__ . '/Modules/Builders/class-pluxo-blueprint-module-builders.php'; 33 34 require_once __DIR__ . '/Modules/Builders/Theme_Builder_Elementor/class-pluxo-blueprint-theme-builder-elementor-repository.php'; 35 require_once __DIR__ . '/Modules/Builders/Theme_Builder_Elementor/class-pluxo-blueprint-theme-builder-elementor-renderer.php'; 36 require_once __DIR__ . '/Modules/Builders/Theme_Builder_Elementor/class-pluxo-blueprint-module-theme-builder-elementor.php'; 37 38 require_once __DIR__ . '/Modules/Header_Footer/class-pluxo-blueprint-header-footer-scan.php'; 39 require_once __DIR__ . '/Modules/Header_Footer/class-pluxo-blueprint-header-footer-repository.php'; 40 require_once __DIR__ . '/Modules/Header_Footer/class-pluxo-blueprint-header-footer-renderer.php'; 41 require_once __DIR__ . '/Modules/Header_Footer/class-pluxo-blueprint-module-header-footer.php'; 42 43 require_once __DIR__ . '/Modules/Menus/class-pluxo-blueprint-menus-repository.php'; 44 require_once __DIR__ . '/Modules/Menus/class-pluxo-blueprint-menus-renderer.php'; 45 require_once __DIR__ . '/Modules/Menus/class-pluxo-blueprint-module-menus.php'; 46 47 require_once __DIR__ . '/Modules/Translators/class-pluxo-blueprint-translators-repository.php'; 48 require_once __DIR__ . '/Modules/Translators/class-pluxo-blueprint-translators-renderer.php'; 49 require_once __DIR__ . '/Modules/Translators/class-pluxo-blueprint-module-translators.php'; 50 51 require_once __DIR__ . '/Modules/Tracking/class-pluxo-blueprint-tracking-repository.php'; 52 require_once __DIR__ . '/Modules/Tracking/class-pluxo-blueprint-tracking-renderer.php'; 53 require_once __DIR__ . '/Modules/Tracking/class-pluxo-blueprint-module-tracking.php'; 54 require_once __DIR__ . '/Modules/Tracking/Services/class-pluxo-blueprint-tracking-scanner.php'; 55 require_once __DIR__ . '/Modules/Tracking/Data/class-pluxo-blueprint-tracking-registry.php'; 56 57 require_once __DIR__ . '/Modules/Cookies_Consent/class-pluxo-blueprint-cookies-consent-registry.php'; 58 require_once __DIR__ . '/Modules/Cookies_Consent/class-pluxo-blueprint-cookies-consent-scan.php'; 59 require_once __DIR__ . '/Modules/Cookies_Consent/class-pluxo-blueprint-module-cookies-consent.php'; 60 61 require_once __DIR__ . '/Modules/Users/class-pluxo-blueprint-users-repository.php'; 62 require_once __DIR__ . '/Modules/Users/class-pluxo-blueprint-module-users.php'; 63 64 require_once __DIR__ . '/Helpers/class-pluxo-blueprint-markdown-helper.php'; 65 12 66 require_once __DIR__ . '/PDF/class-pluxo-blueprint-pdf-generator.php'; 13 67 … … 15 69 16 70 /** 17 * Option name for storing selected export columns. 71 * Admin page hook suffix. 72 * 73 * This is used to load assets only on the plugin admin screen. 18 74 * 19 75 * @var string 20 76 */ 21 private $columns_option_name = 'pluxo_blueprint_columns';22 23 /**24 * Admin page hook suffix.25 *26 * This is used to load assets only on the plugin admin screen.27 *28 * @var string29 */30 77 private $admin_page_hook = ''; 31 78 32 79 /** 80 * Admin page controller. 81 * 82 * @var Pluxo_Blueprint_Admin_Page 83 */ 84 private $admin_page; 85 86 /** 33 87 * Constructor. 34 88 */ 35 89 public function __construct() { 90 $this->admin_page = new Pluxo_Blueprint_Admin_Page( $this ); 36 91 $this->init_hooks(); 37 }38 39 /**40 * Handle CSV export request.41 *42 * Generates and streams a CSV file with the selected export columns.43 */44 public function handle_export_csv() {45 // Security: check capability.46 if ( ! current_user_can( 'manage_options' ) ) {47 wp_die( esc_html__( 'You do not have permission to export this data.', 'pluxo-blueprint' ) );48 }49 50 // Security: verify nonce.51 if (52 ! isset( $_POST['pluxo_blueprint_export_csv_nonce'] ) ||53 ! wp_verify_nonce(54 sanitize_text_field( wp_unslash( $_POST['pluxo_blueprint_export_csv_nonce'] ) ),55 'pluxo_blueprint_export_csv'56 )57 ) {58 wp_die( esc_html__( 'Security check failed. Please try again.', 'pluxo-blueprint' ) );59 }60 61 // Get selected column keys (e.g. [ 'name', 'slug', ... ]).62 $selected_keys = $this->get_selected_export_columns();63 64 if ( empty( $selected_keys ) ) {65 wp_die( esc_html__( 'No columns selected for export.', 'pluxo-blueprint' ) );66 }67 68 // Map selected keys to full column definitions.69 $available_columns = $this->get_export_columns();70 $selected_columns = array();71 72 foreach ( $selected_keys as $key ) {73 if ( isset( $available_columns[ $key ] ) ) {74 $selected_columns[ $key ] = $available_columns[ $key ];75 }76 }77 78 if ( empty( $selected_columns ) ) {79 wp_die( esc_html__( 'Export configuration is not available.', 'pluxo-blueprint' ) );80 }81 82 // Get the full inventory of plugins.83 $inventory = $this->get_plugin_inventory();84 85 // Prepare CSV output.86 $filename = sprintf(87 'pluxo-blueprint-plugins-%s.csv',88 gmdate( 'Ymd-His' )89 );90 91 // Tell the browser this is a CSV download.92 nocache_headers();93 header( 'Content-Type: text/csv; charset=utf-8' );94 header( 'Content-Disposition: attachment; filename="' . $filename . '"' );95 96 // Open output stream.97 $fh = fopen( 'php://output', 'w' );98 99 if ( false === $fh ) {100 wp_die( esc_html__( 'Could not open output stream for CSV export.', 'pluxo-blueprint' ) );101 }102 103 // Build the header row using the column labels.104 $header_row = array();105 foreach ( $selected_columns as $column_key => $column_def ) {106 $header_row[] = isset( $column_def['label'] ) ? $column_def['label'] : $column_key;107 }108 109 fputcsv( $fh, $header_row );110 111 // Output each plugin row with only the selected columns.112 foreach ( $inventory as $plugin ) {113 $row = array();114 115 foreach ( $selected_columns as $column_key => $column_def ) {116 $value = isset( $plugin[ $column_key ] ) ? $plugin[ $column_key ] : '';117 118 // Ensure scalar for CSV.119 if ( is_bool( $value ) ) {120 $value = $value ? '1' : '0';121 } elseif ( is_array( $value ) || is_object( $value ) ) {122 $value = wp_json_encode( $value );123 }124 125 $row[] = $value;126 }127 128 fputcsv( $fh, $row );129 }130 131 exit;132 }133 134 /**135 * Handle JSON export request.136 *137 * Generates and streams a JSON file containing an array of objects138 * (one object per plugin) with the selected export columns.139 */140 public function handle_export_json() {141 // Capability check: only admins (manage_options) can export.142 if ( ! current_user_can( 'manage_options' ) ) {143 wp_die( esc_html__( 'You do not have permission to export this data.', 'pluxo-blueprint' ) );144 }145 146 // Security: nonce check.147 if (148 ! isset( $_POST['pluxo_blueprint_export_json_nonce'] ) ||149 ! wp_verify_nonce(150 sanitize_text_field( wp_unslash( $_POST['pluxo_blueprint_export_json_nonce'] ) ),151 'pluxo_blueprint_export_json'152 )153 ) {154 wp_die( esc_html__( 'Security check failed. Please try again.', 'pluxo-blueprint' ) );155 }156 157 // Get selected column keys (e.g. [ 'name', 'slug', ... ]).158 $selected_keys = $this->get_selected_export_columns();159 160 if ( empty( $selected_keys ) ) {161 wp_die( esc_html__( 'No columns selected for export.', 'pluxo-blueprint' ) );162 }163 164 // Get the full inventory of plugins.165 $inventory = $this->get_plugin_inventory();166 167 $data = array();168 169 // Build an array of objects (associative arrays) using only the selected columns.170 foreach ( $inventory as $plugin ) {171 $item = array();172 173 foreach ( $selected_keys as $column_key ) {174 $value = isset( $plugin[ $column_key ] ) ? $plugin[ $column_key ] : '';175 176 // JSON lida bem com booleanos, por isso mantemos true/false.177 if ( is_bool( $value ) ) {178 $value = $value ? true : false;179 }180 181 $item[ $column_key ] = $value;182 }183 184 $data[] = $item;185 }186 187 // Encode to JSON with pretty print for readability.188 $json = wp_json_encode( $data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES );189 190 if ( false === $json ) {191 // Fallback to empty array if encoding fails.192 $json = '[]';193 }194 195 // Send JSON as a download.196 nocache_headers();197 198 header( 'Content-Type: application/json; charset=utf-8' );199 200 $filename = 'pluxo-blueprint-plugins-' . gmdate( 'Y-m-d' ) . '.json';201 header( 'Content-Disposition: attachment; filename="' . $filename . '"' );202 header( 'Content-Length: ' . strlen( $json ) );203 204 echo $json; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped205 exit;206 }207 208 /**209 * Sanitize a value for safe use inside a Markdown table cell.210 *211 * Confluence and some Markdown parsers may not respect backslash-escaped pipes,212 * so we replace literal pipes with an HTML entity.213 *214 * @param mixed $value Cell value.215 * @return string216 */217 private function sanitize_markdown_cell( $value ) {218 // Normalise to string.219 if ( is_bool( $value ) ) {220 $value = $value ? 'true' : 'false';221 } elseif ( is_array( $value ) || is_object( $value ) ) {222 $value = wp_json_encode( $value );223 }224 225 $value = (string) $value;226 227 // Replace pipes with HTML entity to avoid breaking table columns.228 $value = str_replace( '|', '|', $value );229 230 // Replace newlines/tabs with spaces (tables don't like them).231 $value = preg_replace( '/\r\n|\r|\n|\t/', ' ', $value );232 233 // Trim excessive whitespace.234 $value = trim( preg_replace( '/\s+/', ' ', $value ) );235 236 return $value;237 }238 239 /**240 * Handle Markdown export request.241 *242 * Generates and streams a Markdown table of the plugin inventory243 * using the currently selected export columns.244 */245 public function handle_export_markdown() {246 // Capability check: only admins (manage_options) can export.247 if ( ! current_user_can( 'manage_options' ) ) {248 wp_die( esc_html__( 'You do not have permission to export this data.', 'pluxo-blueprint' ) );249 }250 251 // Security: nonce check.252 if (253 ! isset( $_POST['pluxo_blueprint_export_markdown_nonce'] ) ||254 ! wp_verify_nonce(255 sanitize_text_field( wp_unslash( $_POST['pluxo_blueprint_export_markdown_nonce'] ) ),256 'pluxo_blueprint_export_markdown'257 )258 ) {259 wp_die( esc_html__( 'Security check failed. Please try again.', 'pluxo-blueprint' ) );260 }261 262 // Get selected column keys (e.g. [ 'name', 'slug', ... ]).263 $selected_keys = $this->get_selected_export_columns();264 265 if ( empty( $selected_keys ) ) {266 wp_die( esc_html__( 'No columns selected for export.', 'pluxo-blueprint' ) );267 }268 269 // Map selected keys to full column definitions.270 $available_columns = $this->get_export_columns();271 $selected_columns = array();272 273 foreach ( $selected_keys as $key ) {274 if ( isset( $available_columns[ $key ] ) ) {275 $selected_columns[ $key ] = $available_columns[ $key ];276 }277 }278 279 if ( empty( $selected_columns ) ) {280 wp_die( esc_html__( 'Export configuration is not available.', 'pluxo-blueprint' ) );281 }282 283 // Get the full inventory of plugins.284 $inventory = $this->get_plugin_inventory();285 286 // Build Markdown lines.287 $header_labels = array();288 foreach ( $selected_columns as $column_key => $column_def ) {289 $header_labels[] = isset( $column_def['label'] ) ? $column_def['label'] : $column_key;290 }291 292 $lines = array();293 294 // Header row.295 $lines[] = '| ' . implode( ' | ', $header_labels ) . ' |';296 297 // Separator row.298 $separator_cells = array_fill( 0, count( $header_labels ), ' --- ' );299 $lines[] = '| ' . implode( ' | ', $separator_cells ) . ' |';300 301 // Data rows.302 foreach ( $inventory as $plugin ) {303 $row_values = array();304 305 foreach ( $selected_columns as $column_key => $column_def ) {306 $value = isset( $plugin[ $column_key ] ) ? $plugin[ $column_key ] : '';307 308 // Normalise to string.309 if ( is_bool( $value ) ) {310 $value = $value ? 'true' : 'false';311 } elseif ( is_array( $value ) || is_object( $value ) ) {312 $value = wp_json_encode( $value );313 }314 315 $row_values[] = $this->sanitize_markdown_cell( $value );316 317 }318 319 $lines[] = '| ' . implode( ' | ', $row_values ) . ' |';320 }321 322 $markdown = implode( "\n", $lines );323 324 // Send Markdown as a downloadable file.325 nocache_headers();326 header( 'Content-Type: text/markdown; charset=utf-8' );327 header(328 'Content-Disposition: attachment; filename=pluxo-blueprint-plugins-' . gmdate( 'Ymd-His' ) . '.md'329 );330 331 echo $markdown; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped332 exit;333 }334 335 /**336 * Handle PDF export request.337 *338 * Streams a PDF download with site documentation.339 *340 * @return void341 */342 public function handle_export_pdf() {343 344 if ( ! current_user_can( 'manage_options' ) ) {345 wp_die( esc_html__( 'You do not have permission to export this data.', 'pluxo-blueprint' ) );346 }347 348 check_admin_referer( 'pluxo_blueprint_export_pdf', 'pluxo_blueprint_export_pdf_nonce' );349 350 $generator = new Pluxo_Blueprint_PDF_Generator( PLUXO_BLUEPRINT_PLUGIN_DIR );351 $generator->stream_pdf();352 353 exit;354 92 } 355 93 … … 363 101 add_action( 'admin_menu', array( $this, 'remove_default_pluxo_submenu' ), 999 ); 364 102 365 // Handle saving of export column preferences.366 add_action( 'admin_init', array( $this, 'handle_save_export_columns' ) );367 368 // Handle CSV export action.369 add_action( 'admin_post_pluxo_blueprint_export_csv', array( $this, 'handle_export_csv' ) );370 371 // Handle JSON export action.372 add_action( 'admin_post_pluxo_blueprint_export_json', array( $this, 'handle_export_json' ) );373 374 // Handle Markdown export action.375 add_action( 'admin_post_pluxo_blueprint_export_markdown', array( $this, 'handle_export_markdown' ) );376 377 // Handle PDF export action.378 add_action( 'admin_post_pluxo_blueprint_export_pdf', array( $this, 'handle_export_pdf' ) );379 380 103 // Enqueue admin assets only on our page. 381 104 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) ); 382 105 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_menu_assets' ) ); 106 add_action( 'admin_init', array( $this, 'handle_overview_actions' ) ); 107 108 add_action( 'admin_post_pluxo_blueprint_export_overview_pdf', array( $this, 'handle_export_overview_pdf' ) ); 109 383 110 } 384 111 … … 407 134 'manage_options', // Capability. 408 135 'pluxo-blueprint', // Slug of the actual page. 409 array( $this , 'render_admin_page' )// Your existing renderer.136 array( $this->admin_page, 'render' ) // Your existing renderer. 410 137 ); 411 138 } … … 472 199 true 473 200 ); 474 } 475 201 202 $copy_js_relative_path = 'assets/js/admin-copy-markdown.js'; 203 204 $copy_js_file_path = PLUXO_BLUEPRINT_PLUGIN_DIR . $copy_js_relative_path; 205 $copy_js_file_url = PLUXO_BLUEPRINT_PLUGIN_URL . $copy_js_relative_path; 206 207 $copy_js_version = file_exists( $copy_js_file_path ) ? (string) filemtime( $copy_js_file_path ) : PLUXO_BLUEPRINT_VERSION; 208 209 wp_enqueue_script( 210 'pluxo-blueprint-admin-copy-md', 211 $copy_js_file_url, 212 array(), 213 $copy_js_version, 214 true 215 ); 216 } 217 476 218 /** 477 219 * Enqueue admin menu assets across wp-admin. … … 496 238 497 239 /** 498 * Render the main admin page for the plugin. 499 */ 500 public function render_admin_page() { 240 * Handle Overview actions (e.g. Builders scan). 241 * 242 * @return void 243 */ 244 public function handle_overview_actions() { 245 if ( ! is_admin() ) { 246 return; 247 } 248 249 // Only handle our own admin page submissions. 250 $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : ''; 251 if ( 'pluxo-blueprint' !== $page ) { 252 return; 253 } 254 255 if ( empty( $_POST['pluxo_blueprint_action'] ) ) { 256 return; 257 } 258 259 $action = sanitize_text_field( wp_unslash( $_POST['pluxo_blueprint_action'] ) ); 260 261 if ( 'builders_scan' !== $action ) { 262 return; 263 } 264 265 // Nonce check. 266 if ( empty( $_POST['pluxo_blueprint_builders_scan_nonce'] ) ) { 267 return; 268 } 269 270 $nonce = sanitize_text_field( wp_unslash( $_POST['pluxo_blueprint_builders_scan_nonce'] ) ); 271 272 if ( ! wp_verify_nonce( $nonce, 'pluxo_blueprint_builders_scan' ) ) { 273 return; 274 } 275 276 // Capability check. 501 277 if ( ! current_user_can( 'manage_options' ) ) { 502 278 return; 503 279 } 504 280 505 $inventory = $this->get_plugin_inventory(); 506 $available_columns = $this->get_export_columns(); 507 $selected_columns = $this->get_selected_export_columns(); 508 ?> 509 510 <?php 511 $logo_url = PLUXO_BLUEPRINT_PLUGIN_URL . 'assets/images/logo.png'; 512 ?> 513 514 <div class="wrap pluxo-blueprint-wrap"> 515 <div class="pluxo-blueprint-logo-wrapper"> 516 <img class="pluxo-blueprint-logo" src="<?php echo esc_url( $logo_url ); ?>" alt="<?php esc_attr_e( 'Pluxo Blueprint logo', 'pluxo-blueprint' ); ?>"> 517 <div class="pluxo-blueprint-title"> 518 <h1 class="wp-heading-inline"> 519 <?php echo esc_html__( 'Pluxo Blueprint', 'pluxo-blueprint' ); ?> 520 </h1> 521 <p class="pluxo-blueprint-description"> 522 <?php 523 echo wp_kses_post( 524 sprintf( 525 /* translators: %s: Plugin description. */ 526 __( 527 'Pluxo Blueprint is a WordPress plugin that helps you %1$sgenerate a clear PDF snapshot of your site documentation, including installed plugins, themes, users and roles, detected page builders, and high-level tracking signals.%2$s 528 529 It also allows you to export your plugin inventory to CSV, JSON, or Markdown, making it easy to reuse the data for documentation or development workflows in tools like Confluence, Notion, or OneNote. 530 ', 531 'pluxo-blueprint' 532 ), 533 '<strong>', 534 '</strong><br><br>' 535 ) 536 ); 537 538 ?> 539 </p> 540 </div> 541 </div> 542 543 <div class="pluxo-blueprint-card"> 544 <div class="pluxo-blueprint-card-header"> 545 <h2><?php echo esc_html__( 'PDF Export with Website Documentation', 'pluxo-blueprint' ); ?></h2><br> 546 <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>"> 547 <?php wp_nonce_field( 'pluxo_blueprint_export_pdf', 'pluxo_blueprint_export_pdf_nonce' ); ?> 548 <input type="hidden" name="action" value="pluxo_blueprint_export_pdf" /> 549 <?php submit_button( __( 'Export PDF', 'pluxo-blueprint' ), 'secondary', 'pluxo_blueprint_export_pdf_button', false ); ?> 550 </form><br> 551 <p> 552 <?php 553 echo esc_html__( 554 'Generate a one-click PDF snapshot of your site documentation.', 555 'pluxo-blueprint' 556 ); 557 ?> 558 </p> 559 </div> 560 561 <div class="pluxo-blueprint-card-body"> 562 <p class="description"> 563 <?php 564 echo esc_html__( 565 'The PDF export provides a high-level overview of your WordPress setup, designed for documentation, audits, or sharing with clients.', 566 'pluxo-blueprint' 567 ); 568 ?> 569 </p> 570 571 <ul class="pluxo-blueprint-help-list pluxo-blueprint-help-list--compact"> 572 <li> 573 <strong><?php echo esc_html__( 'Plugins', 'pluxo-blueprint' ); ?></strong> 574 <?php 575 echo esc_html__( 576 '– Lists active and inactive plugins, including version information and update status when available.', 577 'pluxo-blueprint' 578 ); 579 ?> 580 </li> 581 582 <li> 583 <strong><?php echo esc_html__( 'Themes', 'pluxo-blueprint' ); ?></strong> 584 <?php 585 echo esc_html__( 586 '– Shows the active theme and any inactive themes installed on the site.', 587 'pluxo-blueprint' 588 ); 589 ?> 590 </li> 591 592 <li> 593 <strong><?php echo esc_html__( 'Users & Roles', 'pluxo-blueprint' ); ?></strong> 594 <?php 595 echo esc_html__( 596 '– Displays user roles and a summary of assigned users (usernames only).', 597 'pluxo-blueprint' 598 ); 599 ?> 600 </li> 601 602 <li> 603 <strong><?php echo esc_html__( 'Page Builders', 'pluxo-blueprint' ); ?></strong> 604 <?php 605 echo esc_html__( 606 '– Detects common page builders such as Elementor or the WordPress default editor.', 607 'pluxo-blueprint' 608 ); 609 ?> 610 </li> 611 612 <li> 613 <strong><?php echo esc_html__( 'Tracking & Analytics (best-effort)', 'pluxo-blueprint' ); ?></strong> 614 <?php 615 echo esc_html__( 616 '– Reports potential tracking or analytics signals based on detected plugins or theme files.', 617 'pluxo-blueprint' 618 ); 619 ?> 620 </li> 621 622 <li> 623 <strong><?php echo esc_html__( 'Cookies (conditional)', 'pluxo-blueprint' ); ?></strong> 624 <?php 625 echo esc_html__( 626 '– Cookie details are only included if a supported cookie/GDPR plugin is detected (for example, CookieYes).', 627 'pluxo-blueprint' 628 ); 629 ?> 630 </li> 631 </ul> 632 <p class="description"> 633 <?php 634 echo esc_html__( 635 'This report is generated locally and does not make external requests. All information is provided on a best-effort basis and should be reviewed before being shared externally.', 636 'pluxo-blueprint' 637 ); 638 ?> 639 </p> 640 </div> 641 </div> 642 643 <div class="pluxo-blueprint-card"> 644 <div class="pluxo-blueprint-card-header"> 645 <h2><?php esc_html_e( 'Installed Plugins', 'pluxo-blueprint' ); ?></h2><br> 646 <div class="pluxo-blueprint-card-body"> 647 <p class="description"> 648 <?php echo esc_html__( 'Tick the boxes for the columns you want to keep in your exports. You can adjust these settings at any time and Pluxo Blueprint will remember your choices.', 'pluxo-blueprint' ); ?> 649 </p> 650 651 <form method="post"> 652 <?php wp_nonce_field( 'pluxo_blueprint_save_columns', 'pluxo_blueprint_columns_nonce' ); ?> 653 654 <table class="form-table" role="presentation"> 655 <tbody> 656 <tr> 657 <th scope="row"> 658 <label><?php echo esc_html__( 'Columns to export', 'pluxo-blueprint' ); ?></label> 659 </th> 660 <td> 661 <?php foreach ( $available_columns as $column_key => $column ) : ?> 662 <?php 663 $is_required = ( 'name' === $column_key ); 664 $is_checked = in_array( $column_key, $selected_columns, true ); 665 ?> 666 667 <?php if ( $is_required ) : ?> 668 <!-- Hidden input to ensure the "name" column is always submitted --> 669 <input type="hidden" name="pluxo_blueprint_columns[]" value="name" /> 670 <?php endif; ?> 671 672 <label class="pluxo-blueprint-column-option"> 673 <input type="checkbox" name="pluxo_blueprint_columns[]" value="<?php echo esc_attr( $column_key ); ?>" <?php checked( $is_checked ); ?> <?php disabled( $is_required ); ?> /> 674 <?php echo esc_html( $column['label'] ); ?> 675 </label> 676 <?php endforeach; ?> 677 </td> 678 </tr> 679 </tbody> 680 </table> 681 682 <p> 683 <button type="submit" name="pluxo_blueprint_save_columns" class="button button-primary"> 684 <?php echo esc_html__( 'Refresh plugins table below', 'pluxo-blueprint' ); ?> 685 </button> 686 </p> 687 </form><br> 688 </div> 689 <p><?php esc_html_e( 'Review the detected plugins and export them as CSV, JSON or Markdown.', 'pluxo-blueprint' ); ?></p><br> 690 <p class="description"> 691 <?php echo esc_html__( 'Choose the format that best fits your workflow:', 'pluxo-blueprint' ); ?> 692 </p> 693 <ul class="pluxo-blueprint-help-list pluxo-blueprint-help-list--compact"> 694 <li> 695 <strong><?php echo esc_html__( 'CSV', 'pluxo-blueprint' ); ?></strong> 696 <?php echo esc_html__( '– Ideal for spreadsheets or importing into other tools.', 'pluxo-blueprint' ); ?> 697 </li> 698 <li> 699 <strong><?php echo esc_html__( 'JSON', 'pluxo-blueprint' ); ?></strong> 700 <?php echo esc_html__( '– Good for developers and automation workflows.', 'pluxo-blueprint' ); ?> 701 </li> 702 <li> 703 <strong><?php echo esc_html__( 'Markdown', 'pluxo-blueprint' ); ?></strong> 704 <?php echo esc_html__( '– Perfect for documentation, tickets or README files.', 'pluxo-blueprint' ); ?> 705 </li> 706 </ul> 707 </div> 708 709 <div class="pluxo-blueprint-card-body"> 710 <div class="pluxo-blueprint-actions"> 711 <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>"> 712 <?php 713 wp_nonce_field( 'pluxo_blueprint_export_csv', 'pluxo_blueprint_export_csv_nonce' ); 714 ?> 715 <input type="hidden" name="action" value="pluxo_blueprint_export_csv" /> 716 <?php submit_button( __( 'Export CSV', 'pluxo-blueprint' ), 'secondary', 'pluxo_blueprint_export_csv_button', false ); ?> 717 </form> 718 719 <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>"> 720 <?php wp_nonce_field( 'pluxo_blueprint_export_json', 'pluxo_blueprint_export_json_nonce' ); ?> 721 <input type="hidden" name="action" value="pluxo_blueprint_export_json" /> 722 <?php submit_button( __( 'Export JSON', 'pluxo-blueprint' ), 'secondary', 'pluxo_blueprint_export_json_button', false ); ?> 723 </form> 724 725 <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>"> 726 <?php wp_nonce_field( 'pluxo_blueprint_export_markdown', 'pluxo_blueprint_export_markdown_nonce' ); ?> 727 <input type="hidden" name="action" value="pluxo_blueprint_export_markdown" /> 728 <?php submit_button( __( 'Export Markdown', 'pluxo-blueprint' ), 'secondary', 'pluxo_blueprint_export_markdown_button', false ); ?> 729 </form> 730 </div><br> 731 732 <table class="widefat fixed striped pluxo-blueprint-table"> 733 <thead> 734 <tr> 735 <?php foreach ( $selected_columns as $column_key ) : ?> 736 <th scope="col"> 737 <?php 738 if ( isset( $available_columns[ $column_key ]['label'] ) ) { 739 echo esc_html( $available_columns[ $column_key ]['label'] ); 740 } else { 741 echo esc_html( $column_key ); 742 } 743 ?> 744 </th> 745 <?php endforeach; ?> 746 </tr> 747 </thead> 748 <tbody> 749 <?php if ( empty( $inventory ) ) : ?> 750 <tr> 751 <td colspan="<?php echo esc_attr( max( 1, count( $selected_columns ) ) ); ?>"> 752 <?php echo esc_html__( 'No plugins found.', 'pluxo-blueprint' ); ?> 753 </td> 754 </tr> 755 <?php else : ?> 756 <?php foreach ( $inventory as $plugin ) : ?> 757 <tr> 758 <?php foreach ( $selected_columns as $column_key ) : ?> 759 <td> 760 <?php 761 switch ( $column_key ) { 762 case 'name': 763 echo isset( $plugin['name'] ) ? esc_html( $plugin['name'] ) : ''; 764 break; 765 case 'version': 766 echo isset( $plugin['version'] ) ? esc_html( $plugin['version'] ) : ''; 767 break; 768 case 'author': 769 echo isset( $plugin['author'] ) ? esc_html( $plugin['author'] ) : ''; 770 break; 771 case 'status': 772 echo isset( $plugin['status'] ) ? esc_html( ucfirst( $plugin['status'] ) ) : ''; 773 break; 774 case 'slug': 775 echo isset( $plugin['slug'] ) ? esc_html( $plugin['slug'] ) : ''; 776 break; 777 case 'plugin_uri': 778 if ( ! empty( $plugin['plugin_uri'] ) ) { 779 $url = esc_url( $plugin['plugin_uri'] ); 780 $label = esc_html( $plugin['plugin_uri'] ); 781 echo '<a href="' . esc_url( $url ) . '" target="_blank" rel="noopener noreferrer">' . esc_html( $label ) . '</a>'; 782 } else { 783 echo ''; 784 } 785 break; 786 default: 787 // Unknown column, output nothing for now. 788 echo ''; 789 break; 790 } 791 ?> 792 </td> 793 <?php endforeach; ?> 794 </tr> 795 <?php endforeach; ?> 796 <?php endif; ?> 797 </tbody> 798 </table> 799 </div> 800 </div> 801 <div class="pluxo-blueprint-footer"> 802 <p> 803 <?php esc_html_e( 'Made by', 'pluxo-blueprint' ); ?> 804 <a href="https://pluxo.dev/" target="_blank" rel="noopener noreferrer"><strong>Pluxo</strong></a> 805 </p> 806 </div> 807 </div> 808 <?php 809 } 810 811 /** 812 * Get a structured inventory of all installed plugins. 813 * 814 * @return array[] 815 */ 816 public function get_plugin_inventory() { 817 // Ensure the WordPress plugin API functions are available. 818 if ( ! function_exists( 'get_plugins' ) || ! function_exists( 'is_plugin_active' ) ) { 819 require_once ABSPATH . 'wp-admin/includes/plugin.php'; 820 } 821 822 $all_plugins = get_plugins(); // [ 'plugin-folder/plugin-file.php' => [ plugin headers... ] ] 823 $inventory = array(); 824 825 foreach ( $all_plugins as $plugin_file => $plugin_data ) { 826 $is_active = is_plugin_active( $plugin_file ); 827 828 $slug = dirname( $plugin_file ); 829 if ( '.' === $slug ) { 830 $slug = $plugin_file; // fallback. 831 } 832 833 $plugins_base_dir = trailingslashit( dirname( rtrim( PLUXO_BLUEPRINT_PLUGIN_DIR, "/\\" ) ) ); 834 $absolute_path = $plugins_base_dir . ltrim( $plugin_file, "/\\" ); 835 836 $inventory[] = array( 837 'name' => isset( $plugin_data['Name'] ) ? $plugin_data['Name'] : '', 838 'slug' => $slug, 839 'plugin_file' => $plugin_file, 840 'status' => $is_active ? 'active' : 'inactive', 841 'is_active' => $is_active, 842 'version' => isset( $plugin_data['Version'] ) ? $plugin_data['Version'] : '', 843 'plugin_uri' => isset( $plugin_data['PluginURI'] ) ? $plugin_data['PluginURI'] : '', 844 'author' => isset( $plugin_data['Author'] ) ? $plugin_data['Author'] : '', 845 'author_uri' => isset( $plugin_data['AuthorURI'] ) ? $plugin_data['AuthorURI'] : '', 846 'text_domain' => isset( $plugin_data['TextDomain'] ) ? $plugin_data['TextDomain'] : '', 847 'network' => isset( $plugin_data['Network'] ) ? $plugin_data['Network'] : '', 848 'title' => isset( $plugin_data['Title'] ) ? $plugin_data['Title'] : '', 849 'author_name' => isset( $plugin_data['AuthorName'] ) ? $plugin_data['AuthorName'] : '', 850 'path' => $absolute_path, 851 ); 852 } 853 854 // Sort plugins alphabetically by name. 855 usort( 856 $inventory, 857 function( $a, $b ) { 858 return strcasecmp( $a['name'], $b['name'] ); 859 } 860 ); 861 862 return $inventory; 863 } 864 865 /** 866 * Get the available plugin inventory export columns. 867 * 868 * @return array<string, array<string, string>> Column definitions. 869 */ 870 private function get_export_columns() { 871 return array( 872 'name' => array( 873 'label' => __( 'Name', 'pluxo-blueprint' ), 874 'description' => __( 'The display name of the plugin.', 'pluxo-blueprint' ), 875 ), 876 'slug' => array( 877 'label' => __( 'Slug', 'pluxo-blueprint' ), 878 'description' => __( 'The plugin folder slug (directory name).', 'pluxo-blueprint' ), 879 ), 880 'version' => array( 881 'label' => __( 'Version', 'pluxo-blueprint' ), 882 'description' => __( 'The currently installed plugin version.', 'pluxo-blueprint' ), 883 ), 884 'author' => array( 885 'label' => __( 'Author', 'pluxo-blueprint' ), 886 'description' => __( 'The author of the plugin as declared in the plugin header.', 'pluxo-blueprint' ), 887 ), 888 'status' => array( 889 'label' => __( 'Status', 'pluxo-blueprint' ), 890 'description' => __( 'Whether the plugin is active or inactive.', 'pluxo-blueprint' ), 891 ), 892 'plugin_uri' => array( 893 'label' => __( 'Plugin URL', 'pluxo-blueprint' ), 894 'description' => __( 'The plugin web site or documentation URL.', 'pluxo-blueprint' ), 895 ), 896 ); 897 } 898 899 /** 900 * Get the list of selected export columns. 901 * 902 * Ensures the "name" column is always included. 903 * 904 * @return array 905 */ 906 public function get_selected_export_columns() { 907 $columns = $this->get_export_columns(); 908 $saved_columns = get_option( $this->columns_option_name ); 909 $available_keys = array_keys( $columns ); 910 $selected_keys = array(); 911 912 if ( is_array( $saved_columns ) && ! empty( $saved_columns ) ) { 913 // Keep only valid and existing column keys. 914 $selected_keys = array_values( 915 array_intersect( $available_keys, $saved_columns ) 916 ); 917 } else { 918 // Default: all available columns. 919 $selected_keys = $available_keys; 920 } 921 922 // Ensure the "name" column is always selected if it exists. 923 if ( in_array( 'name', $available_keys, true ) && ! in_array( 'name', $selected_keys, true ) ) { 924 array_unshift( $selected_keys, 'name' ); 925 $selected_keys = array_values( array_unique( $selected_keys ) ); 926 } 927 928 return $selected_keys; 929 } 930 931 /** 932 * Handle saving of export column preferences. 933 */ 934 public function handle_save_export_columns() { 935 if ( ! isset( $_POST['pluxo_blueprint_columns_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pluxo_blueprint_columns_nonce'] ) ), 'pluxo_blueprint_save_columns' ) ) { 936 return; 937 } 938 281 // Run scan and save results. 282 if ( class_exists( 'Pluxo_Blueprint_Module_Builders' ) ) { 283 $module = new Pluxo_Blueprint_Module_Builders( $this ); 284 $module->run_scan_and_save(); 285 } 286 287 // Redirect to avoid form resubmission. 288 wp_safe_redirect( admin_url( 'admin.php?page=pluxo-blueprint&tab=overview' ) ); 289 exit; 290 } 291 292 /** 293 * Handle Overview export (print to PDF). 294 * 295 * @return void 296 */ 297 public function handle_export_overview_pdf() { 939 298 if ( ! current_user_can( 'manage_options' ) ) { 940 return; 941 } 942 943 $columns_input = array(); 944 945 if ( isset( $_POST['pluxo_blueprint_columns'] ) ) { 946 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Input is unslashed then sanitised via sanitize_key() below. 947 $raw_columns = (array) wp_unslash( $_POST['pluxo_blueprint_columns'] ); 948 949 $columns_input = array_map( 'sanitize_key', $raw_columns ); 950 $columns_input = array_values( array_filter( $columns_input ) ); 951 952 $allowed_columns = array_keys( $this->get_export_columns() ); 953 $columns_input = array_values( 954 array_intersect( $columns_input, $allowed_columns ) 955 ); 956 } 957 958 $available_columns = $this->get_export_columns(); 959 $available_keys = array_keys( $available_columns ); 960 961 // Keep only valid column keys that exist in the available columns. 962 $columns = array_values( 963 array_intersect( $available_keys, $columns_input ) 964 ); 965 966 // If nothing valid was selected, fall back to all columns. 967 if ( empty( $columns ) ) { 968 $columns = $available_keys; 969 } 970 971 // Ensure the "name" column is always present if it exists. 972 if ( in_array( 'name', $available_keys, true ) && ! in_array( 'name', $columns, true ) ) { 973 array_unshift( $columns, 'name' ); 974 $columns = array_values( array_unique( $columns ) ); 975 } 976 977 update_option( $this->columns_option_name, $columns ); 978 979 // Redirect back to the admin page to avoid resubmission. 980 $redirect_url = add_query_arg( 981 array( 982 'page' => 'pluxo-blueprint', 983 'updated' => 'true', 984 ), 985 admin_url( 'admin.php' ) 986 ); 987 988 wp_safe_redirect( $redirect_url ); 299 wp_die( esc_html__( 'You do not have permission to access this export.', 'pluxo-blueprint' ) ); 300 } 301 302 check_admin_referer( 'pluxo_blueprint_export_overview_pdf' ); 303 304 require_once __DIR__ . '/Admin/class-pluxo-blueprint-overview.php'; 305 306 $overview = new Pluxo_Blueprint_Overview( $this ); 307 308 // Build modules HTML using the existing render() output. 309 ob_start(); 310 $overview->render_export_view(); 311 $modules_html = (string) ob_get_clean(); 312 313 require_once __DIR__ . '/PDF/class-pluxo-blueprint-pdf-generator.php'; 314 315 $plugin_dir = defined( 'PLUXO_BLUEPRINT_PLUGIN_DIR' ) 316 ? PLUXO_BLUEPRINT_PLUGIN_DIR 317 : plugin_dir_path( dirname( __DIR__ ) ); 318 319 $generator = new Pluxo_Blueprint_PDF_Generator( $plugin_dir ); 320 321 $generator->render_overview_print_page( $modules_html ); 322 989 323 exit; 990 324 } 991 992 325 } -
pluxo-blueprint/trunk/pluxo-blueprint.php
r3444793 r3453209 3 3 * Plugin Name: Pluxo Blueprint for Website Documentation 4 4 * Plugin URI: https://pluxo.dev/#pluxo-blueprint 5 * Description: Generate a PDF snapshot of your WordPress for site documentation and export plugin inventory to CSV, JSON, or Markdown.6 * Version: 1. 1.15 * Description: Generate a structured PDF snapshot of your WordPress site documentation, with a modular overview and easy Markdown copy for reuse. 6 * Version: 1.2.0 7 7 * Requires at least: 6.0 8 8 * Requires PHP: 7.4 … … 63 63 64 64 if ( ! defined( 'PLUXO_BLUEPRINT_VERSION' ) ) { 65 define( 'PLUXO_BLUEPRINT_VERSION', '1. 1.1' );65 define( 'PLUXO_BLUEPRINT_VERSION', '1.2.0' ); 66 66 } 67 67 -
pluxo-blueprint/trunk/readme.txt
r3444793 r3453209 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.4 7 Stable tag: 1. 1.17 Stable tag: 1.2.0 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html 10 10 11 Generate a one-click PDF snapshot of your WordPress Website Documentation, including plugins, themes, users, and environment details.11 Generate a one-click PDF snapshot of your WordPress Website Documentation, including site configuration, modules overview, and key technical signals. 12 12 13 13 == Description == 14 Pluxo Blueprint is a WordPress plugin that helps you generate a clear PDF snapshot of your site documentation, including installed plugins, active theme information, users and roles, detected page builders, and high-level tracking signals.14 Pluxo Blueprint is a WordPress plugin that helps you generate a clear, structured overview of your website configuration and documentation. 15 15 16 It also allows you to export your plugin inventory to CSV, JSON, or Markdown, making it easy to reuse the data for documentation or development workflows in tools like Confluence, Notion, or OneNote. 16 Inside the WordPress admin, it provides a clean Overview screen organised into expandable modules (accordions), covering areas such as site information, themes, plugins, users & roles, page builders, tracking sources, cookies & consent, and more. 17 18 You can also copy each module as Markdown (one module at a time), making it easy to reuse the content in documentation tools like Confluence, Notion, or OneNote. 17 19 18 20 Pluxo Blueprint runs entirely inside your WordPress installation and does not rely on external services or tracking. 19 21 20 22 == Features == 21 * Generate a one-click PDF snapshot of your WordPress site documentation 22 * Includes site information such as: 23 * Installed plugins 24 * Active theme 23 * Overview dashboard with multiple documentation modules (accordion layout) 24 * One-click PDF export based on the full Overview content 25 * Per-module “Copy as Markdown” button for easy reuse in external documentation 26 * Includes high-level documentation areas such as: 27 * Site information (versions, language, timezone, etc.) 28 * Themes overview 29 * Plugins overview 30 * Content types overview 25 31 * Users and roles 26 * Detected page builders 27 * High-level tracking signals 28 * View a detailed table of installed plugins in the WordPress admin 29 * Choose which plugin data columns to include in exports 30 * Export plugin inventory to: 31 * CSV 32 * JSON 33 * Markdown (ideal for Notion, Confluence, GitHub, etc.) 32 * Detected page builders and theme builders 33 * Menus and locations 34 * Tracking sources (high-level signals) 35 * Cookies & consent (best-effort, provider-based) 36 * Translators and multilingual tools (best-effort detection) 34 37 * No external services or tracking 35 38 * All data stays inside your WordPress installation 36 39 37 40 == Screenshots == 38 1. Main admin page showing the plugin inventory table and export options.39 2. PDF export option generating site documentation.41 1. Overview screen showing the full list of modules and the PDF export button. 42 2. Example module (Tracking Sources) with the accordion expanded. 40 43 41 44 == Installation == … … 52 55 53 56 = Does the plugin require external libraries? = 54 The plugin bundles all required libraries internally and does not rely on external services.57 No. The PDF export uses a print-friendly page that relies on your browser’s built-in Print → Save as PDF. 55 58 56 59 == Changelog == 60 = 1.2.0 = 61 * Add: New Overview dashboard organised into multiple documentation modules 62 * Add: “Copy as Markdown” button on each module for quick reuse in documentation tools 63 * Improve: PDF export now uses the Overview modules content for a complete documentation snapshot 64 * Remove: CSV/JSON/Markdown file exports (replaced by per-module Markdown copy and the Overview-based PDF export) 65 57 66 = 1.1.1 = 58 67 * Small fixes and change of plugin name … … 76 85 77 86 == Upgrade Notice == 78 = 1. 1.0 =79 Adds PDF export for complete site documentation with no external dependencies.87 = 1.2.0 = 88 Introduces a new Overview dashboard with multiple modules, per-module “Copy as Markdown”, and a PDF export based on the full modules content. Removes CSV/JSON/Markdown file exports.
Note: See TracChangeset
for help on using the changeset viewer.