-
Notifications
You must be signed in to change notification settings - Fork 2
/
wordpress-angular-plugin.php
153 lines (122 loc) · 4.08 KB
/
wordpress-angular-plugin.php
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<?php
/**
* Plugin Name: WordPress Angular Plugin Demo
* Plugin URI: https://github.com/Kevinlearynet/wordpress-angular-plugin
* Description: Demo of an Angular.js app setup inside of a WordPress plugin.
* Author: Kevin Leary
* Version: 0.0.1
* Author URI: http://www.kevinleary.net
*/
class ngApp
{
public $plugin_dir;
public $plugin_url;
public $base_href;
public $api_route;
public $versions;
/**
* Setup plugin
*/
public function __construct() {
// General
$this->plugin_dir = plugin_dir_path( __FILE__ );
$this->plugin_url = plugins_url( '/', __FILE__ );
$this->versions = array();
// Routing
$this->api_route = '^api/weather/(.*)/?'; // Matches /api/weather/{position}
$this->base_href = '/' . basename( dirname( __FILE__ ) ) . '/'; // Matches /wordpress-angular-plugin/
add_filter( 'do_parse_request', array( $this, 'intercept_wp_router' ), 1, 3 );
add_filter( 'rewrite_rules_array', array( $this, 'rewrite_rules' ) );
add_filter( 'query_vars', array( $this, 'query_vars' ) );
add_action( 'wp_loaded', array( $this, 'flush_rewrites' ) );
add_action( 'parse_request', array( $this, 'weather_api' ), 1, 3 );
}
/**
* API Route Handler
*/
public function weather_api( $wp ) {
// Weather API
if ( $wp->matched_rule !== $this->api_route )
return;
// Validate params
if ( empty( $wp->query_vars['api_position'] ) ) {
return wp_send_json_error( 'Missing required position parameters.' );
}
// Lookup weather forecast
$position = esc_attr( $wp->query_vars['api_position'] );
$coords = explode( ':', $position );
$lat = round( floatval( $coords[0] ), 4 );
$long = round( floatval( $coords[1] ), 4 );
$url = "https://api.weather.gov/points/$lat,$long/forecast";
$response = wp_remote_get( $url );
$status = wp_remote_retrieve_response_code( $response );
$body = wp_remote_retrieve_body( $response );
$body = json_decode( $body, true );
// Errors
if ( $status !== 200 )
wp_send_json_error( $body );
// Cache control headers, these will cache the
// users local weather forecast in the browser
// for 1 day to reduce API requests.
$ttl = DAY_IN_SECONDS;
header( "Cache-Control: public, max-age=$ttl" );
header( "Last-Modified: $last_modified" );
// Success response
wp_send_json_success( $body );
}
// flush_rules() if our rules are not yet included
public function flush_rewrites() {
$rules = get_option( 'rewrite_rules' );
if ( ! isset( $rules[ $this->api_route ] ) ) {
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
}
// Add rule for /api/weather/{position}
public function rewrite_rules( $rules ) {
$rules[ $this->api_route ] = 'index.php?api_position=$matches[1]';
return $rules;
}
// Adding the id var so that WP recognizes it
public function query_vars( $vars ) {
array_push( $vars, 'api_position' );
return $vars;
}
/**
* Auto-version Assets
*/
public function auto_version_file( $path_to_file ) {
$file = $this->plugin_dir . $path_to_file;
if ( ! file_exists( $file ) ) return false;
$mtime = filemtime( $file );
$url = $this->plugin_url . $path_to_file . '?v=' . $mtime;
// Store for Last-Modified headers
array_push( $this->versions, $mtime );
return $url;
}
/**
* Intercept WP Router
*
* Intercept WordPress rewrites and serve a
* static HTML page for our angular.js app.
*/
public function intercept_wp_router( $continue, WP $wp, $extra_query_vars ) {
// Conditions for url path
$url_match = ( substr( $_SERVER['REQUEST_URI'], 0, strlen( $this->base_href ) ) === $this->base_href );
if ( ! $url_match )
return $continue;
// Vars for index view
$main_js = $this->auto_version_file( 'dist/js/main.js' );
$main_css = $this->auto_version_file( 'dist/css/main.css' );
$plugin_url = $this->plugin_url;
$base_href = $this->base_href;
$page_title = 'WordPress Angular.js Plugin Demo App | kevinleary.net';
// Browser caching for our main template
$ttl = DAY_IN_SECONDS;
header( "Cache-Control: public, max-age=$ttl" );
// Load index view
include_once( $this->plugin_dir . 'views/index.php' );
exit;
}
} // class ngApp
new ngApp();