@mytechtoday/augment-extensions 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/augment-extensions/domain-rules/wordpress/README.md +163 -0
  2. package/augment-extensions/domain-rules/wordpress/module.json +32 -0
  3. package/augment-extensions/domain-rules/wordpress/rules/coding-standards.md +617 -0
  4. package/augment-extensions/domain-rules/wordpress/rules/directory-structure.md +270 -0
  5. package/augment-extensions/domain-rules/wordpress/rules/file-patterns.md +423 -0
  6. package/augment-extensions/domain-rules/wordpress/rules/gutenberg-blocks.md +493 -0
  7. package/augment-extensions/domain-rules/wordpress/rules/performance.md +568 -0
  8. package/augment-extensions/domain-rules/wordpress/rules/plugin-development.md +510 -0
  9. package/augment-extensions/domain-rules/wordpress/rules/project-detection.md +251 -0
  10. package/augment-extensions/domain-rules/wordpress/rules/rest-api.md +501 -0
  11. package/augment-extensions/domain-rules/wordpress/rules/security.md +564 -0
  12. package/augment-extensions/domain-rules/wordpress/rules/theme-development.md +388 -0
  13. package/augment-extensions/domain-rules/wordpress/rules/woocommerce.md +441 -0
  14. package/augment-extensions/domain-rules/wordpress-plugin/README.md +139 -0
  15. package/augment-extensions/domain-rules/wordpress-plugin/examples/ajax-plugin.md +1599 -0
  16. package/augment-extensions/domain-rules/wordpress-plugin/examples/custom-post-type-plugin.md +1727 -0
  17. package/augment-extensions/domain-rules/wordpress-plugin/examples/gutenberg-block-plugin.md +428 -0
  18. package/augment-extensions/domain-rules/wordpress-plugin/examples/gutenberg-block.md +422 -0
  19. package/augment-extensions/domain-rules/wordpress-plugin/examples/mvc-plugin.md +1623 -0
  20. package/augment-extensions/domain-rules/wordpress-plugin/examples/object-oriented-plugin.md +1343 -0
  21. package/augment-extensions/domain-rules/wordpress-plugin/examples/rest-endpoint.md +734 -0
  22. package/augment-extensions/domain-rules/wordpress-plugin/examples/settings-page-plugin.md +1350 -0
  23. package/augment-extensions/domain-rules/wordpress-plugin/examples/simple-procedural-plugin.md +503 -0
  24. package/augment-extensions/domain-rules/wordpress-plugin/examples/singleton-plugin.md +971 -0
  25. package/augment-extensions/domain-rules/wordpress-plugin/module.json +53 -0
  26. package/augment-extensions/domain-rules/wordpress-plugin/rules/activation-hooks.md +770 -0
  27. package/augment-extensions/domain-rules/wordpress-plugin/rules/admin-interface.md +874 -0
  28. package/augment-extensions/domain-rules/wordpress-plugin/rules/ajax-handlers.md +629 -0
  29. package/augment-extensions/domain-rules/wordpress-plugin/rules/asset-management.md +559 -0
  30. package/augment-extensions/domain-rules/wordpress-plugin/rules/context-providers.md +709 -0
  31. package/augment-extensions/domain-rules/wordpress-plugin/rules/cron-jobs.md +736 -0
  32. package/augment-extensions/domain-rules/wordpress-plugin/rules/database-management.md +1057 -0
  33. package/augment-extensions/domain-rules/wordpress-plugin/rules/documentation-standards.md +463 -0
  34. package/augment-extensions/domain-rules/wordpress-plugin/rules/frontend-functionality.md +478 -0
  35. package/augment-extensions/domain-rules/wordpress-plugin/rules/gutenberg-blocks.md +818 -0
  36. package/augment-extensions/domain-rules/wordpress-plugin/rules/internationalization.md +416 -0
  37. package/augment-extensions/domain-rules/wordpress-plugin/rules/migration.md +667 -0
  38. package/augment-extensions/domain-rules/wordpress-plugin/rules/performance-optimization.md +878 -0
  39. package/augment-extensions/domain-rules/wordpress-plugin/rules/plugin-architecture.md +693 -0
  40. package/augment-extensions/domain-rules/wordpress-plugin/rules/plugin-structure.md +352 -0
  41. package/augment-extensions/domain-rules/wordpress-plugin/rules/rest-api.md +818 -0
  42. package/augment-extensions/domain-rules/wordpress-plugin/rules/scaffolding-workflow.md +624 -0
  43. package/augment-extensions/domain-rules/wordpress-plugin/rules/security-best-practices.md +866 -0
  44. package/augment-extensions/domain-rules/wordpress-plugin/rules/testing-patterns.md +1165 -0
  45. package/augment-extensions/domain-rules/wordpress-plugin/rules/testing.md +414 -0
  46. package/augment-extensions/domain-rules/wordpress-plugin/rules/vscode-integration.md +751 -0
  47. package/augment-extensions/domain-rules/wordpress-plugin/rules/woocommerce-integration.md +949 -0
  48. package/augment-extensions/domain-rules/wordpress-plugin/rules/wordpress-org-submission.md +458 -0
  49. package/augment-extensions/examples/gutenberg-block-plugin/README.md +101 -0
  50. package/augment-extensions/examples/gutenberg-block-plugin/examples/testimonial-block.md +428 -0
  51. package/augment-extensions/examples/gutenberg-block-plugin/module.json +40 -0
  52. package/augment-extensions/examples/rest-api-plugin/README.md +98 -0
  53. package/augment-extensions/examples/rest-api-plugin/examples/task-manager-api.md +1299 -0
  54. package/augment-extensions/examples/rest-api-plugin/module.json +40 -0
  55. package/augment-extensions/examples/woocommerce-extension/README.md +98 -0
  56. package/augment-extensions/examples/woocommerce-extension/examples/product-customizer.md +763 -0
  57. package/augment-extensions/examples/woocommerce-extension/module.json +40 -0
  58. package/augment-extensions/workflows/wordpress-plugin/README.md +232 -0
  59. package/augment-extensions/workflows/wordpress-plugin/ai-prompts.md +839 -0
  60. package/augment-extensions/workflows/wordpress-plugin/bead-decomposition-patterns.md +854 -0
  61. package/augment-extensions/workflows/wordpress-plugin/examples/complete-plugin-example.md +540 -0
  62. package/augment-extensions/workflows/wordpress-plugin/examples/custom-post-type-example.md +1083 -0
  63. package/augment-extensions/workflows/wordpress-plugin/examples/feature-addition-workflow.md +669 -0
  64. package/augment-extensions/workflows/wordpress-plugin/examples/plugin-creation-workflow.md +597 -0
  65. package/augment-extensions/workflows/wordpress-plugin/examples/secure-form-handler-example.md +925 -0
  66. package/augment-extensions/workflows/wordpress-plugin/examples/security-audit-workflow.md +752 -0
  67. package/augment-extensions/workflows/wordpress-plugin/examples/wordpress-org-submission-workflow.md +773 -0
  68. package/augment-extensions/workflows/wordpress-plugin/module.json +49 -0
  69. package/augment-extensions/workflows/wordpress-plugin/rules/best-practices.md +942 -0
  70. package/augment-extensions/workflows/wordpress-plugin/rules/development-workflow.md +702 -0
  71. package/augment-extensions/workflows/wordpress-plugin/rules/submission-workflow.md +728 -0
  72. package/augment-extensions/workflows/wordpress-plugin/rules/testing-workflow.md +775 -0
  73. package/cli/dist/cli.js +5 -1
  74. package/cli/dist/cli.js.map +1 -1
  75. package/cli/dist/commands/show.d.ts.map +1 -1
  76. package/cli/dist/commands/show.js +41 -0
  77. package/cli/dist/commands/show.js.map +1 -1
  78. package/modules.md +52 -0
  79. package/package.json +1 -1
@@ -0,0 +1,1343 @@
1
+ # Object-Oriented Plugin Example
2
+
3
+ ## Overview
4
+
5
+ This example demonstrates **Pattern 3: Object-Oriented Plugin** - a maintainable, extensible architecture using classes for complex WordPress plugins.
6
+
7
+ **Complexity**: Medium-High
8
+ **File Count**: 10-30 files
9
+ **Team Size**: 2-5 developers
10
+ **Use Case**: Complex functionality, extensibility, multiple developers, long-term maintenance
11
+
12
+ ---
13
+
14
+ ## Complete Plugin: "Event Manager Pro"
15
+
16
+ A complete event management plugin demonstrating OOP principles, hook loader pattern, and separation of concerns.
17
+
18
+ ---
19
+
20
+ ## Directory Structure
21
+
22
+ ```
23
+ event-manager-pro/
24
+ ├── event-manager-pro.php # Main plugin file (bootstrap)
25
+ ├── uninstall.php # Uninstall cleanup
26
+ ├── readme.txt # WordPress.org readme
27
+ ├── includes/
28
+ │ ├── class-event-manager.php # Main plugin class
29
+ │ ├── class-loader.php # Hook loader
30
+ │ ├── class-activator.php # Activation logic
31
+ │ ├── class-deactivator.php # Deactivation logic
32
+ │ ├── class-event.php # Event model
33
+ │ └── class-database.php # Database operations
34
+ ├── admin/
35
+ │ ├── class-admin.php # Admin functionality
36
+ │ ├── class-settings.php # Settings page
37
+ │ ├── class-meta-boxes.php # Meta boxes
38
+ │ ├── css/
39
+ │ │ └── admin.css
40
+ │ ├── js/
41
+ │ │ └── admin.js
42
+ │ └── partials/
43
+ │ ├── settings-page.php # Settings view
44
+ │ └── meta-box-event.php # Event meta box view
45
+ ├── public/
46
+ │ ├── class-public.php # Public functionality
47
+ │ ├── class-shortcodes.php # Shortcode handlers
48
+ │ ├── class-widgets.php # Widget classes
49
+ │ ├── css/
50
+ │ │ └── public.css
51
+ │ ├── js/
52
+ │ │ └── public.js
53
+ │ └── partials/
54
+ │ ├── event-single.php # Single event view
55
+ │ └── event-list.php # Event list view
56
+ └── languages/
57
+ └── event-manager-pro.pot
58
+ ```
59
+
60
+ ---
61
+
62
+ ## Main Plugin File
63
+
64
+ ### File: `event-manager-pro.php`
65
+
66
+ ```php
67
+ <?php
68
+ /**
69
+ * Plugin Name: Event Manager Pro
70
+ * Plugin URI: https://example.com/event-manager-pro
71
+ * Description: Professional event management with OOP architecture
72
+ * Version: 1.0.0
73
+ * Author: Your Name
74
+ * Author URI: https://example.com
75
+ * License: GPL-2.0+
76
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
77
+ * Text Domain: event-manager-pro
78
+ * Domain Path: /languages
79
+ *
80
+ * @package Event_Manager_Pro
81
+ */
82
+
83
+ // Exit if accessed directly
84
+ if (!defined('ABSPATH')) {
85
+ exit;
86
+ }
87
+
88
+ // Define plugin constants
89
+ define('EMP_VERSION', '1.0.0');
90
+ define('EMP_PLUGIN_DIR', plugin_dir_path(__FILE__));
91
+ define('EMP_PLUGIN_URL', plugin_dir_url(__FILE__));
92
+ define('EMP_PLUGIN_BASENAME', plugin_basename(__FILE__));
93
+
94
+ /**
95
+ * PSR-4 Autoloader for plugin classes
96
+ */
97
+ spl_autoload_register(function ($class) {
98
+ $prefix = 'Event_Manager_Pro_';
99
+ $base_dir = EMP_PLUGIN_DIR . 'includes/';
100
+
101
+ $len = strlen($prefix);
102
+ if (strncmp($prefix, $class, $len) !== 0) {
103
+ return;
104
+ }
105
+
106
+ $relative_class = substr($class, $len);
107
+ $file = $base_dir . 'class-' . str_replace('_', '-', strtolower($relative_class)) . '.php';
108
+
109
+ if (file_exists($file)) {
110
+ require $file;
111
+ }
112
+ });
113
+
114
+ // Load admin classes
115
+ spl_autoload_register(function ($class) {
116
+ if (strpos($class, 'Event_Manager_Pro_Admin') === 0) {
117
+ $file = EMP_PLUGIN_DIR . 'admin/class-' . str_replace('_', '-', strtolower(str_replace('Event_Manager_Pro_Admin_', '', $class))) . '.php';
118
+ if (file_exists($file)) {
119
+ require $file;
120
+ }
121
+ }
122
+ });
123
+
124
+ // Load public classes
125
+ spl_autoload_register(function ($class) {
126
+ if (strpos($class, 'Event_Manager_Pro_Public') === 0) {
127
+ $file = EMP_PLUGIN_DIR . 'public/class-' . str_replace('_', '-', strtolower(str_replace('Event_Manager_Pro_Public_', '', $class))) . '.php';
128
+ if (file_exists($file)) {
129
+ require $file;
130
+ }
131
+ }
132
+ });
133
+
134
+ /**
135
+ * Activation hook
136
+ */
137
+ function activate_event_manager_pro() {
138
+ require_once EMP_PLUGIN_DIR . 'includes/class-activator.php';
139
+ Event_Manager_Pro_Activator::activate();
140
+ }
141
+ register_activation_hook(__FILE__, 'activate_event_manager_pro');
142
+
143
+ /**
144
+ * Deactivation hook
145
+ */
146
+ function deactivate_event_manager_pro() {
147
+ require_once EMP_PLUGIN_DIR . 'includes/class-deactivator.php';
148
+ Event_Manager_Pro_Deactivator::deactivate();
149
+ }
150
+ register_deactivation_hook(__FILE__, 'deactivate_event_manager_pro');
151
+
152
+ /**
153
+ * Initialize and run the plugin
154
+ */
155
+ function run_event_manager_pro() {
156
+ $plugin = new Event_Manager_Pro();
157
+ $plugin->run();
158
+ }
159
+ run_event_manager_pro();
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Core Classes
165
+
166
+ ### File: `includes/class-event-manager.php`
167
+
168
+ ```php
169
+ <?php
170
+ /**
171
+ * Main plugin class
172
+ *
173
+ * @package Event_Manager_Pro
174
+ */
175
+
176
+ class Event_Manager_Pro {
177
+ /**
178
+ * The loader that's responsible for maintaining and registering all hooks
179
+ *
180
+ * @var Event_Manager_Pro_Loader
181
+ */
182
+ protected $loader;
183
+
184
+ /**
185
+ * The unique identifier of this plugin
186
+ *
187
+ * @var string
188
+ */
189
+ protected $plugin_name;
190
+
191
+ /**
192
+ * The current version of the plugin
193
+ *
194
+ * @var string
195
+ */
196
+ protected $version;
197
+
198
+ /**
199
+ * Initialize the plugin
200
+ */
201
+ public function __construct() {
202
+ $this->version = EMP_VERSION;
203
+ $this->plugin_name = 'event-manager-pro';
204
+
205
+ $this->load_dependencies();
206
+ $this->set_locale();
207
+ $this->define_admin_hooks();
208
+ $this->define_public_hooks();
209
+ }
210
+
211
+ /**
212
+ * Load required dependencies
213
+ */
214
+ private function load_dependencies() {
215
+ require_once EMP_PLUGIN_DIR . 'includes/class-loader.php';
216
+ require_once EMP_PLUGIN_DIR . 'includes/class-event.php';
217
+ require_once EMP_PLUGIN_DIR . 'includes/class-database.php';
218
+ require_once EMP_PLUGIN_DIR . 'admin/class-admin.php';
219
+ require_once EMP_PLUGIN_DIR . 'admin/class-settings.php';
220
+ require_once EMP_PLUGIN_DIR . 'admin/class-meta-boxes.php';
221
+ require_once EMP_PLUGIN_DIR . 'public/class-public.php';
222
+ require_once EMP_PLUGIN_DIR . 'public/class-shortcodes.php';
223
+
224
+ $this->loader = new Event_Manager_Pro_Loader();
225
+ }
226
+
227
+ /**
228
+ * Set the plugin locale for internationalization
229
+ */
230
+ private function set_locale() {
231
+ $this->loader->add_action('plugins_loaded', $this, 'load_plugin_textdomain');
232
+ }
233
+
234
+ /**
235
+ * Load plugin text domain
236
+ */
237
+ public function load_plugin_textdomain() {
238
+ load_plugin_textdomain(
239
+ 'event-manager-pro',
240
+ false,
241
+ dirname(EMP_PLUGIN_BASENAME) . '/languages/'
242
+ );
243
+ }
244
+
245
+ /**
246
+ * Register all admin-related hooks
247
+ */
248
+ private function define_admin_hooks() {
249
+ $admin = new Event_Manager_Pro_Admin($this->plugin_name, $this->version);
250
+
251
+ // Admin menu and assets
252
+ $this->loader->add_action('admin_menu', $admin, 'add_admin_menu');
253
+ $this->loader->add_action('admin_enqueue_scripts', $admin, 'enqueue_styles');
254
+ $this->loader->add_action('admin_enqueue_scripts', $admin, 'enqueue_scripts');
255
+
256
+ // Settings
257
+ $settings = new Event_Manager_Pro_Admin_Settings($this->plugin_name, $this->version);
258
+ $this->loader->add_action('admin_init', $settings, 'register_settings');
259
+
260
+ // Meta boxes
261
+ $meta_boxes = new Event_Manager_Pro_Admin_Meta_Boxes($this->plugin_name, $this->version);
262
+ $this->loader->add_action('add_meta_boxes', $meta_boxes, 'add_meta_boxes');
263
+ $this->loader->add_action('save_post', $meta_boxes, 'save_meta_boxes');
264
+ }
265
+
266
+ /**
267
+ * Register all public-facing hooks
268
+ */
269
+ private function define_public_hooks() {
270
+ $public = new Event_Manager_Pro_Public($this->plugin_name, $this->version);
271
+
272
+ // Public assets
273
+ $this->loader->add_action('wp_enqueue_scripts', $public, 'enqueue_styles');
274
+ $this->loader->add_action('wp_enqueue_scripts', $public, 'enqueue_scripts');
275
+
276
+ // Custom post type
277
+ $this->loader->add_action('init', $public, 'register_event_post_type');
278
+
279
+ // Shortcodes
280
+ $shortcodes = new Event_Manager_Pro_Public_Shortcodes($this->plugin_name, $this->version);
281
+ $this->loader->add_action('init', $shortcodes, 'register_shortcodes');
282
+ }
283
+
284
+ /**
285
+ * Run the loader to execute all hooks
286
+ */
287
+ public function run() {
288
+ $this->loader->run();
289
+ }
290
+
291
+ /**
292
+ * Get the plugin name
293
+ *
294
+ * @return string
295
+ */
296
+ public function get_plugin_name() {
297
+ return $this->plugin_name;
298
+ }
299
+
300
+ /**
301
+ * Get the plugin version
302
+ *
303
+ * @return string
304
+ */
305
+ public function get_version() {
306
+ return $this->version;
307
+ }
308
+
309
+ /**
310
+ * Get the loader
311
+ *
312
+ * @return Event_Manager_Pro_Loader
313
+ */
314
+ public function get_loader() {
315
+ return $this->loader;
316
+ }
317
+ }
318
+ ```
319
+
320
+ ### File: `includes/class-loader.php`
321
+
322
+ ```php
323
+ <?php
324
+ /**
325
+ * Hook loader class
326
+ *
327
+ * Maintains and registers all hooks for the plugin
328
+ *
329
+ * @package Event_Manager_Pro
330
+ */
331
+
332
+ class Event_Manager_Pro_Loader {
333
+ /**
334
+ * Array of actions registered with WordPress
335
+ *
336
+ * @var array
337
+ */
338
+ protected $actions;
339
+
340
+ /**
341
+ * Array of filters registered with WordPress
342
+ *
343
+ * @var array
344
+ */
345
+ protected $filters;
346
+
347
+ /**
348
+ * Initialize the collections
349
+ */
350
+ public function __construct() {
351
+ $this->actions = array();
352
+ $this->filters = array();
353
+ }
354
+
355
+ /**
356
+ * Add a new action to the collection
357
+ *
358
+ * @param string $hook The name of the WordPress action
359
+ * @param object $component A reference to the instance of the object
360
+ * @param string $callback The name of the function definition on the $component
361
+ * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
362
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
363
+ */
364
+ public function add_action($hook, $component, $callback, $priority = 10, $accepted_args = 1) {
365
+ $this->actions = $this->add($this->actions, $hook, $component, $callback, $priority, $accepted_args);
366
+ }
367
+
368
+ /**
369
+ * Add a new filter to the collection
370
+ *
371
+ * @param string $hook The name of the WordPress filter
372
+ * @param object $component A reference to the instance of the object
373
+ * @param string $callback The name of the function definition on the $component
374
+ * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
375
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
376
+ */
377
+ public function add_filter($hook, $component, $callback, $priority = 10, $accepted_args = 1) {
378
+ $this->filters = $this->add($this->filters, $hook, $component, $callback, $priority, $accepted_args);
379
+ }
380
+
381
+ /**
382
+ * Utility function to register hooks
383
+ *
384
+ * @param array $hooks The collection of hooks
385
+ * @param string $hook The name of the WordPress filter/action
386
+ * @param object $component A reference to the instance of the object
387
+ * @param string $callback The name of the function definition on the $component
388
+ * @param int $priority The priority at which the function should be fired
389
+ * @param int $accepted_args The number of arguments that should be passed to the $callback
390
+ * @return array
391
+ */
392
+ private function add($hooks, $hook, $component, $callback, $priority, $accepted_args) {
393
+ $hooks[] = array(
394
+ 'hook' => $hook,
395
+ 'component' => $component,
396
+ 'callback' => $callback,
397
+ 'priority' => $priority,
398
+ 'accepted_args' => $accepted_args
399
+ );
400
+
401
+ return $hooks;
402
+ }
403
+
404
+ /**
405
+ * Register the filters and actions with WordPress
406
+ */
407
+ public function run() {
408
+ foreach ($this->filters as $hook) {
409
+ add_filter(
410
+ $hook['hook'],
411
+ array($hook['component'], $hook['callback']),
412
+ $hook['priority'],
413
+ $hook['accepted_args']
414
+ );
415
+ }
416
+
417
+ foreach ($this->actions as $hook) {
418
+ add_action(
419
+ $hook['hook'],
420
+ array($hook['component'], $hook['callback']),
421
+ $hook['priority'],
422
+ $hook['accepted_args']
423
+ );
424
+ }
425
+ }
426
+ }
427
+ ```
428
+
429
+ ### File: `includes/class-activator.php`
430
+
431
+ ```php
432
+ <?php
433
+ /**
434
+ * Activation handler
435
+ *
436
+ * @package Event_Manager_Pro
437
+ */
438
+
439
+ class Event_Manager_Pro_Activator {
440
+ /**
441
+ * Activate the plugin
442
+ */
443
+ public static function activate() {
444
+ // Register custom post type (needed for flush_rewrite_rules)
445
+ self::register_event_post_type();
446
+
447
+ // Flush rewrite rules
448
+ flush_rewrite_rules();
449
+
450
+ // Create custom database tables
451
+ self::create_tables();
452
+
453
+ // Set default options
454
+ self::set_default_options();
455
+
456
+ // Schedule cron events
457
+ if (!wp_next_scheduled('emp_daily_cleanup')) {
458
+ wp_schedule_event(time(), 'daily', 'emp_daily_cleanup');
459
+ }
460
+ }
461
+
462
+ /**
463
+ * Register event post type (temporary for activation)
464
+ */
465
+ private static function register_event_post_type() {
466
+ register_post_type('emp_event', array(
467
+ 'public' => true,
468
+ 'has_archive' => true,
469
+ 'rewrite' => array('slug' => 'events'),
470
+ ));
471
+ }
472
+
473
+ /**
474
+ * Create custom database tables
475
+ */
476
+ private static function create_tables() {
477
+ global $wpdb;
478
+
479
+ $charset_collate = $wpdb->get_charset_collate();
480
+ $table_name = $wpdb->prefix . 'emp_attendees';
481
+
482
+ $sql = "CREATE TABLE $table_name (
483
+ id bigint(20) NOT NULL AUTO_INCREMENT,
484
+ event_id bigint(20) NOT NULL,
485
+ user_id bigint(20) NOT NULL,
486
+ status varchar(20) NOT NULL DEFAULT 'registered',
487
+ registered_at datetime DEFAULT CURRENT_TIMESTAMP,
488
+ PRIMARY KEY (id),
489
+ KEY event_id (event_id),
490
+ KEY user_id (user_id)
491
+ ) $charset_collate;";
492
+
493
+ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
494
+ dbDelta($sql);
495
+
496
+ // Store database version
497
+ add_option('emp_db_version', '1.0.0');
498
+ }
499
+
500
+ /**
501
+ * Set default plugin options
502
+ */
503
+ private static function set_default_options() {
504
+ $defaults = array(
505
+ 'events_per_page' => 10,
506
+ 'date_format' => 'F j, Y',
507
+ 'time_format' => 'g:i a',
508
+ 'enable_registration' => true,
509
+ );
510
+
511
+ add_option('emp_settings', $defaults);
512
+ }
513
+ }
514
+ ```
515
+
516
+ ### File: `includes/class-deactivator.php`
517
+
518
+ ```php
519
+ <?php
520
+ /**
521
+ * Deactivation handler
522
+ *
523
+ * @package Event_Manager_Pro
524
+ */
525
+
526
+ class Event_Manager_Pro_Deactivator {
527
+ /**
528
+ * Deactivate the plugin
529
+ */
530
+ public static function deactivate() {
531
+ // Unschedule cron events
532
+ $timestamp = wp_next_scheduled('emp_daily_cleanup');
533
+ if ($timestamp) {
534
+ wp_unschedule_event($timestamp, 'emp_daily_cleanup');
535
+ }
536
+
537
+ // Flush rewrite rules
538
+ flush_rewrite_rules();
539
+ }
540
+ }
541
+ ```
542
+
543
+ ### File: `includes/class-event.php`
544
+
545
+ ```php
546
+ <?php
547
+ /**
548
+ * Event model class
549
+ *
550
+ * @package Event_Manager_Pro
551
+ */
552
+
553
+ class Event_Manager_Pro_Event {
554
+ /**
555
+ * Event ID
556
+ *
557
+ * @var int
558
+ */
559
+ private $id;
560
+
561
+ /**
562
+ * Event data
563
+ *
564
+ * @var array
565
+ */
566
+ private $data;
567
+
568
+ /**
569
+ * Constructor
570
+ *
571
+ * @param int $event_id Event post ID
572
+ */
573
+ public function __construct($event_id = 0) {
574
+ if ($event_id > 0) {
575
+ $this->id = $event_id;
576
+ $this->load();
577
+ }
578
+ }
579
+
580
+ /**
581
+ * Load event data
582
+ */
583
+ private function load() {
584
+ $post = get_post($this->id);
585
+
586
+ if (!$post || $post->post_type !== 'emp_event') {
587
+ return false;
588
+ }
589
+
590
+ $this->data = array(
591
+ 'title' => $post->post_title,
592
+ 'description' => $post->post_content,
593
+ 'start_date' => get_post_meta($this->id, '_emp_start_date', true),
594
+ 'end_date' => get_post_meta($this->id, '_emp_end_date', true),
595
+ 'location' => get_post_meta($this->id, '_emp_location', true),
596
+ 'capacity' => get_post_meta($this->id, '_emp_capacity', true),
597
+ 'status' => $post->post_status,
598
+ );
599
+ }
600
+
601
+ /**
602
+ * Get event property
603
+ *
604
+ * @param string $key Property key
605
+ * @return mixed
606
+ */
607
+ public function get($key) {
608
+ return isset($this->data[$key]) ? $this->data[$key] : null;
609
+ }
610
+
611
+ /**
612
+ * Set event property
613
+ *
614
+ * @param string $key Property key
615
+ * @param mixed $value Property value
616
+ */
617
+ public function set($key, $value) {
618
+ $this->data[$key] = $value;
619
+ }
620
+
621
+ /**
622
+ * Save event
623
+ *
624
+ * @return int|WP_Error Event ID on success, WP_Error on failure
625
+ */
626
+ public function save() {
627
+ $post_data = array(
628
+ 'post_title' => $this->data['title'],
629
+ 'post_content' => $this->data['description'],
630
+ 'post_type' => 'emp_event',
631
+ 'post_status' => $this->data['status'] ?? 'publish',
632
+ );
633
+
634
+ if ($this->id > 0) {
635
+ $post_data['ID'] = $this->id;
636
+ $result = wp_update_post($post_data, true);
637
+ } else {
638
+ $result = wp_insert_post($post_data, true);
639
+ if (!is_wp_error($result)) {
640
+ $this->id = $result;
641
+ }
642
+ }
643
+
644
+ if (is_wp_error($result)) {
645
+ return $result;
646
+ }
647
+
648
+ // Save meta data
649
+ update_post_meta($this->id, '_emp_start_date', $this->data['start_date']);
650
+ update_post_meta($this->id, '_emp_end_date', $this->data['end_date']);
651
+ update_post_meta($this->id, '_emp_location', $this->data['location']);
652
+ update_post_meta($this->id, '_emp_capacity', $this->data['capacity']);
653
+
654
+ return $this->id;
655
+ }
656
+
657
+ /**
658
+ * Delete event
659
+ *
660
+ * @return bool
661
+ */
662
+ public function delete() {
663
+ if ($this->id > 0) {
664
+ return wp_delete_post($this->id, true) !== false;
665
+ }
666
+ return false;
667
+ }
668
+
669
+ /**
670
+ * Get attendee count
671
+ *
672
+ * @return int
673
+ */
674
+ public function get_attendee_count() {
675
+ global $wpdb;
676
+ $table_name = $wpdb->prefix . 'emp_attendees';
677
+
678
+ return (int) $wpdb->get_var($wpdb->prepare(
679
+ "SELECT COUNT(*) FROM $table_name WHERE event_id = %d AND status = 'registered'",
680
+ $this->id
681
+ ));
682
+ }
683
+
684
+ /**
685
+ * Check if event is full
686
+ *
687
+ * @return bool
688
+ */
689
+ public function is_full() {
690
+ $capacity = (int) $this->get('capacity');
691
+ if ($capacity <= 0) {
692
+ return false;
693
+ }
694
+
695
+ return $this->get_attendee_count() >= $capacity;
696
+ }
697
+
698
+ /**
699
+ * Get available spots
700
+ *
701
+ * @return int
702
+ */
703
+ public function get_available_spots() {
704
+ $capacity = (int) $this->get('capacity');
705
+ if ($capacity <= 0) {
706
+ return -1; // Unlimited
707
+ }
708
+
709
+ return max(0, $capacity - $this->get_attendee_count());
710
+ }
711
+ }
712
+ ```
713
+
714
+ ---
715
+
716
+ ## Admin Classes
717
+
718
+ ### File: `admin/class-admin.php`
719
+
720
+ ```php
721
+ <?php
722
+ /**
723
+ * Admin functionality
724
+ *
725
+ * @package Event_Manager_Pro
726
+ */
727
+
728
+ class Event_Manager_Pro_Admin {
729
+ private $plugin_name;
730
+ private $version;
731
+
732
+ public function __construct($plugin_name, $version) {
733
+ $this->plugin_name = $plugin_name;
734
+ $this->version = $version;
735
+ }
736
+
737
+ /**
738
+ * Add admin menu
739
+ */
740
+ public function add_admin_menu() {
741
+ add_menu_page(
742
+ __('Event Manager', 'event-manager-pro'),
743
+ __('Events', 'event-manager-pro'),
744
+ 'manage_options',
745
+ 'event-manager-pro',
746
+ array($this, 'display_admin_page'),
747
+ 'dashicons-calendar-alt',
748
+ 25
749
+ );
750
+ }
751
+
752
+ /**
753
+ * Display admin page
754
+ */
755
+ public function display_admin_page() {
756
+ include EMP_PLUGIN_DIR . 'admin/partials/settings-page.php';
757
+ }
758
+
759
+ /**
760
+ * Enqueue admin styles
761
+ */
762
+ public function enqueue_styles() {
763
+ wp_enqueue_style(
764
+ $this->plugin_name,
765
+ EMP_PLUGIN_URL . 'admin/css/admin.css',
766
+ array(),
767
+ $this->version,
768
+ 'all'
769
+ );
770
+ }
771
+
772
+ /**
773
+ * Enqueue admin scripts
774
+ */
775
+ public function enqueue_scripts() {
776
+ wp_enqueue_script(
777
+ $this->plugin_name,
778
+ EMP_PLUGIN_URL . 'admin/js/admin.js',
779
+ array('jquery', 'jquery-ui-datepicker'),
780
+ $this->version,
781
+ false
782
+ );
783
+ }
784
+ }
785
+ ```
786
+
787
+ ### File: `admin/class-meta-boxes.php`
788
+
789
+ ```php
790
+ <?php
791
+ /**
792
+ * Meta boxes for event post type
793
+ *
794
+ * @package Event_Manager_Pro
795
+ */
796
+
797
+ class Event_Manager_Pro_Admin_Meta_Boxes {
798
+ private $plugin_name;
799
+ private $version;
800
+
801
+ public function __construct($plugin_name, $version) {
802
+ $this->plugin_name = $plugin_name;
803
+ $this->version = $version;
804
+ }
805
+
806
+ /**
807
+ * Add meta boxes
808
+ */
809
+ public function add_meta_boxes() {
810
+ add_meta_box(
811
+ 'emp_event_details',
812
+ __('Event Details', 'event-manager-pro'),
813
+ array($this, 'render_event_details_meta_box'),
814
+ 'emp_event',
815
+ 'normal',
816
+ 'high'
817
+ );
818
+ }
819
+
820
+ /**
821
+ * Render event details meta box
822
+ */
823
+ public function render_event_details_meta_box($post) {
824
+ wp_nonce_field('emp_save_event_details', 'emp_event_details_nonce');
825
+
826
+ $start_date = get_post_meta($post->ID, '_emp_start_date', true);
827
+ $end_date = get_post_meta($post->ID, '_emp_end_date', true);
828
+ $location = get_post_meta($post->ID, '_emp_location', true);
829
+ $capacity = get_post_meta($post->ID, '_emp_capacity', true);
830
+
831
+ include EMP_PLUGIN_DIR . 'admin/partials/meta-box-event.php';
832
+ }
833
+
834
+ /**
835
+ * Save meta box data
836
+ */
837
+ public function save_meta_boxes($post_id) {
838
+ // Security checks
839
+ if (!isset($_POST['emp_event_details_nonce'])) {
840
+ return;
841
+ }
842
+
843
+ if (!wp_verify_nonce($_POST['emp_event_details_nonce'], 'emp_save_event_details')) {
844
+ return;
845
+ }
846
+
847
+ if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
848
+ return;
849
+ }
850
+
851
+ if (!current_user_can('edit_post', $post_id)) {
852
+ return;
853
+ }
854
+
855
+ // Save meta data
856
+ if (isset($_POST['emp_start_date'])) {
857
+ update_post_meta($post_id, '_emp_start_date', sanitize_text_field($_POST['emp_start_date']));
858
+ }
859
+
860
+ if (isset($_POST['emp_end_date'])) {
861
+ update_post_meta($post_id, '_emp_end_date', sanitize_text_field($_POST['emp_end_date']));
862
+ }
863
+
864
+ if (isset($_POST['emp_location'])) {
865
+ update_post_meta($post_id, '_emp_location', sanitize_text_field($_POST['emp_location']));
866
+ }
867
+
868
+ if (isset($_POST['emp_capacity'])) {
869
+ update_post_meta($post_id, '_emp_capacity', absint($_POST['emp_capacity']));
870
+ }
871
+ }
872
+ }
873
+ ```
874
+
875
+ ---
876
+
877
+ ## Public Classes
878
+
879
+ ### File: `public/class-public.php`
880
+
881
+ ```php
882
+ <?php
883
+ /**
884
+ * Public-facing functionality
885
+ *
886
+ * @package Event_Manager_Pro
887
+ */
888
+
889
+ class Event_Manager_Pro_Public {
890
+ private $plugin_name;
891
+ private $version;
892
+
893
+ public function __construct($plugin_name, $version) {
894
+ $this->plugin_name = $plugin_name;
895
+ $this->version = $version;
896
+ }
897
+
898
+ /**
899
+ * Register event custom post type
900
+ */
901
+ public function register_event_post_type() {
902
+ $labels = array(
903
+ 'name' => __('Events', 'event-manager-pro'),
904
+ 'singular_name' => __('Event', 'event-manager-pro'),
905
+ 'add_new' => __('Add New Event', 'event-manager-pro'),
906
+ 'add_new_item' => __('Add New Event', 'event-manager-pro'),
907
+ 'edit_item' => __('Edit Event', 'event-manager-pro'),
908
+ 'view_item' => __('View Event', 'event-manager-pro'),
909
+ 'search_items' => __('Search Events', 'event-manager-pro'),
910
+ );
911
+
912
+ $args = array(
913
+ 'labels' => $labels,
914
+ 'public' => true,
915
+ 'has_archive' => true,
916
+ 'menu_icon' => 'dashicons-calendar-alt',
917
+ 'supports' => array('title', 'editor', 'thumbnail', 'excerpt'),
918
+ 'rewrite' => array('slug' => 'events'),
919
+ 'show_in_rest' => true,
920
+ );
921
+
922
+ register_post_type('emp_event', $args);
923
+ }
924
+
925
+ /**
926
+ * Enqueue public styles
927
+ */
928
+ public function enqueue_styles() {
929
+ wp_enqueue_style(
930
+ $this->plugin_name,
931
+ EMP_PLUGIN_URL . 'public/css/public.css',
932
+ array(),
933
+ $this->version,
934
+ 'all'
935
+ );
936
+ }
937
+
938
+ /**
939
+ * Enqueue public scripts
940
+ */
941
+ public function enqueue_scripts() {
942
+ wp_enqueue_script(
943
+ $this->plugin_name,
944
+ EMP_PLUGIN_URL . 'public/js/public.js',
945
+ array('jquery'),
946
+ $this->version,
947
+ false
948
+ );
949
+ }
950
+ }
951
+ ```
952
+
953
+ ### File: `public/class-shortcodes.php`
954
+
955
+ ```php
956
+ <?php
957
+ /**
958
+ * Shortcode handlers
959
+ *
960
+ * @package Event_Manager_Pro
961
+ */
962
+
963
+ class Event_Manager_Pro_Public_Shortcodes {
964
+ private $plugin_name;
965
+ private $version;
966
+
967
+ public function __construct($plugin_name, $version) {
968
+ $this->plugin_name = $plugin_name;
969
+ $this->version = $version;
970
+ }
971
+
972
+ /**
973
+ * Register shortcodes
974
+ */
975
+ public function register_shortcodes() {
976
+ add_shortcode('event_list', array($this, 'event_list_shortcode'));
977
+ add_shortcode('event_single', array($this, 'event_single_shortcode'));
978
+ }
979
+
980
+ /**
981
+ * Event list shortcode
982
+ */
983
+ public function event_list_shortcode($atts) {
984
+ $atts = shortcode_atts(array(
985
+ 'limit' => 10,
986
+ 'order' => 'ASC',
987
+ ), $atts);
988
+
989
+ $args = array(
990
+ 'post_type' => 'emp_event',
991
+ 'posts_per_page' => intval($atts['limit']),
992
+ 'order' => $atts['order'],
993
+ 'meta_key' => '_emp_start_date',
994
+ 'orderby' => 'meta_value',
995
+ );
996
+
997
+ $query = new WP_Query($args);
998
+
999
+ ob_start();
1000
+ if ($query->have_posts()) {
1001
+ include EMP_PLUGIN_DIR . 'public/partials/event-list.php';
1002
+ }
1003
+ wp_reset_postdata();
1004
+
1005
+ return ob_get_clean();
1006
+ }
1007
+
1008
+ /**
1009
+ * Single event shortcode
1010
+ */
1011
+ public function event_single_shortcode($atts) {
1012
+ $atts = shortcode_atts(array(
1013
+ 'id' => 0,
1014
+ ), $atts);
1015
+
1016
+ $event = new Event_Manager_Pro_Event(intval($atts['id']));
1017
+
1018
+ ob_start();
1019
+ include EMP_PLUGIN_DIR . 'public/partials/event-single.php';
1020
+ return ob_get_clean();
1021
+ }
1022
+ }
1023
+ ```
1024
+
1025
+ ---
1026
+
1027
+ ## Key OOP Principles Demonstrated
1028
+
1029
+ ### 1. **Separation of Concerns**
1030
+
1031
+ ✅ **Admin logic** separated from **public logic**
1032
+ ✅ **Model** (Event) separated from **controllers** (Admin, Public)
1033
+ ✅ **Views** in partials directory
1034
+
1035
+ ### 2. **Single Responsibility Principle**
1036
+
1037
+ ✅ Each class has one clear purpose:
1038
+ - `Event_Manager_Pro` - Main orchestrator
1039
+ - `Event_Manager_Pro_Loader` - Hook management
1040
+ - `Event_Manager_Pro_Event` - Event data model
1041
+ - `Event_Manager_Pro_Admin` - Admin functionality
1042
+ - `Event_Manager_Pro_Public` - Public functionality
1043
+
1044
+ ### 3. **Dependency Injection**
1045
+
1046
+ ✅ Plugin name and version injected into classes:
1047
+ ```php
1048
+ $admin = new Event_Manager_Pro_Admin($this->plugin_name, $this->version);
1049
+ ```
1050
+
1051
+ ### 4. **Encapsulation**
1052
+
1053
+ ✅ Private/protected properties and methods
1054
+ ✅ Public getters/setters for controlled access
1055
+ ✅ Data validation in model methods
1056
+
1057
+ ### 5. **Hook Loader Pattern**
1058
+
1059
+ ✅ Centralized hook management
1060
+ ✅ Easy to track all hooks
1061
+ ✅ Testable hook registration
1062
+
1063
+ ---
1064
+
1065
+ ## Advantages of OOP Pattern
1066
+
1067
+ ### ✅ Maintainability
1068
+
1069
+ - **Clear structure**: Easy to find and modify code
1070
+ - **Separation of concerns**: Changes isolated to specific classes
1071
+ - **Consistent patterns**: Predictable code organization
1072
+
1073
+ ### ✅ Extensibility
1074
+
1075
+ - **Easy to extend**: Add new classes without modifying existing ones
1076
+ - **Inheritance**: Can extend base classes for variations
1077
+ - **Interfaces**: Can define contracts for implementations
1078
+
1079
+ ### ✅ Testability
1080
+
1081
+ - **Unit testing**: Each class can be tested independently
1082
+ - **Mocking**: Dependencies can be mocked for testing
1083
+ - **Dependency injection**: Easy to swap implementations
1084
+
1085
+ ### ✅ Collaboration
1086
+
1087
+ - **Multiple developers**: Can work on different classes simultaneously
1088
+ - **Code review**: Smaller, focused classes easier to review
1089
+ - **Documentation**: PHPDoc on classes and methods
1090
+
1091
+ ### ✅ Reusability
1092
+
1093
+ - **Model classes**: Can be reused across admin and public
1094
+ - **Utility classes**: Shared functionality in dedicated classes
1095
+ - **Composition**: Combine classes for complex functionality
1096
+
1097
+ ---
1098
+
1099
+ ## When to Use OOP Pattern
1100
+
1101
+ ### ✅ Good Use Cases
1102
+
1103
+ - **Complex plugins**: Multiple features and functionality
1104
+ - **Team development**: 2-5 developers working together
1105
+ - **Long-term maintenance**: Plugin will be maintained for years
1106
+ - **Extensibility needed**: Other developers will extend the plugin
1107
+ - **Professional plugins**: Commercial or enterprise plugins
1108
+ - **Testing required**: Unit and integration testing needed
1109
+
1110
+ ### ❌ Not Suitable For
1111
+
1112
+ - **Simple plugins**: Single feature, < 200 lines (use Pattern 1)
1113
+ - **Quick prototypes**: Temporary or experimental code
1114
+ - **Solo learning**: Beginners learning WordPress (start with Pattern 1)
1115
+ - **Micro-plugins**: Very specific, focused functionality
1116
+
1117
+ ---
1118
+
1119
+ ## Best Practices
1120
+
1121
+ ### 1. **Class Naming**
1122
+
1123
+ ```php
1124
+ // Good
1125
+ class Event_Manager_Pro_Admin { }
1126
+ class Event_Manager_Pro_Public_Shortcodes { }
1127
+
1128
+ // Bad
1129
+ class Admin { } // Too generic
1130
+ class EMP_A { } // Not descriptive
1131
+ ```
1132
+
1133
+ ### 2. **File Naming**
1134
+
1135
+ ```php
1136
+ // Good
1137
+ class-event-manager.php
1138
+ class-admin.php
1139
+ class-shortcodes.php
1140
+
1141
+ // Bad
1142
+ EventManager.php // Wrong case
1143
+ admin.php // Missing prefix
1144
+ ```
1145
+
1146
+ ### 3. **Autoloading**
1147
+
1148
+ ```php
1149
+ // Use PSR-4 style autoloader
1150
+ spl_autoload_register(function ($class) {
1151
+ $prefix = 'Event_Manager_Pro_';
1152
+ $base_dir = EMP_PLUGIN_DIR . 'includes/';
1153
+
1154
+ // Convert class name to file path
1155
+ $relative_class = substr($class, strlen($prefix));
1156
+ $file = $base_dir . 'class-' . str_replace('_', '-', strtolower($relative_class)) . '.php';
1157
+
1158
+ if (file_exists($file)) {
1159
+ require $file;
1160
+ }
1161
+ });
1162
+ ```
1163
+
1164
+ ### 4. **Dependency Injection**
1165
+
1166
+ ```php
1167
+ // Good - Dependencies injected
1168
+ public function __construct($plugin_name, $version, $database) {
1169
+ $this->plugin_name = $plugin_name;
1170
+ $this->version = $version;
1171
+ $this->database = $database;
1172
+ }
1173
+
1174
+ // Bad - Hard-coded dependencies
1175
+ public function __construct() {
1176
+ $this->database = new Database(); // Hard to test
1177
+ }
1178
+ ```
1179
+
1180
+ ### 5. **Hook Loader**
1181
+
1182
+ ```php
1183
+ // Good - Centralized hook management
1184
+ $this->loader->add_action('init', $public, 'register_post_type');
1185
+ $this->loader->add_filter('the_content', $public, 'filter_content');
1186
+
1187
+ // Bad - Direct hook registration in multiple places
1188
+ add_action('init', array($this, 'register_post_type'));
1189
+ ```
1190
+
1191
+ ### 6. **Model Classes**
1192
+
1193
+ ```php
1194
+ // Good - Model with methods
1195
+ $event = new Event_Manager_Pro_Event($event_id);
1196
+ $event->set('title', 'New Event');
1197
+ $event->save();
1198
+
1199
+ // Bad - Direct post meta manipulation
1200
+ update_post_meta($event_id, '_emp_title', 'New Event');
1201
+ ```
1202
+
1203
+ ### 7. **Security**
1204
+
1205
+ ```php
1206
+ // Always sanitize and validate
1207
+ public function save_meta_boxes($post_id) {
1208
+ // Nonce verification
1209
+ if (!wp_verify_nonce($_POST['nonce'], 'save_event')) {
1210
+ return;
1211
+ }
1212
+
1213
+ // Capability check
1214
+ if (!current_user_can('edit_post', $post_id)) {
1215
+ return;
1216
+ }
1217
+
1218
+ // Sanitize input
1219
+ $value = sanitize_text_field($_POST['value']);
1220
+ }
1221
+ ```
1222
+
1223
+ ---
1224
+
1225
+ ## Testing Example
1226
+
1227
+ ### Unit Test for Event Model
1228
+
1229
+ ```php
1230
+ <?php
1231
+ class Event_Test extends WP_UnitTestCase {
1232
+ public function test_event_creation() {
1233
+ $event = new Event_Manager_Pro_Event();
1234
+ $event->set('title', 'Test Event');
1235
+ $event->set('start_date', '2024-01-01');
1236
+
1237
+ $event_id = $event->save();
1238
+
1239
+ $this->assertGreaterThan(0, $event_id);
1240
+ $this->assertEquals('Test Event', get_the_title($event_id));
1241
+ }
1242
+
1243
+ public function test_event_capacity() {
1244
+ $event = new Event_Manager_Pro_Event();
1245
+ $event->set('capacity', 10);
1246
+ $event->save();
1247
+
1248
+ $this->assertEquals(10, $event->get_available_spots());
1249
+ $this->assertFalse($event->is_full());
1250
+ }
1251
+ }
1252
+ ```
1253
+
1254
+ ---
1255
+
1256
+ ## Comparison with Other Patterns
1257
+
1258
+ | Feature | Simple Procedural | OOP | WPPB |
1259
+ |---------|------------------|-----|------|
1260
+ | **Complexity** | Low | Medium-High | High |
1261
+ | **File Count** | 1-3 | 10-30 | 20-100 |
1262
+ | **Learning Curve** | Easy | Moderate | Steep |
1263
+ | **Maintainability** | Low | High | Very High |
1264
+ | **Testability** | Low | High | Very High |
1265
+ | **Team Size** | 1 | 2-5 | 3-10 |
1266
+ | **Best For** | Simple plugins | Complex plugins | Professional plugins |
1267
+
1268
+ ---
1269
+
1270
+ ## Migration Path
1271
+
1272
+ ### From Simple Procedural to OOP
1273
+
1274
+ 1. **Create main plugin class**
1275
+ 2. **Move functions to methods**
1276
+ 3. **Create loader class**
1277
+ 4. **Separate admin and public**
1278
+ 5. **Create model classes**
1279
+ 6. **Add autoloader**
1280
+
1281
+ ### Example Migration
1282
+
1283
+ **Before (Procedural):**
1284
+ ```php
1285
+ function emp_register_post_type() {
1286
+ register_post_type('emp_event', array(...));
1287
+ }
1288
+ add_action('init', 'emp_register_post_type');
1289
+ ```
1290
+
1291
+ **After (OOP):**
1292
+ ```php
1293
+ class Event_Manager_Pro_Public {
1294
+ public function register_event_post_type() {
1295
+ register_post_type('emp_event', array(...));
1296
+ }
1297
+ }
1298
+
1299
+ $public = new Event_Manager_Pro_Public($plugin_name, $version);
1300
+ $loader->add_action('init', $public, 'register_event_post_type');
1301
+ ```
1302
+
1303
+ ---
1304
+
1305
+ ## Related Patterns
1306
+
1307
+ - **Pattern 1**: [Simple Procedural Plugin](simple-procedural-plugin.md) - For simple plugins
1308
+ - **Pattern 2**: [Organized Procedural Plugin](organized-procedural-plugin.md) - Medium complexity
1309
+ - **Pattern 4**: [WPPB Plugin](wppb-plugin.md) - Professional standard
1310
+ - **Pattern 5**: [Namespace-Based Plugin](namespace-based-plugin.md) - Modern PHP
1311
+
1312
+ ---
1313
+
1314
+ ## Additional Resources
1315
+
1316
+ - [WordPress Plugin Handbook - OOP](https://developer.wordpress.org/plugins/plugin-basics/best-practices/#object-oriented-programming-method)
1317
+ - [SOLID Principles in WordPress](https://carlalexander.ca/designing-class-wordpress-hooks/)
1318
+ - [WordPress Plugin Boilerplate](https://wppb.me/)
1319
+ - [PHPUnit for WordPress](https://make.wordpress.org/core/handbook/testing/automated-testing/phpunit/)
1320
+
1321
+ ---
1322
+
1323
+ ## Summary
1324
+
1325
+ This OOP plugin example demonstrates:
1326
+
1327
+ ✅ **Complete working plugin** with event management functionality
1328
+ ✅ **Proper OOP architecture** with separation of concerns
1329
+ ✅ **Hook loader pattern** for centralized hook management
1330
+ ✅ **Model class** for data encapsulation
1331
+ ✅ **Admin and public separation** for clear organization
1332
+ ✅ **Activation/deactivation** handlers
1333
+ ✅ **Custom database tables** with proper creation
1334
+ ✅ **Meta boxes** with security (nonces, capability checks)
1335
+ ✅ **Shortcodes** with proper output buffering
1336
+ ✅ **Autoloading** for automatic class loading
1337
+ ✅ **Security best practices** throughout
1338
+ ✅ **Testable code** structure
1339
+
1340
+ **Perfect for**: Complex plugins, team development, long-term maintenance, professional/commercial plugins.
1341
+
1342
+ **Next steps**: For even more structure, consider Pattern 4 (WPPB) or Pattern 5 (Namespace-Based) for modern PHP with Composer.
1343
+