PluginProbe
Packeta / 1.2.6
Packeta v1.2.6
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 / Page.php

Page.php in Packeta 1.2.6, at src/Packetery/Module/Options/Page.php

399 lines 13.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class Page
4 *
5 * @package Packetery\Options
6 */
7
8 declare( strict_types=1 );
9
10 namespace Packetery\Module\Options;
11
12 use Packetery\Core\Api\Soap\Request\SenderGetReturnRouting;
13 use Packetery\Core\Log;
14 use Packetery\Module\FormFactory;
15 use Packetery\Module\MessageManager;
16 use PacketeryLatte\Engine;
17 use PacketeryNette\Forms\Form;
18
19 /**
20 * Class Page
21 *
22 * @package Packetery\Options
23 */
24 class Page {
25
26 private const FORM_FIELDS_CONTAINER = 'packetery';
27 private const FORM_FIELD_PACKETA_LABEL_FORMAT = 'packeta_label_format';
28 private const FORM_FIELD_CARRIER_LABEL_FORMAT = 'carrier_label_format';
29
30 private const DEFAULT_VALUE_PACKETA_LABEL_FORMAT = 'A6 on A4';
31 private const DEFAULT_VALUE_CARRIER_LABEL_FORMAT = self::DEFAULT_VALUE_PACKETA_LABEL_FORMAT;
32
33 public const ACTION_VALIDATE_SENDER = 'validate-sender';
34
35 public const SLUG = 'packeta-options';
36
37 /**
38 * PacketeryLatte_engine.
39 *
40 * @var Engine PacketeryLatte engine.
41 */
42 private $latte_engine;
43
44 /**
45 * Options Provider
46 *
47 * @var Provider
48 */
49 private $optionsProvider;
50
51 /**
52 * Form factory.
53 *
54 * @var FormFactory Form factory.
55 */
56 private $formFactory;
57
58 /**
59 * Packeta client.
60 *
61 * @var \Packetery\Core\Api\Soap\Client
62 */
63 private $packetaClient;
64
65 /**
66 * Logger
67 *
68 * @var Log\ILogger
69 */
70 private $logger;
71
72 /**
73 * Message manager.
74 *
75 * @var MessageManager
76 */
77 private $messageManager;
78
79 /**
80 * HTTP request.
81 *
82 * @var \PacketeryNette\Http\Request
83 */
84 private $httpRequest;
85
86 /**
87 * Plugin constructor.
88 *
89 * @param Engine $latte_engine PacketeryLatte_engine.
90 * @param Provider $optionsProvider Options provider.
91 * @param FormFactory $formFactory Form factory.
92 * @param \Packetery\Core\Api\Soap\Client $packetaClient Packeta Client.
93 * @param Log\ILogger $logger Logger.
94 * @param MessageManager $messageManager Message manager.
95 * @param \PacketeryNette\Http\Request $httpRequest HTTP request.
96 */
97 public function __construct( Engine $latte_engine, Provider $optionsProvider, FormFactory $formFactory, \Packetery\Core\Api\Soap\Client $packetaClient, Log\ILogger $logger, MessageManager $messageManager, \PacketeryNette\Http\Request $httpRequest ) {
98 $this->latte_engine = $latte_engine;
99 $this->optionsProvider = $optionsProvider;
100 $this->formFactory = $formFactory;
101 $this->packetaClient = $packetaClient;
102 $this->logger = $logger;
103 $this->messageManager = $messageManager;
104 $this->httpRequest = $httpRequest;
105 }
106
107 /**
108 * Registers WP callbacks.
109 */
110 public function register(): void {
111 add_action( 'admin_init', array( $this, 'admin_init' ) );
112 $icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI1LjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IlZyc3R2YV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIKCSB2aWV3Qm94PSIwIDAgMzcgNDAiIHN0eWxlPSJmaWxsOiNhN2FhYWQiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0MHtmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiAjYTdhYWFkO30KPC9zdHlsZT4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTE5LjQsMTYuMWwtMC45LDAuNGwtMC45LTAuNGwtMTMtNi41bDYuMi0yLjRsMTMuNCw2LjVMMTkuNCwxNi4xeiBNMzIuNSw5LjZsLTQuNywyLjNsLTEzLjUtNmw0LjItMS42CglMMzIuNSw5LjZ6Ii8+CjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0xOSwwbDE3LjIsNi42bC0yLjQsMS45bC0xNS4yLTZMMy4yLDguNkwwLjgsNi42TDE4LDBMMTksMEwxOSwweiBNMzQuMSw5LjFsMi44LTEuMWwtMi4xLDE3LjZsLTAuNCwwLjgKCUwxOS40LDQwbC0wLjUtMy4xbDEzLjQtMTJMMzQuMSw5LjF6IE0yLjUsMjYuNWwtMC40LTAuOEwwLDguMWwyLjgsMS4xbDEuOSwxNS43bDEzLjQsMTJMMTcuNiw0MEwyLjUsMjYuNXoiLz4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTI4LjIsMTIuNGw0LjMtMi43bC0xLjcsMTQuMkwxOC42LDM1bDAuNi0xN2w1LjQtMy4zTDI0LjMsMjNsMy4zLTIuM0wyOC4yLDEyLjR6Ii8+CjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0xNy43LDE3LjlsMC42LDE3bC0xMi4yLTExTDQuNCw5LjhMMTcuNywxNy45eiIvPgo8L3N2Zz4K';
113 add_menu_page(
114 __( 'Packeta', 'packetery' ),
115 __( 'Packeta', 'packetery' ),
116 'manage_options',
117 self::SLUG,
118 '',
119 $icon,
120 55 // todo Move item to last position in menu.
121 );
122 add_submenu_page(
123 self::SLUG,
124 __( 'Settings', 'packetery' ),
125 __( 'Settings', 'packetery' ),
126 'manage_options',
127 self::SLUG,
128 array(
129 $this,
130 'render',
131 ),
132 1
133 );
134 add_action( 'admin_init', [ $this, 'processActions' ] );
135 }
136
137 /**
138 * Sets default values.
139 */
140 public function setDefaultValues(): void {
141 $value = get_option( self::FORM_FIELDS_CONTAINER );
142 $value[ self::FORM_FIELD_PACKETA_LABEL_FORMAT ] = self::DEFAULT_VALUE_PACKETA_LABEL_FORMAT;
143 $value[ self::FORM_FIELD_CARRIER_LABEL_FORMAT ] = self::DEFAULT_VALUE_CARRIER_LABEL_FORMAT;
144 update_option( self::FORM_FIELDS_CONTAINER, $value );
145 }
146
147 /**
148 * Creates settings form.
149 *
150 * @return Form
151 */
152 private function create_form(): Form {
153 $form = $this->formFactory->create();
154 $form->setAction( 'options.php' );
155
156 $container = $form->addContainer( self::FORM_FIELDS_CONTAINER );
157 $container->addText( 'api_password', __( 'API password', 'packetery' ) )
158 ->setRequired()
159 ->addRule( $form::PATTERN, __( 'API password must be 32 characters long and must contain valid characters!', 'packetery' ), '[a-z\d]{32}' );
160 $container->addText( 'sender', __( 'Sender', 'packetery' ) )
161 ->setRequired();
162
163 $packetaLabelFormats = $this->optionsProvider->getPacketaLabelFormats();
164 $container->addSelect(
165 self::FORM_FIELD_PACKETA_LABEL_FORMAT,
166 __( 'Packeta Label Format', 'packetery' ),
167 $packetaLabelFormats
168 )->checkDefaultValue( false )->setDefaultValue( self::DEFAULT_VALUE_PACKETA_LABEL_FORMAT );
169
170 $carrierLabelFormats = $this->optionsProvider->getCarrierLabelFormat();
171 $container->addSelect(
172 self::FORM_FIELD_CARRIER_LABEL_FORMAT,
173 __( 'Carrier Label Format', 'packetery' ),
174 $carrierLabelFormats
175 )->checkDefaultValue( false )->setDefaultValue( self::DEFAULT_VALUE_CARRIER_LABEL_FORMAT );
176
177 $gateways = $this->getAvailablePaymentGateways();
178 $enabledGateways = [];
179 foreach ( $gateways as $gateway ) {
180 $enabledGateways[ $gateway->id ] = $gateway->get_method_title();
181 }
182 $container->addSelect(
183 'cod_payment_method',
184 __( 'Payment method that represents cash on delivery', 'packetery' ),
185 $enabledGateways
186 )->setPrompt( '--' )->checkDefaultValue( false );
187
188 $container->addText( 'packaging_weight', __( 'packagingWeight', 'packetery' ) . ' (kg)' )
189 ->setRequired( true )
190 ->addRule( Form::FLOAT )
191 ->addRule( Form::MIN, null, 0 )
192 ->setDefaultValue( 0 );
193
194 // TODO: Packet status sync.
195
196 $container->addCheckbox( 'replace_shipping_address_with_pickup_point_address', __( 'Replace shipping address with pickup point address', 'packetery' ) )
197 ->setRequired( false );
198
199 if ( $this->optionsProvider->has_any() ) {
200 $container->setDefaults( $this->optionsProvider->data_to_array() );
201 }
202
203 return $form;
204 }
205
206 /**
207 * Get available gateways.
208 *
209 * @return \WC_Payment_Gateway[]
210 */
211 public function getAvailablePaymentGateways(): array {
212 $availableGateways = [];
213
214 foreach ( WC()->payment_gateways()->payment_gateways() as $gateway ) {
215 if ( 'yes' === $gateway->enabled ) {
216 $availableGateways[ $gateway->id ] = $gateway;
217 }
218 }
219
220 return array_filter( (array) apply_filters( 'woocommerce_available_payment_gateways', $availableGateways ), [ $this, 'filterValidGatewayClass' ] );
221 }
222
223 /**
224 * Callback for array filter. Returns true if gateway is of correct type.
225 *
226 * @param object $gateway Gateway to check.
227 * @return bool
228 */
229 protected function filterValidGatewayClass( object $gateway ): bool {
230 return ( $gateway instanceof \WC_Payment_Gateway );
231 }
232
233 /**
234 * Admin_init callback.
235 */
236 public function admin_init(): void {
237 register_setting( self::FORM_FIELDS_CONTAINER, self::FORM_FIELDS_CONTAINER, array( $this, 'options_validate' ) );
238 add_settings_section( 'packetery_main', __( 'Main Settings', 'packetery' ), '', self::SLUG );
239 }
240
241 /**
242 * Validates options.
243 *
244 * @param array $options Packetery_options.
245 *
246 * @return array
247 */
248 public function options_validate( array $options ): array {
249 $form = $this->create_form();
250 $form[ self::FORM_FIELDS_CONTAINER ]->setValues( $options );
251 if ( $form->isValid() === false ) {
252 foreach ( $form[ self::FORM_FIELDS_CONTAINER ]->getControls() as $control ) {
253 if ( $control->hasErrors() === false ) {
254 continue;
255 }
256
257 add_settings_error( $control->getCaption(), esc_attr( $control->getName() ), $control->getError() );
258 $options[ $control->getName() ] = '';
259 }
260 }
261
262 $api_password = $form[ self::FORM_FIELDS_CONTAINER ]['api_password'];
263 if ( $api_password->hasErrors() === false ) {
264 $api_pass = $api_password->getValue();
265 $options['api_key'] = substr( $api_pass, 0, 16 );
266 $this->packetaClient->setApiPassword( $api_pass );
267 } else {
268 $options['api_key'] = '';
269 }
270
271 $this->validateSender( $options['sender'] );
272
273 return $options;
274 }
275
276 /**
277 * Validates sender.
278 *
279 * @param string $senderLabel Sender lbel.
280 *
281 * @return bool|null
282 */
283 private function validateSender( string $senderLabel ): ?bool {
284 $senderValidationRequest = new SenderGetReturnRouting( $senderLabel );
285 $senderValidationResponse = $this->packetaClient->senderGetReturnRouting( $senderValidationRequest );
286
287 $senderValidationLog = new Log\Record();
288 $senderValidationLog->action = Log\Record::ACTION_SENDER_VALIDATION;
289
290 $senderValidationLog->status = Log\Record::STATUS_SUCCESS;
291 $senderValidationLog->title = __( 'senderValidationSuccessLogTitle', 'packetery' );
292
293 if ( $senderValidationResponse->hasFault() ) {
294 $senderValidationLog->status = Log\Record::STATUS_ERROR;
295 $senderValidationLog->params = [
296 'errorMessage' => $senderValidationResponse->getFaultString(),
297 ];
298 $senderValidationLog->title = __( 'senderValidationErrorLogTitle', 'packetery' );
299 }
300
301 $this->logger->add( $senderValidationLog );
302
303 $senderExists = $senderValidationResponse->senderExists();
304
305 if ( false === $senderExists ) {
306 $this->messageManager->flash_message( __( 'specifiedSenderDoesNotExist', 'packetery' ), MessageManager::TYPE_INFO, MessageManager::RENDERER_PACKETERY, 'plugin-options' );
307 }
308
309 if ( null === $senderExists ) {
310 $this->messageManager->flash_message( __( 'unableToCheckSpecifiedSender', 'packetery' ), MessageManager::TYPE_INFO, MessageManager::RENDERER_PACKETERY, 'plugin-options' );
311 }
312
313 return $senderExists;
314 }
315
316 /**
317 * Process actions.
318 *
319 * @return void
320 */
321 public function processActions(): void {
322 $action = $this->httpRequest->getQuery( 'action' );
323 if ( self::ACTION_VALIDATE_SENDER === $action ) {
324 $result = $this->validateSender( $this->optionsProvider->get_sender() );
325
326 if ( true === $result ) {
327 $this->messageManager->flash_message( __( 'specifiedSenderIsOk', 'packetery' ), MessageManager::TYPE_SUCCESS, MessageManager::RENDERER_PACKETERY, 'plugin-options' );
328 }
329
330 $doRedirect = wp_safe_redirect(
331 add_query_arg(
332 [
333 'page' => self::SLUG,
334 ],
335 get_admin_url( null, 'admin.php' )
336 )
337 );
338
339 if ( $doRedirect ) {
340 exit;
341 }
342 }
343 }
344
345 /**
346 * Renders page.
347 */
348 public function render(): void {
349 $latteParams = [ 'form' => $this->create_form() ];
350 if ( ! extension_loaded( 'soap' ) ) {
351 $latteParams['error'] = __( 'This plugin requires an active SOAP library for proper operation. Contact your web hosting administrator.', 'packetery' );
352 }
353
354 $latteParams['apiPasswordLink'] = trim( $this->latte_engine->renderToString( PACKETERY_PLUGIN_DIR . '/template/options/help-block-link.latte', [ 'href' => 'https://client.packeta.com/support' ] ) );
355
356 $latteParams['senderDescription'] = sprintf(
357 /* translators: 1: emphasis start 2: emphasis end 3: client section link start 4: client section link end */
358 esc_html__( 'senderDescription', 'packetery' ),
359 '<strong>',
360 '</strong>',
361 '<a href="https://client.packeta.com/senders" target="_blank">',
362 '</a>'
363 );
364
365 $latteParams['exportLink'] = add_query_arg(
366 [
367 'page' => self::SLUG,
368 'action' => Exporter::ACTION_EXPORT_SETTINGS,
369 ],
370 get_admin_url( null, 'admin.php' )
371 );
372
373 $latteParams['canValidateSender'] = (bool) $this->optionsProvider->get_sender();
374 $latteParams['senderValidationLink'] = add_query_arg(
375 [
376 'page' => self::SLUG,
377 'action' => self::ACTION_VALIDATE_SENDER,
378 ],
379 get_admin_url( null, 'admin.php' )
380 );
381
382 $lastExport = null;
383 $lastExportOption = get_option( Exporter::OPTION_LAST_SETTINGS_EXPORT );
384 if ( false !== $lastExportOption ) {
385 $date = \DateTime::createFromFormat( DATE_ATOM, $lastExportOption );
386 if ( false !== $date ) {
387 $date->setTimezone( wp_timezone() );
388 $lastExport = $date->format( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
389 }
390 }
391 if ( $lastExport ) {
392 $latteParams['lastExport'] = $lastExport;
393 }
394
395 $latteParams['messages'] = $this->messageManager->renderToString( MessageManager::RENDERER_PACKETERY, 'plugin-options' );
396 $this->latte_engine->render( PACKETERY_PLUGIN_DIR . '/template/options/page.latte', $latteParams );
397 }
398 }
399