PluginProbe
Tiered Pricing Table for WooCommerce / 8.1.0
Tiered Pricing Table for WooCommerce v8.1.0
8.1.0 8.0.2 7.1.7 7.1.5 7.1.4 7.1.1 6.5.0 6.4.0 6.1.0 trunk 1.0 1.1 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.3.0 2.3.1 2.3.2 All 92 releases
tier-pricing-table / src / Addons / GlobalTieredPricing / CPT / Form / Form.php

Form.php in Tiered Pricing Table for WooCommerce 8.1.0, at src/Addons/GlobalTieredPricing/CPT/Form/Form.php

424 lines 11.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php namespace TierPricingTable\Addons\GlobalTieredPricing\CPT\Form;
2
3 use TierPricingTable\Addons\GlobalTieredPricing\CPT\Form\Tabs\ProductAndCategories;
4 use TierPricingTable\Addons\GlobalTieredPricing\CPT\Form\Tabs\Quantity;
5 use TierPricingTable\Addons\GlobalTieredPricing\CPT\Form\Tabs\Pricing;
6 use TierPricingTable\Addons\GlobalTieredPricing\CPT\Form\Tabs\Settings;
7 use TierPricingTable\Addons\GlobalTieredPricing\CPT\Form\Tabs\UsersAndRoles;
8 use TierPricingTable\Addons\GlobalTieredPricing\CPT\GlobalTieredPricingCPT;
9 use TierPricingTable\Addons\GlobalTieredPricing\GlobalPricingRule;
10 use TierPricingTable\Addons\GlobalTieredPricing\RuleOverlaps;
11 use TierPricingTable\Core\ServiceContainerTrait;
12 use WP_Post;
13
14 class Form {
15
16 use ServiceContainerTrait;
17
18 /**
19 * Tabs
20 *
21 * @var FormTab[]
22 */
23 protected $tabs;
24
25 protected $defaultTab = 'pricing';
26
27 protected $pricingRuleInstance = null;
28
29 /**
30 * @var Guide
31 */
32 protected $guide;
33
34 public function __construct() {
35
36 $this->guide = new Guide();
37
38 add_action( 'init', function () {
39 $tabs = array(
40 new Pricing( $this ),
41 new ProductAndCategories( $this ),
42 new UsersAndRoles( $this ),
43 new Quantity( $this ),
44 );
45
46 $tabs[] = new Settings( $this );
47
48 $this->tabs = apply_filters( 'tiered_pricing_table/global_pricing/form_tabs', $tabs, $this );
49 } );
50
51 add_action( 'edit_form_after_title', function ( WP_Post $post ) {
52 if ( GlobalTieredPricingCPT::SLUG !== $post->post_type ) {
53 return;
54 }
55
56 $this->render( $post );
57 } );
58
59 new UpgradeTip();
60 }
61
62 protected function includeAssets() {
63 ?>
64 <style>
65 /**
66 * Externals
67 */
68 /* do not display any notices on rule creation */
69 .wrap .notice:not(.notice-success, .tpt__admin__feedback-discount-banner) {
70 display: none
71 }
72
73 .tpt-global-pricing-rule-form .woocommerce-help-tip {
74 margin-left: 5px;
75 }
76
77 .tpt-global-pricing-rule-hint {
78 display: flex;
79 align-items: center;
80 padding: 10px;
81 border-left: 3px solid var(--wp-admin-theme-color, #2271b1);
82 background: #f6f7f7;
83 color: var(--wp-admin-theme-color, #2271b1) !important;
84 margin-bottom: 20px;
85 }
86
87 .tpt-global-pricing-rule-hint--top-level {
88 margin-top: 10px;
89 border: 1px solid #888;
90 }
91
92 .tpt-global-pricing-rule-hint--warning {
93 border-left-color: #dba617;
94 background: #fcf9e8;
95 color: #6d4f00 !important;
96 }
97
98 .tpt-global-pricing-rule-hint--top-level + .tpt-global-pricing-rule-hint--top-level {
99 margin-top: -10px;
100 }
101
102 .tpt-global-pricing-rule-hint__icon {
103 margin-right: 10px;
104 }
105
106 .tpt-global-pricing-rule-form {
107 margin: 20px 0;
108 display: flex;
109 overflow: hidden;
110 border-radius: 3px;
111 flex-wrap: nowrap;
112 }
113
114 .tpt-global-pricing-rule-form__tabs {
115 width: 30%;
116 max-width: 300px;
117 min-width: 250px;
118 }
119
120 .tpt-global-pricing-rule-form-tab {
121 background: #fff;
122 border-bottom: 1px solid #e8e8e8;
123 border-left: 1px solid #e8e8e8;
124 overflow: hidden;
125 cursor: pointer;
126 display: flex;
127 align-items: center;
128 padding: 15px 10px;
129 }
130
131 .tpt-global-pricing-rule-form-tab:first-child {
132 border-top: 1px solid #e8e8e8;
133 }
134
135 .tpt-global-pricing-rule-form-tab:hover:not(.tpt-global-pricing-rule-form-tab--active) {
136 background: #fbfbfb;
137 }
138
139 .tpt-global-pricing-rule-form-tab--active {
140 cursor: default;
141 background: #f6f7f7;
142 }
143
144 .tpt-global-pricing-rule-form-tab__icon {
145 transition: all .1s;
146 margin-right: 10px;
147 height: 40px;
148 aspect-ratio: 1/1;
149 border-radius: 50%;
150 background: #f6f7f7;
151 text-align: center;
152 color: var(--wp-admin-theme-color, #2271b1);
153 font-size: 20px;
154 font-weight: bold;
155 display: flex;
156 justify-content: center;
157 align-items: center;
158 }
159
160 .tpt-global-pricing-rule-form-tab--active h3,
161 .tpt-global-pricing-rule-form-tab--active div {
162 color: var(--wp-admin-theme-color, #2271b1) !important;
163 }
164
165 .tpt-global-pricing-rule-form-tab--active .tpt-global-pricing-rule-form-tab__icon {
166 background: #fff;
167 }
168
169 .tpt-global-pricing-rule-form-tab__title h3 {
170 font-size: 1.1em;
171 margin: 0;
172 }
173
174 .tpt-global-pricing-rule-form-tab__title div {
175 margin-top: 5px;
176 color: #777;
177 }
178
179 .tpt-global-pricing-rule-form-tab-content {
180 display: none;
181 }
182
183 .tpt-global-pricing-rule-form-tab-content--active {
184 display: block;
185 }
186
187 .tpt-global-pricing-rule-form__content {
188 width: 70%;
189 background: #fff;
190 flex-grow: 1;
191 padding: 10px;
192 border: 1px solid #e8e8e8;
193 box-shadow: 0 0 8px rgba(0, 0, 0, .1);
194 }
195
196 .tpt-global-pricing-rule-form input[type="text"],
197 .tpt-global-pricing-rule-form input[type="number"],
198 .tpt-global-pricing-rule-form .tiered-pricing-pricing-rules-form-row__inputs {
199 width: 75% !important;
200 }
201
202 .tpt-global-pricing-rule-form #tiered_pricing_type {
203 max-width: 75%;
204 width: 75% !important;
205 }
206
207 @media screen and (max-width: 1248px) {
208
209 .tpt-global-pricing-rule-form input[type="text"],
210 .tpt-global-pricing-rule-form input[type="number"],
211 .tpt-global-pricing-rule-form .tiered-pricing-pricing-rules-form-row__inputs {
212 width: 100% !important;
213 }
214
215 .tpt-global-pricing-rule-form #tiered_pricing_type {
216 max-width: 100%;
217 width: 100% !important;
218 }
219
220
221 .tpt-global-pricing-rule-form {
222 flex-wrap: wrap;
223 }
224
225 .tpt-global-pricing-rule-form__tabs {
226 display: flex;
227 max-width: 100%;
228 width: 100%;
229 }
230
231 .tpt-global-pricing-rule-form-tab__icon {
232 display: none;
233 }
234
235 .tpt-global-pricing-rule-form-tab--active {
236 border-bottom: 3px solid var(--wp-admin-theme-color, #2271b1);
237 }
238 }
239
240 @media screen and (max-width: 500px) {
241 .tiered-pricing-form-block {
242 padding: 5px 20px !important;
243 }
244 }
245
246 /* Accordion styles */
247 .tpt-exclusions-accordion {
248 margin-top: 20px;
249 background: #fff;
250 }
251
252 .tpt-exclusions-accordion summary {
253 cursor: pointer;
254 list-style: none;
255 display: flex;
256 align-items: center;
257 justify-content: space-between;
258 padding: 12px 15px;
259 background: #f6f7f7;
260 border: 1px solid #e8e8e8;
261 font-size: 14px;
262 font-weight: 600;
263 color: #1d2327;
264 transition: background-color 0.2s ease;
265 }
266
267 .tpt-exclusions-accordion summary::-webkit-details-marker {
268 display: none;
269 }
270
271 .tpt-exclusions-accordion summary:hover {
272 background: #f0f0f1;
273 }
274
275 .tpt-exclusions-accordion[open] summary {
276 border-bottom-left-radius: 0;
277 border-bottom-right-radius: 0;
278 border-bottom: 1px solid #e8e8e8;
279 }
280
281 .tpt-exclusions-accordion[open] summary .tpt-accordion-icon {
282 transform: rotate(180deg);
283 }
284
285 .tpt-accordion-icon {
286 transition: transform 0.3s ease;
287 color: #787c82;
288 }
289
290 .tpt-exclusions-accordion-content {
291 padding: 15px 0;
292 border: 1px solid #e8e8e8;
293 border-top: none;
294 border-radius: 0 0 4px 4px;
295 }
296 </style>
297 <script>
298 jQuery(document).ready(function () {
299 let tabs = jQuery('.tpt-global-pricing-rule-form-tab');
300 let tabsContent = jQuery('.tpt-global-pricing-rule-form-tab-content');
301
302 tabs.click(function (e) {
303 e.preventDefault();
304
305 tabsContent.removeClass('tpt-global-pricing-rule-form-tab-content--active');
306 tabs.removeClass('tpt-global-pricing-rule-form-tab--active');
307
308 jQuery(this).addClass('tpt-global-pricing-rule-form-tab--active');
309
310 const target = jQuery(this).data('target');
311
312 jQuery('#' + target).addClass('tpt-global-pricing-rule-form-tab-content--active');
313 });
314 });
315 </script>
316 <?php
317 }
318
319 protected function render( WP_Post $post ) {
320
321 $this->includeAssets();
322
323 $this->guide->render();
324
325 // a rule that changes nothing is flagged as "Skipped" by the Rule status box; no second notice here
326 if ( ! $this->isNewRule() ) {
327 $this->renderStatusHints( $this->getPricingRuleInstance( $post ) );
328 }
329
330 ?>
331 <div class="tpt-global-pricing-rule-form">
332
333 <nav class="tpt-global-pricing-rule-form__tabs">
334 <?php foreach ( $this->tabs as $tab ) : ?>
335 <div class="tpt-global-pricing-rule-form-tab <?php echo esc_attr( $tab->getId() === $this->defaultTab ? 'tpt-global-pricing-rule-form-tab--active' : '' ); ?>"
336 data-target="tpt-global-pricing-rule-form-tab-<?php echo esc_attr( $tab->getId() ); ?>">
337
338 <div class="tpt-global-pricing-rule-form-tab__icon" style="">
339 <?php if ( strpos( $tab->getIcon(), 'dashicons-' ) === 0 ) : ?>
340 <span class="dashicons <?php echo esc_attr( $tab->getIcon() ); ?>"></span>
341 <?php else : ?>
342 <span><?php echo esc_html( $tab->getIcon() ); ?></span>
343 <?php endif; ?>
344 </div>
345
346 <div class="tpt-global-pricing-rule-form-tab__title">
347 <h3>
348 <?php echo esc_html( $tab->getTitle() ); ?>
349 </h3>
350 <div><?php echo esc_html( $tab->getDescription() ); ?></div>
351 </div>
352 </div>
353 <?php endforeach; ?>
354 </nav>
355
356 <section class="tpt-global-pricing-rule-form__content woocommerce_options_panel">
357 <?php foreach ( $this->tabs as $tab ) : ?>
358 <div class="tpt-global-pricing-rule-form-tab-content <?php echo esc_attr( $tab->getId() === $this->defaultTab ? 'tpt-global-pricing-rule-form-tab-content--active' : '' ); ?>"
359 id="tpt-global-pricing-rule-form-tab-<?php echo esc_attr( $tab->getId() ); ?>">
360 <?php
361 $tab->render( $this->getPricingRuleInstance( $post ) );
362
363 do_action( 'tiered_pricing_table/global_pricing/form/tab_end', $tab,
364 $this->getPricingRuleInstance( $post ) );
365 ?>
366 </div>
367 <?php endforeach; ?>
368 </section>
369 </div>
370 <?php
371 }
372
373 /**
374 * What the admin should know before editing: other rules have a higher priority for products and
375 * customers they share, so this rule is skipped there. The Rule status box lists them.
376 */
377 protected function renderStatusHints( GlobalPricingRule $rule ) {
378 // a suspended, expired or skipped rule is not applied anyway, so nothing overrides it
379 if ( 'publish' !== get_post_status( $rule->getId() ) || ! $rule->canBeOverridden() ) {
380 return;
381 }
382
383 $overriding = ( new RuleOverlaps() )->findOverriding( $rule, GlobalTieredPricingCPT::getGlobalRules( true, false ) );
384
385 if ( ! $overriding ) {
386 return;
387 }
388
389 $this->tabs[0]->renderHint(
390 sprintf(
391 /* translators: %d: number of rules */
392 _n(
393 '%d other rule has a higher priority and is applied instead of this rule for the products and customers they both match. See "Overridden by" in the Rule status box.',
394 '%d other rules have a higher priority and are applied instead of this rule for the products and customers they both match. See "Overridden by" in the Rule status box.',
395 count( $overriding ),
396 'tier-pricing-table'
397 ),
398 count( $overriding )
399 ),
400 array( 'custom_class' => 'tpt-global-pricing-rule-hint--top-level tpt-global-pricing-rule-hint--warning' )
401 );
402 }
403
404 /**
405 * Get pricing rule instance
406 *
407 * @param WP_Post $post
408 *
409 * @return GlobalPricingRule
410 */
411 public function getPricingRuleInstance( WP_Post $post ): GlobalPricingRule {
412 if ( empty( $this->pricingRuleInstance ) ) {
413 $this->pricingRuleInstance = GlobalPricingRule::build( $post->ID );
414 }
415
416 return $this->pricingRuleInstance;
417 }
418
419 public function isNewRule(): bool {
420 global $pagenow;
421
422 return 'post-new.php' == $pagenow;
423 }
424 }