PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 4.6.0
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v4.6.0
4.6.1 4.6.0 4.5.1 4.5.0 4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.11.1 1.11.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.13.0 2.14.0 2.14.1 2.15.0 2.15.1 2.16.0 2.16.1 2.16.2 2.16.3 2.17.0 2.17.1 2.17.2 2.18.0 2.19.0 2.19.2 2.19.3 2.19.4 2.2.0 2.2.1 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.26.0 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.2 2.29.3 2.29.4 2.3.0 2.3.1 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.40.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.9.0 3.0.0 3.0.0-RC1 3.0.0-RC2 3.0.0-beta1 3.0.0-beta2 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.10.0 3.10.1 3.11.0 3.12.0 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.14.0 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.16.6 3.16.7 3.16.8 3.17.0 3.17.1 3.17.2 3.17.3 3.17.4 3.17.5 3.17.6 3.18.0 3.19.0 3.19.1 3.19.2 3.2.0 3.2.1 3.2.2 3.20.0 3.20.1 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 trunk 4.1.0 0.2.19.1 4.1.1 1.0.0 4.2.0 1.0.1 1.0.2
surecart / app / src / Controllers / Web / BuyPageController.php
surecart / app / src / Controllers / Web Last commit date
.gitkeep 4 years ago BasePageController.php 1 year ago BuyPageController.php 5 days ago CheckoutFormsController.php 2 years ago DashboardController.php 4 months ago PurchaseController.php 4 years ago SubscriptionsController.php 4 years ago UpsellPageController.php 1 year ago WebhookController.php 2 years ago
BuyPageController.php
274 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 $is_bundle = ! empty( $this->model->bundle );
54 $url_key = $is_bundle ? 'bundle' : 'product';
55 $wp_admin_bar->add_node(
56 [
57 'id' => 'edit',
58 'title' => $is_bundle ? __( 'Edit Bundle', 'surecart' ) : __( 'Edit Product', 'surecart' ),
59 'href' => esc_url( \SureCart::getUrl()->edit( $url_key, $this->model->id ) ),
60 ]
61 );
62 }
63
64 /**
65 * Show the product page
66 *
67 * @param \SureCartCore\Requests\RequestInterface $request Request.
68 * @param \SureCartCore\View $view View.
69 * @param string $id The id of the product.
70 * @return function
71 */
72 public function show( $request, $view, $id ) {
73 // The route always passes a product slug here.
74 $id = get_query_var( 'sc_checkout_product_id' );
75
76 // fetch the product by id/slug. Bundle expands carry live component
77 // variant stock, so the buy page renders fresh availability in one fetch.
78 $this->model = \SureCart\Models\Product::with(
79 \SureCart\Models\Product::storefrontExpands()
80 )->find( $id );
81
82 if ( is_wp_error( $this->model ) ) {
83 return $this->handleError( $this->model );
84 }
85
86 // if this buy page is not enabled, check read permissions.
87 if ( ! $this->model->buyLink()->isEnabled() && ! current_user_can( 'read_sc_products' ) ) {
88 return $this->notFound();
89 }
90
91 // slug changed or we are using the id, redirect.
92 if ( $this->model->slug !== $id ) {
93 return \SureCart::redirect()->to( esc_url_raw( \SureCart::routeUrl( 'product', [ 'id' => $this->model->slug ] ) ) );
94 }
95
96 // get active prices.
97 $active_prices = $this->model->active_prices;
98
99 // must have at least one active price.
100 if ( empty( $active_prices[0] ) ) {
101 return $this->notFound();
102 }
103
104 // prevent 404 redirects by 3rd party plugins.
105 $_SERVER['REQUEST_URI'] = $request->getUrl();
106
107 // add the filters.
108 $this->filters();
109
110 // prepare data.
111 $this->model = $this->model->withActivePrices()->withSortedPrices();
112 $first_variant_with_stock = $this->model->first_variant_with_stock;
113
114 if ( ! empty( $this->model->prices->data[0]->id ) ) {
115 $line_item = array_merge(
116 [
117 'price_id' => $this->model->prices->data[0]->id,
118 'quantity' => 1,
119 ],
120 ! empty( $first_variant_with_stock->id ) ? [ 'variant_id' => $first_variant_with_stock->id ] : []
121 );
122
123 // Bundles require a variant selection per variable component on checkout creation.
124 if ( ! empty( $this->model->bundle ) ) {
125 $bundle_component_variants = (array) ( new \SureCart\Models\Blocks\ProductPageBlock() )
126 ->getInitialBundleComponentVariants( $this->model );
127 if ( ! empty( $bundle_component_variants ) ) {
128 $line_item['bundle_component_variants'] = $bundle_component_variants;
129 }
130 }
131
132 sc_initial_state(
133 [
134 'checkout' => [
135 'initialLineItems' => sc_initial_line_items( [ $line_item ] ),
136 ],
137 ]
138 );
139 }
140
141 // render the view.
142 return \SureCart::view( 'web/buy' )->with(
143 [
144 'product' => $this->model,
145 'terms_text' => $this->termsText(),
146 'mode' => $this->model->buyLink()->getMode(),
147 'store_name' => \SureCart::account()->name ?? get_bloginfo(),
148 'logo_url' => \SureCart::theme()->logoUrl(),
149 'logo_width' => \SureCart::settings()->get( 'buy_link_logo_width', '180px' ),
150 'user' => wp_get_current_user(),
151 'logout_link' => wp_logout_url( $request->getUrl() ),
152 'dashboard_link' => \SureCart::pages()->url( 'dashboard' ),
153 'enabled' => $this->model->buyLink()->isEnabled(),
154 'show_logo' => $this->model->buyLink()->templatePartEnabled( 'logo' ),
155 'show_terms' => $this->model->buyLink()->templatePartEnabled( 'terms' ),
156 'show_image' => $this->model->buyLink()->templatePartEnabled( 'image' ),
157 'show_description' => $this->model->buyLink()->templatePartEnabled( 'description' ),
158 'show_coupon' => $this->model->buyLink()->templatePartEnabled( 'coupon' ),
159 'success_url' => $this->model->buyLink()->getSuccessUrl(),
160 ]
161 );
162 }
163
164 /**
165 * Enqueue styles.
166 *
167 * @return void
168 */
169 public function styles() {
170 wp_enqueue_style(
171 'surecart/instant-checkout',
172 trailingslashit( \SureCart::core()->assets()->getUrl() ) . 'dist/templates/instant-checkout.css',
173 [],
174 filemtime( trailingslashit( plugin_dir_path( SURECART_PLUGIN_FILE ) ) . 'dist/templates/instant-checkout.css' ),
175 );
176
177 // add recaptcha if enabled.
178 if ( \SureCart::settings()->recaptcha()->isEnabled() ) {
179 wp_enqueue_script( 'surecart-google-recaptcha' );
180 }
181 }
182
183 /**
184 * Generate the terms html.
185 *
186 * @return string
187 */
188 public function termsText() {
189 $terms_url = \SureCart::account()->customer_portal_protocol->terms_url;
190 $privacy_url = \SureCart::account()->customer_portal_protocol->privacy_url;
191
192 if ( ! empty( $terms_url ) && ! empty( $privacy_url ) ) {
193 return sprintf(
194 // 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.
195 __( "I agree to %1$1s's %2$2sTerms%3$3s and %4$4sPrivacy Policy%5$5s", 'surecart' ),
196 esc_html( \SureCart::account()->name ),
197 '<a href="' . esc_url( $terms_url ) . '" target="_blank">',
198 '</a>',
199 '<a href="' . esc_url( $privacy_url ) . '" target="_blank">',
200 '</a>'
201 );
202 }
203
204 if ( $terms_url ) {
205 return sprintf(
206 // translators: %1$1s is the store name, %2$2s is the opening anchor tag, %3$3s is the closing anchor tag.
207 __( "I agree to %1$1s's %2$2sTerms%3$3s", 'surecart' ),
208 esc_html( \SureCart::account()->name ),
209 '<a href="' . esc_url( $terms_url ) . '" target="_blank">',
210 '</a>'
211 );
212 }
213
214 if ( $privacy_url ) {
215 return sprintf(
216 // translators: %1$1s is the store name, %2$2s is the opening anchor tag, %3$3s is the closing anchor tag.
217 __( "I agree to %1$1s's %2$2sPrivacy Policy%3$3s", 'surecart' ),
218 esc_html( \SureCart::account()->name ),
219 '<a href="' . esc_url( $privacy_url ) . '" target="_blank">',
220 '</a>'
221 );
222 }
223
224 return '';
225 }
226
227 /**
228 * Add the SEO meta data.
229 *
230 * @return void
231 */
232 public function addSeoMetaData(): void {
233 $product = $this->model;
234
235 if ( empty( $product ) ) {
236 return;
237 }
238
239 $display_seo_meta = apply_filters( 'sc_display_instant_checkout_seo_meta', true, $product );
240 if ( ! $display_seo_meta ) {
241 return;
242 }
243
244 // render the seo meta.
245 \SureCart::productPost()->renderProductSeoMeta( $product );
246 }
247
248 /**
249 * Add the JSON-LD schema for the product.
250 *
251 * @return void
252 */
253 public function addProductJsonSchema(): void {
254 $product = $this->model;
255
256 if ( empty( $product ) ) {
257 return;
258 }
259
260 $display_schema = apply_filters( 'sc_display_instant_checkout_json_ld_schema', true, $product );
261 if ( ! $display_schema ) {
262 return;
263 }
264
265 $schema = \SureCart::productPost()->getJsonSchemaArray( $product ) ?? [];
266 if ( empty( $schema ) ) {
267 return;
268 }
269 ?>
270 <script type="application/ld+json"><?php echo wp_json_encode( $schema ); ?></script>
271 <?php
272 }
273 }
274