public static function poll() { // This is a super lightweight API to get posts and comments from WP // It's intended for use with o2 // @todo Allow requesting a specific post or comment, and a post with all comments // Need to sort things because they're queried separately function o2_date_sort($a, $b) { if ($a->unixtime == $b->unixtime) { return 0; } return $a->unixtime > $b->unixtime ? -1 : 1; } $ok_to_serve_data = true; $ok_to_serve_data = apply_filters('o2_read_api_ok_to_serve_data', $ok_to_serve_data); $data = array(); if ($ok_to_serve_data) { $posts = self::get_posts(); $comments = self::get_comments(); // Clean up posts and comments $data = array(); if (count($posts)) { foreach ($posts as $post) { $data[] = o2_Fragment::get_fragment($post); } } if (count($comments)) { foreach ($comments as $comment) { $data[] = o2_Fragment::get_fragment($comment); } } // Shuffle up and deal usort($data, 'o2_date_sort'); } // Let the client know if the user is logged in or not $is_logged_in = is_user_logged_in(); // Generate an updated nonce (they expire after all, and our "app" may be open for a long time) $new_nonce = wp_create_nonce('o2_nonce'); if ($is_logged_in) { // @todo change to another way, and one that is less costly - see also below // $current_user_id = get_current_user_id(); // update_user_meta( $current_user_id, 'o2_last_poll_gmt', time() ); } $response = array("data" => $data, "newNonce" => $new_nonce, "loggedIn" => $is_logged_in); // Check for unloaded scripts and styles if there are polled posts if (!empty($data)) { // Attach scripts if (isset($_REQUEST['scripts'])) { // Parse and sanitize the script handles already output if (!is_array($_REQUEST['scripts'])) { $_REQUEST['scripts'] = explode(',', $_REQUEST['scripts']); } $initial_scripts = is_array($_REQUEST['scripts']) ? array_map('sanitize_text_field', $_REQUEST['scripts']) : null; if (is_array($initial_scripts)) { global $wp_scripts; if (!$wp_scripts instanceof WP_Scripts) { $wp_scripts = new WP_Scripts(); } // Identify new scripts needed by the polled posts $polled_scripts = array_diff($wp_scripts->done, $initial_scripts); // If new scripts are needed, extract relevant data from $wp_scripts if (!empty($polled_scripts)) { $response['scripts'] = array(); foreach ($polled_scripts as $handle) { // Abort if the handle doesn't match a registered script if (!isset($wp_scripts->registered[$handle])) { continue; } // Provide basic script data $script_data = array('handle' => $handle, 'footer' => is_array($wp_scripts->in_footer) && in_array($handle, $wp_scripts->in_footer), 'extra_data' => $wp_scripts->print_extra_script($handle, false)); // Base source $src = $wp_scripts->registered[$handle]->src; // Take base_url into account if (strpos($src, '//') === 0) { $src = is_ssl() ? 'https:' . $src : 'http:' . $src; } // Deal with root-relative URLs if (strpos($src, '/') === 0) { $src = $wp_scripts->base_url . $src; } if (strpos($src, 'http') !== 0) { $src = $wp_scripts->base_url . $src; } // Version and additional arguments if (null === $wp_scripts->registered[$handle]->ver) { $ver = ''; } else { $ver = $wp_scripts->registered[$handle]->ver ? $wp_scripts->registered[$handle]->ver : $wp_scripts->default_version; } if (isset($wp_scripts->args[$handle])) { $ver = $ver ? $ver . '&' . $wp_scripts->args[$handle] : $wp_scripts->args[$handle]; } // Full script source with version info $script_data['src'] = add_query_arg('ver', $ver, $src); // Add script to data that will be returned to o2 array_push($response['scripts'], $script_data); } } } } // Attach styles if (isset($_REQUEST['styles'])) { // Parse and sanitize the script handles already output if (!is_array($_REQUEST['styles'])) { $_REQUEST['styles'] = explode(',', $_REQUEST['styles']); } // Parse and sanitize the style handles already output $initial_styles = is_array($_REQUEST['styles']) ? array_map('sanitize_text_field', $_REQUEST['styles']) : null; if (is_array($initial_styles)) { global $wp_styles; // Identify new styles needed by the polled posts $polled_styles = array_diff($wp_styles->done, $initial_styles); // If new styles are needed, extract relevant data from $wp_styles if (!empty($polled_styles)) { $response['styles'] = array(); foreach ($polled_styles as $handle) { // Abort if the handle doesn't match a registered stylesheet if (!isset($wp_styles->registered[$handle])) { continue; } // Provide basic style data $styles_data = array('handle' => $handle, 'media' => 'all'); // Base source $src = $wp_styles->registered[$handle]->src; // Take base_url into account if (strpos($src, 'http') !== 0) { $src = $wp_styles->base_url . $src; } // Version and additional arguments if (null === $wp_styles->registered[$handle]->ver) { $ver = ''; } else { $ver = $wp_styles->registered[$handle]->ver ? $wp_styles->registered[$handle]->ver : $wp_styles->default_version; } if (isset($wp_styles->args[$handle])) { $ver = $ver ? $ver . '&' . $wp_styles->args[$handle] : $wp_styles->args[$handle]; } // Full script source with version info $script_data['src'] = add_query_arg('ver', $ver, $src); // @todo Handle parsing conditional comments // Parse requested media context for stylesheet if (isset($wp_styles->registered[$handle]->args)) { $style_data['media'] = esc_attr($wp_styles->registered[$handle]->args); } // Add script to data that will be returned to o2 array_push($response['styles'], $style_data); } } } } } wp_send_json_success($response); }