| 1 |
# WordPress Plugin Structure |
| 2 |
|
| 3 |
CartFlows follows WordPress coding conventions with PSR-4 PHP namespacing in its admin layer and strict coding standards enforced by PHPCS. |
| 4 |
|
| 5 |
## File Naming Conventions |
| 6 |
|
| 7 |
| Type | Pattern | Example | |
| 8 |
|------|---------|---------| |
| 9 |
| Class files | `class-cartflows-{name}.php` | `class-cartflows-loader.php` | |
| 10 |
| Include files | `{name}.php` | `admin-loader.php` | |
| 11 |
| Template files | `{name}.php` | `checkout-form.php` | |
| 12 |
| Interface files | `class-cartflows-{name}-interface.php` | `class-cartflows-logger-interface.php` | |
| 13 |
|
| 14 |
## Prefixes |
| 15 |
|
| 16 |
All CartFlows identifiers use consistent prefixes to avoid conflicts with other plugins: |
| 17 |
|
| 18 |
| Identifier type | Prefix | Example | |
| 19 |
|-----------------|--------|---------| |
| 20 |
| Hook names (actions/filters) | `cartflows_` | `cartflows_before_checkout_form` | |
| 21 |
| Option names | `cartflows_` | `cartflows_global_settings` | |
| 22 |
| Post meta keys | `wcf-` | `wcf-checkout-layout` | |
| 23 |
| AJAX actions | `cartflows_` | `wp_ajax_cartflows_flows` | |
| 24 |
| CSS classes | `wcf-` | `wcf-checkout-wrap` | |
| 25 |
| JS global objects | `wcf` / `cartflows` | `wcfEditorAppData` | |
| 26 |
|
| 27 |
## Capabilities |
| 28 |
|
| 29 |
Admin operations require the `manage_options` capability. This is the standard WordPress administrator capability used for all CartFlows settings and flow management operations. |
| 30 |
|
| 31 |
```php |
| 32 |
// Example permission check pattern used in REST API controllers |
| 33 |
'permission_callback' => function() { |
| 34 |
return current_user_can( 'manage_options' ); |
| 35 |
}, |
| 36 |
``` |
| 37 |
|
| 38 |
## PHP Namespaces |
| 39 |
|
| 40 |
The admin layer uses PSR-4 namespacing: |
| 41 |
|
| 42 |
``` |
| 43 |
CartflowsAdmin\AdminCore\Api → admin-core/api/ |
| 44 |
CartflowsAdmin\AdminCore\Ajax → admin-core/ajax/ |
| 45 |
``` |
| 46 |
|
| 47 |
Core plugin classes (`classes/`) follow WordPress global class naming conventions without namespaces. |
| 48 |
|
| 49 |
## Singleton Pattern |
| 50 |
|
| 51 |
The main bootstrap class uses the singleton pattern: |
| 52 |
|
| 53 |
```php |
| 54 |
// In class-cartflows-loader.php |
| 55 |
public static function get_instance() { |
| 56 |
if ( ! isset( self::$instance ) ) { |
| 57 |
self::$instance = new self(); |
| 58 |
} |
| 59 |
return self::$instance; |
| 60 |
} |
| 61 |
``` |
| 62 |
|
| 63 |
Called from `cartflows.php`: |
| 64 |
```php |
| 65 |
Cartflows_Loader::get_instance(); |
| 66 |
``` |
| 67 |
|
| 68 |
## Custom Post Types |
| 69 |
|
| 70 |
CartFlows registers two custom post types: |
| 71 |
|
| 72 |
| CPT Slug | Label | Purpose | |
| 73 |
|----------|-------|---------| |
| 74 |
| `wcf-flow` | Flow / Funnel | A complete sales funnel (container) | |
| 75 |
| `wcf-step` | Step | An individual page within a funnel | |
| 76 |
|
| 77 |
Steps are linked to flows via post meta. The flow editor (React) renders a visual canvas showing all steps in a flow. |
| 78 |
|
| 79 |
## WordPress Hooks Integration |
| 80 |
|
| 81 |
CartFlows hooks into WordPress and WooCommerce at several points: |
| 82 |
|
| 83 |
- **`plugins_loaded`** — Main plugin bootstrap |
| 84 |
- **`init`** — CPT registration, shortcodes |
| 85 |
- **`wp_enqueue_scripts`** — Frontend assets |
| 86 |
- **`admin_enqueue_scripts`** — Admin React app assets |
| 87 |
- **`woocommerce_checkout_*`** — Checkout customisations |
| 88 |
- **`rest_api_init`** — REST endpoint registration |
| 89 |
|
| 90 |
## Security Conventions |
| 91 |
|
| 92 |
Every user-facing operation follows the WordPress security trifecta: |
| 93 |
|
| 94 |
1. **Nonce verification** — All AJAX handlers verify nonces via `AjaxBase` |
| 95 |
2. **Capability checks** — `current_user_can( 'manage_options' )` before mutations |
| 96 |
3. **Input sanitisation** — `sanitize_text_field()`, `wc_clean()`, `absint()` |
| 97 |
4. **Output escaping** — `esc_html()`, `esc_attr()`, `esc_url()`, `wp_kses_post()` |
| 98 |
|
| 99 |
Note: `wc_clean()` is registered as a custom sanitizer in `phpcs.xml.dist` so PHPCS recognises it. |
| 100 |
|
| 101 |
## Template Override System |
| 102 |
|
| 103 |
WooCommerce templates are overridden by placing files in `woocommerce/`: |
| 104 |
|
| 105 |
``` |
| 106 |
woocommerce/ |
| 107 |
├── checkout/ |
| 108 |
│ ├── form-checkout.php |
| 109 |
│ └── review-order.php |
| 110 |
└── ... |
| 111 |
``` |
| 112 |
|
| 113 |
This follows standard WooCommerce template override conventions. |
| 114 |
|
| 115 |
## WordPress Options Storage |
| 116 |
|
| 117 |
Plugin-wide settings are stored in `wp_options`: |
| 118 |
|
| 119 |
| Option | Purpose | |
| 120 |
|--------|---------| |
| 121 |
| `cartflows_global_settings` | Global plugin configuration | |
| 122 |
| `cartflows_version` | Installed plugin version (used for upgrade routines) | |
| 123 |
|
| 124 |
## Autoloading |
| 125 |
|
| 126 |
PHP classes in `admin-core/` are autoloaded via Composer's PSR-4 autoloader configured in `composer.json`. Core classes in `classes/` are manually required by the loader. |
| 127 |
|
| 128 |
## Related Pages |
| 129 |
|
| 130 |
- [](Architecture-OverviewArchitecture-Overview](Architecture-Overview](Architecture-Overview) |
| 131 |
- [](REST-API-ReferenceREST-API-Reference](REST-API-Reference](REST-API-Reference) |
| 132 |
- [](AJAX-API-ReferenceAJAX-API-Reference](AJAX-API-Reference](AJAX-API-Reference) |
| 133 |
- [](Database-SchemaDatabase-Schema](Database-Schema](Database-Schema) |
| 134 |
- [](WordPress-Coding-StandardsWordPress-Coding-Standards](WordPress-Coding-Standards](WordPress-Coding-Standards) |
| 135 |
|