PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 3.1.2
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v3.1.2
3.3.0 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.1 trunk 1.0.4 1.1.0 1.1.0.1 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 All 162 releases
cartflows / admin-core / api / flows.php

flows.php in CartFlows – Funnel Builder & Checkout Plugin for WooCommerce 3.1.2, at admin-core/api/flows.php

361 lines 10.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * CartFlows Flows Query.
4 *
5 * @package CartFlows
6 */
7
8 namespace CartflowsAdmin\AdminCore\Api;
9
10 // Exit if accessed directly.
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 use CartflowsAdmin\AdminCore\Api\ApiBase;
16
17 /**
18 * Class Admin_Query.
19 */
20 class Flows extends ApiBase {
21
22 /**
23 * Route base.
24 *
25 * @var string
26 */
27 protected $rest_base = '/admin/flows/';
28
29 /**
30 * Instance
31 *
32 * @access private
33 * @var object Class object.
34 * @since 1.0.0
35 */
36 private static $instance;
37
38 /**
39 * Initiator
40 *
41 * @since 1.0.0
42 * @return object initialized object of class.
43 */
44 public static function get_instance() {
45 if ( ! isset( self::$instance ) ) {
46 self::$instance = new self();
47 }
48 return self::$instance;
49 }
50
51 /**
52 * Init Hooks.
53 *
54 * @since 1.0.0
55 * @return void
56 */
57 public function register_routes() {
58
59 // Eg. http://example.local/wp-json/cartflows/v1/admin/flows/.
60 $namespace = $this->get_api_namespace();
61
62 register_rest_route(
63 $namespace,
64 $this->rest_base,
65 array(
66 array(
67 'methods' => 'POST', // WP_REST_Server::READABLE.
68 'callback' => array( $this, 'get_items' ),
69 'permission_callback' => array( $this, 'get_items_permissions_check' ),
70 'args' => array(), // get_collection_params may use.
71 ),
72 'schema' => array( $this, 'get_public_item_schema' ),
73 )
74 );
75 }
76
77 /**
78 * Get items
79 *
80 * @param WP_REST_Request $request Full details about the request.
81 * @return WP_REST_Response
82 */
83 public function get_items( $request ) {
84
85 $post_status = 'any';
86 $post_count = 10;
87
88 if ( null !== $request->get_param( 'per_page' ) ) {
89 $post_count = min( absint( $request->get_param( 'per_page' ) ), 100 );
90 }
91
92 $args = array(
93 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
94 'post_status' => $post_status,
95 'orderby' => 'ID',
96 );
97
98 // checking if store checkout is available and removing it from the list of flows.
99 $store_checkout_id = intval( \Cartflows_Helper::get_global_setting( '_cartflows_store_checkout' ) );
100 if ( 0 !== $store_checkout_id ) {
101 $args['post__not_in'] = array( $store_checkout_id );
102 }
103
104 if ( null !== $request->get_param( 'paged' ) ) {
105 $args['paged'] = absint( $request->get_param( 'paged' ) );
106 }
107
108 $mode = $request->get_param( 'mode' );
109
110 if ( null !== $mode ) {
111
112 if ( 'sandbox' === $mode ) {
113 $args['meta_query'] = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
114 array(
115 'key' => 'wcf-testing',
116 'value' => 'yes',
117 ),
118 );
119 } else {
120 $args['meta_query'] = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
121 'relation' => 'OR',
122 array(
123 'key' => 'wcf-testing',
124 'value' => 'no',
125 ),
126 array(
127 'key' => 'wcf-testing',
128 'compare' => 'NOT EXISTS',
129 ),
130 );
131 }
132 }
133
134 if ( 'any' === $post_status ) {
135
136 if ( null !== $request->get_param( 's' ) ) {
137 $args['s'] = sanitize_text_field( $request->get_param( 's' ) );
138 }
139
140
141 if ( null !== $request->get_param( 'post_status' ) ) {
142
143 $status = $request->get_param( 'post_status' );
144
145 // Allowlist of valid post statuses for flows.
146 $allowed_statuses = array( 'active', 'inactive', 'publish', 'draft', 'pending', 'trash' );
147
148 if ( 'active' === $status ) {
149 $args['post_status'] = 'publish';
150 } elseif ( 'inactive' === $status ) {
151 $args['post_status'] = 'draft';
152 } elseif ( in_array( $status, $allowed_statuses, true ) ) {
153 $args['post_status'] = sanitize_text_field( $status );
154 }
155 // Invalid statuses are silently ignored, falling through to the default below.
156 }
157
158 if ( ! isset( $args['post_status'] ) || null === $request->get_param( 'post_status' ) ) {
159 $args['post_status'] = 'publish';
160 }
161
162 $start_date = $request->get_param( 'start_date' );
163 $end_date = $request->get_param( 'end_date' );
164
165 if ( ! empty( $start_date ) && ! empty( $end_date ) ) {
166 $args['date_query'] = array(
167 array(
168 'after' => sanitize_text_field( $start_date ) . ' 00:00:00',
169 'before' => sanitize_text_field( $end_date ) . ' 23:59:59',
170 'inclusive' => true,
171 'column' => 'post_date',
172 ),
173 );
174 }
175 }
176
177 if ( ! empty( $post_count ) ) {
178 $args['posts_per_page'] = $post_count;
179 }
180
181 $result = new \WP_Query( $args );
182
183 $data = array(
184 'items' => array(),
185 'pagination' => array(),
186 );
187
188 if ( $result->have_posts() ) {
189 while ( $result->have_posts() ) {
190 $result->the_post();
191
192 global $post;
193
194 $post_data = (array) $post;
195
196 // Modify the date Format just to display it.
197 $post_data['post_modified'] = date_format( date_create( $post_data['post_modified'] ), 'yy/m/d' );
198 $post_data['post_status'] = ucwords( $post_data['post_status'] );
199
200 $first_step_url = \Cartflows_Flow_Post_Type::get_instance()->get_first_step_url( $post );
201 $view = $first_step_url ? $first_step_url : '#';
202 $edit = admin_url( 'admin.php?page=cartflows&path=flows&action=wcf-edit-flow&flow_id=' . $post->ID );
203 $delete = '#';
204 $clone = '#';
205 $export = '#';
206 $post_data['flow_test_mode'] = ( 'yes' === wcf()->options->get_flow_meta_value( $post->ID, 'wcf-testing' ) ) ? true : false;
207 $flow_steps = get_post_meta( $post->ID, 'wcf-steps', true );
208 $post_data['step_count'] = is_array( $flow_steps ) ? count( $flow_steps ) : 0;
209 $post_data['actions'] = array(
210 'view' => array(
211 'action' => 'edit',
212 'class' => '',
213 'attr' => array( 'target' => '_blank' ),
214 'text' => __( 'View', 'cartflows' ),
215 'link' => $view,
216
217 ),
218 'edit' => array(
219 'action' => 'edit',
220 'class' => '',
221 'attr' => array(),
222 'text' => __( 'Edit', 'cartflows' ),
223 'link' => $edit,
224
225 ),
226 'duplicate' => array(
227 'action' => 'clone',
228 'attr' => array(),
229 'class' => '',
230 'text' => __( 'Duplicate', 'cartflows' ),
231 'link' => $clone,
232 ),
233 'export' => array(
234 'action' => 'export',
235 'attr' => array(),
236 'class' => '',
237 'text' => __( 'Export', 'cartflows' ),
238 'link' => $export,
239 ),
240 'delete' => array(
241 'action' => 'delete',
242 'attr' => array(),
243 'class' => '',
244 'text' => __( 'Delete', 'cartflows' ),
245 'link' => $delete,
246 ),
247 );
248
249 // Fetch the revenue only for free version for the PRO it will be fetched and added by the filter later in the code.
250 if ( ! _is_cartflows_pro() && ! is_wcf_pro_plan() ) {
251 $post_data['revenue'] = $this->get_per_flow_revenue( $post->ID );
252 }
253
254 $data['items'][] = $post_data;
255 }
256 }
257
258 $data['found_posts'] = $result->found_posts;
259 $data['post_status'] = isset( $post_data['post_status'] ) ? $post_data['post_status'] : $args['post_status'];
260
261 $data['active_flows_count'] = intval( wp_count_posts( CARTFLOWS_FLOW_POST_TYPE )->publish );
262 $data['trash_flows_count'] = intval( wp_count_posts( CARTFLOWS_FLOW_POST_TYPE )->trash );
263 $data['draft_flows_count'] = intval( wp_count_posts( CARTFLOWS_FLOW_POST_TYPE )->draft );
264
265 $data['pagination'] = array(
266 'found_posts' => $result->found_posts,
267 'paged' => $result->query['paged'],
268 'max_pages' => $result->max_num_pages,
269 );
270
271 // Reducing count of active_flows_count if store checkout is set.
272 if ( 0 !== $store_checkout_id ) {
273 $data['active_flows_count']--;
274 }
275
276 wp_reset_postdata();
277
278 $data['status'] = true;
279
280 // Retrieve the revenue data from the PRO to display it on the flow listing page.
281 if ( _is_cartflows_pro() && is_wcf_pro_plan() ) {
282 $data = apply_filters( 'cartflows_admin_flows_page_data', $data );
283 }
284
285 if ( ! $result->have_posts() ) {
286 $data['status'] = false;
287 $response = new \WP_REST_Response( $data );
288 $response->set_status( 200 );
289 return $response;
290 }
291
292 $response = new \WP_REST_Response( $data );
293 $response->set_status( 200 );
294
295 return $response;
296 }
297
298 /**
299 * Check whether a given request has permission to read notes.
300 *
301 * @param WP_REST_Request $request Full details about the request.
302 * @return WP_Error|boolean
303 */
304 public function get_items_permissions_check( $request ) {
305
306 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
307 return new \WP_Error( 'cartflows_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'cartflows' ), array( 'status' => rest_authorization_required_code() ) );
308 }
309
310 return true;
311 }
312
313 /**
314 * Get revenue of flow.
315 *
316 * @param int $flow_id flow id.
317 * @return int
318 */
319 public function get_per_flow_revenue( $flow_id ) {
320
321 $gross_sale = 0;
322
323 // Return if WooCommerce is not active.
324 if ( ! wcf()->is_woo_active ) {
325 return $gross_sale;
326 }
327
328 // Fetch primary orders: Checkout, Order Bumps.
329 $args = array(
330 'status' => array( 'completed', 'processing', 'cancelled' ), // Accepts a string: one of 'pending', 'processing', 'on-hold', 'completed', 'refunded, 'failed', 'cancelled', or a custom order status.
331 'meta_key' => '_wcf_flow_id', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
332 'meta_value' => $flow_id, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
333 'meta_compare' => '=', // Possible values are ‘=’, ‘!=’, ‘>’, ‘>=’, ‘<‘, ‘<=’, ‘LIKE’, ‘NOT LIKE’, ‘IN’, ‘NOT IN’, ‘BETWEEN’, ‘NOT BETWEEN’, ‘EXISTS’ (only in WP >= 3.5), and ‘NOT EXISTS’ (also only in WP >= 3.5). Values ‘REGEXP’, ‘NOT REGEXP’ and ‘RLIKE’ were added in WordPress 3.7. Default value is ‘=’.
334 'return' => 'ids', // Accepts a string: 'ids' or 'objects'. Default: 'objects'.
335 );
336
337 $orders = wc_get_orders( $args );
338
339 if ( ! empty( $orders ) && is_array( $orders ) ) {
340
341 foreach ( $orders as $order_id ) {
342
343 $order = wc_get_order( $order_id );
344 $user_id = $order->get_user_id();
345
346 // skip the orders which are placed by the user whose user role is Administrator.
347 if ( $user_id && user_can( $user_id, 'cartflows_manage_flows_steps' ) ) {
348 continue;
349 }
350
351 $order_total = $order->get_total();
352 if ( ! $order->has_status( 'cancelled' ) ) {
353 $gross_sale += (float) $order_total;
354 }
355 }
356 }
357
358 return str_replace( '&nbsp;', '', wc_price( $gross_sale ) );
359 }
360 }
361