PluginProbe
Packeta / 1.5.0
Packeta v1.5.0
2.3.2 2.3.1 trunk 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3.0 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 All 56 releases
packeta / src / Packetery / Module / Options / FeatureFlagManager.php

FeatureFlagManager.php in Packeta 1.5.0, at src/Packetery/Module/Options/FeatureFlagManager.php

224 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class FeatureFlagManager
4 *
5 * @package Packetery
6 */
7
8 declare( strict_types=1 );
9
10 namespace Packetery\Module\Options;
11
12 use DateTimeImmutable;
13 use Exception;
14 use Packetery\Core\Helper;
15 use Packetery\Module\Exception\DownloadException;
16 use Packetery\Module\Plugin;
17 use PacketeryGuzzleHttp\Client;
18 use PacketeryGuzzleHttp\Exception\GuzzleException;
19 use PacketeryGuzzleHttp\PacketeryPsr7\Response;
20 use PacketeryLatte\Engine;
21
22 /**
23 * Class FeatureFlagManager
24 *
25 * @package Packetery
26 */
27 class FeatureFlagManager {
28
29 private const ENDPOINT_URL = 'https://pes-features-prod-pes.prod.packeta-com.codenow.com/v1/wp';
30 private const VALID_FOR_HOURS = 4;
31 private const FLAGS_OPTION_ID = 'packeta_feature_flags';
32 private const FLAGS_LAST_DOWNLOAD = 'lastDownload';
33 private const TRANSIENT_SHOW_SPLIT_MESSAGE = 'packeta_show_split_message';
34 public const ACTION_HIDE_SPLIT_MESSAGE = 'dismiss_split_message';
35
36 private const FLAG_SPLIT_ACTIVE = 'splitActive';
37
38 /**
39 * Guzzle client.
40 *
41 * @var Client Guzzle client.
42 */
43 private $client;
44
45 /**
46 * Latte engine.
47 *
48 * @var Engine
49 */
50 private $latteEngine;
51
52 /**
53 * Options provider.
54 *
55 * @var Provider
56 */
57 private $optionsProvider;
58
59 /**
60 * Downloader constructor.
61 *
62 * @param Client $guzzleClient Guzzle client.
63 * @param Engine $latteEngine Latte engine.
64 * @param Provider $optionsProvider Options provider.
65 */
66 public function __construct( Client $guzzleClient, Engine $latteEngine, Provider $optionsProvider ) {
67 $this->client = $guzzleClient;
68 $this->latteEngine = $latteEngine;
69 $this->optionsProvider = $optionsProvider;
70 }
71
72 /**
73 * Downloads flags.
74 *
75 * @return array
76 * @throws DownloadException Download exception.
77 * @throws Exception From DateTimeImmutable.
78 */
79 private function fetchFlags(): array {
80 /**
81 * Guzzle response.
82 *
83 * @var Response $response Guzzle response.
84 */
85 try {
86 $response = $this->client->get(
87 self::ENDPOINT_URL,
88 [
89 'query' => [
90 'api_key' => $this->optionsProvider->get_api_key(),
91 ],
92 ]
93 );
94 } catch ( GuzzleException $exception ) {
95 throw new DownloadException( $exception->getMessage() );
96 }
97 $responseJson = $response->getBody()->getContents();
98 $responseDecoded = json_decode( $responseJson, true );
99
100 $flags = [
101 self::FLAG_SPLIT_ACTIVE => (bool) $responseDecoded['features']['split'],
102 ];
103
104 $lastDownload = new DateTimeImmutable( 'now', new \DateTimeZone( 'UTC' ) );
105 $flags[ self::FLAGS_LAST_DOWNLOAD ] = $lastDownload->format( Helper::MYSQL_DATETIME_FORMAT );
106 update_option( self::FLAGS_OPTION_ID, $flags );
107
108 return $flags;
109 }
110
111 /**
112 * Gets or downloads flags.
113 *
114 * @return array
115 * @throws DownloadException Download exception.
116 * @throws Exception From DateTimeImmutable.
117 */
118 private function getFlags(): array {
119 static $flags;
120
121 if ( ! isset( $flags ) ) {
122 $flags = get_option( self::FLAGS_OPTION_ID );
123 }
124
125 $hasApiKey = ( null !== $this->optionsProvider->get_api_key() );
126 if ( false === $flags ) {
127 if ( ! $hasApiKey ) {
128 $flags = [];
129
130 return $flags;
131 }
132
133 $flags = $this->fetchFlags();
134
135 return $flags;
136 }
137
138 if ( $hasApiKey ) {
139 $now = new DateTimeImmutable( 'now', new \DateTimeZone( 'UTC' ) );
140 $lastUpdate = DateTimeImmutable::createFromFormat(
141 Helper::MYSQL_DATETIME_FORMAT,
142 $flags[ self::FLAGS_LAST_DOWNLOAD ],
143 new \DateTimeZone( 'UTC' )
144 );
145 $ageHours = ( ( $now->getTimestamp() - $lastUpdate->getTimestamp() ) / HOUR_IN_SECONDS );
146 if ( $ageHours >= self::VALID_FOR_HOURS ) {
147 $oldFlags = $flags;
148 $flags = $this->fetchFlags();
149 }
150
151 if (
152 isset( $oldFlags ) &&
153 false === $oldFlags[ self::FLAG_SPLIT_ACTIVE ] &&
154 true === $flags[ self::FLAG_SPLIT_ACTIVE ]
155 ) {
156 set_transient( self::TRANSIENT_SHOW_SPLIT_MESSAGE, 'yes' );
157 }
158 }
159
160 return $flags;
161 }
162
163 /**
164 * Tells if split is active.
165 *
166 * @return bool
167 * @throws DownloadException Download exception.
168 */
169 public function isSplitActive(): bool {
170 $flags = $this->getFlags();
171 if ( isset( $flags[ self::FLAG_SPLIT_ACTIVE ] ) ) {
172 return (bool) $flags[ self::FLAG_SPLIT_ACTIVE ];
173 }
174
175 return false;
176 }
177
178 /**
179 * Dismiss split notice.
180 *
181 * @return void
182 */
183 public function dismissSplitActivationNotice(): void {
184 delete_transient( self::TRANSIENT_SHOW_SPLIT_MESSAGE );
185 }
186
187 /**
188 * Determines whether to display split notice.
189 *
190 * @return bool
191 */
192 public function hasSplitActivationNotice(): bool {
193 return ( 'yes' === get_transient( self::TRANSIENT_SHOW_SPLIT_MESSAGE ) );
194 }
195
196 /**
197 * Print split activation notice.
198 *
199 * @return void
200 */
201 public function renderSplitActivationNotice(): void {
202 $dismissUrl = add_query_arg( [ Plugin::PARAM_PACKETERY_ACTION => self::ACTION_HIDE_SPLIT_MESSAGE ] );
203 $this->latteEngine->render(
204 PACKETERY_PLUGIN_DIR . '/template/admin-notice.latte',
205 [
206 'message' => [
207 'type' => 'warning',
208 'escape' => false,
209 'message' => sprintf(
210 // translators: 1: documentation link start 2: link end 3: dismiss link start 4: link end.
211 __(
212 'We have just enabled new options for setting Packeta pickup points. You can now choose a different price for Z-Box and pickup points in the carrier settings. More information can be found in %1$sthe plugin documentation%2$s. %3$sDismiss this message%4$s',
213 'packeta'
214 ),
215 ...Plugin::createLinkParts( 'https://github.com/Zasilkovna/WooCommerce/wiki', '_blank' ),
216 ...Plugin::createLinkParts( $dismissUrl, null, 'button button-primary' )
217 ),
218 ],
219 ]
220 );
221 }
222
223 }
224