Changeset 3491360
- Timestamp:
- 03/26/2026 01:51:41 AM (8 days ago)
- Location:
- praison-file-content-git
- Files:
-
- 2 added
- 4 edited
- 1 copied
-
tags/1.6.0 (copied) (copied from praison-file-content-git/trunk)
-
tags/1.6.0/praisonpressgit.php (modified) (3 diffs)
-
tags/1.6.0/src/Admin/SettingsPage.php (added)
-
tags/1.6.0/src/Core/Bootstrap.php (modified) (5 diffs)
-
trunk/praisonpressgit.php (modified) (3 diffs)
-
trunk/src/Admin/SettingsPage.php (added)
-
trunk/src/Core/Bootstrap.php (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
praison-file-content-git/tags/1.6.0/praisonpressgit.php
r3490698 r3491360 3 3 * Plugin Name: PraisonAI Git Posts 4 4 * Description: Load WordPress content from files (Markdown, JSON, YAML) without database writes, with Git-based version control 5 * Version: 1. 5.05 * Version: 1.6.0 6 6 * Author: MervinPraison 7 7 * Author URI: https://mer.vin … … 13 13 14 14 // Define constants 15 define('PRAISON_VERSION', '1. 5.0');15 define('PRAISON_VERSION', '1.6.0'); 16 16 define('PRAISON_PLUGIN_DIR', __DIR__); 17 17 define('PRAISON_PLUGIN_URL', trailingslashit(plugins_url('', __FILE__))); … … 105 105 } 106 106 107 // Auto-generate _index.json for any existing content 108 if (!wp_next_scheduled('praisonpress_rebuild_index')) { 109 wp_schedule_single_event(time() + 5, 'praisonpress_rebuild_index'); 110 } 111 107 112 // Flush rewrite rules 108 113 flush_rewrite_rules(); -
praison-file-content-git/tags/1.6.0/src/Core/Bootstrap.php
r3490698 r3491360 48 48 49 49 /** 50 * Check if file-based content delivery is enabled in site-config.ini 50 * Check if file-based content delivery is enabled. 51 * Priority: wp_options (Settings page) > site-config.ini > default (false) 51 52 */ 52 53 private function isContentEnabled() { 54 // 1. Check WordPress options (Settings page) 55 $options = get_option('praisonpress_options', []); 56 if (isset($options['content_enabled'])) { 57 return (bool) $options['content_enabled']; 58 } 59 60 // 2. Fallback to site-config.ini 53 61 $config = self::getConfig(); 54 // Default to false if not set — explicit opt-in required55 if (!isset($config['content']['enabled'])) {56 return false;57 }58 $val = $config['content']['enabled'];59 return f ilter_var($val, FILTER_VALIDATE_BOOLEAN);62 if (isset($config['content']['enabled'])) { 63 return filter_var($config['content']['enabled'], FILTER_VALIDATE_BOOLEAN); 64 } 65 66 // 3. Default: disabled (safe) 67 return false; 60 68 } 61 69 … … 70 78 add_filter('posts_pre_query', [$this, 'injectFilePosts'], 10, 2); 71 79 72 // Initialize export page early (before admin_menu)80 // Register Settings page in admin 73 81 if (is_admin()) { 74 82 new ExportPage(); 75 } 83 84 // Settings page (WordPress-native config) 85 if (file_exists(PRAISON_PLUGIN_DIR . '/src/Admin/SettingsPage.php')) { 86 $settingsPage = new \PraisonPress\Admin\SettingsPage(); 87 $settingsPage->register(); 88 } 89 } 90 91 // Register index rebuild handler (triggered by Settings page button) 92 add_action('admin_post_praison_rebuild_index', [$this, 'handleRebuildIndex']); 93 94 // Register background index rebuild (triggered on settings save) 95 add_action('praisonpress_rebuild_index', [$this, 'doBackgroundIndexRebuild']); 76 96 77 97 // Admin features (priority 10 - default) … … 134 154 135 155 /** 136 * Get the allowed post types from site-config.ini 137 * 138 * @return array|null Array of allowed types, or null if setting doesn't exist (allow all) 156 * Get the allowed post types. 157 * Priority: wp_options (Settings page) > site-config.ini > null (allow all) 139 158 */ 140 159 private function getAllowedPostTypes() { 141 160 if ($this->allowedPostTypes !== null) { 142 // false is our internal sentinel for "checked but not found" → return null (allow all)143 161 return $this->allowedPostTypes === false ? null : $this->allowedPostTypes; 144 162 } 145 163 164 // 1. Check WordPress options (Settings page) 165 $options = get_option('praisonpress_options', []); 166 if (!empty($options['post_types']) && is_array($options['post_types'])) { 167 $this->allowedPostTypes = $options['post_types']; 168 return $this->allowedPostTypes; 169 } 170 171 // 2. Fallback to site-config.ini 146 172 $config = self::getConfig(); 147 173 if (isset($config['content']['post_types']) && is_array($config['content']['post_types'])) { … … 150 176 } 151 177 152 $this->allowedPostTypes = false; // Use false internally to denote "checked but not found"153 return null; // Return null to mean "allow all"178 $this->allowedPostTypes = false; 179 return null; 154 180 } 155 181 … … 970 996 971 997 /** 998 * Handle "Rebuild Index Now" button from Settings page 999 */ 1000 public function handleRebuildIndex() { 1001 if (!isset($_GET['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'])), 'praison_rebuild_index')) { 1002 wp_die('Security check failed'); 1003 } 1004 1005 if (!current_user_can('manage_options')) { 1006 wp_die('Unauthorized'); 1007 } 1008 1009 // Run index rebuild synchronously 1010 $result = $this->doBackgroundIndexRebuild(); 1011 1012 wp_safe_redirect(add_query_arg([ 1013 'page' => 'praison-settings', 1014 'index_rebuilt' => $result ? '1' : '0', 1015 ], admin_url('admin.php'))); 1016 exit; 1017 } 1018 1019 /** 1020 * Rebuild _index.json for all content types. 1021 * Called from: Settings page button, background cron, activation hook. 1022 * Uses the existing IndexCommand logic. 1023 * 1024 * @return bool True on success 1025 */ 1026 public function doBackgroundIndexRebuild() { 1027 $content_dir = PRAISON_CONTENT_DIR; 1028 if (!is_dir($content_dir)) { 1029 return false; 1030 } 1031 1032 // Reuse the IndexCommand's indexing logic 1033 if (!class_exists('PraisonPress\\CLI\\IndexCommand')) { 1034 $file = PRAISON_PLUGIN_DIR . '/src/CLI/IndexCommand.php'; 1035 if (file_exists($file)) { 1036 require_once $file; 1037 } 1038 } 1039 1040 $success = true; 1041 $dirs = @scandir($content_dir); 1042 if (!$dirs) return false; 1043 1044 foreach ($dirs as $dir) { 1045 if ($dir[0] === '.' || $dir === 'config' || !is_dir($content_dir . '/' . $dir)) { 1046 continue; 1047 } 1048 1049 $type_dir = $content_dir . '/' . $dir; 1050 $md_files = glob($type_dir . '/*.md'); 1051 if (empty($md_files)) continue; 1052 1053 // Build index data 1054 $index = []; 1055 require_once PRAISON_PLUGIN_DIR . '/src/Parsers/FrontMatterParser.php'; 1056 $parser = new \PraisonPress\Parsers\FrontMatterParser(); 1057 1058 foreach ($md_files as $file) { 1059 $content = @file_get_contents($file); 1060 if ($content === false) continue; 1061 1062 $parsed = $parser->parse($content); 1063 $meta = $parsed['meta'] ?? []; 1064 $slug = $meta['slug'] ?? pathinfo($file, PATHINFO_FILENAME); 1065 1066 $entry = [ 1067 'file' => basename($file), 1068 'slug' => $slug, 1069 'title' => $meta['title'] ?? ucwords(str_replace('-', ' ', $slug)), 1070 'date' => $meta['date'] ?? date('Y-m-d H:i:s', filemtime($file)), 1071 'modified' => date('Y-m-d H:i:s', filemtime($file)), 1072 'status' => $meta['status'] ?? 'publish', 1073 'excerpt' => $meta['excerpt'] ?? '', 1074 'categories' => $meta['categories'] ?? [], 1075 'tags' => $meta['tags'] ?? [], 1076 ]; 1077 1078 // Include custom fields from frontmatter 1079 $reserved = ['title', 'date', 'slug', 'status', 'excerpt', 'categories', 'tags', 'featured_image', 'author']; 1080 $custom = []; 1081 foreach ($meta as $k => $v) { 1082 if (!in_array($k, $reserved)) { 1083 $custom[$k] = $v; 1084 } 1085 } 1086 if (!empty($custom)) { 1087 $entry['custom_fields'] = $custom; 1088 } 1089 1090 $index[] = $entry; 1091 } 1092 1093 // Write _index.json 1094 $index_path = $type_dir . '/_index.json'; 1095 $written = @file_put_contents($index_path, json_encode($index, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); 1096 if ($written === false) { 1097 $success = false; 1098 } 1099 } 1100 1101 return $success; 1102 } 1103 1104 /** 972 1105 * Handle cache clear action 973 1106 */ -
praison-file-content-git/trunk/praisonpressgit.php
r3490698 r3491360 3 3 * Plugin Name: PraisonAI Git Posts 4 4 * Description: Load WordPress content from files (Markdown, JSON, YAML) without database writes, with Git-based version control 5 * Version: 1. 5.05 * Version: 1.6.0 6 6 * Author: MervinPraison 7 7 * Author URI: https://mer.vin … … 13 13 14 14 // Define constants 15 define('PRAISON_VERSION', '1. 5.0');15 define('PRAISON_VERSION', '1.6.0'); 16 16 define('PRAISON_PLUGIN_DIR', __DIR__); 17 17 define('PRAISON_PLUGIN_URL', trailingslashit(plugins_url('', __FILE__))); … … 105 105 } 106 106 107 // Auto-generate _index.json for any existing content 108 if (!wp_next_scheduled('praisonpress_rebuild_index')) { 109 wp_schedule_single_event(time() + 5, 'praisonpress_rebuild_index'); 110 } 111 107 112 // Flush rewrite rules 108 113 flush_rewrite_rules(); -
praison-file-content-git/trunk/src/Core/Bootstrap.php
r3490698 r3491360 48 48 49 49 /** 50 * Check if file-based content delivery is enabled in site-config.ini 50 * Check if file-based content delivery is enabled. 51 * Priority: wp_options (Settings page) > site-config.ini > default (false) 51 52 */ 52 53 private function isContentEnabled() { 54 // 1. Check WordPress options (Settings page) 55 $options = get_option('praisonpress_options', []); 56 if (isset($options['content_enabled'])) { 57 return (bool) $options['content_enabled']; 58 } 59 60 // 2. Fallback to site-config.ini 53 61 $config = self::getConfig(); 54 // Default to false if not set — explicit opt-in required55 if (!isset($config['content']['enabled'])) {56 return false;57 }58 $val = $config['content']['enabled'];59 return f ilter_var($val, FILTER_VALIDATE_BOOLEAN);62 if (isset($config['content']['enabled'])) { 63 return filter_var($config['content']['enabled'], FILTER_VALIDATE_BOOLEAN); 64 } 65 66 // 3. Default: disabled (safe) 67 return false; 60 68 } 61 69 … … 70 78 add_filter('posts_pre_query', [$this, 'injectFilePosts'], 10, 2); 71 79 72 // Initialize export page early (before admin_menu)80 // Register Settings page in admin 73 81 if (is_admin()) { 74 82 new ExportPage(); 75 } 83 84 // Settings page (WordPress-native config) 85 if (file_exists(PRAISON_PLUGIN_DIR . '/src/Admin/SettingsPage.php')) { 86 $settingsPage = new \PraisonPress\Admin\SettingsPage(); 87 $settingsPage->register(); 88 } 89 } 90 91 // Register index rebuild handler (triggered by Settings page button) 92 add_action('admin_post_praison_rebuild_index', [$this, 'handleRebuildIndex']); 93 94 // Register background index rebuild (triggered on settings save) 95 add_action('praisonpress_rebuild_index', [$this, 'doBackgroundIndexRebuild']); 76 96 77 97 // Admin features (priority 10 - default) … … 134 154 135 155 /** 136 * Get the allowed post types from site-config.ini 137 * 138 * @return array|null Array of allowed types, or null if setting doesn't exist (allow all) 156 * Get the allowed post types. 157 * Priority: wp_options (Settings page) > site-config.ini > null (allow all) 139 158 */ 140 159 private function getAllowedPostTypes() { 141 160 if ($this->allowedPostTypes !== null) { 142 // false is our internal sentinel for "checked but not found" → return null (allow all)143 161 return $this->allowedPostTypes === false ? null : $this->allowedPostTypes; 144 162 } 145 163 164 // 1. Check WordPress options (Settings page) 165 $options = get_option('praisonpress_options', []); 166 if (!empty($options['post_types']) && is_array($options['post_types'])) { 167 $this->allowedPostTypes = $options['post_types']; 168 return $this->allowedPostTypes; 169 } 170 171 // 2. Fallback to site-config.ini 146 172 $config = self::getConfig(); 147 173 if (isset($config['content']['post_types']) && is_array($config['content']['post_types'])) { … … 150 176 } 151 177 152 $this->allowedPostTypes = false; // Use false internally to denote "checked but not found"153 return null; // Return null to mean "allow all"178 $this->allowedPostTypes = false; 179 return null; 154 180 } 155 181 … … 970 996 971 997 /** 998 * Handle "Rebuild Index Now" button from Settings page 999 */ 1000 public function handleRebuildIndex() { 1001 if (!isset($_GET['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'])), 'praison_rebuild_index')) { 1002 wp_die('Security check failed'); 1003 } 1004 1005 if (!current_user_can('manage_options')) { 1006 wp_die('Unauthorized'); 1007 } 1008 1009 // Run index rebuild synchronously 1010 $result = $this->doBackgroundIndexRebuild(); 1011 1012 wp_safe_redirect(add_query_arg([ 1013 'page' => 'praison-settings', 1014 'index_rebuilt' => $result ? '1' : '0', 1015 ], admin_url('admin.php'))); 1016 exit; 1017 } 1018 1019 /** 1020 * Rebuild _index.json for all content types. 1021 * Called from: Settings page button, background cron, activation hook. 1022 * Uses the existing IndexCommand logic. 1023 * 1024 * @return bool True on success 1025 */ 1026 public function doBackgroundIndexRebuild() { 1027 $content_dir = PRAISON_CONTENT_DIR; 1028 if (!is_dir($content_dir)) { 1029 return false; 1030 } 1031 1032 // Reuse the IndexCommand's indexing logic 1033 if (!class_exists('PraisonPress\\CLI\\IndexCommand')) { 1034 $file = PRAISON_PLUGIN_DIR . '/src/CLI/IndexCommand.php'; 1035 if (file_exists($file)) { 1036 require_once $file; 1037 } 1038 } 1039 1040 $success = true; 1041 $dirs = @scandir($content_dir); 1042 if (!$dirs) return false; 1043 1044 foreach ($dirs as $dir) { 1045 if ($dir[0] === '.' || $dir === 'config' || !is_dir($content_dir . '/' . $dir)) { 1046 continue; 1047 } 1048 1049 $type_dir = $content_dir . '/' . $dir; 1050 $md_files = glob($type_dir . '/*.md'); 1051 if (empty($md_files)) continue; 1052 1053 // Build index data 1054 $index = []; 1055 require_once PRAISON_PLUGIN_DIR . '/src/Parsers/FrontMatterParser.php'; 1056 $parser = new \PraisonPress\Parsers\FrontMatterParser(); 1057 1058 foreach ($md_files as $file) { 1059 $content = @file_get_contents($file); 1060 if ($content === false) continue; 1061 1062 $parsed = $parser->parse($content); 1063 $meta = $parsed['meta'] ?? []; 1064 $slug = $meta['slug'] ?? pathinfo($file, PATHINFO_FILENAME); 1065 1066 $entry = [ 1067 'file' => basename($file), 1068 'slug' => $slug, 1069 'title' => $meta['title'] ?? ucwords(str_replace('-', ' ', $slug)), 1070 'date' => $meta['date'] ?? date('Y-m-d H:i:s', filemtime($file)), 1071 'modified' => date('Y-m-d H:i:s', filemtime($file)), 1072 'status' => $meta['status'] ?? 'publish', 1073 'excerpt' => $meta['excerpt'] ?? '', 1074 'categories' => $meta['categories'] ?? [], 1075 'tags' => $meta['tags'] ?? [], 1076 ]; 1077 1078 // Include custom fields from frontmatter 1079 $reserved = ['title', 'date', 'slug', 'status', 'excerpt', 'categories', 'tags', 'featured_image', 'author']; 1080 $custom = []; 1081 foreach ($meta as $k => $v) { 1082 if (!in_array($k, $reserved)) { 1083 $custom[$k] = $v; 1084 } 1085 } 1086 if (!empty($custom)) { 1087 $entry['custom_fields'] = $custom; 1088 } 1089 1090 $index[] = $entry; 1091 } 1092 1093 // Write _index.json 1094 $index_path = $type_dir . '/_index.json'; 1095 $written = @file_put_contents($index_path, json_encode($index, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); 1096 if ($written === false) { 1097 $success = false; 1098 } 1099 } 1100 1101 return $success; 1102 } 1103 1104 /** 972 1105 * Handle cache clear action 973 1106 */
Note: See TracChangeset
for help on using the changeset viewer.