.gitkeep
3 years ago
BasePageController.php
1 year ago
BuyPageController.php
1 year ago
CheckoutFormsController.php
2 years ago
DashboardController.php
1 year ago
PurchaseController.php
3 years ago
SubscriptionsController.php
3 years ago
UpsellPageController.php
1 year ago
WebhookController.php
2 years ago
BuyPageController.php
258 lines
| 1 | <?php |
| 2 | namespace SureCart\Controllers\Web; |
| 3 | |
| 4 | /** |
| 5 | * Handles Instant Checkout Page. |
| 6 | */ |
| 7 | class BuyPageController extends BasePageController { |
| 8 | /** |
| 9 | * Handle filters. |
| 10 | * |
| 11 | * @return void |
| 12 | */ |
| 13 | public function filters(): void { |
| 14 | parent::filters(); |
| 15 | // Add edit product link to admin bar. |
| 16 | add_action( 'admin_bar_menu', [ $this, 'addEditProductLink' ], 99 ); |
| 17 | // add styles. |
| 18 | add_action( 'wp_enqueue_scripts', [ $this, 'styles' ] ); |
| 19 | // add scripts. |
| 20 | add_action( 'wp_enqueue_scripts', [ $this, 'scripts' ] ); |
| 21 | // add seo meta data. |
| 22 | add_action( 'wp_head', [ $this, 'addSeoMetaData' ] ); |
| 23 | // add json schema. |
| 24 | add_action( 'wp_head', [ $this, 'addProductJsonSchema' ] ); |
| 25 | } |
| 26 | |
| 27 | /** |
| 28 | * Preload the image above the fold. |
| 29 | * |
| 30 | * @return void |
| 31 | */ |
| 32 | public function preloadImage(): void { |
| 33 | if ( empty( $this->model->product_medias->data ) || is_wp_error( $this->model->product_medias->data ) ) { |
| 34 | return; |
| 35 | } |
| 36 | $product_media = $this->model->product_medias->data[0]; |
| 37 | ?> |
| 38 | <link rel="preload" fetchpriority="high" as="image" href="<?php echo esc_url( $product_media->getUrl( 450 ) ); ?>"> |
| 39 | <?php |
| 40 | } |
| 41 | |
| 42 | /** |
| 43 | * Add edit links |
| 44 | * |
| 45 | * @param \WP_Admin_bar $wp_admin_bar The admin bar. |
| 46 | * |
| 47 | * @return void |
| 48 | */ |
| 49 | public function addEditProductLink( $wp_admin_bar ) { |
| 50 | if ( empty( $this->model->id ) ) { |
| 51 | return; |
| 52 | } |
| 53 | $wp_admin_bar->add_node( |
| 54 | [ |
| 55 | 'id' => 'edit', |
| 56 | 'title' => __( 'Edit Product', 'surecart' ), |
| 57 | 'href' => esc_url( \SureCart::getUrl()->edit( 'product', $this->model->id ) ), |
| 58 | ] |
| 59 | ); |
| 60 | } |
| 61 | |
| 62 | /** |
| 63 | * Show the product page |
| 64 | * |
| 65 | * @param \SureCartCore\Requests\RequestInterface $request Request. |
| 66 | * @param \SureCartCore\View $view View. |
| 67 | * @param string $id The id of the product. |
| 68 | * @return function |
| 69 | */ |
| 70 | public function show( $request, $view, $id ) { |
| 71 | $id = get_query_var( 'sc_checkout_product_id' ); |
| 72 | |
| 73 | // fetch the product by id/slug. |
| 74 | $this->model = \SureCart\Models\Product::with( [ 'image', 'prices', 'product_medias', 'product_media.media', 'variants', 'variant_options' ] )->find( $id ); |
| 75 | |
| 76 | if ( is_wp_error( $this->model ) ) { |
| 77 | return $this->handleError( $this->model ); |
| 78 | } |
| 79 | |
| 80 | // if this buy page is not enabled, check read permissions. |
| 81 | if ( ! $this->model->buyLink()->isEnabled() && ! current_user_can( 'read_sc_products' ) ) { |
| 82 | return $this->notFound(); |
| 83 | } |
| 84 | |
| 85 | // slug changed or we are using the id, redirect. |
| 86 | if ( $this->model->slug !== $id ) { |
| 87 | return \SureCart::redirect()->to( esc_url_raw( \SureCart::routeUrl( 'product', [ 'id' => $this->model->slug ] ) ) ); |
| 88 | } |
| 89 | |
| 90 | // get active prices. |
| 91 | $active_prices = $this->model->active_prices; |
| 92 | |
| 93 | // must have at least one active price. |
| 94 | if ( empty( $active_prices[0] ) ) { |
| 95 | return $this->notFound(); |
| 96 | } |
| 97 | |
| 98 | // prevent 404 redirects by 3rd party plugins. |
| 99 | $_SERVER['REQUEST_URI'] = $request->getUrl(); |
| 100 | |
| 101 | // add the filters. |
| 102 | $this->filters(); |
| 103 | |
| 104 | // prepare data. |
| 105 | $this->model = $this->model->withActivePrices()->withSortedPrices(); |
| 106 | $first_variant_with_stock = $this->model->first_variant_with_stock; |
| 107 | |
| 108 | if ( ! empty( $this->model->prices->data[0]->id ) ) { |
| 109 | $line_item = array_merge( |
| 110 | [ |
| 111 | 'price_id' => $this->model->prices->data[0]->id, |
| 112 | 'quantity' => 1, |
| 113 | ], |
| 114 | ! empty( $first_variant_with_stock->id ) ? [ 'variant_id' => $first_variant_with_stock->id ] : [] |
| 115 | ); |
| 116 | sc_initial_state( |
| 117 | [ |
| 118 | 'checkout' => [ |
| 119 | 'initialLineItems' => sc_initial_line_items( [ $line_item ] ), |
| 120 | ], |
| 121 | ] |
| 122 | ); |
| 123 | } |
| 124 | |
| 125 | // render the view. |
| 126 | return \SureCart::view( 'web/buy' )->with( |
| 127 | [ |
| 128 | 'product' => $this->model, |
| 129 | 'terms_text' => $this->termsText(), |
| 130 | 'mode' => $this->model->buyLink()->getMode(), |
| 131 | 'store_name' => \SureCart::account()->name ?? get_bloginfo(), |
| 132 | 'logo_url' => \SureCart::account()->brand->logo_url, |
| 133 | 'logo_width' => \SureCart::settings()->get( 'buy_link_logo_width', '180px' ), |
| 134 | 'user' => wp_get_current_user(), |
| 135 | 'logout_link' => wp_logout_url( $request->getUrl() ), |
| 136 | 'dashboard_link' => \SureCart::pages()->url( 'dashboard' ), |
| 137 | 'enabled' => $this->model->buyLink()->isEnabled(), |
| 138 | 'show_logo' => $this->model->buyLink()->templatePartEnabled( 'logo' ), |
| 139 | 'show_terms' => $this->model->buyLink()->templatePartEnabled( 'terms' ), |
| 140 | 'show_image' => $this->model->buyLink()->templatePartEnabled( 'image' ), |
| 141 | 'show_description' => $this->model->buyLink()->templatePartEnabled( 'description' ), |
| 142 | 'show_coupon' => $this->model->buyLink()->templatePartEnabled( 'coupon' ), |
| 143 | 'success_url' => $this->model->buyLink()->getSuccessUrl(), |
| 144 | ] |
| 145 | ); |
| 146 | } |
| 147 | |
| 148 | /** |
| 149 | * Enqueue styles. |
| 150 | * |
| 151 | * @return void |
| 152 | */ |
| 153 | public function styles() { |
| 154 | wp_enqueue_style( |
| 155 | 'surecart/instant-checkout', |
| 156 | trailingslashit( \SureCart::core()->assets()->getUrl() ) . 'dist/templates/instant-checkout.css', |
| 157 | [], |
| 158 | filemtime( trailingslashit( plugin_dir_path( SURECART_PLUGIN_FILE ) ) . 'dist/templates/instant-checkout.css' ), |
| 159 | ); |
| 160 | |
| 161 | // add recaptcha if enabled. |
| 162 | if ( \SureCart::settings()->recaptcha()->isEnabled() ) { |
| 163 | wp_enqueue_script( 'surecart-google-recaptcha' ); |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | /** |
| 168 | * Generate the terms html. |
| 169 | * |
| 170 | * @return string |
| 171 | */ |
| 172 | public function termsText() { |
| 173 | $terms_url = \SureCart::account()->portal_protocol->terms_url; |
| 174 | $privacy_url = \SureCart::account()->portal_protocol->privacy_url; |
| 175 | |
| 176 | if ( ! empty( $terms_url ) && ! empty( $privacy_url ) ) { |
| 177 | return sprintf( |
| 178 | // translators: %1$1s is the store name, %2$2s is the opening anchor tag, %3$3s is the closing anchor tag, %4$4s is the opening anchor tag, %5$5s is the closing anchor tag. |
| 179 | __( "I agree to %1$1s's %2$2sTerms%3$3s and %4$4sPrivacy Policy%5$5s", 'surecart' ), |
| 180 | esc_html( \SureCart::account()->name ), |
| 181 | '<a href="' . esc_url( $terms_url ) . '" target="_blank">', |
| 182 | '</a>', |
| 183 | '<a href="' . esc_url( $privacy_url ) . '" target="_blank">', |
| 184 | '</a>' |
| 185 | ); |
| 186 | } |
| 187 | |
| 188 | if ( $terms_url ) { |
| 189 | return sprintf( |
| 190 | // translators: %1$1s is the store name, %2$2s is the opening anchor tag, %3$3s is the closing anchor tag. |
| 191 | __( "I agree to %1$1s's %2$2sTerms%3$3s", 'surecart' ), |
| 192 | esc_html( \SureCart::account()->name ), |
| 193 | '<a href="' . esc_url( $terms_url ) . '" target="_blank">', |
| 194 | '</a>' |
| 195 | ); |
| 196 | } |
| 197 | |
| 198 | if ( $privacy_url ) { |
| 199 | return sprintf( |
| 200 | // translators: %1$1s is the store name, %2$2s is the opening anchor tag, %3$3s is the closing anchor tag. |
| 201 | __( "I agree to %1$1s's %2$2sPrivacy Policy%3$3s", 'surecart' ), |
| 202 | esc_html( \SureCart::account()->name ), |
| 203 | '<a href="' . esc_url( $privacy_url ) . '" target="_blank">', |
| 204 | '</a>' |
| 205 | ); |
| 206 | } |
| 207 | |
| 208 | return ''; |
| 209 | } |
| 210 | |
| 211 | /** |
| 212 | * Add the SEO meta data. |
| 213 | * |
| 214 | * @return void |
| 215 | */ |
| 216 | public function addSeoMetaData(): void { |
| 217 | $product = $this->model; |
| 218 | |
| 219 | if ( empty( $product ) ) { |
| 220 | return; |
| 221 | } |
| 222 | |
| 223 | $display_seo_meta = apply_filters( 'sc_display_instant_checkout_seo_meta', true, $product ); |
| 224 | if ( ! $display_seo_meta ) { |
| 225 | return; |
| 226 | } |
| 227 | |
| 228 | // render the seo meta. |
| 229 | \SureCart::productPost()->renderProductSeoMeta( $product ); |
| 230 | } |
| 231 | |
| 232 | /** |
| 233 | * Add the JSON-LD schema for the product. |
| 234 | * |
| 235 | * @return void |
| 236 | */ |
| 237 | public function addProductJsonSchema(): void { |
| 238 | $product = $this->model; |
| 239 | |
| 240 | if ( empty( $product ) ) { |
| 241 | return; |
| 242 | } |
| 243 | |
| 244 | $display_schema = apply_filters( 'sc_display_instant_checkout_json_ld_schema', true, $product ); |
| 245 | if ( ! $display_schema ) { |
| 246 | return; |
| 247 | } |
| 248 | |
| 249 | $schema = \SureCart::productPost()->getJsonSchemaArray( $product ) ?? []; |
| 250 | if ( empty( $schema ) ) { |
| 251 | return; |
| 252 | } |
| 253 | ?> |
| 254 | <script type="application/ld+json"><?php echo wp_json_encode( $schema ); ?></script> |
| 255 | <?php |
| 256 | } |
| 257 | } |
| 258 |