PluginProbe
WpStream – Live Streaming, Video on Demand, Pay Per View / 4.8.2
WpStream – Live Streaming, Video on Demand, Pay Per View v4.8.2
4.14.1 4.14.0 4.13.2 4.13.1 4.13 4.12.5 4.12.4 4.12.3 4.12.2 4.12.1 4.12 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5 4.5.1 4.5.11 4.5.11.1 4.5.11.2 4.5.11.4 4.5.11.5 4.5.11.6 All 181 releases
← All changes | includes/class-wpstream.php +513 -676 4.14.14.8.2 View file →
@@ -11,14 +11,8 @@
11 11 * @package Wpstream
12 12 * @subpackage Wpstream/includes
13 13 */
14 14
15 -
16 -// Exit if accessed directly.
17 -if ( ! defined( 'ABSPATH' ) ) {
18 - exit;
19 -}
20 -
21 15 /**
22 16 * The core plugin class.
23 17 *
24 18 * This is used to define internationalization, admin-specific hooks, and
@@ -40,9 +34,8 @@
40 34 * @since 3.0.1
41 35 * @var object The main class.
42 36 */
43 37 public $main;
44 - /** @var Wpstream_Admin The admin-area controller instance. */
45 38 public $admin;
46 39
47 40 /**
48 41 * The loader that's responsible for maintaining and registering all hooks that power
@@ -81,44 +74,16 @@
81 74 *
82 75 * @since 3.0.1
83 76 */
84 77
85 - /** @var Wpstream_Live_Api_Connection Cloud API client for channels/quota. */
86 78 public $wpstream_live_connection;
87 - /** @var Wpstream_Player Player/rendering service. */
88 79 public $wpstream_player;
89 - /** @var Wpstream_Quota_Manager Quota cache manager. */
90 - public $quota_manager;
91 - /** @var Wpstream_Channel_Settings Deep Module for per-Channel streaming settings. */
92 - public $channel_settings;
93 - /** @var Wpstream_Streaming_Content_Creation Deep Module for Live Channel and VOD creation. */
94 - public $streaming_content_creation;
95 - /** @var Wpstream_Drm_Key_Delivery Deep Module for live and VOD DRM Key delivery. */
96 - public $drm_key_delivery;
97 - /** @var Wpstream_Media_List Deep Module for Channel and VOD lists. */
98 - public $media_list;
99 - /** @var Wpstream_Playback_Presentation Deep Module for approved player presentation. */
100 - public $playback_presentation;
101 - /** @var object User quota service resolved from the live connection. */
102 - public $user_quota_service;
103 - /** @var mixed Unused/reserved property. */
104 80 public $xtest;
105 - /** @var Wpstream_Admin Admin controller (also stored in $admin). */
106 81 public $plugin_admin;
107 - /** @var Wpstream_Onboarding|null Lazily-created onboarding workflow module. */
108 - private $onboarding;
109 - /** @var Wpstream_Live_Channel_Presentation|null Lazily-created Live Channel presentation module. */
110 - private $live_channel_presentation;
111 -
112 - /**
113 - * Bootstrap the plugin: resolve version/name, load dependencies, then wire
114 - * all admin, public, AJAX, template, and service objects together.
115 - */
82 +
116 83 public function __construct() {
117 - // Expose this instance as the shared "main" service locator.
118 84 $this->main = $this;
119 85
120 - // Resolve the plugin version from the defined constant, else fall back.
121 86 if ( defined( 'WPSTREAM_PLUGIN_VERSION' ) ) {
122 87 $this->version = WPSTREAM_PLUGIN_VERSION;
123 88 } else {
124 89 $this->version = '3.0.1';
@@ -123,379 +88,201 @@
123 88 } else {
124 89 $this->version = '3.0.1';
125 90 }
126 91
127 - // Text-domain / unique plugin identifier.
128 92 $this->plugin_name = 'wpstream';
129 93
130 - // Require class files and instantiate the hook loader.
131 94 $this->load_dependencies();
132 - // Register admin-area hooks (menus, metaboxes, WooCommerce, onboarding).
133 95 $this->define_admin_hooks();
134 - // Register public-facing hooks (scripts, endpoints, shortcodes).
135 96 $this->define_public_hooks();
136 - // Register AJAX handlers.
137 97 $this->define_ajax_hooks();
138 - // Register the front-end page/single template loader.
139 98 $this->wpstream_load_page_templates();
140 - // Register the "theme update available" admin notice.
141 99 $this->wpstream_load_theme_notice();
142 100
143 - // Instantiate the cloud API connection (and user quota service).
144 - $this->wpstream_connection();
145 - // Compose the deep Channel Settings Module with its WordPress and Baker Adapters.
146 - $this->channel_settings = new Wpstream_Channel_Settings(
147 - new Wpstream_WordPress_Channel_Settings_Storage(),
148 - new Wpstream_Baker_Channel_Settings_Adapter( $this->wpstream_live_connection )
149 - );
150 - $this->wpstream_live_connection->set_channel_settings( $this->channel_settings );
151 - $this->drm_key_delivery = new Wpstream_Drm_Key_Delivery(
152 - $this->channel_settings,
153 - new Wpstream_WordPress_Drm_Key_Remote_Fetch()
154 - );
155 - $this->media_list = new Wpstream_Media_List(
156 - new Wpstream_Baker_Media_List_Active_Catalog( $this->wpstream_live_connection )
157 - );
158 - $this->playback_presentation = new Wpstream_Playback_Presentation( $this );
159 - $this->streaming_content_creation = new Wpstream_Streaming_Content_Creation(
160 - $this,
161 - $this->channel_settings,
162 - new Wpstream_Baker_Streaming_Content_Provisioning( $this->wpstream_live_connection ),
163 - new Wpstream_Baker_Streaming_Content_Recording_Catalog( $this->wpstream_live_connection )
164 - );
165 - $this->wpstream_live_connection->set_streaming_content_creation( $this->streaming_content_creation );
166 - // Instantiate the player service.
101 + $this->wpstream_conection();
167 102 $this->wpstream_player();
168 - // Instantiate the quota cache manager.
169 - $this->wpstream_init_quota_manager();
170 103
171 104 }
172 105
173 -
174 -
175 -
176 -
177 - /**
178 - * Convert a quota figure from megabytes to gigabytes.
179 - *
180 - * @param float|int $megabytes Value in megabytes.
181 - * @return float Value in gigabytes, floored to two decimals.
182 - */
183 - public function wpstream_convert_band( $megabytes ) {
184 - // Quota payloads use binary megabytes. Never round remaining allowance up.
185 - return $this->wpstream_floor_decimals( (float) $megabytes / 1024, 2 );
106 +
107 +
108 +
109 +
110 + public function wpstream_convert_band($megabits){
111 + $gigabit = $megabits * 0.001;
112 + $gigabit = floatval(sprintf('%.1f', $gigabit));
113 + return $gigabit;
186 114 }
187 115
188 - /**
189 - * Floor a number to a given number of decimal places.
190 - *
191 - * @param float $value The number to floor.
192 - * @param int $decimals Number of decimal places.
193 - * @return float
194 - */
195 - public function wpstream_floor_decimals( $value, $decimals = 2 ) {
196 - // Clamp decimals to a non-negative integer.
197 - $decimals = max( 0, (int) $decimals );
198 - // Scale factor for the requested precision.
199 - $factor = pow( 10, $decimals );
200 116
201 - // Multiply, floor, divide back, then format to fixed precision.
202 - return floatval( sprintf( '%.' . $decimals . 'f', floor( (float) $value * $factor ) / $factor ) );
203 - }
204 -
205 -
206 - /** @var WpStream_Ajax The AJAX handler service. */
207 117 public $wpstream_ajax;
208 118
209 - /**
210 - * Load and instantiate the AJAX handler service.
211 - */
212 119 private function define_ajax_hooks() {
213 - // Construct the AJAX service with the main instance (class autoloads).
120 + require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-wpstream-ajax.php';
214 121 $this->wpstream_ajax = new WpStream_Ajax( $this->main );
215 122 }
216 -
217 -
218 - /**
219 - * Load the cloud API connection and resolve the user quota service.
220 - */
221 - private function wpstream_connection(){
222 - // Instantiate the live/cloud API client (class autoloads).
123 +
124 +
125 + private function wpstream_conection(){
126 + require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wpstream-live-api-connection.php';
223 127 $this->wpstream_live_connection = new Wpstream_Live_Api_Connection();
224 - // Cache the user quota service exposed by the connection.
225 - $this->user_quota_service = $this->wpstream_live_connection->get_user_quota_service();
226 128 }
227 -
228 -
229 - /**
230 - * Load and instantiate the player service.
231 - */
129 +
130 +
232 131 private function wpstream_player(){
233 - // Build the player service with the main instance (class autoloads).
132 + require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wpstream-player.php';
234 133 $this->wpstream_player = new Wpstream_Player($this->main);
235 134 }
236 135
237 - /**
238 - * Load and instantiate the quota cache manager.
239 - */
240 - private function wpstream_init_quota_manager() {
241 - // Build the quota cache manager with this main instance (class autoloads).
242 - $this->quota_manager = new Wpstream_Quota_Manager( $this );
243 - }
244 136
245 -
246 - /**
247 - * Load and register the front-end template loader.
248 - */
249 137 private function wpstream_load_page_templates() {
250 - // Register the template loader's hooks by constructing it (class autoloads).
138 + require_once WPSTREAM_PLUGIN_PATH . 'includes/class-wpstream-templates.php';
251 139 new WpStream_Template_Loader();
252 140 }
253 141
254 - /**
255 - * Load and register the companion-theme update admin notice.
256 - */
257 142 private function wpstream_load_theme_notice() {
258 - // Register the notice by constructing it (class autoloads).
143 + require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wpstream-theme-notice.php';
259 144 new WPStream_Theme_Notice();
260 145 }
261 146
262 147
263 148 /**
264 - * Load the dependencies the classmap autoloader cannot serve.
149 + * Load the required dependencies for this plugin.
265 150 *
266 - * Plugin classes resolve through Wpstream_Autoloader on first use, so this
267 - * only requires what an autoloader can never load: the WooCommerce product
268 - * types (kept behind a WooCommerce guard because they extend WC_Product)
269 - * and the function-only helper files. It then creates the hook loader that
270 - * the define_*_hooks() methods populate.
151 + * Include the following files that make up the plugin:
271 152 *
153 + * - Wpstream_Loader. Orchestrates the hooks of the plugin.
154 + * - Wpstream_i18n. Defines internationalization functionality.
155 + * - Wpstream_Admin. Defines all hooks for the admin area.
156 + * - Wpstream_Public. Defines all hooks for the public side of the site.
157 + *
158 + * Create an instance of the loader which will be used to register the hooks
159 + * with WordPress.
160 + *
272 161 * @since 3.0.1
273 162 * @access private
274 163 */
275 164 private function load_dependencies() {
276 165
277 - // WooCommerce product-type classes extend WC_Product, so loading them
278 - // without WooCommerce active would fatal at class-link time; they stay
279 - // behind this guard instead of the classmap.
280 - if( class_exists( 'WooCommerce' ) ){
281 - // Paid live-stream product type.
282 - require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wc-product-live-stream.php';
283 - // Paid video-on-demand product type.
284 - require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wc-product-video-on-demand.php';
285 - }
166 + /**
167 + * The class responsible for orchestrating the actions and filters of the
168 + * core plugin.
169 + */
170 + require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wpstream-loader.php';
286 171
287 - // Function-only helper files: no class inside, so the autoloader can
288 - // never serve them and they must be required eagerly.
172 + /**
173 + * The class responsible for defining internationalization functionality
174 + * of the plugin.
175 + */
176 + require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wpstream-i18n.php';
289 177
290 - // Channel-ownership authorization helper (wpstream_can_manage_channel),
291 - // used by every live/broadcast handler to enforce per-channel ownership.
292 - require_once plugin_dir_path(__FILE__) . 'Helpers/wpstream-authorization.php';
178 + /**
179 + * The class responsible for defining all actions that occur in the admin area.
180 + */
181 + require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wpstream-admin.php';
293 182
294 - // Viewing-entitlement helper (wpstream_user_entitled_for_product),
295 - // the single rule every playback access gate must call.
296 - require_once plugin_dir_path(__FILE__) . 'Helpers/wpstream-entitlement.php';
183 + /**
184 + * The class responsible for defining all actions that occur in the public-facing
185 + * side of the site.
186 + */
187 + require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-wpstream-public.php';
188 + /**
189 + * The class responsible for custom post type
190 +
191 + */
192 + require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wpstream_product.php';
193 + if( class_exists( 'WooCommerce' ) ){
194 + require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wc_product_live_stream.php';
195 + require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wc_product_video_on_demand.php';
196 + }
297 197
298 - // WpStream account credential accessors (constant override + options).
299 - require_once plugin_dir_path(__FILE__) . 'Helpers/wpstream-credentials.php';
198 + require_once plugin_dir_path(__FILE__) . 'Helpers/class-wpstream-log-entry.php';
199 + require_once plugin_dir_path(__FILE__) . 'Logger/class-wpstream-logger.php';
300 200
301 - // Viewer-facing presentation strings (wpstream_not_live_message), shared by
302 - // the player, the public JS config and the bundled theme framework.
303 - require_once plugin_dir_path(__FILE__) . 'Helpers/wpstream-presentation.php';
304 -
305 - // My Account list collector (wpstream_account_list_products) shared by the
306 - // event-list and video-list templates.
307 - require_once plugin_dir_path(__FILE__) . 'Helpers/wpstream-account-lists.php';
308 -
309 - // Tunables (wpstream_tunable): cache TTLs, poll intervals and limits run
310 - // through their filter and are clamped in one place.
311 - require_once plugin_dir_path(__FILE__) . 'Helpers/wpstream-tunables.php';
312 -
313 - // Create the hook loader that other define_*_hooks() methods populate.
314 201 $this->loader = new Wpstream_Loader();
315 202
316 203 }
317 204
318 205 /**
319 - * Register all of the hooks related to the admin area functionality
320 - * of the plugin.
206 + * Define the locale for this plugin for internationalization.
321 207 *
208 + * Uses the Wpstream_i18n class in order to set the domain and to register the hook
209 + * with WordPress.
210 + *
322 211 * @since 3.0.1
323 212 * @access private
324 213 */
325 - /**
326 - * Whether a post edit route can present Live Channel controls.
327 - *
328 - * @param string $post_type Current post type.
329 - * @param WP_Post|null $post Current post, when one exists.
330 - * @return bool
331 - */
332 - private function is_live_channel_admin_post( $post_type, $post = null ) {
333 - if ( 'wpstream_product' === $post_type ) {
334 - return true;
335 - }
214 + private function set_locale() {
336 215
337 - if ( 'product' !== $post_type ) {
338 - return false;
339 - }
216 + $plugin_i18n = new Wpstream_i18n();
340 217
341 - $post_id = $post instanceof WP_Post ? intval( $post->ID ) : 0;
342 - if ( ! $post_id && isset( $_GET['post'] ) ) {
343 - $post_id = absint( wp_unslash( $_GET['post'] ) );
344 - }
218 + $this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain', 1 );
345 219
346 - if ( $post_id ) {
347 - $product_type = wpstream_get_product_type_slug( $post_id );
348 - return 'live_stream' === $product_type
349 - || ( 'subscription' === $product_type && 'yes' === get_post_meta( $post_id, '_subscript_live_event', true ) );
350 - }
351 -
352 - return isset( $_GET['new_stream'] ) && 'new' === sanitize_key( wp_unslash( $_GET['new_stream'] ) );
353 220 }
354 221
355 222 /**
356 - * Whether the current wp-admin screen presents Live Channel controls.
223 + * Register all of the hooks related to the admin area functionality
224 + * of the plugin.
357 225 *
358 - * @param WP_Screen|null $screen Current WordPress screen.
359 - * @return bool
226 + * @since 3.0.1
227 + * @access private
360 228 */
361 - private function is_live_channel_admin_screen( $screen ) {
362 - if ( ! $screen ) {
363 - return false;
364 - }
365 -
366 - if ( 'wpstream_page_wpstream_live_channels' === $screen->base ) {
367 - return true;
368 - }
369 -
370 - global $post;
371 - return $this->is_live_channel_admin_post( $screen->post_type, $post instanceof WP_Post ? $post : null );
372 - }
373 -
374 229 private function define_admin_hooks() {
375 230
376 - // Build the admin controller and keep a reference to it.
377 231 $plugin_admin = new Wpstream_Admin( $this->get_plugin_name(), $this->get_version(), $this->main );
378 232
379 233 $this->admin = $plugin_admin;
380 234
381 - // Admin CSS/JS and the plugin's admin menu (late priority).
382 235 $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_styles' );
383 236 $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts' );
384 - add_action(
385 - 'admin_enqueue_scripts',
386 - function () {
387 - $screen = get_current_screen();
388 - if ( $this->is_live_channel_admin_screen( $screen ) ) {
389 - $this->get_live_channel_presentation()->enqueue_assets();
390 - }
391 - },
392 - 20
393 - );
394 237 $this->loader->add_action( 'admin_menu', $plugin_admin, 'wpstream_manage_admin_menu',999);
395 238
396 - // "Chat Room" metabox: bind an existing Better Messages room to a channel.
397 - new Wpstream_Chat_Room_Binding();
398 -
399 - // Register the custom post types on init.
400 239 $plugin_post_types = new Wpstream_Product();
401 240 $this->loader->add_action( 'init', $plugin_post_types, 'create_custom_post_type', 999 );
402 241
403 242 // save and render metaboxed
404 - // Register product metaboxes; persist their values on save; and,
405 - // on publish, create the remote streaming channel.
406 243 $this->loader->add_action( 'add_meta_boxes', $plugin_admin, 'add_wpstream_product_metaboxes' );
407 244 $this->loader->add_action( 'save_post', $plugin_admin, 'wpstream_free_product_update_post',1,2 );
408 245 $this->loader->add_action( 'publish_wpstream_product', $plugin_admin, 'wpstream_publish_wpstream_product',1,2 );
409 - $this->loader->add_action( 'publish_wpstream_product', $plugin_admin, 'wpstream_create_remote_channel_on_publish',20,2 );
410 - $this->loader->add_action( 'publish_wpstream_product_vod', $plugin_admin, 'wpstream_create_remote_channel_on_publish', 20, 2 );
411 - $this->loader->add_action( 'publish_product', $plugin_admin, 'wpstream_create_remote_channel_on_publish', 20, 2 );
412 - // Mirror of the publish hooks above: a permanently deleted Live
413 - // Channel is deleted at the service too (trash is untouched).
414 - $this->loader->add_action( 'before_delete_post', $plugin_admin, 'wpstream_delete_remote_channel_on_delete', 10, 2 );
415 - $this->loader->add_action( 'before_delete_post', $plugin_admin, 'wpstream_invalidate_vod_drm_on_delete', 5, 2 );
416 - $this->loader->add_action( 'transition_post_status', $plugin_admin, 'wpstream_invalidate_vod_drm_on_status_change', 10, 3 );
417 - // WooCommerce restores products to their previous published status.
418 - // Paid Live Channels follow the safer channel lifecycle instead:
419 - // restore as draft and require an explicit republish.
420 - $this->loader->add_filter( 'wp_untrash_post_status', $plugin_admin, 'wpstream_paid_live_untrash_status', 20, 3 );
421 246
422 247
423 248
424 249 // make product virtual
425 250 $this->loader->add_action( 'save_post', $plugin_admin, 'wpstream_make_product_virtual', 99999, 2 );
251 +
252 +
253 +
254 + // show streaming controls on sidebar
255 + $this->loader->add_action('add_meta_boxes', $plugin_admin, 'wpstream_startstreaming_sidebar_meta');
426 256
257 + // on boarding actions
258 + $this->loader->add_action('admin_footer',$plugin_admin, 'wpstream_admin_footer_onboarding');
259 + $this->loader->add_action( 'wp_ajax_wpstream_on_board_create_channel', $plugin_admin,'wpstream_on_board_create_channel' );
260 + $this->loader->add_action( 'wp_ajax_wpstream_on_board_create_channel_ppv', $plugin_admin,'wpstream_on_board_create_channel_ppv' );
261 + $this->loader->add_action( 'wp_ajax_wpstream_on_board_create_free_vod', $plugin_admin,'wpstream_on_board_create_free_vod' );
262 + $this->loader->add_action( 'wp_ajax_wpstream_on_board_create_ppv_vod', $plugin_admin,'wpstream_on_board_create_ppv_vod' );
427 263
428 264
429 - // Add Live Channel controls only on edit screens that can own them.
430 - add_action(
431 - 'add_meta_boxes',
432 - function ( $post_type, $post ) {
433 - if ( $this->is_live_channel_admin_post( $post_type, $post ) ) {
434 - $this->get_live_channel_presentation()->register_metaboxes();
435 - }
436 - },
437 - 10,
438 - 2
439 - );
440 -
441 - // Load onboarding only when its page assets or one of its AJAX routes runs.
442 - add_action(
443 - 'admin_enqueue_scripts',
444 - function () {
445 - $screen = get_current_screen();
446 - $is_quickstart = $screen && 'wpstream_page_wpstream_onboard' === $screen->base;
447 - $is_post_edit = isset( $_GET['onboard'] ) && 'yes' === $_GET['onboard'];
448 -
449 - if ( $is_quickstart || $is_post_edit ) {
450 - $this->get_onboarding()->enqueue_assets();
451 - }
452 - },
453 - 20
454 - );
455 -
456 - $onboarding_ajax_actions = array(
457 - 'wpstream_on_board_create_channel',
458 - 'wpstream_on_board_create_channel_ppv',
459 - 'wpstream_on_board_create_free_vod',
460 - 'wpstream_on_board_create_ppv_vod',
461 - 'wpstream_on_board_login',
462 - 'wpstream_on_board_register',
463 - 'wpstream_get_captcha_challenge',
464 - );
465 - foreach ( $onboarding_ajax_actions as $onboarding_ajax_action ) {
466 - add_action(
467 - 'wp_ajax_' . $onboarding_ajax_action,
468 - function () use ( $onboarding_ajax_action ) {
469 - return $this->get_onboarding()->handle_ajax( $onboarding_ajax_action );
470 - }
471 - );
472 - }
265 + $this->loader->add_action( 'wp_ajax_wpstream_on_board_login', $plugin_admin,'wpstream_on_board_login' );
266 + $this->loader->add_action( 'wp_ajax_wpstream_on_board_register', $plugin_admin,'wpstream_on_board_register' );
473 267
474 268 // Register AJAX actions for multipart uploads
475 269 $this->loader->add_action( 'wp_ajax_wpstream_initiate_multipart_upload', $plugin_admin, 'handle_initiate_multipart_upload' );
476 270 $this->loader->add_action( 'wp_ajax_wpstream_complete_multipart_upload', $plugin_admin, 'handle_complete_multipart_upload' );
477 271
478 - // General and plugin-update admin notices.
479 272 $this->loader->add_action( 'admin_notices', $plugin_admin,'wpstream_admin_notice' );
480 - $this->loader->add_action( 'admin_notices', $plugin_admin,'wpstream_plugin_update_available_notice' );
481 -
482 - // Dismiss-cache-notice AJAX endpoint.
483 273 $this->loader->add_action( 'wp_ajax_wpstream_update_cache_notice', $plugin_admin,'wpstream_update_cache_notice' );
484 274 // $this->loader->add_action( 'wp_ajax_wpstream_get_videos_list', $plugin_admin,'wpstream_get_videos_list' );
485 275
486 276
487 - // Settings-tab "update plugin" AJAX endpoint.
488 277 $this->loader->add_action( 'wp_ajax_wpstream_settings_tab_update_plugin', $plugin_admin, 'wpstream_settings_tab_update_plugin' );
489 278
490 279 // add and save category extra fields
491 - // The same add/edit/create/save callbacks are shared across every taxonomy below.
492 280 $this->loader->add_action( 'category_edit_form_fields', $plugin_post_types, 'wpstream_category_callback_function', 10, 2);
493 281 $this->loader->add_action( 'category_add_form_fields', $plugin_post_types, 'wpstream_category_callback_add_function' );
494 282 $this->loader->add_action( 'created_category', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
495 283 $this->loader->add_action( 'edited_category', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
496 284
497 - // Same extra fields on the WooCommerce product category taxonomy.
498 285 $this->loader->add_action( 'product_cat_edit_form_fields', $plugin_post_types, 'wpstream_category_callback_function', 10, 2);
499 286 $this->loader->add_action( 'product_cat_add_form_fields', $plugin_post_types, 'wpstream_category_callback_add_function' );
500 287 $this->loader->add_action( 'created_product_cat', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
501 288 $this->loader->add_action( 'edited_product_cat', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
@@ -500,9 +287,8 @@
500 287 $this->loader->add_action( 'created_product_cat', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
501 288 $this->loader->add_action( 'edited_product_cat', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
502 289
503 290
504 - // Same extra fields on the plugin's own wpstream_category taxonomy.
505 291 $this->loader->add_action( 'wpstream_category_edit_form_fields', $plugin_post_types, 'wpstream_category_callback_function', 10, 2);
506 292 $this->loader->add_action( 'wpstream_category_add_form_fields', $plugin_post_types, 'wpstream_category_callback_add_function' );
507 293 $this->loader->add_action( 'created_wpstream_category', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
508 294 $this->loader->add_action( 'edited_wpstream_category', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
@@ -507,15 +293,13 @@
507 293 $this->loader->add_action( 'created_wpstream_category', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
508 294 $this->loader->add_action( 'edited_wpstream_category', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
509 295
510 296
511 - // Same extra fields on the wpstream_actors taxonomy.
512 297 $this->loader->add_action( 'wpstream_actors_edit_form_fields', $plugin_post_types, 'wpstream_category_callback_function', 10, 2);
513 298 $this->loader->add_action( 'wpstream_actors_add_form_fields', $plugin_post_types, 'wpstream_category_callback_add_function' );
514 299 $this->loader->add_action( 'created_wpstream_actors', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
515 300 $this->loader->add_action( 'edited_wpstream_actors', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
516 301
517 - // Same extra fields on the wpstream_movie_rating taxonomy.
518 302 $this->loader->add_action( 'wpstream_movie_rating_edit_form_fields', $plugin_post_types, 'wpstream_category_callback_function', 10, 2);
519 303 $this->loader->add_action( 'wpstream_movie_rating_add_form_fields', $plugin_post_types, 'wpstream_category_callback_add_function' );
520 304 $this->loader->add_action( 'created_wpstream_movie_rating', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
521 305 $this->loader->add_action( 'edited_wpstream_movie_rating', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
@@ -520,39 +304,23 @@
520 304 $this->loader->add_action( 'created_wpstream_movie_rating', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
521 305 $this->loader->add_action( 'edited_wpstream_movie_rating', $plugin_post_types, 'wpstream_category_save_extra_fields_callback', 10, 2);
522 306
523 307
524 - // WooCommerce-only admin hooks: register the custom product types,
525 - // their data tabs/fields, pricing visibility, and add-to-cart handling.
526 - // Deferred to plugins_loaded because WooCommerce may load after this
527 - // plugin, and detection uses class_exists (not the active_plugins
528 - // option) so network-activated WooCommerce on multisite is seen too.
529 - // Registered directly (not via the loader) because the loader runs
530 - // before plugins_loaded fires; every hook below fires later than
531 - // plugins_loaded, so nothing is missed by the deferral.
532 - add_action( 'plugins_loaded', function () use ( $plugin_admin ) {
533 - // Without WooCommerce none of these hooks have anything to do.
534 - if ( ! class_exists( 'WooCommerce' ) ) {
535 - return;
536 - }
308 + if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
537 309
538 - // Register product types and map them to their PHP classes.
539 - add_action( 'init', array( $plugin_admin, 'wpstream_add_custom_wc_products' ) );
540 - add_filter( 'product_type_selector', array( $plugin_admin, 'wpstream_add_products' ) );
541 - add_filter( 'woocommerce_product_class', array( $plugin_admin, 'wpstream_add_products_class' ), 10, 2 );
542 - // Pricing-field visibility, tab hiding, and purchasability rules.
543 - add_action( 'admin_enqueue_scripts', array( $plugin_admin, 'wpstream_enqueue_wc_product_pricing_visibility' ), 20 );
544 - add_filter( 'woocommerce_product_data_tabs', array( $plugin_admin, 'wpstream_hide_attributes_data_panel' ), 10, 1 );
545 - add_filter( 'woocommerce_is_purchasable', array( $plugin_admin, 'wpstream_hide_buy_now_subscription_mode' ), 10, 2 );
546 -
547 - // Custom general-tab fields (render + save) and add-to-cart wiring.
548 - add_action( 'woocommerce_product_options_general_product_data', array( $plugin_admin, 'wpstream_add_custom_general_fields' ), 20 );
549 - add_filter( 'woocommerce_process_product_meta', array( $plugin_admin, 'wpstream_add_custom_general_fields_save' ), 10, 1 );
550 - add_action( 'woocommerce_process_product_meta', array( $plugin_admin, 'wpstream_initialize_paid_streaming_product' ), 30, 1 );
551 - add_action( 'woocommerce_live_stream_add_to_cart', array( $plugin_admin, 'wpstream_add_to_cart' ), 10, 1 );
552 - add_action( 'woocommerce_video_on_demand_add_to_cart', array( $plugin_admin, 'wpstream_add_to_cart' ), 10, 1 );
553 - add_filter( 'woocommerce_loop_add_to_cart_link', array( $plugin_admin, 'replacing_add_to_cart_button' ), 10, 2 );
554 - } );
310 + $this->loader->add_action( 'init', $plugin_admin, 'wpstream_add_custom_wc_products' );
311 + $this->loader->add_filter( 'product_type_selector', $plugin_admin, 'wpstream_add_products' );
312 + $this->loader->add_filter( 'woocommerce_product_class', $plugin_admin, 'wpstream_add_products_class', 10, 2 );
313 + $this->loader->add_action( 'admin_footer', $plugin_admin, 'wpstream_products_custom_js' );
314 + $this->loader->add_filter( 'woocommerce_product_data_tabs', $plugin_admin, 'wpstream_hide_attributes_data_panel',10,1 );
315 + $this->loader->add_filter( 'woocommerce_is_purchasable', $plugin_admin, 'wpstream_hide_buy_now_subscription_mode',10,2);
316 +
317 + $this->loader->add_filter( 'woocommerce_product_options_general_product_data',$plugin_admin, 'wpstream_add_custom_general_fields', 10,1);
318 + $this->loader->add_filter( 'woocommerce_process_product_meta',$plugin_admin, 'wpstream_add_custom_general_fields_save',10,1 );
319 + $this->loader->add_action( 'woocommerce_live_stream_add_to_cart', $plugin_admin, 'wpstream_add_to_cart',10,1);
320 + $this->loader->add_action( 'woocommerce_video_on_demand_add_to_cart', $plugin_admin, 'wpstream_add_to_cart',10,1);
321 + $this->loader->add_filter( 'woocommerce_loop_add_to_cart_link', $plugin_admin,'replacing_add_to_cart_button', 10, 2 );
322 + }
555 323 }
556 324
557 325
558 326
@@ -566,24 +334,17 @@
566 334 * @access private
567 335 */
568 336 private function define_public_hooks() {
569 337
570 - // Build the public-facing controller.
571 338 $plugin_public = new Wpstream_Public( $this->get_plugin_name(), $this->get_version(), $this->main );
572 339
573 - // Front-end styles.
574 340 $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' );
575 - // Registered on `wp` (not `wp_enqueue_scripts`/`wp_head`) because block themes render
576 - // the Post Content block - and thus our `the_content` filter that enqueues/localizes
577 - // these scripts - before `wp_head` ever fires, leaving the handles unregistered.
578 - $this->loader->add_action( 'wp', $plugin_public, 'enqueue_scripts' );
341 + $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' );
579 342
580 - // Custom rewrite endpoints and their query vars.
581 343 $this->loader->add_action( 'init', $plugin_public,'wpstream_my_custom_endpoints' );
582 344 $this->loader->add_filter( 'query_vars',$plugin_public, 'wpstream_my_custom_query_vars', 0 );
583 345
584 346 //live stream action
585 - // Streaming cookies plus the RTMP/3rd-party/VOD streaming-key handlers.
586 347 $this->loader->add_action('init',$plugin_public,'wpstream_set_cookies',0);
587 348 $this->loader->add_action('init',$plugin_public,'wpstream_live_streaming_key');
588 349 $this->loader->add_action('init',$plugin_public,'wpstream_live_streaming_key_for_3rdparty');
589 350 $this->loader->add_action('init',$plugin_public,'wpstream_live_streaming_key_vod',10);
@@ -588,31 +349,23 @@
588 349 $this->loader->add_action('init',$plugin_public,'wpstream_live_streaming_key_for_3rdparty');
589 350 $this->loader->add_action('init',$plugin_public,'wpstream_live_streaming_key_vod',10);
590 351
591 352 // woo action
592 - // Product-page content wrappers and order/email extras.
593 353 $this->loader->add_action( 'woocommerce_before_single_product', $plugin_public,'wpstream_non_image_content_wrapper_start', 20 );
594 354 $this->loader->add_action( 'woocommerce_after_single_product', $plugin_public,'wpstream_non_image_content_wrapper_end', 20 );
595 355 $this->loader->add_action( 'woocommerce_thankyou_order_received_text', $plugin_public,'wpstream_thankyou_extra', 20,2 );
596 356 $this->loader->add_action( 'woocommerce_email_order_details', $plugin_public,'wpstream_email_order_details', 20,4 );
597 357
598 - // My Account: add the Events/Videos menu items and their endpoint content.
599 - // Run after themes have built their account navigation so a theme that
600 - // replaces the menu cannot discard the plugin-owned Events/Videos links.
601 - $this->loader->add_filter( 'woocommerce_account_menu_items', $plugin_public, 'wpstream_custom_my_account_menu_items', 99 );
358 + $this->loader->add_filter( 'woocommerce_account_menu_items', $plugin_public,'wpstream_custom_my_account_menu_items' );
602 359 $this->loader->add_action( 'woocommerce_account_event-list_endpoint', $plugin_public,'wpstream_custom_endpoint_content_event_list' );
603 360 $this->loader->add_action( 'woocommerce_account_video-list_endpoint', $plugin_public,'wpstream_custom_endpoint_video_list' );
604 361
605 - // Flush rewrite rules on theme switch; register plugin and WPBakery shortcodes.
606 362 $this->loader->add_action( 'after_switch_theme', $plugin_public,'wpstream_custom_flush_rewrite_rules' );
607 363 $this->loader->add_action('init', $plugin_public,'wpstream_shortcodes');
608 364 $this->loader->add_action('vc_before_init', $plugin_public,'wpstream_bakery_shortcodes');
609 365
610 - // CORS preflight check for the API (uses a plain function callback).
611 366 $this->loader->add_action('wo_before_api', 'wpstream_cors_check_and_response',10,1);
612 367
613 - // Theme-integration filters/actions: search, sidebars, archives, and
614 - // author/episode/past-broadcast content resolution by post type.
615 368 $this->loader->add_filter( 'wpstream_search_template_item_post_type', $plugin_public, 'wpstream_search_template_add_item_post_type' );
616 369 $this->loader->add_filter( 'wpstream_sidebar_id_by_post_type', $plugin_public, 'wpstream_sidebar_id_by_post_type' );
617 370 $this->loader->add_filter( 'wpstream_header_search_values', $plugin_public, 'wpstream_header_search_values' );
618 371 $this->loader->add_filter( 'wpstream_extend_category_archive_query_filter', $plugin_public, 'wpstream_extend_category_archive_query_filter_callback' );
@@ -634,9 +387,8 @@
634 387 *
635 388 * @since 3.0.1
636 389 */
637 390 public function run() {
638 - // Hand off to the loader, which calls add_action/add_filter for every hook.
639 391 $this->loader->run();
640 392 }
641 393
642 394 /**
@@ -646,9 +398,8 @@
646 398 * @since 3.0.1
647 399 * @return string The name of the plugin.
648 400 */
649 401 public function get_plugin_name() {
650 - // Return the stored text-domain / identifier string.
651 402 return $this->plugin_name;
652 403 }
653 404
654 405 /**
@@ -657,9 +408,8 @@
657 408 * @since 3.0.1
658 409 * @return Wpstream_Loader Orchestrates the hooks of the plugin.
659 410 */
660 411 public function get_loader() {
661 - // Return the hook loader instance.
662 412 return $this->loader;
663 413 }
664 414
665 415 /**
@@ -668,164 +418,293 @@
668 418 * @since 3.0.1
669 419 * @return string The version number of the plugin.
670 420 */
671 421 public function get_version() {
672 - // Return the resolved plugin version string.
673 422 return $this->version;
674 423 }
675 424
676 - /**
677 - * Return the onboarding workflow, creating it only when an onboarding route
678 - * actually needs it.
679 - *
680 - * @return Wpstream_Onboarding
681 - */
682 - public function get_onboarding() {
683 - if ( ! $this->onboarding ) {
684 - $this->onboarding = new Wpstream_Onboarding( $this );
685 - }
686 -
687 - return $this->onboarding;
688 - }
689 -
690 - /**
691 - * Return the Live Channel admin presentation, creating it only when a
692 - * relevant screen or shared go-live card needs it.
693 - *
694 - * @return Wpstream_Live_Channel_Presentation
695 - */
696 - public function get_live_channel_presentation() {
697 - if ( ! $this->live_channel_presentation ) {
698 - $this->live_channel_presentation = new Wpstream_Live_Channel_Presentation( $this );
699 - }
700 -
701 - return $this->live_channel_presentation;
702 - }
703 -
704 - /**
705 - * Whether WordPress currently reports a pending update for this plugin.
706 - *
707 - * @return bool True when an update is available in the update_plugins transient.
708 - */
709 425 public function is_plugin_outdated(){
710 - // WordPress caches pending plugin updates in this site transient.
711 426 $update_data = get_site_transient('update_plugins');
712 - // The plugin's basename key within that transient.
713 427 $plugin_path = 'wpstream/wpstream.php';
714 428
715 - // Presence of a response entry means an update is offered.
716 429 if (isset($update_data->response[$plugin_path])) {
717 430 return true;
718 431 }
719 432
720 - // No entry -> up to date.
721 433 return false;
722 434 }
723 435
724 436
725 437
726 - /**
727 - * Print the account resource summary (data/storage or hours) shown in the UI.
728 - *
729 - * @param array $pack_details Quota payload for the current account.
730 - */
731 438 public function show_user_data($pack_details){
732 - // Branch A: data/storage (megabyte) plans - when NOT using streaming hours.
733 - if ( ! isset( $pack_details['use_streaming_hours'] ) || $pack_details['use_streaming_hours'] !== true ) {
734 - // Only render when both data and storage figures are present.
735 - if ( isset( $pack_details['available_data_mb'] ) && isset( $pack_details['available_storage_mb'] ) ) {
736 - // Convert available data MB to GB, clamping negatives to zero.
737 - $wpstream_convert_band = $this->wpstream_convert_band( $pack_details['available_data_mb'] );
738 - if ( $wpstream_convert_band < 0 ) {
739 - $wpstream_convert_band = 0;
740 - }
439 + if( isset($pack_details['available_data_mb']) && isset( $pack_details['available_storage_mb']) ){
440 + $wpstream_convert_band = $this->wpstream_convert_band($pack_details['available_data_mb']);
441 + if( $wpstream_convert_band < 0 ) {
442 + $wpstream_convert_band = 0;
443 + }
741 444
742 - // Convert available storage MB to GB, clamping negatives to zero.
743 - $wpstream_convert_storage = $this->wpstream_convert_band( $pack_details['available_storage_mb'] );
744 - if ( $wpstream_convert_storage < 0 ) {
745 - $wpstream_convert_storage = 0;
746 - }
445 + $wpstream_convert_storage = $this->wpstream_convert_band($pack_details['available_storage_mb']);
446 + if( $wpstream_convert_storage < 0 ) {
447 + $wpstream_convert_storage = 0;
448 + }
449 +
450 + print '<div class="pack_details_wrapper">'
451 + . '<strong>' . __('Your account information: ', 'wpstream') . '</strong> '
452 + . __('You have', 'wpstream') . '<strong> ' . abs( $wpstream_convert_band ) . ' GB</strong> '
453 + . __('available cloud data and', 'wpstream') . ' '
454 + . '<strong>' . $wpstream_convert_storage . ' GB</strong> '
455 + . __('available cloud storage', 'wpstream') . '.';
747 456
748 - // Output the cloud data + storage summary line.
749 - print '<div class="pack_details_wrapper">'
750 - . '<strong>' . __( 'Your account information: ', 'wpstream' ) . '</strong> '
751 - . __( 'You have ', 'wpstream' ) . '<strong id="wpstream_available_data">' . abs( $wpstream_convert_band ) . ' GB</strong> '
752 - . __( 'available cloud data and ', 'wpstream' )
753 - . '<strong id="wpstream_available_storage">' . abs( $wpstream_convert_storage ) . ' GB</strong> '
754 - . __( 'available cloud storage', 'wpstream' ) . '.';
457 + print '<a href="https://wpstream.net/pricing/" class="wpstream_upgrade_topbar" target="_blank">'.esc_html__('Upgrade Plan','wpstream').'</a>';
458 + print '</div>';
459 + print'<input type="hidden" id="wpstream_band" value="'.$pack_details['available_data_mb'].'">';
460 + print'<input type="hidden" id="wpstream_storage" value="'.$pack_details['available_storage_mb'].'">';
755 461
756 - // Upgrade link plus hidden inputs carrying the raw MB figures for JS.
757 - print '<a href="https://wpstream.net/pricing/" class="wpstream_upgrade_topbar" target="_blank">' . esc_html__( 'Upgrade Plan', 'wpstream' ) . '</a>';
758 - print '</div>';
759 - print '<input type="hidden" id="wpstream_band" value="' . esc_attr( $pack_details['available_data_mb'] ) . '">';
760 - print '<input type="hidden" id="wpstream_storage" value="' . esc_attr( $pack_details['available_storage_mb'] ) . '">';
761 - }
762 - } else {
763 - // Branch B: streaming-hours plans (viewer/broadcast/storage hours).
764 - if ( isset( $pack_details['available_viewer_hours'] ) && isset( $pack_details['available_broadcast_hours'] ) && isset( $pack_details['available_storage_hours'] ) ) {
765 - // Normalize viewer hours to a non-negative float.
766 - $available_viewer_hours = floatval( $pack_details['available_viewer_hours'] );
767 - if ( $available_viewer_hours < 0 ) {
768 - $available_viewer_hours = 0;
769 - }
462 + }
463 + }
770 464
771 - // Normalize broadcast hours to a non-negative float.
772 - $available_broadcast_hours = floatval( $pack_details['available_broadcast_hours'] );
773 - if ( $available_broadcast_hours < 0 ) {
774 - $available_broadcast_hours = 0;
775 - }
465 +
466 + /**
467 + * help function for media list elementor widget
468 + *
469 + * @since 3.0.1
470 + * @return string
471 + */
472 +
473 + public function wpstream_media_list_elementor_function($attributes, $content = null){
474 +
475 +
476 + $media_number=3;
477 + if ( isset($attributes['media_number']) ){
478 + $media_number=$attributes['media_number'];
479 + }
480 +
481 +
482 + $row_number=3;
483 + if ( isset($attributes['row_number']) ){
484 + $row_number=$attributes['row_number'];
485 + }
486 + if($row_number>4){
487 + $row_number=4;
488 + }
776 489
777 - // Normalize storage hours to a non-negative float.
778 - $available_storage_hours = floatval( $pack_details['available_storage_hours'] );
779 - if ( $available_storage_hours < 0 ) {
780 - $available_storage_hours = 0;
781 - }
490 +
491 + ob_start();
782 492
783 - // Floor each figure to two decimals for display.
784 - $formatted_viewer_hours = $this->wpstream_floor_decimals( $available_viewer_hours, 2 );
785 - $formatted_broadcast_hours = $this->wpstream_floor_decimals( $available_broadcast_hours, 2 );
786 - $formatted_storage_hours = $this->wpstream_floor_decimals( $available_storage_hours, 2 );
493 + // check if is vod or live stream
494 + $meta_query = array();
495 + $tax_query_array= array();
496 + $tax_query = array();
497 +
498 + // check if the media is paid or free
499 + $event_types = array();
500 + $product_type_free_paid = 0;
501 + if ( isset($attributes['product_type_free_paid']) ){
502 + $product_type_free_paid=$attributes['product_type_free_paid'];
503 +
504 + if($product_type_free_paid==0){
505 + $event_types=array('wpstream_product');
506 +
507 + if ( isset($attributes['product_type']) && intval($attributes['product_type'])==2){
508 + $event_types=array('wpstream_product_vod');
509 + }
787 510
788 - // Output the viewer/broadcast/storage hours summary line.
789 - print '<div class="pack_details_wrapper">'
790 - . __( 'Available streaming resources: ', 'wpstream' )
791 - . '<strong id="wpstream_available_viewer_hours">' . abs( $formatted_viewer_hours ) . ' viewer</strong> '
792 - . __( 'hours, ', 'wpstream' )
793 - . '<strong id="wpstream_available_broadcast_hours">' . abs( $formatted_broadcast_hours ) . ' broadcast</strong> '
794 - . __( 'hours, ', 'wpstream' )
795 - . '<strong id="wpstream_available_storage_hours">' . $formatted_storage_hours . ' storage</strong> '
796 - . __( 'hours', 'wpstream' ) . '.';
511 + }else{
512 + $event_types=array('product');
513 + if ( isset($attributes['product_type']) ){
514 + $product_type = $attributes['product_type'];
515 + $product_type_slug = 'video_on_demand';
516 + if($product_type==1){
517 + $product_type_slug ='live_stream';
518 + }
519 +
520 + $tax_query_array = array(
521 + 'taxonomy' => 'product_type',
522 + 'field' => 'slug',
523 + 'terms' => $product_type_slug
524 + );
525 +
526 + $tax_query= array(
527 + 'relation' => 'AND',
528 + $tax_query_array
529 + );
530 +
531 + }
532 + }
533 +
534 + }
535 + $see_product='';
536 + if(isset($attributes['free_label'])){
537 + $see_product=$attributes['free_label'];
538 + }
539 +
540 + // pagination
541 + $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
542 + if( is_front_page() ){
543 + $paged= (get_query_var('page')) ? get_query_var('page') : 1;
544 + }
797 545
798 - // Upgrade link plus hidden inputs carrying the raw hour figures for JS.
799 - print '<a href="https://wpstream.net/pricing/" class="wpstream_upgrade_topbar" target="_blank">' . esc_html__( 'Upgrade Plan', 'wpstream' ) . '</a>';
800 - print '</div>';
801 - print '<input type="hidden" id="wpstream_viewer_hours" value="' . esc_attr( $pack_details['available_viewer_hours'] ) . '">';
802 - print '<input type="hidden" id="wpstream_broadcast_hours" value="' . esc_attr( $pack_details['available_broadcast_hours'] ) . '">';
803 - print '<input type="hidden" id="wpstream_storage_hours" value="' . esc_attr( $pack_details['available_storage_hours'] ) . '">';
804 - }
805 - }
806 - }
546 +
547 + //order
548 + $orderby='ID';
549 + $order ='ASC';
550 + if ( isset($attributes['order_by']) ){
551 + $order_by=intval($attributes['order_by']);
552 + switch ($order_by) {
553 + case 0:
554 + $orderby='ID';
555 + $order ='ASC';
556 + break;
557 + case 1:
558 + $orderby='ID';
559 + $order ='DESC';
560 + break;
561 + case 2:
562 + $orderby='title';
563 + $order ='ASC';
564 + break;
565 + case 3:
566 + $orderby='title';
567 + $order ='DESC';
568 + break;
569 + }
570 + }
571 +
572 + // building wp_query arg array
573 + $args = array(
574 + 'post_type' => $event_types,
575 + 'post_status' => 'publish',
576 + 'meta_query' => $meta_query,
577 + 'posts_per_page' => $media_number,
578 + 'paged' => $paged,
579 + 'orderby' => $orderby,
580 + 'order' => $order,
581 + 'tax_query' => $tax_query
582 + );
583 +
584 +
585 +
586 + // show live events
587 + if ( isset($attributes['product_show_live']) && $attributes['product_show_live']=='yes'){
588 + $live_event_for_user = $this->main->wpstream_live_connection->api20_wpstream_request_live_stream_for_user_for_shortcode('shortcode');
589 +
590 +
591 + if( is_array($live_event_for_user) ){
592 + $live_event_for_user[]=0;
593 +
594 + $args['post__in']=$live_event_for_user;
595 + }
596 + }
597 +
598 +
599 +
807 600
601 + $media_list= new WP_Query($args);
602 + if($media_list->have_posts()){
603 + print '<ul class="wpstream_media_list_wrapper products columns-'.esc_attr($row_number).'" >';
604 + while($media_list->have_posts()):$media_list->the_post();
605 + if($product_type_free_paid==0 ){
606 +
607 + $thumb=wp_get_attachment_image_src(get_post_thumbnail_id(),'medium');
608 +
609 + $thumb_src='';
610 + if( isset($thumb[0]) ){
611 + $thumb_src=$thumb[0];
612 + }
613 +
614 + if(($thumb_src)==''){
615 + $thumb_src= plugin_dir_url( dirname( __FILE__ ) ). 'img/default_300.png';
616 + }
617 + print '<li class="wpstream_product_unit">'
618 + .'<a href="'.get_permalink().'" class="product_title" ><div class="product_image" style="background-image:url('.esc_url($thumb_src).')"></div></a>'
619 + .'<a href="'.get_permalink().'" class="product_title" >'.get_the_title().'</a>';
620 +
621 + if($see_product!=''){
622 + print '<a href="'.get_permalink().'"class="see_product">'.$see_product.'</a>';
623 + }
624 + print '</li>';
625 + }else{
626 + wc_get_template_part( 'content', 'product' );
627 + }
628 + endwhile;
629 + print '</ul>';
630 + }else{
631 + print esc_html__('No media found! ','wpstream');
632 + }
633 +
634 +
635 + wp_reset_query();
636 + wp_reset_postdata();
637 +
638 + $this->wpstream_pagination($media_list->max_num_pages,$range=2);
639 + $return_string= ob_get_contents();
640 + ob_end_clean();
641 +
642 + return $return_string;
643 + }
808 644
809 - /**
810 - * help function for media list elementor widget
811 - *
812 - * Compatibility delegate for customer themes that call the historical
813 - * renderer on the main plugin object.
814 - *
815 - * @since 3.0.1
816 - * @param array $attributes Widget attributes (counts, type, order, labels).
817 - * @param string|null $content Unused shortcode inner content.
818 - * @return string Rendered HTML markup for the media grid.
819 - */
645 +
646 +
647 +
648 +
649 +
650 + /*
651 + *
652 + *
653 + * Pagination for media lista
654 + *
655 + *
656 + *
657 + */
658 +
659 +
820 660
821 - public function wpstream_media_list_elementor_function($attributes, $content = null){
822 - $kind = isset( $attributes['product_type'] ) && 2 === intval( $attributes['product_type'] )
823 - ? 'vod'
824 - : 'live_channel';
825 - return $this->media_list->render( $kind, is_array( $attributes ) ? $attributes : array() );
661 +
662 + function wpstream_pagination($pages = '', $range = 2){
663 +
664 + $showitems = ($range * 2)+1;
665 + global $paged;
666 + if(empty($paged)) $paged = 1;
667 +
668 +
669 + if($pages == ''){
670 + global $wp_query;
671 + $pages = $wp_query->max_num_pages;
672 + if(!$pages)
673 + {
674 + $pages = 1;
675 + }
826 676 }
827 677
678 + if(1 != $pages){
679 + print '<ul class="wpstream_pagination ">';
680 + print '<li class="roundleft"><a href="'.get_pagenum_link($paged - 1).'"> < </a></li>';
681 +
682 + for ($i=1; $i <= $pages; $i++)
683 + {
684 + if (1 != $pages &&( !($i >= $paged+$range+1 || $i <= $paged-$range-1) || $pages <= $showitems ))
685 + {
686 + if ($paged == $i){
687 + print '<li class="active"><a href="'.esc_url(get_pagenum_link($i)).'" >'.$i.'</a><li>';
688 + }else{
689 + print '<li><a href="'.esc_url(get_pagenum_link($i)).'" >'.$i.'</a><li>';
690 + }
691 + }
692 + }
693 +
694 + $prev_page= get_pagenum_link($paged + 1);
695 + if ( ($paged +1) > $pages){
696 + $prev_page= get_pagenum_link($paged );
697 + }else{
698 + $prev_page= get_pagenum_link($paged + 1);
699 + }
700 +
701 +
702 + print '<li class="roundright"><a href="'.$prev_page.'"> > </a><li>';
703 + print '</ul>';
704 + }
705 + }
706 +
828 707
829 708
830 709
831 710
@@ -839,22 +718,16 @@
839 718
840 719 /**
841 720 * help function for player elementr widget
842 721 *
843 - * Renders the standard video player for a given product id, or resolves the
844 - * author's first channel when only a user_id is supplied.
845 - *
846 722 * @since 3.0.1
847 - * @param array $attributes Widget attributes ('id', 'user_id').
848 - * @param string|null $content Unused shortcode inner content.
849 - * @return string Rendered player markup.
723 + * @return string
850 724 */
851 -
725 +
852 726 public function wpstream_insert_player_elementor($attributes, $content = null){
853 - // Normalize incoming attributes with defaults.
854 727 $product_id = '';
855 728 $return_string = '';
856 - $attributes = shortcode_atts(
729 + $attributes = shortcode_atts(
857 730 array(
858 731 'id' => 0,
859 732 'user_id' => 0,
860 733 ), $attributes) ;
@@ -859,27 +732,23 @@
859 732 'user_id' => 0,
860 733 ), $attributes) ;
861 734
862 735
863 - // Explicit product id, if provided.
864 736 if ( isset($attributes['id']) ){
865 737 $product_id=$attributes['id'];
866 738 }
867 - // Optional author id used to look up a channel.
868 739 if ( isset($attributes['user_id']) ){
869 740 $user_id = intval( $attributes['user_id'] );
870 741 }
871 -
872 - // No product id but a user id: resolve that author's first channel.
742 +
873 743 if(intval($product_id)==0 && $user_id!=0 ){
874 - $product_id= $this->wpstream_player_retrieve_first_id($user_id);
744 + $product_id= $this->wpstream_player_retrive_first_id($user_id);
875 745 }
876 -
877 -
878 -
879 - // Buffer the player output so it can be returned as a string.
746 +
747 +
748 +
749 +
880 750 ob_start();
881 - // Render the player shortcode inside the wrapper markup below.
882 751 ?>
883 752 <div class="wpstream_insert_player_elementor_wrapper">
884 753 <?php
885 754 $this->main->wpstream_player->wpstream_video_player_shortcode($product_id);
@@ -885,103 +754,127 @@
885 754 $this->main->wpstream_player->wpstream_video_player_shortcode($product_id);
886 755 ?>
887 756 </div>
888 757 <?php
889 - // Capture and return the buffered markup.
890 758 $return_string= ob_get_contents();
891 - ob_end_clean();
759 + ob_end_clean();
892 760
893 761 return $return_string;
894 762 }
895 763
764 + /**
765 + * help function for player low latency elementor widget
766 + *
767 + * @since 3.0.1
768 + * @return string
769 + */
770 +
771 + public function wpstream_insert_player__low_latency_elementor($attributes, $content = null){
772 + $product_id = '';
773 + $return_string = '';
774 + $attributes = shortcode_atts(
775 + array(
776 + 'id' => 0,
777 + 'user_id' => 0,
778 + ), $attributes) ;
896 779
897 - /**
898 - * Resolve the first channel/event id belonging to a given author.
899 - *
900 - * @param string|int $received_user_id Author user id.
901 - * @return int|string Post id of the author's first channel, or 0 when none.
902 - */
903 - public function wpstream_player_retrieve_first_id($received_user_id=''){
904 - // Free vs paid channel type is a site-wide option.
780 +
781 + if ( isset($attributes['id']) ){
782 + $product_id=$attributes['id'];
783 + }
784 +
785 + if ( isset($attributes['user_id']) ){
786 + $user_id = intval( $attributes['user_id'] );
787 + }
788 +
789 + if(intval($product_id)==0 && $user_id!=0){
790 + $product_id= $this->wpstream_player_retrive_first_id($user_id);
791 + }
792 +
793 +
794 + ob_start();
795 + $this->main->wpstream_player->wpstream_video_player_shortcode_low_latency($product_id);
796 + $return_string= ob_get_contents();
797 + ob_end_clean();
798 +
799 + return $return_string;
800 + }
801 +
802 +
803 +
804 + public function wpstream_player_retrive_first_id($received_user_id=''){
905 805 $channel_type = get_option ('wpstream_user_streaming_channel_type');
906 - // Look up the author's most relevant event id for that type.
907 806 $product_id = $this->wpstream_get_current_event_per_author($received_user_id,$channel_type);
908 807 return $product_id;
909 808 }
809 +
810 +
811 +
812 + /**
813 + * help function for chat elementor widget
814 + *
815 + * @since 3.0.1
816 + * @return string
817 + */
818 +
819 + public function wpstream_insert_chat_elementor($attributes, $content = null){
820 + $product_id = '';
821 + $return_string = '';
822 + $attributes = shortcode_atts(
823 + array(
824 + 'id' => 0,
825 + ), $attributes) ;
910 826
911 - /**
912 - * Deprecated misspelled alias of wpstream_player_retrieve_first_id().
913 - *
914 - * Kept because the method is public and may be called by external code.
915 - *
916 - * @deprecated 4.13.4 Use wpstream_player_retrieve_first_id() instead.
917 - */
918 - public function wpstream_player_retrive_first_id($received_user_id=''){
919 - return $this->wpstream_player_retrieve_first_id($received_user_id);
827 +
828 + if ( isset($attributes['id']) ){
829 + $product_id=$attributes['id'];
830 + }
831 +
832 + $return_string.= '<div class="wpstream_plugin_chat_wrapper">';
833 + ob_start();
834 + $this->main->wpstream_player->wpstream_chat_wrapper($product_id);
835 + $return_string.= ob_get_contents();
836 + ob_end_clean();
837 + $return_string.='</div>';
838 + $this->main->wpstream_player->wpstream_connect_to_chat($product_id);
839 +
840 + return $return_string;
920 841 }
921 842
922 843
923 -
924 844 /**
925 - * edited 4.0
845 + * edited 4.0
926 846 *
927 - * Check if the current user is allowed to stream.
847 + * Check if user is allowed to stream
928 848 *
929 - * The one broadcasting-permission rule: administrators always may; other
930 - * users need their primary role on the "streamer roles" list or the
931 - * "regular users may stream" option. The verdict passes through the
932 - * wpstream_user_can_stream filter, so membership plugins replace the
933 - * role rule in one place. Guests are refused before the filter.
934 - *
935 849 * @since 3.7
936 - * @return bool
937 850 */
938 851
939 852 public function wpstream_check_user_can_stream(){
940 - // Current user for the role/capability checks below.
941 853 $current_user = wp_get_current_user();
942 -
943 - // Guests can never stream.
854 +
944 855 if( !is_user_logged_in() ){
945 856 return false;
857 + exit('user not logged in');
946 858 }
947 -
948 - // Admins can always broadcast.
949 - $can = current_user_can( 'administrator' );
950 -
951 - if ( ! $can ) {
952 - // Site-configured list of roles that are allowed to stream.
953 - $extra_roles = get_option( 'wpstream_stream_role', true );
954 - // The user's primary role (first in the roles array).
955 - $user_role = '';
956 - if( is_array( $current_user->roles) && count( $current_user->roles ) > 0 ){
957 - $user_role = $current_user->roles[0];
958 - }
959 -
960 - // Allow when the user's role is in the configured allow-list.
961 - if ( is_array($extra_roles) && in_array( $user_role, $extra_roles ) ) {
962 - $can = true;
963 - }
964 -
965 - // Allow when the "regular users may stream" option is enabled.
966 - if(function_exists('wpstream_get_option') && intval(wpstream_get_option('allow_streaming_regular_users',''))==1 ){
967 - $can = true;
968 - }
859 +
860 + if(current_user_can('administrator')){
861 + // admins can always brodcast
862 + return true;
969 863 }
970 -
971 - /**
972 - * Filters whether the current (logged-in) user may broadcast.
973 - *
974 - * Gates every go-live surface: the start/stop endpoints, the
975 - * start-streaming dashboard and channel creation.
976 - *
977 - * @since 4.14.0
978 - *
979 - * @param bool $can The built-in verdict (administrator, streamer
980 - * role list, or the regular-users option).
981 - * @param int $user_id Current user ID.
982 - */
983 - return (bool) apply_filters( 'wpstream_user_can_stream', $can, intval( $current_user->ID ) );
864 +
865 + $extra_roles = get_option( 'wpstream_stream_role', true );
866 + $user_role = $current_user->roles[0];
867 +
868 + if (is_array($extra_roles) && in_array($user_role, $extra_roles)){
869 + return true;
870 + }
871 +
872 + if(function_exists('wpstream_get_option') && intval(wpstream_get_option('allow_streaming_regular_users',''))==1 ){
873 + return true;
874 + }
875 +
876 + return false;
984 877 }
985 878
986 879
987 880 /**
@@ -986,37 +879,23 @@
986 879
987 880 /**
988 881 * Start Streaming wrapper
989 882 *
990 - * Ensures a channel exists (creating one for front-end streamers when
991 - * needed), prints the error-modal scaffolding, then renders the start-
992 - * streaming unit.
993 - *
994 883 * @since 3.7
995 - * @param int $item_id Channel/product id, or 0 to auto-resolve.
996 - * @param string $type Streaming unit type/context.
997 884 */
885 +
998 886 public function wpstream_live_stream_unit_wrapper($item_id,$type){
999 - // Coerce to an integer id.
1000 887 $item_id = intval($item_id);
1001 -
1002 - // The unit's controller script (+ its QR dependency chain) and the shared
1003 - // admin stylesheet are registered on every page but only enqueued here,
1004 - // where the go-live unit actually renders (scripts print in the footer).
1005 - wp_enqueue_script( 'wpstream-start-streaming' );
1006 - wp_enqueue_style( 'wpstream_front_style' );
1007 -
888 +
1008 889 if($item_id == 0){
1009 890 //retrive or create channel for front end streamers
1010 - $item_id=$this->wpstream_retrieve_front_end_channel();
891 + $item_id=$this->wpstream_retrive_front_end_channel();
1011 892 }
1012 - // Modal backdrop and reusable error-notification markup.
1013 - print'<div class="wpstream_modal_background"></div>';
893 + print'<div class="wpstream_modal_background"></div>';
1014 894 print '<div class="wpstream_error_modal_notification"><div class="wpstream_error_content">er2</div>
1015 895 <div class="wpstream_error_ok wpstream_button" type="button">'.esc_html__('Close','wpstream').'</div>
1016 896 </div>';
1017 - // Render through the shared Live Channel presentation module.
1018 - $this->get_live_channel_presentation()->render_channel( $item_id, $type );
897 + $this->admin->wpstream_live_stream_unit( $item_id,$type );
1019 898 }
1020 899
1021 900
1022 901 /**
@@ -1021,35 +900,23 @@
1021 900
1022 901 /**
1023 902 * Start Streaming wrapper for wpstream theme
1024 903 *
1025 - * Same as wpstream_live_stream_unit_wrapper() but renders the theme's
1026 - * variant of the start-streaming unit.
1027 - *
1028 904 * @since 3.7
1029 - * @param int $item_id Channel/product id, or 0 to auto-resolve.
1030 - * @param string $type Streaming unit type/context.
1031 905 */
1032 -
906 +
1033 907 public function wpstream_live_stream_unit_wrapper_for_theme($item_id,$type){
1034 - // Coerce to an integer id.
1035 908 $item_id = intval($item_id);
1036 -
1037 - // Same render-time asset loading as wpstream_live_stream_unit_wrapper().
1038 - wp_enqueue_script( 'wpstream-start-streaming' );
1039 - wp_enqueue_style( 'wpstream_front_style' );
1040 -
909 +
1041 910 if($item_id == 0){
1042 911 //retrive or create channel for front end streamers
1043 - $item_id=$this->wpstream_retrieve_front_end_channel();
912 + $item_id=$this->wpstream_retrive_front_end_channel();
1044 913 }
1045 - // Modal backdrop and reusable error-notification markup.
1046 914 print'<div class="wpstream_modal_background"></div>';
1047 915 print '<div class="wpstream_error_modal_notification"><div class="wpstream_error_content">er2</div>
1048 916 <div class="wpstream_error_ok wpstream_button" type="button">'.esc_html__('Close','wpstream').'</div>
1049 917 </div>';
1050 - // Render the companion-theme variant through the same presentation module.
1051 - $this->get_live_channel_presentation()->render_channel( $item_id, 'theme' );
918 + $this->admin->wpstream_live_stream_unit_for_theme( $item_id,$type );
1052 919 }
1053 920
1054 921
1055 922 /**
@@ -1054,104 +921,77 @@
1054 921
1055 922 /**
1056 923 * retrive channel for front end streaming
1057 924 *
1058 - * Returns the current user's front-end channel id, creating a new event
1059 - * when the user does not yet have one.
1060 - *
1061 925 * @since 3.7
1062 - * @return int Channel/product id for the current user.
1063 926 */
1064 - public function wpstream_retrieve_front_end_channel(){
1065 -
1066 - // Current user plus the site-wide channel type and default price.
927 + public function wpstream_retrive_front_end_channel(){
928 +
1067 929 $current_user = wp_get_current_user();
1068 930 $channel_type = get_option ('wpstream_user_streaming_channel_type');
1069 931 $channel_price = floatval( get_option ('wpstream_user_streaming_default_price') );
1070 -
1071 - // Look for an existing channel owned by this user.
932 +
1072 933 $front_end_streamin_channel = $this->wpstream_get_current_event_per_author($current_user->ID,$channel_type);
1073 -
1074 - // None found: create one on the fly.
934 +
1075 935 if(intval($front_end_streamin_channel) == 0){
1076 - $front_end_streamin_channel= $this->wpstream_create_front_end_event($current_user->ID,$current_user->user_login ,$channel_type,$channel_price);
936 + $front_end_streamin_channel= $this->wpstrea_create_front_end_event($current_user->ID,$current_user->user_login ,$channel_type,$channel_price);
1077 937 }
1078 938 return $front_end_streamin_channel;
1079 -
939 +
1080 940 }
1081 -
941 +
1082 942 /**
1083 - * Deprecated misspelled alias of wpstream_retrieve_front_end_channel().
1084 - *
1085 - * Kept because the method is public and may be called by external code.
1086 - *
1087 - * @deprecated 4.13.4 Use wpstream_retrieve_front_end_channel() instead.
1088 - */
1089 - public function wpstream_retrive_front_end_channel(){
1090 - return $this->wpstream_retrieve_front_end_channel();
1091 - }
1092 -
1093 - /**
1094 943 * create the event from front end
1095 944 *
1096 - * Inserts a new channel post (free CPT or paid WooCommerce product),
1097 - * setting price/terms for paid channels, and flags it as a live event.
1098 - *
1099 945 * @since 3.7
1100 - * @param int $userID Author user id.
1101 - * @param string $userLogin Author login, used in the channel title.
1102 - * @param string $channel_type 'paid' for a WooCommerce product, else free.
1103 - * @param float $channel_price Price to set for paid channels.
1104 - * @return int|void New post id, or void when the user may not stream.
1105 946 */
1106 -
1107 - public function wpstream_create_front_end_event($userID,$userLogin,$channel_type,$channel_price){
1108 - $request = array(
1109 - 'actor_id' => intval( $userID ),
1110 - 'owner_id' => intval( $userID ),
1111 - 'kind' => 'live_channel',
1112 - 'access' => 'paid' === $channel_type ? 'paid' : 'free',
1113 - 'title' => sprintf( esc_html__( '%s Channel', 'wpstream' ), $userLogin ),
1114 - );
1115 - if ( 'paid' === $request['access'] ) {
1116 - $request['price'] = $channel_price;
1117 - }
1118 -
1119 - $result = $this->streaming_content_creation->create( $request );
1120 - return ! empty( $result['success'] ) ? intval( $result['content_id'] ) : null;
1121 - }
1122 -
1123 - /**
1124 - * Deprecated misspelled alias of wpstream_create_front_end_event().
1125 - *
1126 - * Kept because the method is public and may be called by external code.
1127 - *
1128 - * @deprecated 4.13.4 Use wpstream_create_front_end_event() instead.
1129 - */
947 +
1130 948 public function wpstrea_create_front_end_event($userID,$userLogin,$channel_type,$channel_price){
1131 - return $this->wpstream_create_front_end_event($userID,$userLogin,$channel_type,$channel_price);
949 +
950 + if( !$this->wpstream_check_user_can_stream() ){
951 + return;
952 + }
953 +
954 + $post_type='wpstream_product';
955 + if($channel_type=='paid'){
956 + $post_type='product';
957 + }
958 +
959 + $post = array(
960 + 'post_title' => sprintf( esc_html__('%s Channel','wpstream'),$userLogin),
961 + 'post_content' => '',
962 + 'post_type' => $post_type ,
963 + 'post_author' => $userID,
964 + 'post_status' => 'publish',
965 + );
966 + $post_id = wp_insert_post($post );
967 + if($channel_type=='paid'){
968 + $product = wc_get_product($post_id);
969 + $price = wc_format_decimal($channel_price);
970 +
971 + $product = wc_get_product( $post_id );
972 + // Set the product active price (regular)
973 + $product->set_price( $price );
974 + $product->set_regular_price( $price ); // To be sure
975 + $product->save();
976 + update_post_meta ($post_id,'event_passed',0);
977 + wp_set_object_terms( $post_id, 'live_stream', 'product_type' );
978 + }
979 + update_post_meta($post_id,'wpstream_product_type',1);
980 +
981 + return $post_id;
1132 982 }
1133 -
1134 -
1135 -
1136 - /**
1137 - * Find the first channel/event id owned by a given author.
1138 - *
1139 - * @param int $userID Author user id.
1140 - * @param string $channel_type 'paid' for a WooCommerce product, else free.
1141 - * @return int Post id of the author's first matching channel, or 0.
1142 - */
983 +
984 +
1143 985 public function wpstream_get_current_event_per_author($userID,$channel_type){
1144 -
1145 - // Free channels are CPTs; paid channels are WooCommerce products.
986 +
1146 987 $post_type='wpstream_product';
1147 988 if($channel_type=='paid'){
1148 989 $post_type='product';
1149 990 }
1150 -
1151 - // Query for a single post id owned by this author.
991 +
1152 992 $args = array(
1153 -
993 +
1154 994 'post_type' => $post_type,
1155 995 'author' => $userID,
1156 996 'posts_per_page' => 1,
1157 997 'fields' => 'ids'
@@ -1157,9 +997,8 @@
1157 997 'fields' => 'ids'
1158 998 )
1159 999 ;
1160 1000 $author_posts = new WP_Query( $args );
1161 - // Use the found id, or 0 when the author has no channel.
1162 1001 if( $author_posts->have_posts() ) {
1163 1002 $author_posts->the_post();
1164 1003 $the_id= get_the_ID();
1165 1004 }else{
@@ -1164,10 +1003,9 @@
1164 1003 $the_id= get_the_ID();
1165 1004 }else{
1166 1005 $the_id= 0;
1167 1006 }
1168 -
1169 - // Restore global post/query state after the custom query.
1007 +
1170 1008 wp_reset_query();
1171 1009 wp_reset_postdata();
1172 1010 return $the_id;
1173 1011 }
@@ -1175,9 +1013,8 @@
1175 1013 /**
1176 1014 * Cleanup old logs
1177 1015 */
1178 1016 public function cleanup_logs() {
1179 - // Delegate to the logger, which prunes entries past its retention window.
1180 1017 $logger = new WPStream_Logger();
1181 1018 $logger->clear_old_logs();
1182 1019 }
1183 1020 }