| @@ -18,8 +18,9 @@ | ||
| 18 | 18 | |
| 19 | 19 | namespace ThinkRank\API; |
| 20 | 20 | |
| 21 | 21 | use ThinkRank\API\Traits\CSRF_Protection; |
| 22 | +use ThinkRank\Core\Capability_Manager; | |
| 22 | 23 | use ThinkRank\SEO\Email_Report_Manager; |
| 23 | 24 | use WP_REST_Controller; |
| 24 | 25 | use WP_REST_Request; |
| 25 | 26 | use WP_REST_Response; |
| @@ -83,10 +84,13 @@ | ||
| 83 | 84 | |
| 84 | 85 | /** |
| 85 | 86 | * GET /email-report/config |
| 86 | 87 | * |
| 87 | - * Returns the resolved config (on/off, frequency, recipients, sections) | |
| 88 | - * along with the section catalog and the next scheduled run. | |
| 88 | + * Returns the resolved config (on/off, frequency, recipients, sections, | |
| 89 | + * last skip reason) along with the section catalog, the next scheduled | |
| 90 | + * run and the readiness of the data sources — whether Search Console is | |
| 91 | + * connected, so the panel can say a report is paused rather than let it | |
| 92 | + * look healthy (#742). | |
| 89 | 93 | */ |
| 90 | 94 | public function get_config(WP_REST_Request $request): WP_REST_Response { |
| 91 | 95 | $manager = $this->resolve_manager(); |
| 92 | 96 | if ($manager === null) { |
| @@ -95,11 +99,12 @@ | ||
| 95 | 99 | ], 500); |
| 96 | 100 | } |
| 97 | 101 | |
| 98 | 102 | return new WP_REST_Response([ |
| 99 | - 'config' => $manager->config()->get(), | |
| 100 | - 'sections' => $manager->registry()->describe_for_ui(), | |
| 101 | - 'next_run' => $manager->scheduler()->next_run_iso(), | |
| 103 | + 'config' => $manager->config()->get(), | |
| 104 | + 'sections' => $manager->registry()->describe_for_ui(), | |
| 105 | + 'next_run' => $manager->scheduler()->next_run_iso(), | |
| 106 | + 'readiness' => $manager->data_provider()->readiness(), | |
| 102 | 107 | ]); |
| 103 | 108 | } |
| 104 | 109 | |
| 105 | 110 | /** |
| @@ -121,11 +126,12 @@ | ||
| 121 | 126 | |
| 122 | 127 | $saved = $manager->config()->save($input); |
| 123 | 128 | |
| 124 | 129 | return new WP_REST_Response([ |
| 125 | - 'success' => true, | |
| 126 | - 'config' => $saved, | |
| 127 | - 'next_run' => $manager->scheduler()->next_run_iso(), | |
| 130 | + 'success' => true, | |
| 131 | + 'config' => $saved, | |
| 132 | + 'next_run' => $manager->scheduler()->next_run_iso(), | |
| 133 | + 'readiness' => $manager->data_provider()->readiness(), | |
| 128 | 134 | ]); |
| 129 | 135 | } |
| 130 | 136 | |
| 131 | 137 | /** |
| @@ -143,10 +149,13 @@ | ||
| 143 | 149 | $result = $manager->generator()->generate_test(); |
| 144 | 150 | |
| 145 | 151 | $status = !empty($result['success']) ? 200 : 400; |
| 146 | 152 | return new WP_REST_Response([ |
| 147 | - 'success' => (bool) ($result['success'] ?? false), | |
| 148 | - 'result' => $result, | |
| 153 | + 'success' => (bool) ($result['success'] ?? false), | |
| 154 | + // True when the test went out as the "connect Search Console" | |
| 155 | + // email rather than a report, so the panel can say so. | |
| 156 | + 'not_connected' => !empty($result['not_connected']), | |
| 157 | + 'result' => $result, | |
| 149 | 158 | ], $status); |
| 150 | 159 | } |
| 151 | 160 | |
| 152 | 161 | /** |
| @@ -156,9 +165,11 @@ | ||
| 156 | 165 | public function check_admin_read_permissions(WP_REST_Request $request) { |
| 157 | 166 | if (!is_user_logged_in()) { |
| 158 | 167 | return new WP_Error('rest_forbidden', __('Not logged in.', 'thinkrank'), ['status' => 401]); |
| 159 | 168 | } |
| 160 | - if (!current_user_can('manage_options')) { | |
| 169 | + // route_map() maps the email-report prefix to thinkrank_analytics, | |
| 170 | + // which is what an Analytics grant in the Role Manager gives (#844). | |
| 171 | + if (!Capability_Manager::current_user_can('thinkrank_analytics')) { | |
| 161 | 172 | return new WP_Error('rest_forbidden', __('Insufficient permissions.', 'thinkrank'), ['status' => 403]); |
| 162 | 173 | } |
| 163 | 174 | return true; |
| 164 | 175 | } |
| @@ -175,9 +186,11 @@ | ||
| 175 | 186 | public function check_admin_csrf_permissions(WP_REST_Request $request) { |
| 176 | 187 | if (!is_user_logged_in()) { |
| 177 | 188 | return new WP_Error('rest_forbidden', __('Not logged in.', 'thinkrank'), ['status' => 401]); |
| 178 | 189 | } |
| 179 | - if (!current_user_can('manage_options')) { | |
| 190 | + // route_map() maps the email-report prefix to thinkrank_analytics, | |
| 191 | + // which is what an Analytics grant in the Role Manager gives (#844). | |
| 192 | + if (!Capability_Manager::current_user_can('thinkrank_analytics')) { | |
| 180 | 193 | return new WP_Error('rest_forbidden', __('Insufficient permissions.', 'thinkrank'), ['status' => 403]); |
| 181 | 194 | } |
| 182 | 195 | if (!$this->verify_request_nonce($request)) { |
| 183 | 196 | return new WP_Error('rest_forbidden', __('Invalid security token. Please refresh the page and try again.', 'thinkrank'), ['status' => 403]); |