PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
← All changes | inc/TemplateHooks/Profile/ProfileOrderTemplate.php +411 -326 4.3.84.4.8 View file →
@@ -1,326 +1,411 @@
1 -<?php
2 -/**
3 - * Class ProfileOrdersTemplate.
4 - *
5 - * @since 4.2.6.4
6 - * @version 1.0.2
7 - */
8 -
9 -namespace LearnPress\TemplateHooks\Profile;
10 -
11 -use LearnPress\Models\UserModel;
12 -use LP_Order;
13 -use LP_Profile;
14 -use LearnPress\Helpers\Template;
15 -use LearnPress\TemplateHooks\TemplateAJAX;
16 -use LP_Order_DB;
17 -use LP_Filter;
18 -use stdClass;
19 -
20 -class ProfileOrderTemplate {
21 - public static function instance() {
22 - static $instance = null;
23 -
24 - if ( is_null( $instance ) ) {
25 - $instance = new self();
26 - }
27 -
28 - return $instance;
29 - }
30 -
31 - public static function content() {
32 - do_action( 'learn-press/profile/layout/order-detail' );
33 - }
34 -
35 - protected function __construct() {
36 - add_action( 'learn-press/profile/layout/order-detail', [ $this, 'sections' ] );
37 - add_filter( 'lp/rest/ajax/allow_callback', array( $this, 'allow_callback' ) );
38 - }
39 -
40 - public static function init() {
41 - self::instance();
42 - }
43 -
44 - public function sections() {
45 - $profile = LP_Profile::instance();
46 - $order = $profile->get_view_order();
47 - if ( false === $order ) {
48 - return;
49 - }
50 -
51 - $can_view = false;
52 - if ( current_user_can( ADMIN_ROLE ) ) {
53 - $can_view = true;
54 - } elseif ( (int) $order->get_user_id() === get_current_user_id() ) {
55 - $can_view = true;
56 - }
57 -
58 - if ( ! $can_view ) {
59 - return;
60 - }
61 -
62 - if ( ! isset( $order ) ) {
63 - echo esc_html__( 'Invalid order', 'learnpress' );
64 -
65 - return;
66 - }
67 -
68 - $args = array(
69 - 'id_url' => 'lp-profile-view-order-details',
70 - 'order_id' => $order->get_id(),
71 - 'paged' => 1,
72 - );
73 - $call_back = array(
74 - 'class' => self::class,
75 - 'method' => 'render_order_details',
76 - );
77 - echo TemplateAJAX::load_content_via_ajax( $args, $call_back );
78 - }
79 -
80 - /**
81 - * Allow callback for AJAX.
82 - *
83 - * @use self::render_order_details
84 - *
85 - * @param array $callbacks
86 - *
87 - * @return array
88 - */
89 - public function allow_callback( array $callbacks ): array {
90 - $callbacks[] = get_class( $this ) . ':render_order_details';
91 -
92 - return $callbacks;
93 - }
94 -
95 - /**
96 - * Render order details content via AJAX.
97 - *
98 - * @param array $args
99 - *
100 - * @return stdClass
101 - * @since 4.3.2
102 - * @version 1.0.1
103 - */
104 - public static function render_order_details( array $args ): stdClass {
105 - $content = new stdClass();
106 -
107 - $order_id = $args['order_id'] ?? 0;
108 - $paged = $args['paged'] ?? 1;
109 -
110 - $can_view = false;
111 - $user_id = get_current_user_id();
112 -
113 - if ( current_user_can( UserModel::ROLE_ADMINISTRATOR ) ) {
114 - $can_view = true;
115 - } else {
116 - $order = learn_press_get_order( $order_id );
117 - if ( $order && (int) $order->get_user_id() === $user_id ) {
118 - $can_view = true;
119 - }
120 - }
121 -
122 - if ( ! $can_view ) {
123 - return $content;
124 - }
125 -
126 - $limit = 10;
127 - $lp_order_db = LP_Order_DB::getInstance();
128 - $filter = new LP_Filter();
129 - $filter->limit = $limit;
130 - $filter->page = $paged;
131 - $total_row = 0;
132 - $items = $lp_order_db->get_items( $filter, $order_id, $total_row );
133 - $html_items = '';
134 - $order = learn_press_get_order( $order_id );
135 -
136 - if ( empty( $items ) ) {
137 - $html_items = sprintf(
138 - '<tr class="order-item"><td colspan="4">%s</td></tr>',
139 - __( 'No items found', 'learnpress' )
140 - );
141 - } else {
142 - foreach ( $items as $item ) {
143 - $item_course_id_meta = learn_press_get_order_item_meta( $item->order_item_id, '_course_id' );
144 - // For old data, the data not migrated yet to new column.
145 - if ( ( empty( $item->item_type ) || empty( $item->item_id ) )
146 - && ! empty( $item_course_id_meta ) ) {
147 - $item->item_id = $item_course_id_meta;
148 - $item->item_type = LP_COURSE_CPT;
149 - }
150 -
151 - $html_items .= self::order_item_row_html( $order, $item );
152 - }
153 - }
154 - $total_pages = $lp_order_db::get_total_pages( $limit, $total_row );
155 - $html_pagination = Template::instance()->html_pagination(
156 - [
157 - 'total_pages' => $total_pages,
158 - 'paged' => $paged,
159 - ]
160 - );
161 - if ( ! empty( $html_pagination ) ) {
162 - $html_pagination = sprintf(
163 - '<tr class="order-item">
164 - <td class="lp-order-items-wrapper" style="margin:0;text-align:left;" colspan="2">%s</td>
165 - </tr>',
166 - $html_pagination
167 - );
168 - }
169 -
170 - $section = array(
171 - 'header' => sprintf(
172 - '<h3>%s</h3>',
173 - esc_html__( 'Order Details', 'learnpress' )
174 - ),
175 - 'table' => '<table class="lp-list-table order-table-details">',
176 - 'table-header' => self::table_header(),
177 - 'table-body' => '<tbody>',
178 - 'items' => $html_items,
179 - 'pagination' => $html_pagination,
180 - 'do_action_items' => self::action_table_items( $order ),
181 - 'table-body-end' => '</tbody>',
182 - 'table-footer' => self::table_footer( $order ),
183 - 'table-end' => '</table>',
184 - 'footer' => self::order_detail_content_footer( $order ),
185 - );
186 - $content->content = Template::combine_components( $section );
187 -
188 - return $content;
189 - }
190 -
191 - public static function table_header() {
192 - $section = array(
193 - 'wrap' => '<thead>',
194 - 'row' => sprintf(
195 - '<tr>
196 - <th>%s</th>
197 - <th>%s</th>
198 - </tr>',
199 - __( 'Item', 'learnpress' ),
200 - __( 'Total', 'learnpress' )
201 - ),
202 - 'wrap-end' => '</thead>',
203 - );
204 -
205 - return Template::combine_components( $section );
206 - }
207 -
208 - /**
209 - * HTML for table footer in order detail page.
210 - *
211 - * @param LP_Order $order
212 - *
213 - * @return string
214 - * @since 4.3.2
215 - * @version 1.0.1
216 - */
217 - public static function table_footer( $order ): string {
218 - ob_start();
219 - do_action( 'learn-press/order/items-table-foot', $order );
220 - $html_after_subtotal_row = ob_get_clean();
221 -
222 - $section = array(
223 - 'wrap' => '<tfoot>',
224 - 'subtotal_row' => sprintf(
225 - '<tr><th scope="row">%s</th><td>%s</td></tr>',
226 - esc_html__( 'Subtotal', 'learnpress' ),
227 - esc_html( $order->get_formatted_order_subtotal() )
228 - ),
229 - 'action' => $html_after_subtotal_row,
230 - 'total_row' => sprintf(
231 - '<tr><th scope="row">%s</th><td>%s</td></tr>',
232 - esc_html__( 'Total', 'learnpress' ),
233 - esc_html( $order->get_formatted_order_total() )
234 - ),
235 - 'wrap-end' => '</tfoot>',
236 - );
237 -
238 - return Template::combine_components( $section );
239 - }
240 -
241 - public static function action_table_items( $order ) {
242 - ob_start();
243 - do_action( 'learn-press/order/items-table', $order );
244 -
245 - return ob_get_clean();
246 - }
247 -
248 - /**
249 - * HTMl for each order item row in order detail page.
250 - *
251 - * @param LP_Order $order
252 - * @param object $item
253 - *
254 - * @return string
255 - * @since 4.3.2
256 - * @version 1.0.1
257 - */
258 - public static function order_item_row_html( $order, $item ): string {
259 - $total = learn_press_get_order_item_meta( $item->order_item_id, '_total' );
260 - $total = ! empty( $total ) ? $total : 0;
261 - $quantity = learn_press_get_order_item_meta( $item->order_item_id, '_quantity' );
262 - $currency_symbol = learn_press_get_currency_symbol( $order->get_currency() ?? learn_press_get_currency() );
263 - $item_label = esc_html( $item->order_item_name );
264 - if ( $item->item_type === LP_COURSE_CPT ) {
265 - $item_label = sprintf(
266 - '<a href="%s">%s</a>',
267 - esc_url_raw( get_permalink( $item->item_id ) ),
268 - esc_html( $item->order_item_name )
269 - );
270 - }
271 - $item_label = apply_filters(
272 - 'learn-press/profile/order/item-label',
273 - $item_label,
274 - (array) $item,
275 - $order
276 - );
277 -
278 - $section = apply_filters(
279 - 'learn-press/profile/order/item-row-html',
280 - array(
281 - 'wrap' => '<tr class="order-item">',
282 - 'name-cell' => sprintf(
283 - '<td>%s</td>',
284 - $item_label
285 - ),
286 - 'total-cell' => sprintf(
287 - '<td><span class="course-price">%s</span></td>',
288 - learn_press_format_price( $total, $currency_symbol )
289 - ),
290 - 'wrap-end' => '</tr>',
291 - )
292 - );
293 -
294 - return Template::combine_components( $section );
295 - }
296 -
297 - /**
298 - * HTML content footer, below table list items for order detail page.
299 - *
300 - * @param LP_Order $order
301 - *
302 - * @return string
303 - * @since 4.3.2
304 - * @version 1.0.1
305 - */
306 - public static function order_detail_content_footer( $order ): string {
307 - $section = array(
308 - 'order_key' => sprintf(
309 - '<p><strong>%s</strong> %s</p>',
310 - esc_html__( 'Order key:', 'learnpress' ),
311 - esc_html( $order->get_order_key() )
312 - ),
313 - 'order_status' => sprintf(
314 - '<p>
315 - <strong>%s</strong>
316 - <span class="lp-label label-%s">%s</span>
317 - </p>',
318 - esc_html__( 'Order status:', 'learnpress' ),
319 - esc_attr( $order->get_status() ),
320 - wp_kses_post( $order->get_order_status_html() )
321 - ),
322 - );
323 -
324 - return Template::combine_components( $section );
325 - }
326 -}
1 +<?php
2 +/**
3 + * Class ProfileOrdersTemplate.
4 + *
5 + * @since 4.2.6.4
6 + * @version 1.0.2
7 + */
8 +
9 +namespace LearnPress\TemplateHooks\Profile;
10 +
11 +use LearnPress\Models\UserModel;
12 +use LP_Order;
13 +use LP_Profile;
14 +use LearnPress\Helpers\Template;
15 +use LearnPress\TemplateHooks\TemplateAJAX;
16 +use LP_Order_DB;
17 +use LP_Filter;
18 +use stdClass;
19 +
20 +class ProfileOrderTemplate {
21 + public static function instance() {
22 + static $instance = null;
23 +
24 + if ( is_null( $instance ) ) {
25 + $instance = new self();
26 + }
27 +
28 + return $instance;
29 + }
30 +
31 + public static function content() {
32 + do_action( 'learn-press/profile/layout/order-detail' );
33 + }
34 +
35 + protected function __construct() {
36 + add_action( 'learn-press/profile/layout/order-detail', array( $this, 'sections' ) );
37 + add_filter( 'lp/rest/ajax/allow_callback', array( $this, 'allow_callback' ) );
38 + }
39 +
40 + public static function init() {
41 + self::instance();
42 + }
43 +
44 + public function sections() {
45 + $profile = LP_Profile::instance();
46 + $order = $profile->get_view_order();
47 + if ( false === $order ) {
48 + return;
49 + }
50 +
51 + $can_view = false;
52 + if ( current_user_can( ADMIN_ROLE ) ) {
53 + $can_view = true;
54 + } elseif ( (int) $order->get_user_id() === get_current_user_id() ) {
55 + $can_view = true;
56 + }
57 +
58 + if ( ! $can_view ) {
59 + return;
60 + }
61 +
62 + if ( ! isset( $order ) ) {
63 + echo esc_html__( 'Invalid order', 'learnpress' );
64 +
65 + return;
66 + }
67 +
68 + $args = array(
69 + 'id_url' => 'lp-profile-view-order-details',
70 + 'order_id' => $order->get_id(),
71 + 'paged' => 1,
72 + );
73 + $call_back = array(
74 + 'class' => self::class,
75 + 'method' => 'render_order_details',
76 + );
77 + echo TemplateAJAX::load_content_via_ajax( $args, $call_back );
78 + }
79 +
80 + /**
81 + * Allow callback for AJAX.
82 + *
83 + * @use self::render_order_details
84 + *
85 + * @param array $callbacks
86 + *
87 + * @return array
88 + */
89 + public function allow_callback( array $callbacks ): array {
90 + $callbacks[] = get_class( $this ) . ':render_order_details';
91 +
92 + return $callbacks;
93 + }
94 +
95 + /**
96 + * Render order details content via AJAX.
97 + *
98 + * @param array $args
99 + *
100 + * @return stdClass
101 + * @since 4.3.2
102 + * @version 1.0.1
103 + */
104 + public static function render_order_details( array $args ): stdClass {
105 + $content = new stdClass();
106 +
107 + $order_id = $args['order_id'] ?? 0;
108 + $paged = $args['paged'] ?? 1;
109 +
110 + $can_view = false;
111 + $user_id = get_current_user_id();
112 +
113 + if ( current_user_can( UserModel::ROLE_ADMINISTRATOR ) ) {
114 + $can_view = true;
115 + } else {
116 + $order = learn_press_get_order( $order_id );
117 + if ( $order && (int) $order->get_user_id() === $user_id ) {
118 + $can_view = true;
119 + }
120 + }
121 +
122 + if ( ! $can_view ) {
123 + return $content;
124 + }
125 +
126 + $limit = 10;
127 + $lp_order_db = LP_Order_DB::getInstance();
128 + $filter = new LP_Filter();
129 + $filter->limit = $limit;
130 + $filter->page = $paged;
131 + $total_row = 0;
132 + $items = $lp_order_db->get_items( $filter, $order_id, $total_row );
133 + $html_items = '';
134 + $order = learn_press_get_order( $order_id );
135 +
136 + if ( empty( $items ) ) {
137 + $html_items = sprintf(
138 + '<tr class="order-item"><td colspan="4">%s</td></tr>',
139 + __( 'No items found', 'learnpress' )
140 + );
141 + } else {
142 + foreach ( $items as $item ) {
143 + $item_course_id_meta = learn_press_get_order_item_meta( $item->order_item_id, '_course_id' );
144 + // For old data, the data not migrated yet to new column.
145 + if ( ( empty( $item->item_type ) || empty( $item->item_id ) )
146 + && ! empty( $item_course_id_meta ) ) {
147 + $item->item_id = $item_course_id_meta;
148 + $item->item_type = LP_COURSE_CPT;
149 + }
150 +
151 + $html_items .= self::order_item_row_html( $order, $item );
152 + }
153 + }
154 + $total_pages = $lp_order_db::get_total_pages( $limit, $total_row );
155 + $html_pagination = Template::instance()->html_pagination(
156 + array(
157 + 'total_pages' => $total_pages,
158 + 'paged' => $paged,
159 + )
160 + );
161 + if ( ! empty( $html_pagination ) ) {
162 + $html_pagination = sprintf(
163 + '<tr class="order-item">
164 + <td class="lp-order-items-wrapper" style="margin:0;text-align:left;" colspan="2">%s</td>
165 + </tr>',
166 + $html_pagination
167 + );
168 + }
169 +
170 + $section = array(
171 + 'header' => sprintf(
172 + '<h3>%s</h3>',
173 + esc_html__( 'Order Details', 'learnpress' )
174 + ),
175 + 'table' => '<div class="lp-table-wrap"><table class="lp-list-table order-table-details">',
176 + 'table-header' => self::table_header(),
177 + 'table-body' => '<tbody>',
178 + 'items' => $html_items,
179 + 'pagination' => $html_pagination,
180 + 'do_action_items' => self::action_table_items( $order ),
181 + 'table-body-end' => '</tbody>',
182 + 'table-footer' => self::table_footer( $order ),
183 + 'table-end' => '</table></div>',
184 + 'footer' => self::order_detail_content_footer( $order ),
185 + );
186 + $content->content = Template::combine_components( $section );
187 +
188 + return $content;
189 + }
190 +
191 + public static function table_header() {
192 + $section = array(
193 + 'wrap' => '<thead>',
194 + 'row' => sprintf(
195 + '<tr>
196 + <th>%s</th>
197 + <th>%s</th>
198 + </tr>',
199 + __( 'Item', 'learnpress' ),
200 + __( 'Total', 'learnpress' )
201 + ),
202 + 'wrap-end' => '</thead>',
203 + );
204 +
205 + return Template::combine_components( $section );
206 + }
207 +
208 + /**
209 + * HTML for table footer in order detail page.
210 + *
211 + * @param LP_Order $order
212 + *
213 + * @return string
214 + * @since 4.3.2
215 + * @version 1.0.1
216 + */
217 + public static function table_footer( $order ): string {
218 + ob_start();
219 + do_action( 'learn-press/order/items-table-foot', $order );
220 + $html_after_subtotal_row = ob_get_clean();
221 +
222 + $section = array(
223 + 'wrap' => '<tfoot>',
224 + 'subtotal_row' => sprintf(
225 + '<tr><th scope="row">%s</th><td>%s</td></tr>',
226 + esc_html__( 'Subtotal', 'learnpress' ),
227 + esc_html( $order->get_formatted_order_subtotal() )
228 + ),
229 + 'action' => $html_after_subtotal_row,
230 + 'total_row' => sprintf(
231 + '<tr><th scope="row">%s</th><td>%s</td></tr>',
232 + esc_html__( 'Total', 'learnpress' ),
233 + esc_html( $order->get_formatted_order_total() )
234 + ),
235 + 'wrap-end' => '</tfoot>',
236 + );
237 +
238 + return Template::combine_components( $section );
239 + }
240 +
241 + public static function action_table_items( $order ) {
242 + ob_start();
243 + do_action( 'learn-press/order/items-table', $order );
244 +
245 + return ob_get_clean();
246 + }
247 +
248 + /**
249 + * HTMl for each order item row in order detail page.
250 + *
251 + * @param LP_Order $order
252 + * @param object $item
253 + *
254 + * @return string
255 + * @since 4.3.2
256 + * @version 1.0.1
257 + */
258 + public static function order_item_row_html( $order, $item ): string {
259 + $total = learn_press_get_order_item_meta( $item->order_item_id, '_total' );
260 + $total = ! empty( $total ) ? $total : 0;
261 + $quantity = learn_press_get_order_item_meta( $item->order_item_id, '_quantity' );
262 + $currency_symbol = learn_press_get_currency_symbol( $order->get_currency() ?? learn_press_get_currency() );
263 + $item_label = esc_html( $item->order_item_name );
264 + if ( $item->item_type === LP_COURSE_CPT ) {
265 + $item_label = sprintf(
266 + '<a href="%s">%s</a>',
267 + esc_url_raw( get_permalink( $item->item_id ) ),
268 + esc_html( $item->order_item_name )
269 + );
270 + }
271 + $item_label = apply_filters(
272 + 'learn-press/profile/order/item-label',
273 + $item_label,
274 + (array) $item,
275 + $order
276 + );
277 +
278 + $section = apply_filters(
279 + 'learn-press/profile/order/item-row-html',
280 + array(
281 + 'wrap' => '<tr class="order-item">',
282 + 'name-cell' => sprintf(
283 + '<td>%s</td>',
284 + $item_label
285 + ),
286 + 'total-cell' => sprintf(
287 + '<td><span class="course-price">%s</span></td>',
288 + learn_press_format_price( $total, $currency_symbol )
289 + ),
290 + 'wrap-end' => '</tr>',
291 + )
292 + );
293 +
294 + return Template::combine_components( $section );
295 + }
296 +
297 + /**
298 + * HTML content footer, below table list items for order detail page.
299 + *
300 + * @param LP_Order $order
301 + *
302 + * @return string
303 + * @since 4.3.2
304 + * @version 1.0.1
305 + */
306 + public static function order_detail_content_footer( $order ): string {
307 + $section = array(
308 + 'order_key' => sprintf(
309 + '<p><strong>%s</strong> %s</p>',
310 + esc_html__( 'Order key:', 'learnpress' ),
311 + esc_html( $order->get_order_key() )
312 + ),
313 + 'order_status' => sprintf(
314 + '<p>
315 + <strong>%s</strong>
316 + <span class="lp-label label-%s">%s</span>
317 + </p>',
318 + esc_html__( 'Order status:', 'learnpress' ),
319 + esc_attr( $order->get_status() ),
320 + wp_kses_post( $order->get_order_status_html() )
321 + ),
322 + 'refund_request_status' => self::refund_request_status_html( $order ),
323 + 'refund_note' => self::refund_note_html( $order ),
324 + );
325 +
326 + return Template::combine_components( $section );
327 + }
328 +
329 + /**
330 + * HTML for refund request status in order detail page.
331 + *
332 + * @param LP_Order $order
333 + *
334 + * @return string
335 + * @since 4.3.9
336 + * @version 1.0.0
337 + */
338 + public static function refund_request_status_html( $order ): string {
339 +
340 + $refund_request_status = $order->get_refund_request();
341 + if ( empty( $refund_request_status ) ) {
342 + return '';
343 + }
344 +
345 + $status_labels = array(
346 + 'pending' => __( 'Pending', 'learnpress' ),
347 + 'rejected' => __( 'Rejected', 'learnpress' ),
348 + 'approved' => __( 'Accepted', 'learnpress' ),
349 + 'auto-approved' => __( 'Accepted', 'learnpress' ),
350 + );
351 + $status_label = $status_labels[ $refund_request_status ] ?? ucwords( str_replace( '-', ' ', $refund_request_status ) );
352 +
353 + $html_status = sprintf(
354 + '<p class="lp-order-refund-request-status">
355 + <strong>%s</strong>
356 + <span class="lp-label label-%s">%s</span>
357 + </p>',
358 + esc_html__( 'Refund request:', 'learnpress' ),
359 + esc_attr( $refund_request_status ),
360 + esc_html( $status_label )
361 + );
362 +
363 + $currency_symbol = learn_press_get_currency_symbol( $order->get_currency() );
364 + $refunded_amount = (float) $order->get_meta( LP_Order::META_KEY_REFUNDED_AMOUNT );
365 + $html_amount = '';
366 + if ( $refunded_amount > 0 ) {
367 + $refunded_amount = learn_press_format_price( $refunded_amount, $currency_symbol );
368 + $html_amount = sprintf(
369 + '<p class="lp-order-refunded-amount">
370 + <strong>%s</strong>
371 + <span>%s</span>
372 + </p>',
373 + esc_html__( 'Refund amount:', 'learnpress' ),
374 + esc_html( $refunded_amount )
375 + );
376 + }
377 +
378 + return Template::combine_components(
379 + [
380 + 'status' => $html_status,
381 + 'amount' => $html_amount,
382 + ]
383 + );
384 + }
385 +
386 + /**
387 + * HTML for refund note in order detail page.
388 + *
389 + * @param LP_Order $order
390 + *
391 + * @return string
392 + * @since 4.3.9
393 + * @version 1.0.0
394 + */
395 + public static function refund_note_html( $order ): string {
396 +
397 + $refund_note = trim( (string) get_post_meta( $order->get_id(), '_lp_refund_note', true ) );
398 + if ( empty( $refund_note ) ) {
399 + return '';
400 + }
401 +
402 + return sprintf(
403 + '<p class="lp-order-refund-note">
404 + <strong>%s</strong>
405 + <span>%s</span>
406 + </p>',
407 + esc_html__( 'Refund note:', 'learnpress' ),
408 + nl2br( esc_html( $refund_note ) )
409 + );
410 + }
411 +}