=== Kitgenix Document Manager === Contributors: kitgenix Donate link: https://donate.stripe.com/9B65kDgG3fTQ2Kzcmwf7i00 Tags: documents, downloads, file manager, private files, stable links Requires at least: 6.0 Tested up to: 7.0 Requires PHP: 8.1 Stable tag: 1.0.0 License: GPLv3 or later License URI: https://www.gnu.org/licenses/gpl-3.0.html Plugin URI: https://wordpress.org/plugins/kitgenix-document-manager/ Author: Kitgenix Author URI: https://kitgenix.com/ Author Plugin URI: https://kitgenix.com/plugins/kitgenix-document-manager Documentation URI: https://kitgenix.com/plugins/kitgenix-document-manager/documentation Support URI: https://wordpress.org/support/plugin/kitgenix-document-manager/ Author Support URI: https://kitgenix.com/plugins/kitgenix-document-manager/support Feature Request URI: https://kitgenix.com/plugins/kitgenix-document-manager/feature-request Manage document downloads with stable links, version history, and private file access. == Description == Kitgenix Document Manager lets admins upload documents and share a stable link like: /kitgenix-document-manager/{slug}/ When you replace the file, the link stays the same and serves the new version. == Key Features == * Stable links: replace the file without changing the URL * Admin documents table with search, copy link, and “Open link” action * Quick edit modal (popup) for editing documents without leaving the table * Document Categories: create categories and assign documents for easier organization * Visibility controls: Public or Private documents * Private behavior: redirect to login or return 403 * Serving mode: Inline (browser) or Download (attachment) * Optional version history per document, including restore/delete for older versions * Bulk version cleanup: delete all old versions for a document (Versions tab + modal action) * Select from Media Library: optionally pick an existing Media Library file instead of uploading * Safer serving: correct Content-Type where possible, security headers, and conditional caching for public docs == Usage == 1. Go to **Kitgenix → Document Manager** 2. Add a document (name + optional slug) and upload the initial file 3. Copy the stable URL from the table and share it 4. To update a document later, use **Edit** (modal) and upload a replacement file 5. If **Keep version history** is enabled for that document, older files will appear in the Versions panel (restore/delete) Categories: * Use the **Categories** tab to add/edit/delete categories * Assign a category when adding/editing a document Note: Inline viewing works best for PDFs and images. Office documents (DOCX/XLSX/etc.) typically download because browsers can’t render them natively. == Installation == 1. Upload the plugin folder to /wp-content/plugins/ 2. Activate the plugin through the 'Plugins' menu. 3. Go to Kitgenix -> Document Manager. == Settings == Settings are available under the **Settings** tab: * Allowed file extensions * Default visibility (Public/Private) * Serving mode: * Inline (browser) * Download (attachment) * Versioning defaults (keep history by default, delete old versions when history is disabled) * Private document behavior (login redirect or 403) * Delete all plugin data on uninstall (optional) Frontend card options are available under the **Frontend** tab: * Default document card button label * Button style (Outline or Solid) * Preview image size * File type/file size alignment * Button alignment * Button colors (normal + hover) * Option to open the “View” button in a new tab * Toggle showing file type and file size * Toggle showing document description * Shortcode Builder (generate a shortcode for one or multiple documents) == Security & Caching == * Private documents are not cached (no-store) and require login (or return 403) * Public documents use conditional caching (ETag/Last-Modified) so browsers/CDNs can revalidate efficiently (including 304 Not Modified responses) * Responses include security hardening headers like `X-Content-Type-Options: nosniff` * Private documents include `X-Robots-Tag: noindex, nofollow` == External Services == This plugin includes a shared “Kitgenix hub” component in wp-admin which may fetch publicly available plugin metadata from WordPress.org using the WordPress core `plugins_api()` function (WordPress.org Plugins API). * When it runs: only in wp-admin (Kitgenix plugin admin pages) * Data sent: plugin slug(s) (no personal data) * Data received: publicly available plugin information (e.g. active installs, ratings) * Caching: responses are cached locally using transients for ~1 day: * `kitgenix_hub_wporg_active_installs_v1` * `kitgenix_hub_wporg_ratings_v1` == Developer Notes (Internal Reference) == This section documents internal identifiers used by the plugin (useful for developers, debugging, and advanced users). = Options (Settings) = * Option name: `kitgenix_document_manager_settings` (constant: `KITGENIX_DOCUMENT_MANAGER_OPTION_NAME`) * Settings group: `kitgenix_document_manager_settings_group` * Keys (defaults): * `allowed_extensions`: `["pdf","doc","docx","xls","xlsx","ppt","pptx","txt"]` (stored as an array; comma-separated strings are accepted and normalized) * `default_visibility`: `public` (public|private) * `serving_mode`: `attachment` (attachment|inline) * `keep_version_history`: `true` * `delete_old_versions`: `false` * `private_behavior`: `login` (login|403) * `delete_data_on_uninstall`: `false` * `card_button_label`: `"View"` * `card_button_style`: `"outline"` (outline|solid) * `card_open_new_tab`: `false` * `card_show_file_type`: `true` * `card_show_file_size`: `true` * `card_show_description`: `false` * `card_image_size`: `96` (px) * `card_meta_alignment`: `"justify"` (justify|left|center|right) * `card_button_alignment`: `"center"` (justify|left|center|right) * `card_button_text_color`: `""` (hex or blank) * `card_button_bg_color`: `""` (hex or blank) * `card_button_border_color`: `""` (hex or blank) * `card_button_hover_text_color`: `""` (hex or blank) * `card_button_hover_bg_color`: `""` (hex or blank) * `card_button_hover_border_color`: `""` (hex or blank) = Data Model = * Custom Post Type: `kitgenix_dm_doc` * Taxonomy (categories): `kitgenix_dm_cat` * Capability: `manage_kitgenix_document_manager_documents` (assigned to Administrators and Shop Managers on activation) = Post Meta = * `_kitgenix_document_manager_current_attachment_id` (current attachment ID) * `_kitgenix_document_manager_description` (optional document description shown on cards) * `_kitgenix_document_manager_visibility` (`public`|`private`) * `_kitgenix_document_manager_versioning_enabled` (0|1) * `_kitgenix_document_manager_versions` (array of attachment IDs) = Stable Link Endpoint = * Base path: `/kitgenix-document-manager/{slug}/` * Query var: `kitgenix_document_manager_slug` = REST API = * `GET /wp-json/kitgenix-document-manager/v1/doc/{slug}` * Returns: `slug`, `title`, `updated` (ISO 8601), `visibility`, `stable_url` * Private documents return 403 when logged out = Shortcode = * `[kitgenix_document_manager_link slug="my-doc" label="Download"]` * If `label` is omitted, the document title is used. * Private documents render nothing for logged-out users. * `[kitgenix_document_manager_document slug="my-doc" button_label="View"]` * Renders a small preview (thumbnail/icon), the document title, file type, file size, and a “View” button. * Private documents render nothing for logged-out users. * Optional attributes: `button_style="outline"|"solid"`, `image_size="96"`, `meta_align="justify"|"left"|"center"|"right"`, `button_align="justify"|"left"|"center"|"right"`, `show_description="0"|"1"`, `new_tab="0"|"1"`, `show_type="0"|"1"`, `show_size="0"|"1"`. * To render multiple documents inline, use `slugs` instead of `slug`, e.g. `[kitgenix_document_manager_document slugs="doc-a,doc-b,doc-c"]`. = Admin Actions (admin-post.php) = The Document Manager screen uses admin-post actions, including: * `kitgenix_document_manager_document_save` * Nonce field: `kitgenix_document_manager_document_nonce` * Nonce action: `kitgenix_document_manager_document_save` * `kitgenix_document_manager_document_delete` (nonce query parameter `nonce`) * `kitgenix_document_manager_version_restore` (nonce query parameter `nonce`) * `kitgenix_document_manager_version_delete` (nonce query parameter `nonce`) * `kitgenix_document_manager_versions_delete_all` (nonce query parameter `nonce`) * `kitgenix_document_manager_category_save` * Nonce field: `kitgenix_document_manager_category_nonce` * Nonce action: `kitgenix_document_manager_category_save` * `kitgenix_document_manager_category_delete` (nonce query parameter `nonce`) WordPress action hook names for the above screen actions: * `admin_post_kitgenix_document_manager_document_save` * `admin_post_kitgenix_document_manager_document_delete` * `admin_post_kitgenix_document_manager_version_restore` * `admin_post_kitgenix_document_manager_version_delete` * `admin_post_kitgenix_document_manager_versions_delete_all` * `admin_post_kitgenix_document_manager_category_save` * `admin_post_kitgenix_document_manager_category_delete` The (hidden) CPT edit screen metabox uses: * `kitgenix_document_manager_upload_initial` (nonce field `kitgenix_document_manager_file_nonce`) * `kitgenix_document_manager_replace_file` (nonce field `kitgenix_document_manager_file_nonce`) * Visibility/versioning meta save nonce: * Nonce field: `kitgenix_document_manager_meta_nonce` * Nonce action: `kitgenix_document_manager_save_meta` = Hooks, Filters & Assets (Internal) = This list is intended as a comprehensive map of WordPress integration points used by the plugin. * `plugins_loaded` (bootstrap init) * `init` (register CPT/taxonomy; add rewrite rules) * Filter: `query_vars` (adds query var `kitgenix_document_manager_slug`) * `template_redirect` (serves stable link responses) * `rest_api_init` (registers REST route) * `admin_menu` (registers Kitgenix menu + Document Manager submenu) * `admin_head` (outputs Kitgenix admin menu icon CSS) * `admin_init` (registers Settings API option) * `admin_enqueue_scripts` (enqueues Kitgenix hub CSS; enqueues Document Manager admin assets) * `add_meta_boxes` (adds the CPT file/visibility metaboxes) * `save_post` (saves visibility + versioning meta) * `admin_post_kitgenix_document_manager_upload_initial` (metabox upload) * `admin_post_kitgenix_document_manager_replace_file` (metabox replace) * `admin_notices` (metabox success/error notices via `kitgenix_dm_notice`) * Filter: `manage_kitgenix_dm_doc_posts_columns` (adds list table columns) * `manage_kitgenix_dm_doc_posts_custom_column` (renders list table columns) * Filter: `post_row_actions` (adds “Replace File” row action) * Filter: `site_status_tests` (registers Site Health test) * Shortcode: `kitgenix_document_manager_link` Other admin UI identifiers: - Admin list-table column key: `kitgenix_dm_actions` - Version restore notice query arg: `kitgenix_version_restored=1` Admin asset handles (wp-admin): * Styles: * `kitgenix-hub` (Kitgenix hub page) * `kitgenix-admin-ui` (shared Kitgenix admin UI) * `kitgenix-document-manager-admin` (Document Manager settings screen) * Scripts: * `kitgenix-admin-tabs` (shared Kitgenix tabs UI) * `kitgenix-document-manager-admin` (Document Manager admin JS) = Site Health (Internal) = * Registers Site Health test ID: `kitgenix_document_manager_uploads` (checks uploads directory exists and is writable) = Notes (Internal) = * Uninstall deletes a legacy transient `kitgenix_document_manager_site_health` for backwards compatibility, even though v1 does not set it. == Frequently Asked Questions == = Where are files stored? = When you upload a document inside Document Manager, files are stored in: wp-content/uploads/kitgenix-document-manager/ If you select an existing file from the Media Library, the plugin uses that attachment’s existing location inside your normal WordPress uploads directory. = Why does my file download even in “Inline (browser)” mode? = Browsers can only display some file types inline (PDFs, images, and many text types). For formats that the browser can’t render (e.g. DOCX/XLSX), the file will download. = My stable link returns 404. What should I do? = Go to **Settings → Permalinks** and click **Save Changes** to flush rewrite rules. = Can I restore an older file? = Yes. Enable **Keep version history** for that document, then use **Edit** to open the modal and restore/delete older versions from the Versions panel. == Upgrade Notice == = 1.0.0 = Maintenance and compatibility update. Recommended for all sites. == Changelog == = 1.0.0 (18 March 2026) = * Initial release. * Added a document card shortcode for embedding a document preview with file type/size and a “View” button (includes button label/new tab/field toggles and outline/solid button style). * Added a stable link endpoint: /kitgenix-document-manager/{slug}/ (file can be replaced without changing the URL). * Added a Document Manager admin area under the Kitgenix menu with tabs for Documents, Categories, Versions, Settings and Support. * Added an admin documents table with search plus quick actions (copy link, open link, edit, replace file). * Added a quick edit modal for editing documents without leaving the documents table. * Added Document Categories (create/manage categories and assign them to documents). * Added per-document visibility (Public/Private) plus private behavior options (redirect to login or return 403). * Added file serving modes (inline vs download/attachment) with safer inline handling. * Added optional per-document version history, including restore and delete for older versions. * Added bulk version cleanup tools (delete all old versions for a document via the Versions tab and modal actions). * Added Media Library selection support (choose an existing Media Library file instead of uploading). * Added Settings for allowed file extensions plus sensible defaults for visibility, serving mode and versioning. * Added safer file serving with traversal checks, security headers, and conditional caching for public documents (ETag/Last-Modified) while private documents are not cached (no-store). * Added a Site Health test for the Kitgenix Document Manager uploads directory. * Added uninstall behavior that removes plugin settings, with an option to delete all Document Manager data (documents and related attachments/versions). * UI: Improved the Kitgenix admin header layout and social icon links (compact icon buttons) across settings and the Kitgenix hub. * Fix: Admin notices now display above the Kitgenix header using the WordPress standard notice area. * Fix: Added defensive notice normalization to prevent notices being relocated into the header by other scripts. * UI: Admin tables inside Kitgenix pages now use Kitgenix styling for a more consistent branded look. * Fix: Added spacing between adjacent action links/buttons (e.g., Edit/Delete). * Security: Normalised metabox and admin-post request handling so POST values are read only after nonce verification, and upload arrays are sanitized before use. * Fix: Stream documents with validated file paths and safe response headers instead of reading file contents into memory for output. * Fix: Escaped shared Kitgenix hub card media output for WordPress coding standards compliance. * Maintenance: Updated the plugin Author URI to the public Kitgenix WordPress.org profile and replaced the old custom admin-menu icon CSS with the native Dashicons icon.