Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
2.65% covered (danger)
2.65%
3 / 113
10.00% covered (danger)
10.00%
1 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
QuickAddProduct
2.65% covered (danger)
2.65%
3 / 113
10.00% covered (danger)
10.00%
1 / 10
804.78
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 init
28.57% covered (danger)
28.57%
2 / 7
0.00% covered (danger)
0.00%
0 / 1
6.28
 enqueue_scripts
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 1
20
 register_dashboard_widgets
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 output_dashboard_widget
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 register_routes
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 output_modal_root
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 get_product_types
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
90
 can_access_global_ctb
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 handle_product_type_on_add_product
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
42
1<?php
2
3namespace NewfoldLabs\WP\Module\ECommerce;
4
5use NewfoldLabs\WP\Module\Solutions\Solutions;
6use NewfoldLabs\WP\ModuleLoader\Container;
7
8/**
9 * Quick Add Product Class
10 */
11class QuickAddProduct {
12
13    /**
14     * Holds the container object
15     *
16     * @var Container
17     */
18    protected $container;
19
20    /**
21     * Constructor
22     *
23     * @param Container $container Plugin container.
24     */
25    public function __construct( Container $container ) {
26        $this->container = $container;
27    }
28
29    /**
30     * Initialize class hooks/filters
31     *
32     * @return void
33     */
34    public function init() {
35        // Enable it only for Bluehost brand plugin.
36        if ( 'bluehost' !== $this->container->plugin()->id || ! function_exists( 'WC' ) ) {
37            return;
38        }
39
40        // Enqueue scripts in admin.
41        \add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
42        // Register dashboard widget.
43        \add_action( 'wp_dashboard_setup', array( $this, 'register_dashboard_widgets' ) );
44        // Register API routes.
45        \add_action( 'rest_api_init', array( $this, 'register_routes' ) );
46        // Output root for modal.
47        \add_action( 'admin_footer', array( $this, 'output_modal_root' ) );
48
49        // Handle special product type page.
50        \add_action( 'admin_footer', array( $this, 'handle_product_type_on_add_product' ) );
51    }
52
53
54    /**
55     * Enqueue scripts
56     *
57     * @return void
58     */
59    public function enqueue_scripts() {
60        global $current_screen;
61
62        $asset_file = NFD_ECOMMERCE_BUILD_DIR . 'quick-add-product/index.asset.php';
63        if ( file_exists( $asset_file ) ) {
64            $asset = require $asset_file;
65
66            // Add WC accounting script to the dependencies array.
67            $asset['dependencies'][] = 'accounting';
68
69            // Register script.
70            wp_register_script(
71                'quick-add-product',
72                NFD_ECOMMERCE_PLUGIN_URL . 'vendor/newfold-labs/wp-module-ecommerce/build/quick-add-product/index.js',
73                array_merge(
74                    $asset['dependencies'],
75                    array( 'newfold-global-ctb', 'nfd-installer-listener', 'nfd-installer' ),
76                ),
77                $asset['version'],
78                true
79            );
80
81            wp_localize_script(
82                'quick-add-product',
83                'quickAddProduct',
84                array(
85                    'productTypes'  => $this->get_product_types(),
86                    'addProductUrl' => add_query_arg( array( 'post_type' => 'product' ), \admin_url( 'post-new.php' ) ),
87                    'money'         => array(
88                        'decimals'          => wc_get_price_decimals(),
89                        'thousandSeparator' => wc_get_price_thousand_separator(),
90                        'decimalSeparator'  => wc_get_price_decimal_separator(),
91                        'currencySymbol'    => get_woocommerce_currency_symbol(),
92                    ),
93                )
94            );
95
96            wp_register_style(
97                'quick-add-product',
98                NFD_ECOMMERCE_PLUGIN_URL . 'vendor/newfold-labs/wp-module-ecommerce/build/quick-add-product/quick-add-product.css',
99                array( 'newfold-global-ctb-style', 'nfd-installer' ),
100                $asset['version']
101            );
102
103            // Maybe enqueue scripts.
104            if ( ! empty( $current_screen ) && in_array( $current_screen->id, array( 'dashboard', 'edit-product' ), true ) ) {
105
106                wp_enqueue_global_styles_css_custom_properties();
107                wp_enqueue_media();
108
109                wp_enqueue_script( 'quick-add-product' );
110                wp_enqueue_style( 'quick-add-product' );
111            }
112        }
113    }
114
115    /**
116     * Register dashboard widget
117     *
118     * @return void
119     */
120    public function register_dashboard_widgets() {
121        wp_add_dashboard_widget(
122            'nfd_quick_add_product_widget',
123            esc_html__( 'Quick Add Product', 'wp-module-ecommerce' ),
124            array( $this, 'output_dashboard_widget' ),
125            null,
126            null,
127            'column3',
128            'high'
129        );
130    }
131
132    /**
133     * Output the dashboard widget
134     *
135     * @return void
136     */
137    public function output_dashboard_widget() {
138        echo '<div id="nfd-quick-add-product-widget"></div>';
139    }
140
141    /**
142     * Register create product API route
143     *
144     * @return void
145     */
146    public function register_routes() {
147        ( new \NewfoldLabs\WP\Module\ECommerce\RestApi\QuickAddProductController() )->register_routes();
148    }
149
150    /**
151     * Output modal root
152     *
153     * @return void
154     */
155    public function output_modal_root() {
156        if ( ! wp_script_is( 'quick-add-product', 'enqueued' ) ) {
157            return;
158        }
159
160        echo '<div id="nfd-quick-add-product-modal"></div>';
161    }
162
163    /**
164     * Return an array of product types.
165     *
166     * @return array
167     */
168    protected function get_product_types() {
169
170        // Init types with default.
171        $types = array(
172            array(
173                'key'         => 'virtual',
174                'title'       => __( 'Digital products or services', 'wp-module-ecommerce' ),
175                'description' => __( 'EX: eBooks, stock photos, software, templates, podcasts, apps, videos, etc. No physical products or shipping management.', 'wp-module-ecommerce' ),
176            ),
177            array(
178                'key'         => 'physical',
179                'title'       => __( 'Physical products', 'wp-module-ecommerce' ),
180                'description' => __( 'Ex: clothing, furniture, accessories — any type of product that needs to be physically shipped to your customers.', 'wp-module-ecommerce' ),
181            ),
182        );
183
184        // Get entitlements.
185        if ( ! class_exists( 'NewfoldLabs\WP\Module\Solutions\Solutions' ) ) {
186            return $types;
187        }
188
189        $entitlements_data = Solutions::get_enhanced_entitlment_data();
190        $entitlements      = array_merge(
191            isset( $entitlements_data['entitlements'] ) ? $entitlements_data['entitlements'] : array(),
192            isset( $entitlements_data['premium'] ) ? $entitlements_data['premium'] : array()
193        );
194
195        $premium_types = array(
196            'yith-woocommerce-booking-premium/init.php' => array(
197                'key'         => 'booking',
198                'title'       => __( 'Bookings/Appointments', 'wp-module-ecommerce' ),
199                'description' => __( 'Ex: apartment bookings, rental of products, medical appointments, personal training, etc — any type of bookable product or service.', 'wp-module-ecommerce' ),
200            ),
201            'wp-plugin-subscriptions/wp-plugin-subscriptions.php'          => array(
202                'key'         => 'subscription',
203                'title'       => __( 'Subscription', 'wp-module-ecommerce' ),
204                'description' => __( 'Ex: a monthly subscription box, a magazine subscription, streaming service like Netflix, etc - any type of product your customer pays for on a recurring basis.', 'wp-module-ecommerce' ),
205            ),
206        );
207
208        foreach ( $entitlements as $entitlement ) {
209            if ( ! is_array( $entitlement ) || ! array_key_exists( $entitlement['basename'], $premium_types ) ) {
210                continue;
211            }
212
213            $premium_type = $premium_types[ $entitlement['basename'] ];
214            // If plugin is active add redirect flag to handle modal type correctly.
215            if ( is_plugin_active( $entitlement['basename'] ) ) {
216                $premium_type['redirect'] = true;
217            } elseif ( $this->can_access_global_ctb() ) { // Can access global CTB, handle it.
218                $premium_type['premiumData'] = $entitlement;
219            }
220
221            $types[] = $premium_type;
222        }
223
224        return $types;
225    }
226
227    /**
228     * Can current user access global CTB?
229     */
230    protected function can_access_global_ctb(): bool {
231        return (bool) $this->container->get( 'capabilities' )->get( 'canAccessGlobalCTB' );
232    }
233
234    /**
235     * Handle product type (booking|subscription) for single product add-new page.
236     *
237     * @return void
238     */
239    public function handle_product_type_on_add_product() {
240        global $pagenow;
241
242        if ( 'post-new.php' !== $pagenow || ! isset( $_GET['post_type'], $_GET['product_type'] )
243            || 'product' !== sanitize_text_field( wp_unslash( $_GET['post_type'] ) )
244        ) {
245            return;
246        }
247
248        $product_type = sanitize_text_field( wp_unslash( $_GET['product_type'] ) );
249
250        if ( 'booking' === $product_type ) {
251            \wp_print_inline_script_tag( "jQuery(() => jQuery('#product-type').val('booking').change())" );
252        } elseif ( 'subscription' === $product_type ) {
253            \wp_print_inline_script_tag( "jQuery(() => jQuery('input[name=_bh_subscriptions_subscription]').prop('checked', true).change())" );
254        }
255    }
256}