PluginProbe
Extendify / 3.1.6
Extendify v3.1.6
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / app / Shared / Services / PluginsActivation / Metricool.php

Metricool.php in Extendify 3.1.6, at app/Shared/Services/PluginsActivation/Metricool.php

94 lines 3.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Extendify\Shared\Services\PluginsActivation;
4
5 defined('ABSPATH') || die('No direct access.');
6
7 class Metricool extends PluginActivation
8 {
9 public static function slug(): string
10 {
11 return 'metricool';
12 }
13
14 public static function createAccountRoute(): string
15 {
16 // Metricool registers its logout route only when the request URL contains "/metricool/v".
17 return '/' . static::slug() . '/v1/create-account';
18 }
19
20 public static function scriptData(): array
21 {
22 return [
23 'recaptchaSiteKey' => static::recaptchaSiteKey(),
24 'recaptchaAction' => 'signup',
25 ];
26 }
27
28 // Metricool assesses the captcha itself, so a token minted with any other site key fails.
29 protected static function recaptchaSiteKey(): string
30 {
31 $config = WP_PLUGIN_DIR . '/' . static::slug() . '/config/env.php';
32 $env = is_readable($config) ? require $config : [];
33 $key = $env['metricool']['google_recaptcha_key'] ?? '';
34
35 return is_string($key) ? $key : '';
36 }
37
38 public static function createAccount(\WP_REST_Request $request): \WP_REST_Response
39 {
40 if (!static::isActive()) {
41 return static::pluginNotActiveResponse();
42 }
43
44 $create = static::dispatch('onboarding/create_account', [
45 'email' => \sanitize_email($request->get_param('email')),
46 'terms' => (bool) $request->get_param('termsAgreed'),
47 'marketing' => (bool) $request->get_param('marketingConsent'),
48 'captcha' => \sanitize_text_field($request->get_param('captcha_token')),
49 'password' => static::generatePassword(),
50 ]);
51 if ($create->is_error()) {
52 // Metricool 500 = account created but a later step failed; not retryable.
53 if ($create->get_status() >= 500) {
54 static::dispatch('logout');
55 }
56 return $create;
57 }
58
59 $finish = static::dispatch('onboarding/finish_onboarding');
60 $completed = $finish->get_data()['data']['onboarding']['state']['completed'] ?? false;
61 if ($finish->is_error() || !$completed) {
62 static::dispatch('logout');
63 return $finish->is_error() ? $finish : new \WP_REST_Response([
64 'code' => 'metricool_onboarding_incomplete',
65 'message' => \__('Metricool onboarding did not complete.', 'extendify-local'),
66 ], 500);
67 }
68
69 return new \WP_REST_Response(['success' => true], 200);
70 }
71
72 protected static function generatePassword(): string
73 {
74 // wp_generate_password() draws uniformly — a class Metricool requires can be missing.
75 do {
76 $password = \wp_generate_password(20, true);
77 } while (!preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^a-zA-Z\d]).{8,20}$/', $password));
78
79 return $password;
80 }
81
82 protected static function dispatch(string $route, array $body = []): \WP_REST_Response
83 {
84 $request = new \WP_REST_Request('POST', '/metricool/v1/' . $route);
85 $request->set_header('Content-Type', 'application/json');
86 $request->set_body(\wp_json_encode(array_merge(
87 $body,
88 ['nonce' => \wp_create_nonce('metricool_nonce')]
89 )));
90
91 return \rest_do_request($request);
92 }
93 }
94