1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Main Cassava plugin file. |
4
|
|
|
* |
5
|
|
|
* @version 1.2.0 |
6
|
|
|
* @since 1.2.0 |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
namespace Cassava; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Main plugin class. |
13
|
|
|
* |
14
|
|
|
* @since 1.0.0 |
15
|
|
|
*/ |
16
|
|
|
class Plugin { |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Plugin version. |
20
|
|
|
*/ |
21
|
|
|
const VERSION = '1.2.3'; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* Plugin slug. |
25
|
|
|
*/ |
26
|
|
|
const SLUG = 'wp-cas-server'; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* Default endpoint slug. |
30
|
|
|
*/ |
31
|
|
|
const ENDPOINT_SLUG = 'wp-cas'; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Plugin file. |
35
|
|
|
*/ |
36
|
|
|
const FILE = 'wp-cas-server/wp-cas-server.php'; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* Query variable used to pass the requested CAS route. |
40
|
|
|
*/ |
41
|
|
|
const QUERY_VAR_ROUTE = 'cas_route'; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Transient prefix for ticket reuse validation. |
45
|
|
|
*/ |
46
|
|
|
const TRANSIENT_PREFIX = 'cas_'; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* CAS server instance. |
50
|
|
|
* @var \Cassava\CAS\Server |
51
|
|
|
*/ |
52
|
|
|
protected $server; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* CAS server plugin admin instance. |
56
|
|
|
* @var \Cassava\Admin |
57
|
|
|
*/ |
58
|
|
|
protected $admin; |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* WP CAS Server plugin constructor. |
62
|
|
|
* |
63
|
|
|
* @param CAS\Server $server CAS server instance. |
64
|
|
|
* |
65
|
|
|
* @uses is_admin() |
66
|
|
|
* @uses register_activation_hook() |
67
|
|
|
* @uses register_deactivation_hook() |
68
|
|
|
* @uses add_action() |
69
|
|
|
*/ |
70
|
|
|
public function __construct( CAS\Server $server ) { |
71
|
|
|
$this->server = $server; |
72
|
|
|
|
73
|
|
|
if ( is_admin() ) { |
74
|
|
|
$this->admin = new Admin(); |
75
|
|
|
} |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* Bootstrap plugin. |
80
|
|
|
*/ |
81
|
|
|
public function ready() { |
82
|
|
|
\register_activation_hook( __FILE__, array( $this, 'activation' ) ); |
83
|
|
|
\register_deactivation_hook( __FILE__, array( $this, 'deactivation' ) ); |
84
|
|
|
\add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) ); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* Plugin activation callback. |
89
|
|
|
* |
90
|
|
|
* @param bool $network_wide Plugin is activated for the entire network. |
91
|
|
|
* |
92
|
|
|
* @uses flush_rewrite_rules() |
93
|
|
|
*/ |
94
|
|
|
public function activation( $network_wide ) { |
95
|
|
|
$this->call( $network_wide, function () { |
96
|
|
|
$this->addRewriteRules(); |
97
|
|
|
\flush_rewrite_rules(); |
98
|
|
|
} ); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* Plugin deactivation callback to flush rewrite rules. |
103
|
|
|
* |
104
|
|
|
* @param bool $network_wide Plugin is activated for the entire network. |
105
|
|
|
* |
106
|
|
|
* @uses flush_rewrite_rules() |
107
|
|
|
* |
108
|
|
|
* @SuppressWarnings(CamelCaseParameterName) |
109
|
|
|
* @SuppressWarnings(CamelCaseVariableName) |
110
|
|
|
*/ |
111
|
|
|
public function deactivation( $network_wide ) { |
112
|
|
|
$this->call( $network_wide, function () { |
113
|
|
|
\flush_rewrite_rules(); |
114
|
|
|
} ); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* Executes a callback on every site on a multisite install. |
119
|
|
|
* |
120
|
|
|
* @param bool $network_wide Whether the callback should run network-wide. |
121
|
|
|
* @param Callable $callback Callback to run on every site. |
122
|
|
|
* @param array $arguments Optional callback argument list. |
123
|
|
|
* |
124
|
|
|
* @uses \is_multisite() |
125
|
|
|
* @uses \restore_current_blog() |
126
|
|
|
* @uses \switch_to_blog() |
127
|
|
|
* @uses \wp_get_sites() |
128
|
|
|
*/ |
129
|
|
|
private function call( $network_wide, $callback, $arguments = array() ) { |
130
|
|
|
if ( function_exists( 'is_multisite' ) && \is_multisite() && $network_wide ) { |
131
|
|
|
$sites = \wp_get_sites(); |
132
|
|
|
foreach ( $sites as $site ) { |
133
|
|
|
\switch_to_blog( $site['blog_id'] ); |
134
|
|
|
call_user_func_array( $callback, $arguments ); |
135
|
|
|
} |
136
|
|
|
\restore_current_blog(); |
137
|
|
|
return; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
call_user_func_array( $callback, $arguments ); |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* Plugin loading callback. |
145
|
|
|
* |
146
|
|
|
* @uses add_action() |
147
|
|
|
* @uses add_filter() |
148
|
|
|
* |
149
|
|
|
* @SuppressWarnings(CamelCaseMethodName) |
150
|
|
|
*/ |
151
|
|
|
public function plugins_loaded() { |
152
|
|
|
add_action( 'init' , array( $this, 'init' ) ); |
153
|
|
|
add_action( 'template_redirect' , array( $this, 'template_redirect' ), -100 ); |
154
|
|
|
add_filter( 'allowed_redirect_hosts', array( $this, 'allowed_redirect_hosts' ) ); |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* Plugin initialization callback. |
159
|
|
|
* |
160
|
|
|
* @global WP $wp |
161
|
|
|
* |
162
|
|
|
* @uses apply_filters() |
163
|
|
|
* @uses load_plugin_textdomain() |
164
|
|
|
* @uses load_textdomain() |
165
|
|
|
* @uses trailingslashit() |
166
|
|
|
*/ |
167
|
|
|
public function init() { |
168
|
|
|
global $wp; |
|
|
|
|
169
|
|
|
|
170
|
|
|
$domain = static::SLUG; |
171
|
|
|
$locale = \apply_filters( 'plugin_locale', \get_locale(), 'wp-cas-server' ); |
172
|
|
|
|
173
|
|
|
\load_textdomain( $domain, \trailingslashit( WP_LANG_DIR ) . $domain . '/' . $domain . '-' . $locale . '.mo' ); |
174
|
|
|
\load_plugin_textdomain( $domain, FALSE, basename( \plugin_dir_path( dirname( __FILE__ ) ) ) . '/languages/' ); |
175
|
|
|
|
176
|
|
|
if ( ! Options::getAll() ) { |
177
|
|
|
Options::setDefaults(); |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
$wp->add_query_var( static::QUERY_VAR_ROUTE ); |
181
|
|
|
$this->addRewriteRules(); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* Serve the CAS request and stop. |
186
|
|
|
* |
187
|
|
|
* @global WP $wp |
188
|
|
|
*/ |
189
|
|
|
public function template_redirect() { |
190
|
|
|
global $wp; |
|
|
|
|
191
|
|
|
|
192
|
|
|
// Abort unless processing a CAS request: |
193
|
|
|
if ( empty( $wp->query_vars[ static::QUERY_VAR_ROUTE ] ) ) { |
194
|
|
|
return; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
echo $this->server->handleRequest( $wp->query_vars[ static::QUERY_VAR_ROUTE ] ); |
198
|
|
|
|
199
|
|
|
exit; |
|
|
|
|
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* Callback to filter the hosts WordPress allows redirecting to. |
204
|
|
|
* |
205
|
|
|
* @param array $allowed List of valid redirection target hosts. |
206
|
|
|
* |
207
|
|
|
* @return array Filtered list of valid redirection target hosts. |
208
|
|
|
* |
209
|
|
|
* @SuppressWarnings(CamelCaseMethodName) |
210
|
|
|
*/ |
211
|
|
|
public function allowed_redirect_hosts( $allowed = array() ) { |
212
|
|
|
|
213
|
|
|
foreach ( (array) Options::get( 'allowed_services' ) as $uri ) { |
214
|
|
|
// `allowed_redirect_hosts` returns a list of **hosts**, not URIs: |
215
|
|
|
$host = parse_url( $uri, PHP_URL_HOST ); |
216
|
|
|
|
217
|
|
|
if ( ! empty( $host ) ) { |
218
|
|
|
$allowed[] = $host; |
219
|
|
|
} |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
return $allowed; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* Register new rewrite rules for the CAS server URIs. |
227
|
|
|
* |
228
|
|
|
* @uses \add_rewrite_endpoint() |
229
|
|
|
* |
230
|
|
|
* @SuppressWarnings(CamelCaseMethodName) |
231
|
|
|
*/ |
232
|
|
|
private function addRewriteRules() { |
233
|
|
|
$path = Options::get( 'endpoint_slug' ); |
234
|
|
|
|
235
|
|
|
if ( empty( $path ) ) { |
236
|
|
|
$path = static::ENDPOINT_SLUG; |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
\add_rewrite_endpoint( $path, EP_ROOT, static::QUERY_VAR_ROUTE ); |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
} |
243
|
|
|
|
Instead of relying on
global
state, we recommend one of these alternatives:1. Pass all data via parameters
2. Create a class that maintains your state