Repository navigation
Expand file tree
/
Copy pathpl-example.php
More file actions
111 lines (100 loc) · 3.54 KB
/
Copy pathpl-example.php
File metadata and controls
111 lines (100 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<?php
/**
* Plugin Name: Example Plugin
* Plugin URI: https://example.com/pl-example
* Description: An example WordPress plugin scaffolded with wp-agentic-kit. Replace this sentence with what your plugin actually does.
* Version: 0.1.0
* Requires at least: 6.7
* Requires PHP: 8.2
* Author: Example Author
* License: MIT
* License URI: https://opensource.org/licenses/MIT
* Text Domain: pl-example
* Domain Path: /languages
*
* @package PLExample
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
define( 'PL_EXAMPLE_VERSION', '0.1.0' );
define( 'PL_EXAMPLE_FILE', __FILE__ );
define( 'PL_EXAMPLE_PATH', plugin_dir_path( __FILE__ ) );
define( 'PL_EXAMPLE_URL', plugin_dir_url( __FILE__ ) );
/*
* Composer's autoloader covers third-party packages only — the plugin's own
* classes are resolved below, without it. Guarded because `vendor/` is
* gitignored: a git-based deploy installs the repo as cloned, and an
* unconditional require fatals on activation before anything else runs.
*
* If you add a package to `require` (not `require-dev`), make
* `composer install --no-dev` part of your deploy lane. This guard keeps the
* plugin from fataling; it can't conjure a dependency that isn't there.
*/
if ( is_readable( PL_EXAMPLE_PATH . 'vendor/autoload.php' ) ) {
require_once PL_EXAMPLE_PATH . 'vendor/autoload.php';
}
/**
* Autoload the plugin's own classes from includes/ using WordPress-style
* filenames (PLExample\Api\Rest_Hello => includes/api/class-rest-hello.php).
*
* This is the only autoloader for the plugin's own classes. `composer.json`
* deliberately declares no `autoload` section: a classmap covering the same
* files would register first and mask any bug in this resolver until someone
* added a class and forgot to re-dump. One loader, always exercised. It also
* finds new files the moment you add them — no `composer dump-autoload` step.
*
* @param string $fqcn Fully-qualified class name being loaded.
*/
spl_autoload_register(
static function ( string $fqcn ): void {
$prefix = 'PLExample\\';
if ( 0 !== strncmp( $fqcn, $prefix, strlen( $prefix ) ) ) {
return;
}
$parts = explode( '\\', substr( $fqcn, strlen( $prefix ) ) );
$class_name = array_pop( $parts );
$subdir = $parts ? strtolower( implode( '/', $parts ) ) . '/' : '';
$file = PL_EXAMPLE_PATH . 'includes/' . $subdir . 'class-' . strtolower( str_replace( '_', '-', $class_name ) ) . '.php';
if ( is_readable( $file ) ) {
require_once $file;
}
}
);
/**
* Bootstrap. Single instance, hooks wired here and nowhere else.
*/
final class PL_Example_Plugin {
/**
* The single shared instance.
*
* @var self|null
*/
private static ?self $instance = null;
/**
* Return the shared instance, creating it on first call.
*
* @return self
*/
public static function get_instance(): self {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Wire the plugin's hooks. The only place hooks are registered.
*/
private function __construct() {
add_action( 'init', array( $this, 'load_textdomain' ) );
( new PLExample\Api\Rest() )->register();
}
/**
* Load the plugin text domain for translations.
*/
public function load_textdomain(): void {
load_plugin_textdomain( 'pl-example', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
}
}
register_activation_hook( __FILE__, array( 'PL_Example_Plugin', 'get_instance' ) );
add_action( 'plugins_loaded', array( 'PL_Example_Plugin', 'get_instance' ) );