update
This commit is contained in:
1429
wp-content/plugins/youtube-feed-pro/inc/Admin/SBY_Admin.php
Normal file
1429
wp-content/plugins/youtube-feed-pro/inc/Admin/SBY_Admin.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,992 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Admin;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\Feed_Locator;
|
||||
|
||||
abstract class SBY_Admin_Abstract {
|
||||
|
||||
protected $vars;
|
||||
|
||||
protected $base_path;
|
||||
|
||||
protected $slug;
|
||||
|
||||
protected $plugin_name;
|
||||
|
||||
protected $capability;
|
||||
|
||||
protected $icon;
|
||||
|
||||
protected $tabs;
|
||||
|
||||
protected $active_tab;
|
||||
|
||||
protected $settings_sections;
|
||||
|
||||
protected $display_your_feed_sections;
|
||||
|
||||
protected $option_name;
|
||||
|
||||
protected $types;
|
||||
|
||||
protected $layouts;
|
||||
|
||||
protected $false_fields;
|
||||
|
||||
protected $textarea_fields;
|
||||
|
||||
protected $position;
|
||||
|
||||
protected $settings;
|
||||
|
||||
public function __construct( $vars, $base_path, $slug, $plugin_name, $capability, $icon, $position, $tabs, $settings, $active_tab = false, $option_name = 'sbspf_settings' ) {
|
||||
$this->vars = $vars;
|
||||
$this->base_path = $base_path;
|
||||
$this->slug = $slug;
|
||||
$this->plugin_name = $plugin_name;
|
||||
$this->capability = $capability;
|
||||
$this->icon = $icon;
|
||||
$this->position = $position;
|
||||
|
||||
$this->tabs = $tabs;
|
||||
|
||||
if ( $active_tab ) {
|
||||
$this->set_active_tab( $active_tab );
|
||||
} else {
|
||||
$this->set_active_tab( $tabs[0]['slug'] );
|
||||
}
|
||||
$this->settings = $settings;
|
||||
$this->option_name = $option_name;
|
||||
$this->false_fields = array();
|
||||
$this->textarea_fields = array();
|
||||
$this->display_your_feed_sections = array();
|
||||
}
|
||||
|
||||
public function get_vars() {
|
||||
return $this->vars;
|
||||
}
|
||||
|
||||
public function get_option_name() {
|
||||
return $this->option_name;
|
||||
}
|
||||
|
||||
public function verify_post( $post ) {
|
||||
return wp_verify_nonce( $post[ $this->option_name . '_validate' ], $this->option_name . '_validate' );
|
||||
}
|
||||
|
||||
public function hidden_fields_for_tab( $tab ) {
|
||||
wp_nonce_field( $this->get_option_name() . '_validate', $this->get_option_name() . '_validate', true, true );
|
||||
?>
|
||||
<input type="hidden" name="<?php echo $this->get_option_name() . '_tab_marker'; ?>" value="<?php echo esc_attr( $tab ); ?>"/>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function init() {
|
||||
// add_action( 'admin_menu', array( $this, 'create_menus' ) );
|
||||
add_action( 'admin_init', array( $this, 'settings_init' ) );
|
||||
add_action( 'admin_init', array( $this, 'additional_settings_init' ) );
|
||||
|
||||
}
|
||||
|
||||
public function settings_init() {
|
||||
/**
|
||||
* Configure Tab
|
||||
*/
|
||||
$args = array(
|
||||
'id' => 'sbspf_types',
|
||||
'tab' => 'configure',
|
||||
'save_after' => 'true'
|
||||
);
|
||||
$this->add_settings_section( $args );
|
||||
|
||||
/* Types */
|
||||
$locator_html = '';
|
||||
if ( Feed_Locator::count_unique() > -1 ) {
|
||||
$locator_html .= '<div class="sby_locations_link">';
|
||||
$locator_html .= '<a href="?page=' . $this->slug .'&tab=allfeeds"><svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="search" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-search fa-w-16 fa-2x"><path fill="currentColor" d="M508.5 468.9L387.1 347.5c-2.3-2.3-5.3-3.5-8.5-3.5h-13.2c31.5-36.5 50.6-84 50.6-136C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c52 0 99.5-19.1 136-50.6v13.2c0 3.2 1.3 6.2 3.5 8.5l121.4 121.4c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17zM208 368c-88.4 0-160-71.6-160-160S119.6 48 208 48s160 71.6 160 160-71.6 160-160 160z" class=""></path></svg> ' . __( 'Feed Finder', 'feeds-for-youtube' ) . '</a>';
|
||||
$locator_html .= '</div>';
|
||||
}
|
||||
$args = array(
|
||||
'name' => 'type',
|
||||
'section' => 'sbspf_types',
|
||||
'callback' => 'types',
|
||||
'title' => '<label>' . __( 'Select a Feed Type', 'feeds-for-youtube' ) .'</label>',
|
||||
'shortcode' => array(
|
||||
'key' => 'type',
|
||||
'example' => 'channel',
|
||||
'description' => __( 'Type of feed to display', 'feeds-for-youtube' ) . ' e.g. channel, playlist, search, favorites, live',
|
||||
'after_description' => $locator_html,
|
||||
'display_section' => 'configure'
|
||||
),
|
||||
'types' => $this->types
|
||||
);
|
||||
$this->add_settings_field( $args );
|
||||
|
||||
/* Cache */
|
||||
$args = array(
|
||||
'name' => 'cache',
|
||||
'section' => 'sbspf_types',
|
||||
'callback' => 'cache',
|
||||
'title' => __( 'Check for new posts', 'feeds-for-youtube' )
|
||||
);
|
||||
$this->add_settings_field( $args );
|
||||
|
||||
/**
|
||||
* Customize Tab
|
||||
*/
|
||||
$args = array(
|
||||
'title' => __( 'General', 'feeds-for-youtube' ),
|
||||
'id' => 'sbspf_general',
|
||||
'tab' => 'customize',
|
||||
'save_after' => 'true'
|
||||
);
|
||||
$this->add_settings_section( $args );
|
||||
|
||||
/* Width and Height */
|
||||
$select_options = array(
|
||||
array(
|
||||
'label' => '%',
|
||||
'value' => '%'
|
||||
),
|
||||
array(
|
||||
'label' => 'px',
|
||||
'value' => 'px'
|
||||
)
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'name' => 'width',
|
||||
'default' => '100',
|
||||
'section' => 'sbspf_general',
|
||||
'callback' => 'text',
|
||||
'min' => 1,
|
||||
'size' => 4,
|
||||
'title' => __( 'Width of Feed', 'feeds-for-youtube' ),
|
||||
'shortcode' => array(
|
||||
'key' => 'width',
|
||||
'example' => '300px',
|
||||
'description' => __( 'The width of your feed. Any number with a unit like "px" or "%".', 'feeds-for-youtube' ),
|
||||
'display_section' => 'customize'
|
||||
),
|
||||
'select_name' => 'widthunit',
|
||||
'select_options' => $select_options,
|
||||
'hidden' => array(
|
||||
'callback' => 'checkbox',
|
||||
'name' => 'width_responsive',
|
||||
'label' => __( 'Set to be 100% width on mobile?', 'feeds-for-youtube' ),
|
||||
'before' => '<div id="sbspf_width_options">',
|
||||
'after' => '</div>',
|
||||
'tooltip_info' => __( 'If you set a width on the feed then this will be used on mobile as well as desktop. Check this setting to set the feed width to be 100% on mobile so that it is responsive.', 'feeds-for-youtube' )
|
||||
),
|
||||
);
|
||||
$this->add_settings_field( $args );
|
||||
|
||||
$select_options = array(
|
||||
array(
|
||||
'label' => '%',
|
||||
'value' => '%'
|
||||
),
|
||||
array(
|
||||
'label' => 'px',
|
||||
'value' => 'px'
|
||||
)
|
||||
);
|
||||
$args = array(
|
||||
'name' => 'height',
|
||||
'default' => '',
|
||||
'section' => 'sbspf_general',
|
||||
'callback' => 'text',
|
||||
'min' => 1,
|
||||
'size' => 4,
|
||||
'title' => __( 'Height of Feed', 'feeds-for-youtube' ),
|
||||
'shortcode' => array(
|
||||
'key' => 'height',
|
||||
'example' => '500px',
|
||||
'description' => __( 'The height of your feed. Any number with a unit like "px" or "em".', 'feeds-for-youtube' ),
|
||||
'display_section' => 'customize'
|
||||
),
|
||||
'select_name' => 'heightunit',
|
||||
'select_options' => $select_options,
|
||||
);
|
||||
$this->add_settings_field( $args );
|
||||
|
||||
$args = array(
|
||||
'name' => 'background',
|
||||
'default' => '',
|
||||
'section' => 'sbspf_general',
|
||||
'callback' => 'color',
|
||||
'title' => __( 'Background Color', 'feeds-for-youtube' ),
|
||||
'shortcode' => array(
|
||||
'key' => 'background',
|
||||
'example' => '#f00',
|
||||
'description' => __( 'Background color for the feed. Any hex color code.', 'feeds-for-youtube' ),
|
||||
'display_section' => 'customize'
|
||||
),
|
||||
);
|
||||
$this->add_settings_field( $args );
|
||||
|
||||
$args = array(
|
||||
'title' => __( 'Layout', 'feeds-for-youtube' ),
|
||||
'id' => 'sbspf_layout',
|
||||
'tab' => 'customize',
|
||||
'save_after' => 'true'
|
||||
);
|
||||
$this->add_settings_section( $args );
|
||||
|
||||
$args = array(
|
||||
'name' => 'layout',
|
||||
'section' => 'sbspf_layout',
|
||||
'callback' => 'layout',
|
||||
'title' => __( 'Layout Type', 'feeds-for-youtube' ),
|
||||
'layouts' => $this->layouts,
|
||||
'shortcode' => array(
|
||||
'key' => 'layout',
|
||||
'example' => 'list',
|
||||
'description' => __( 'How your posts are display visually.', 'feeds-for-youtube' ),
|
||||
'display_section' => 'layout'
|
||||
)
|
||||
);
|
||||
$this->add_settings_field( $args );
|
||||
}
|
||||
|
||||
public function additional_settings_init() {
|
||||
|
||||
}
|
||||
|
||||
public function add_false_field( $name, $tab ) {
|
||||
$this->false_fields[ $tab ][] = $name;
|
||||
}
|
||||
|
||||
public function get_false_fields( $tab ) {
|
||||
if ( isset( $this->false_fields[ $tab ] ) ) {
|
||||
return $this->false_fields[ $tab ];
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function add_textarea_field( $name, $tab ) {
|
||||
$this->textarea_fields[ $tab ][] = $name;
|
||||
}
|
||||
|
||||
public function get_textarea_fields( $tab ) {
|
||||
if ( isset( $this->textarea_fields[ $tab ] ) ) {
|
||||
return $this->textarea_fields[ $tab ];
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function blank() {
|
||||
|
||||
}
|
||||
|
||||
public function add_settings_section( $args ) {
|
||||
$title = isset( $args['title'] ) ? $args['title'] : '';
|
||||
$callback = isset( $args['callback'] ) ? $args['callback'] : array( $this, 'blank' );
|
||||
add_settings_section(
|
||||
$args['id'],
|
||||
$title,
|
||||
$callback,
|
||||
$args['id']
|
||||
);
|
||||
|
||||
$save_after = isset( $args['save_after'] ) ? $args['save_after'] : false;
|
||||
$this->settings_sections[ $args['tab'] ][] = array(
|
||||
'id' => $args['id'],
|
||||
'save_after' => $save_after
|
||||
);
|
||||
}
|
||||
|
||||
public function add_settings_field( $args ) {
|
||||
$title_after = '';
|
||||
$shortcode = false;
|
||||
if ( isset( $args['shortcode'] ) ) {
|
||||
$title_after = isset( $args['shortcode']['after'] ) ? $args['shortcode']['after'] : '';
|
||||
$shortcode = $args['shortcode'];
|
||||
}
|
||||
|
||||
if ( $shortcode ) {
|
||||
$this->display_your_feed_sections[ $shortcode['display_section'] ]['settings'][] = $shortcode;
|
||||
}
|
||||
|
||||
if ( $args['callback'] === 'types' ) {
|
||||
$formatted_label = '<label for="' . $this->option_name . '_' . $args['name'] . '">' . $args['title'] .'</label>';
|
||||
$formatted_label .= '<code class="sbspf_shortcode">type'. "\n";
|
||||
foreach ( $args['types'] as $type ) {
|
||||
$shortcode = array(
|
||||
'key' => $type['slug'],
|
||||
'example' => $type['example'],
|
||||
'description' => $type['description'],
|
||||
'display_section' => 'configure'
|
||||
);
|
||||
$this->display_your_feed_sections[ $shortcode['display_section'] ]['settings'][] = $shortcode;
|
||||
|
||||
|
||||
$formatted_label .= 'Eg: type=' . $type['slug'] . '<br>';
|
||||
$formatted_label .= $type['slug'] . '="' . substr( $type['example'], 0, 14) . '"<br>';
|
||||
|
||||
}
|
||||
$formatted_label .= '</code><br>';
|
||||
|
||||
if ( isset( $args['shortcode']['after_description'] ) ) {
|
||||
$formatted_label .= $args['shortcode']['after_description'];
|
||||
}
|
||||
$title = $formatted_label;
|
||||
} else {
|
||||
$title = $this->format_title( $args['title'], $args['name'], $shortcode, $title_after );
|
||||
}
|
||||
|
||||
if ( $args['callback'] === 'checkbox' || (isset( $args['falsefield'] ) && $args['falsefield'] === true) ) {
|
||||
$tab = 'none';
|
||||
foreach ( $this->settings_sections as $key => $settings_sections ) {
|
||||
foreach ( $settings_sections as $this_tab_sections ) {
|
||||
if ( $this_tab_sections['id'] === $args['section'] ) {
|
||||
$tab = $key;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
$this->add_false_field( $args['name'], $tab );
|
||||
}
|
||||
|
||||
if ( $args['callback'] === 'layout' || $args['callback'] === 'sub_option' ) {
|
||||
$tab = 'none';
|
||||
foreach ( $this->settings_sections as $key => $settings_sections ) {
|
||||
foreach ( $settings_sections as $this_tab_sections ) {
|
||||
if ( $this_tab_sections['id'] === $args['section'] ) {
|
||||
$tab = $key;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
$sub_options = isset( $args['layouts'] ) ? $args['layouts'] : $args['sub_options'];
|
||||
foreach ( $sub_options as $sub_option ) {
|
||||
if ( isset( $sub_option['options'] ) ) {
|
||||
foreach( $sub_option['options'] as $sub_sub_option ) {
|
||||
if ( ! empty( $sub_sub_option['shortcode'] ) ) {
|
||||
$key = ! empty( $sub_sub_option['shortcode']['key'] ) ? $sub_sub_option['shortcode']['key'] : $sub_option['slug'] . $sub_sub_option['name'];
|
||||
$example = ! empty( $sub_sub_option['shortcode']['example'] ) ? $sub_sub_option['shortcode']['example'] : '';
|
||||
$description = ! empty( $sub_sub_option['shortcode']['description'] ) ? $sub_sub_option['shortcode']['description'] : '';
|
||||
$display_section = ! empty( $sub_sub_option['shortcode']['display_section'] ) ? $sub_sub_option['shortcode']['display_section'] : str_replace( 'sbspf_', '', $args['section'] );
|
||||
$sub_shortcode = array(
|
||||
'key' => $key,
|
||||
'example' => $example,
|
||||
'description' => $description,
|
||||
'display_section' => $display_section
|
||||
);
|
||||
if ( isset( $this->display_your_feed_sections[ $display_section ] ) ) {
|
||||
$this->display_your_feed_sections[ $display_section ]['settings'][] = $sub_shortcode;
|
||||
}
|
||||
}
|
||||
if ( $sub_sub_option['callback'] === 'checkbox' ) {
|
||||
$this->add_false_field( $sub_option['slug'] . $sub_sub_option['name'], $tab );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $args['callback'] === 'textarea' ) {
|
||||
$tab = 'none';
|
||||
foreach ( $this->settings_sections as $key => $settings_sections ) {
|
||||
foreach ( $settings_sections as $this_tab_sections ) {
|
||||
if ( $this_tab_sections['id'] === $args['section'] ) {
|
||||
$tab = $key;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
$this->add_textarea_field( $args['name'], $tab );
|
||||
}
|
||||
|
||||
add_settings_field(
|
||||
$args['name'],
|
||||
$title,
|
||||
array( $this, $args['callback'] ),
|
||||
$args['section'],
|
||||
$args['section'],
|
||||
$args
|
||||
);
|
||||
|
||||
if ( isset( $args['hidden'] ) ) {
|
||||
if ( $args['hidden']['callback'] === 'checkbox' ) {
|
||||
$tab = 'none';
|
||||
foreach ( $this->settings_sections as $key => $settings_sections ) {
|
||||
foreach ( $settings_sections as $this_tab_sections ) {
|
||||
if ( $this_tab_sections['id'] === $args['section'] ) {
|
||||
$tab = $key;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
$this->add_false_field( $args['hidden']['name'], $tab );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function set_feed_types( $types ) {
|
||||
$this->types = $types;
|
||||
}
|
||||
|
||||
public function set_feed_layouts( $layouts ) {
|
||||
$this->layouts = $layouts;
|
||||
}
|
||||
|
||||
public function set_display_table_sections( $headings ) {
|
||||
foreach ( $headings as $heading ) {
|
||||
$this->display_your_feed_sections[ $heading['slug'] ] = array(
|
||||
'label' => $heading['label'],
|
||||
'settings' => array()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function checkbox( $args ) {
|
||||
$default = isset( $args['default'] ) ? $args['default'] : false;
|
||||
$selected = isset( $this->settings[ $args['name'] ] ) ? $this->settings[ $args['name'] ] : $default;
|
||||
$label = isset( $args['label'] ) ? $args['label'] : __( 'Yes' );
|
||||
$tooltip_text = isset( $args['tooltip_text'] ) ? $args['label'] : $this->default_tooltip_text();
|
||||
$has_shortcode = isset( $args['has_shortcode'] ) && $args['has_shortcode'] ? '1' : '';
|
||||
?>
|
||||
<input name="<?php echo $this->option_name .'['.esc_attr( $args['name'] ).']'; ?>" id="<?php echo $this->option_name . '_' . $args['name']; ?>" class="sbspf_single_checkbox" type="checkbox"<?php if ( $selected ) echo ' checked'; ?>/>
|
||||
<label for="<?php echo $this->option_name . '_' . $args['name'] . $has_shortcode; ?>"><?php echo esc_html( $label ); ?></label><?php if ( $has_shortcode === '1' ) : ?><code class="sbspf_shortcode"> <?php echo $args['name'] . "\n"; ?>
|
||||
Eg: <?php echo $args['name']; ?>=<?php echo $args['shortcode_example']; ?></code><br><?php endif; ?>
|
||||
<?php if ( isset( $args['tooltip_info'] ) ) : ?>
|
||||
<a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php echo $tooltip_text; ?></a>
|
||||
<p class="sbspf_tooltip sbspf_more_info"><?php echo $args['tooltip_info']; ?></p>
|
||||
<?php
|
||||
endif;
|
||||
}
|
||||
|
||||
public function multi_checkbox( $args ) {
|
||||
$default = isset( $args['default'] ) ? $args['default'] : false;
|
||||
$selection_array = isset( $this->settings[ $args['name'] ] ) ? (array)$this->settings[ $args['name'] ] : (array)$default;
|
||||
$tooltip_text = isset( $args['tooltip_text'] ) ? $args['label'] : $this->default_tooltip_text();
|
||||
$index = 0;
|
||||
?>
|
||||
<?php foreach ( $args['select_options'] as $select_option ) :
|
||||
$selected = in_array( $select_option['value'], $selection_array, true );
|
||||
$pro_only = (isset( $select_option['pro'] ) && $select_option['pro']) ? ' sbspf_pro_only' : '';
|
||||
$class = ! empty( $select_option['class'] ) ? ' ' . $select_option['class'] : '';
|
||||
?>
|
||||
<div class="sbspf_multi_checkbox_option<?php echo $pro_only . $class; ?>">
|
||||
<input name="<?php echo $this->option_name .'['.esc_attr( $args['name'] ).'][]'; ?>" id="<?php echo $this->option_name . '_' . $args['name']. '_' . $index; ?>" value="<?php echo esc_attr( $select_option['value'] ); ?>" type="checkbox"<?php if ( $selected ) echo ' checked'; ?>/>
|
||||
<label for="<?php echo $this->option_name . '_' . $args['name'] . '_' . $index; ?>"><?php echo esc_html( $select_option['label'] ); ?></label>
|
||||
</div>
|
||||
<?php
|
||||
$index++;
|
||||
endforeach; ?>
|
||||
|
||||
<?php if ( isset( $args['tooltip_info'] ) ) : ?>
|
||||
<a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php echo $tooltip_text; ?></a>
|
||||
<p class="sbspf_tooltip sbspf_more_info"><?php echo $args['tooltip_info']; ?></p>
|
||||
<?php
|
||||
endif;
|
||||
}
|
||||
|
||||
public function text( $args ) {
|
||||
$default = isset( $args['default'] ) ? $args['default'] : '';
|
||||
$value = isset( $this->settings[ $args['name'] ] ) ? $this->settings[ $args['name'] ] : $default;
|
||||
$size = ( isset( $args['size'] ) ) ? ' size="'. $args['size'].'"' : '';
|
||||
$class = isset( $args['class'] ) ? ' class="'. esc_attr( $args['class'] ) . '"' : '';
|
||||
|
||||
$tooltip_text = isset( $args['tooltip_text'] ) ? $args['label'] : $this->default_tooltip_text();
|
||||
|
||||
if ( isset( $args['min'] ) ) :
|
||||
$min = ( isset( $args['min'] ) ) ? ' min="'. $args['min'].'"' : '';
|
||||
$max = ( isset( $args['max'] ) ) ? ' max="'. $args['max'].'"' : '';
|
||||
$step = ( isset( $args['step'] ) ) ? ' step="'. $args['step'].'"' : '';
|
||||
$class = isset( $args['class'] ) ? ' class="sbspf_number_field sbspf_size_' . $args['size'] . ' '. esc_attr( $args['class'] ) . '"' : ' class="sbspf_number_field sbspf_size_' . $args['size'] . '"';
|
||||
?>
|
||||
<input name="<?php echo $this->option_name.'['.$args['name'].']'; ?>" id="<?php echo $this->option_name . '_' . $args['name']; ?>"<?php echo $class; ?> type="number"<?php echo $size; ?><?php echo $min; ?><?php echo $max; ?><?php echo $step; ?> value="<?php echo esc_attr( $value ); ?>" />
|
||||
<?php elseif ( isset( $args['color'] ) ) : ?>
|
||||
<input name="<?php echo $this->option_name.'['.$args['name'].']'; ?>" id="<?php echo $this->option_name . '_' . $args['name']; ?>" class="sbspf_colorpicker" type="text" value="#<?php echo esc_attr( str_replace('#', '', $value ) ); ?>" />
|
||||
<?php else: ?>
|
||||
<input name="<?php echo $this->option_name.'['.$args['name'].']'; ?>" id="<?php echo $this->option_name . '_' . $args['name']; ?>"<?php echo $class; ?> type="text" value="<?php echo esc_attr( stripslashes( $value ) ); ?>" />
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( isset( $args['select_options'] ) ) :
|
||||
$value = isset( $this->settings[ $args['select_name'] ] ) ? $this->settings[ $args['select_name'] ] : $args['select_options'][0]['value'];
|
||||
?>
|
||||
<select name="<?php echo $this->option_name.'['.$args['select_name'].']'; ?>" id="<?php echo $this->option_name . '_' . $args['select_name']; ?>">
|
||||
<?php foreach ( $args['select_options'] as $select_option ) : ?>
|
||||
<option value="<?php echo esc_attr( $select_option['value'] ); ?>"<?php if ( (string)$select_option['value'] === (string)$value ) echo ' selected'; ?>><?php echo esc_html( $select_option['label'] ); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( isset( $args['hidden'] ) ) : ?>
|
||||
|
||||
<?php
|
||||
if ( is_callable( array( $this, $args['hidden']['callback'] ) ) ){
|
||||
echo $args['hidden']['before'];
|
||||
call_user_func_array(
|
||||
array( $this, $args['hidden']['callback'] ),
|
||||
array( $args['hidden'] )
|
||||
);
|
||||
echo $args['hidden']['after'];
|
||||
}
|
||||
?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( isset( $args['additional'] ) ) : ?>
|
||||
<?php echo $args['additional']; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( isset( $args['tooltip_info'] ) ) : ?>
|
||||
<a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php echo $tooltip_text; ?></a>
|
||||
<p class="sbspf_tooltip sbspf_more_info"><?php echo $args['tooltip_info']; ?></p>
|
||||
<?php
|
||||
endif;
|
||||
}
|
||||
|
||||
public function select( $args ) {
|
||||
$default = isset( $args['default'] ) ? $args['default'] : $args['options'][0]['value'];
|
||||
$value = isset( $this->settings[ $args['name'] ] ) ? $this->settings[ $args['name'] ] : $default;
|
||||
|
||||
if ( isset( $args['min'] ) && isset( $args['max'] ) && ((int)$args['min'] < (int)$args['max']) && empty( $args['options'] ) ) {
|
||||
$args['options'] = array();
|
||||
$i = (int)$args['min'];
|
||||
|
||||
while ( $i <= (int)$args['max'] ) {
|
||||
$args['options'][] = array(
|
||||
'label' => $i,
|
||||
'value' => $i
|
||||
);
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
$tooltip_text = isset( $args['tooltip_text'] ) ? $args['label'] : $this->default_tooltip_text();
|
||||
?>
|
||||
<select name="<?php echo $this->option_name.'['.$args['name'].']'; ?>" id="<?php echo $this->option_name . '_' . $args['name']; ?>">
|
||||
<?php foreach ( $args['options'] as $select_option ) : ?>
|
||||
<option value="<?php echo esc_attr( $select_option['value'] ); ?>"<?php if ( (string)$select_option['value'] === (string)$value ) echo ' selected'; ?>><?php echo esc_html( $select_option['label'] ); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
|
||||
<?php if ( isset( $args['additional'] ) ) : ?>
|
||||
<?php echo $args['additional']; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( isset( $args['tooltip_info'] ) ) : ?>
|
||||
<a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php echo $tooltip_text; ?></a>
|
||||
<p class="sbspf_tooltip sbspf_more_info"><?php echo $args['tooltip_info']; ?></p>
|
||||
<?php endif;
|
||||
}
|
||||
|
||||
public function textarea( $args ) {
|
||||
$default = isset( $args['default'] ) ? $args['default'] : '';
|
||||
$value = isset( $this->settings[ $args['name'] ] ) ? stripslashes( $this->settings[ $args['name'] ] ) : $default;
|
||||
|
||||
if ( isset( $args['tooltip_info'] ) ) : ?>
|
||||
<span><?php echo $args['tooltip_info']; ?></span><br>
|
||||
<?php endif; ?>
|
||||
|
||||
<textarea name="<?php echo $this->option_name.'['.$args['name'].']'; ?>" id="<?php echo $this->option_name . '_' . $args['name']; ?>"rows="7"><?php echo $value; ?></textarea>
|
||||
|
||||
<?php if ( isset( $args['note'] ) ) : ?>
|
||||
<br><span class="sbspf_note"><?php echo $args['note']; ?></span>
|
||||
<?php endif;
|
||||
}
|
||||
|
||||
public function color( $args ) {
|
||||
$args['color'] = true;
|
||||
$this->text( $args );
|
||||
}
|
||||
|
||||
public function types( $args ) {
|
||||
$type_selected = isset( $this->settings[ $args['name'] ] ) ? $this->settings[ $args['name'] ] : $args['types'][0]['slug'];
|
||||
|
||||
foreach ( $args['types'] as $type ) :
|
||||
$input_type = isset( $type['input_type'] ) ? $type['input_type'] : 'connected_account';
|
||||
$selected = ! empty( $this->settings[ $type['slug'] ] ) ? $this->settings[ $type['slug'] ] : $type['default'];
|
||||
if ( $input_type === 'connected_account' ) {
|
||||
$selected = isset( $this->settings[ $type['slug'] . '_ids' ] ) ? $this->settings[ $type['slug'] . '_ids' ] : array();
|
||||
}
|
||||
$on_select = isset( $type['onselect'] ) ? $type['onselect'] : false;
|
||||
?>
|
||||
<div class="sbspf_row sbspf_type_row" style="min-height: 29px;">
|
||||
<div class="sbspf_col sbspf_one">
|
||||
<input type="radio" name="<?php echo $this->option_name.'['.esc_attr( $args['name'] ).']'; ?>" class="sbspf_type_input" id="sbspf_type_<?php echo esc_attr( $type['slug'] ); ?>" value="<?php echo esc_attr( $type['slug'] ); ?>"<?php if ( $type_selected === $type['slug'] ) echo 'checked'; ?>>
|
||||
<label class="sbspf_radio_label" for="sbspf_type_<?php echo esc_attr( $type['slug'] ); ?>"><?php echo esc_html( $type['label'] ); ?>: <a class="sbspf_type_tooltip_link" href="JavaScript:void(0);"><i class="fa fa-question-circle" aria-hidden="true" style="margin-left: 2px;"></i></a></label>
|
||||
</div>
|
||||
<div class="sbspf_col sbspf_two">
|
||||
<?php if ( $input_type === 'text' ) :
|
||||
$placeholder = isset( $type['note'] ) ? ' placeholder="' . esc_attr( $type['note'] ). '"' : '';
|
||||
?>
|
||||
<input name="<?php echo $this->option_name.'['.esc_attr( $type['slug'] ).']'; ?>" id="sbspf_<?php echo esc_attr( $type['slug'] ); ?>" type="text" value="<?php echo esc_attr( $selected ); ?>" size="45"<?php echo $placeholder; ?>>
|
||||
<?php else :
|
||||
$connected_accounts = $this->get_connected_accounts(); ?>
|
||||
<div class="sbspf_<?php echo esc_attr( $type['slug'] ); ?>_feed_ids_wrap">
|
||||
<?php foreach ( $connected_accounts as $connected_account ) : if ( in_array( $connected_account['channel_id'], $selected, true ) ) : ?>
|
||||
<div id="sbspf_<?php echo esc_attr( $type['slug'] ); ?>_feed_id_<?php echo esc_attr( $connected_account['channel_id'] ); ?>" class="sbspf_<?php echo esc_attr( $type['slug'] ); ?>_feed_account_wrap">
|
||||
<strong><?php echo esc_html( $connected_account['username'] ); ?></strong> <span>(<?php echo esc_attr( $connected_account['channel_id'] ); ?>)</span><input type="hidden" name="<?php echo $this->option_name.'['.esc_attr( $type['slug'] ).'_feed_ids][]'; ?>" value="<?php echo esc_attr( $connected_account['channel_id'] ); ?>">
|
||||
</div>
|
||||
<?php endif; endforeach; ?>
|
||||
</div>
|
||||
<?php if ( empty( $selected ) ) : ?>
|
||||
<p class="sbspf_no_accounts" style="margin-top: -3px; margin-right: 10px;"><?php _e( 'Connect an account above', 'feeds-for-youtube' ); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php endif; ?>
|
||||
<?php if ( $input_type !== 'text' && isset( $type['note'] ) ) : ?>
|
||||
<br><span class="sbspf_note"><?php echo $type['note']; ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ( $on_select ) : ?>
|
||||
<div class="sbspf_onselect">
|
||||
<?php call_user_func_array( array( $this, $on_select ), array( $type ) ); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="sbspf_tooltip sbspf_type_tooltip sbspf_more_info">
|
||||
<?php if ( ! empty( $type['tooltip'] ) ) : ?>
|
||||
<?php echo $type['tooltip']; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<?php endforeach;
|
||||
}
|
||||
|
||||
public function sub_option( $args ) {
|
||||
$value = isset( $this->settings[ $args['name'] ] ) ? $this->settings[ $args['name'] ] : 'related';
|
||||
|
||||
$cta_options = $args['sub_options'];
|
||||
?>
|
||||
<?php if ( ! empty( $args['before'] ) ) {
|
||||
echo $args['before'];
|
||||
}?>
|
||||
|
||||
<div class="sbspf_sub_options">
|
||||
<?php foreach ( $cta_options as $sub_option ) : ?>
|
||||
<div class="sbspf_sub_option_cell">
|
||||
<input class="sbspf_sub_option_type" id="sbspf_sub_option_type_<?php echo esc_attr( $sub_option['slug'] ); ?>" name="<?php echo $this->option_name.'['.$args['name'].']'; ?>" type="radio" value="<?php echo esc_attr( $sub_option['slug'] ); ?>"<?php if ( $sub_option['slug'] === $value ) echo ' checked'?>><label for="sbspf_sub_option_type_<?php echo esc_attr( $sub_option['slug'] ); ?>"><span class="sbspf_label"><?php echo $sub_option['label']; ?></span></label>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<div class="sbspf_box_setting">
|
||||
<?php if ( isset( $cta_options ) ) : foreach ( $cta_options as $sub_option ) : ?>
|
||||
<div class="sbspf_sub_option_settings sbspf_sub_option_type_<?php echo esc_attr( $sub_option['slug'] ); ?>">
|
||||
|
||||
<div class="sbspf_sub_option_setting">
|
||||
<?php echo sby_admin_icon( 'info-circle', 'sbspf_small_svg' ); ?> <span class="sbspf_note" style="margin-left: 0;"><?php echo $sub_option['note']; ?></span>
|
||||
</div>
|
||||
<?php if ( ! empty( $sub_option['options'] ) ) : ?>
|
||||
<?php foreach ( $sub_option['options'] as $option ) :
|
||||
$option['name'] = $sub_option['slug'].$option['name'];
|
||||
?>
|
||||
<div class="sbspf_sub_option_setting">
|
||||
<?php if ( $option['callback'] !== 'checkbox' ) :
|
||||
if ( isset( $option['shortcode'] ) ) : ?>
|
||||
<label title="<?php echo __( 'Click for shortcode option', 'feeds-for-youtube' ); ?>"><?php echo $option['label']; ?></label><code class="sbspf_shortcode"> <?php echo $option['name'] . "\n"; ?>
|
||||
Eg: <?php echo $option['name']; ?>=<?php echo $option['shortcode']['example']; ?></code><br>
|
||||
<?php else: ?>
|
||||
<label><?php echo $option['label']; ?></label><br>
|
||||
<?php endif; ?>
|
||||
<?php else:
|
||||
$option['shortcode_example'] = $option['shortcode']['example'];
|
||||
$option['has_shortcode'] = true;
|
||||
endif; ?>
|
||||
<?php call_user_func_array( array( $this, $option['callback'] ), array( $option ) ); ?>
|
||||
|
||||
</div>
|
||||
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
|
||||
<?php endforeach; endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function cache( $args ) {
|
||||
$social_network = $this->vars->social_network();
|
||||
$type_selected = isset( $this->settings['caching_type'] ) ? $this->settings['caching_type'] : 'page';
|
||||
$caching_time = isset( $this->settings['caching_time'] ) ? $this->settings['caching_time'] : 1;
|
||||
$cache_time_unit_selected = isset( $this->settings['cache_time_unit'] ) ? $this->settings['cache_time_unit'] : 'hours';
|
||||
$cache_cron_interval_selected = isset( $this->settings['cache_cron_interval'] ) ? $this->settings['cache_cron_interval'] : '';
|
||||
$cache_cron_time = isset( $this->settings['cache_cron_time'] ) ? $this->settings['cache_cron_time'] : '';
|
||||
$cache_cron_am_pm = isset( $this->settings['cache_cron_am_pm'] ) ? $this->settings['cache_cron_am_pm'] : '';
|
||||
|
||||
?>
|
||||
<div class="sbspf_cache_settings_wrap">
|
||||
<div class="sbspf_row">
|
||||
<input type="radio" name="<?php echo $this->option_name.'[caching_type]'; ?>" class="sbspf_caching_type_input" id="sbspf_caching_type_page" value="page"<?php if ( $type_selected === 'page' ) echo ' checked'?>>
|
||||
<label class="sbspf_radio_label" for="sbspf_caching_type_page"><?php _e ( 'When the page loads', 'feeds-for-youtube' ); ?></label>
|
||||
<a class="sbspf_tooltip_link" href="JavaScript:void(0);" style="position: relative; top: 2px;"><?php echo $this->default_tooltip_text() ?></a>
|
||||
<p class="sbspf_tooltip sbspf_more_info"><?php echo sprintf( __( "Your %s data is temporarily cached by the plugin in your WordPress database. There are two ways that you can set the plugin to check for new data:<br><br>
|
||||
<b>1. When the page loads</b><br>Selecting this option means that when the cache expires then the plugin will check %s for new posts the next time that the feed is loaded. You can choose how long this data should be cached for with a minimum time of 15 minutes. If you set the time to 60 minutes then the plugin will clear the cached data after that length of time, and the next time the page is viewed it will check for new data. <b>Tip:</b> If you're experiencing an issue with the plugin not updating automatically then try enabling the setting labeled <b>'Cron Clear Cache'</b> which is located on the 'Customize' tab.<br><br>
|
||||
<b>2. In the background</b><br>Selecting this option means that the plugin will check for new data in the background so that the feed is updated behind the scenes. You can select at what time and how often the plugin should check for new data using the settings below. <b>Please note</b> that the plugin will initially check for data from YouTube when the page first loads, but then after that will check in the background on the schedule selected - unless the cache is cleared.", 'feeds-for-youtube' ), $social_network, $social_network ); ?>
|
||||
</p>
|
||||
</div>
|
||||
<div class="sbspf_row sbspf-caching-page-options" style="display: none;">
|
||||
<?php _e ( 'Every', 'feeds-for-youtube' ); ?>:
|
||||
<input name="<?php echo $this->option_name.'[caching_time]'; ?>" type="text" value="<?php echo esc_attr( $caching_time ); ?>" size="4">
|
||||
<select name="<?php echo $this->option_name.'[caching_time_unit]'; ?>">
|
||||
<option value="minutes"<?php if ( $cache_time_unit_selected === 'minutes' ) echo ' selected'?>><?php _e ( 'Minutes', 'feeds-for-youtube' ); ?></option>
|
||||
<option value="hours"<?php if ( $cache_time_unit_selected === 'hours' ) echo ' selected'?>><?php _e ( 'Hours', 'feeds-for-youtube' ); ?></option>
|
||||
<option value="days"<?php if ( $cache_time_unit_selected === 'days' ) echo ' selected'?>><?php _e ( 'Days', 'feeds-for-youtube' ); ?></option>
|
||||
</select>
|
||||
<a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php _e ( 'What does this mean?', 'feeds-for-youtube' ); ?></a>
|
||||
<p class="sbspf_tooltip sbspf_more_info"><?php echo sprintf( __("Your %s posts are temporarily cached by the plugin in your WordPress database. You can choose how long the posts should be cached for. If you set the time to 1 hour then the plugin will clear the cache after that length of time and check %s for posts again.", 'feeds-for-youtube' ), $social_network, $social_network ); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="sbspf_row">
|
||||
<input type="radio" name="<?php echo $this->option_name.'[caching_type]'; ?>" id="sbspf_caching_type_cron" class="sbspf_caching_type_input" value="background" <?php if ( $type_selected === 'background' ) echo ' checked'?>>
|
||||
<label class="sbspf_radio_label" for="sbspf_caching_type_cron"><?php _e ( 'In the background', 'feeds-for-youtube' ); ?></label>
|
||||
</div>
|
||||
<div class="sbspf_row sbspf-caching-cron-options" style="display: block;">
|
||||
|
||||
<select name="<?php echo $this->option_name.'[cache_cron_interval]'; ?>" id="sbspf_cache_cron_interval">
|
||||
<option value="30mins"<?php if ( $cache_cron_interval_selected === '30mins' ) echo ' selected'?>><?php _e ( 'Every 30 minutes', 'feeds-for-youtube' ); ?></option>
|
||||
<option value="1hour"<?php if ( $cache_cron_interval_selected === '1hour' ) echo ' selected'?>><?php _e ( 'Every hour', 'feeds-for-youtube' ); ?></option>
|
||||
<option value="12hours"<?php if ( $cache_cron_interval_selected === '12hours' ) echo ' selected'?>><?php _e ( 'Every 12 hours', 'feeds-for-youtube' ); ?></option>
|
||||
<option value="24hours"<?php if ( $cache_cron_interval_selected === '24hours' ) echo ' selected'?>><?php _e ( 'Every 24 hours', 'feeds-for-youtube' ); ?></option>
|
||||
</select>
|
||||
|
||||
<div id="sbspf-caching-time-settings" style="">
|
||||
<?php _e ( 'at', 'feeds-for-youtube' ); ?>
|
||||
<select name="<?php echo $this->option_name.'[cache_cron_time]'; ?>" style="width: 80px">
|
||||
<option value="1"<?php if ( (int)$cache_cron_time === 1 ) echo ' selected'?>>1:00</option>
|
||||
<option value="2"<?php if ( (int)$cache_cron_time === 2 ) echo ' selected'?>>2:00</option>
|
||||
<option value="3"<?php if ( (int)$cache_cron_time === 3 ) echo ' selected'?>>3:00</option>
|
||||
<option value="4"<?php if ( (int)$cache_cron_time === 4 ) echo ' selected'?>>4:00</option>
|
||||
<option value="5"<?php if ( (int)$cache_cron_time === 5 ) echo ' selected'?>>5:00</option>
|
||||
<option value="6"<?php if ( (int)$cache_cron_time === 6 ) echo ' selected'?>>6:00</option>
|
||||
<option value="7"<?php if ( (int)$cache_cron_time === 7 ) echo ' selected'?>>7:00</option>
|
||||
<option value="8"<?php if ( (int)$cache_cron_time === 8 ) echo ' selected'?>>8:00</option>
|
||||
<option value="9"<?php if ( (int)$cache_cron_time === 9 ) echo ' selected'?>>9:00</option>
|
||||
<option value="10"<?php if ( (int)$cache_cron_time === 10 ) echo ' selected'?>>10:00</option>
|
||||
<option value="11"<?php if ( (int)$cache_cron_time === 11 ) echo ' selected'?>>11:00</option>
|
||||
<option value="0"<?php if ( (int)$cache_cron_time === 0 ) echo ' selected'?>>12:00</option>
|
||||
</select>
|
||||
|
||||
<select name="<?php echo $this->option_name.'[cache_cron_am_pm]'; ?>" style="width: 50px">
|
||||
<option value="am"<?php if ( $cache_cron_am_pm === 'am' ) echo ' selected'?>><?php _e ( 'AM', 'feeds-for-youtube' ); ?></option>
|
||||
<option value="pm"<?php if ( $cache_cron_am_pm === 'pm' ) echo ' selected'?>><?php _e ( 'PM', 'feeds-for-youtube' ); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if ( wp_next_scheduled( 'sbspf_feed_update' ) ) {
|
||||
$time_format = get_option( 'time_format' );
|
||||
if ( ! $time_format ) {
|
||||
$time_format = 'g:i a';
|
||||
}
|
||||
//
|
||||
$schedule = wp_get_schedule( 'sbspf_feed_update' );
|
||||
if ( $schedule == '30mins' ) $schedule = __( 'every 30 minutes', 'feeds-for-youtube' );
|
||||
if ( $schedule == 'twicedaily' ) $schedule = __( 'every 12 hours', 'feeds-for-youtube' );
|
||||
$sbspf_next_cron_event = wp_next_scheduled( 'sbspf_feed_update' );
|
||||
echo '<p class="sbspf-caching-sched-notice"><span><b>' . __( 'Next check', 'feeds-for-youtube' ) . ': ' . date( $time_format, $sbspf_next_cron_event + sbspf_get_utc_offset() ) . ' (' . $schedule . ')</b> - ' . __( 'Note: Saving the settings on this page will clear the cache and reset this schedule', 'feeds-for-youtube' ) . '</span></p>';
|
||||
} else {
|
||||
echo '<p style="font-size: 11px; color: #666;">' . __( 'Nothing currently scheduled', 'feeds-for-youtube' ) . '</p>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function layout( $args ) {
|
||||
$default = isset( $args['default'] ) ? $args['default'] : $args['layouts'][0]['slug'];
|
||||
$value = isset( $this->settings[ $args['name'] ] ) ? $this->settings[ $args['name'] ] : $default;
|
||||
?>
|
||||
<div class="sbspf_layouts">
|
||||
<?php foreach ( $args['layouts'] as $layout ) : ?>
|
||||
<div class="sbspf_layout_cell">
|
||||
<input class="sbspf_layout_type" id="sbspf_layout_type_<?php echo esc_attr( $layout['slug'] ); ?>" name="<?php echo $this->option_name.'['.$args['name'].']'; ?>" type="radio" value="<?php echo esc_attr( $layout['slug'] ); ?>"<?php if ( $layout['slug'] === $value ) echo ' checked'?>><label for="sbspf_layout_type_<?php echo esc_attr( $layout['slug'] ); ?>"><span class="sbspf_label"><?php echo $layout['label']; ?></span><img src="<?php echo esc_url( $this->vars->plugin_url() . $layout['image'] ); ?>" alt=""></label>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<div class="sbspf_layout_options_wrap">
|
||||
<?php foreach ( $args['layouts'] as $layout ) : ?>
|
||||
<div class="sbspf_layout_settings sbspf_layout_type_<?php echo esc_attr( $layout['slug'] ); ?>">
|
||||
|
||||
<div class="sbspf_layout_setting">
|
||||
<?php echo sby_admin_icon( 'info-circle' ); ?> <span class="sbspf_note" style="margin-left: 0;"><?php echo $layout['note']; ?></span>
|
||||
</div>
|
||||
<?php if ( ! empty( $layout['options'] ) ) : ?>
|
||||
<?php foreach ( $layout['options'] as $option ) :
|
||||
$option['name'] = $layout['slug'].$option['name'];
|
||||
?>
|
||||
<div class="sbspf_layout_setting">
|
||||
<?php if ( $option['callback'] !== 'checkbox' ) : ?>
|
||||
<label title="<?php echo __( 'Click for shortcode option', 'feeds-for-youtube' ); ?>"><?php echo $option['label']; ?></label><code class="sbspf_shortcode"> <?php echo $option['name'] . "\n"; ?>
|
||||
Eg: <?php echo $option['name']; ?>=<?php echo $option['shortcode']['example']; ?></code><br>
|
||||
<?php else:
|
||||
$option['shortcode_example'] = $option['shortcode']['example'];
|
||||
$option['has_shortcode'] = true;
|
||||
endif; ?>
|
||||
<?php call_user_func_array( array( $this, $option['callback'] ), array( $option ) ); ?>
|
||||
|
||||
</div>
|
||||
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function instructions( $args ) {
|
||||
?>
|
||||
<div class="sbspf_instructions_wrap">
|
||||
<?php echo $args['instructions']?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function format_title( $label, $name, $shortcode_args = false, $after = '' ) {
|
||||
$formatted_label = '<label for="' . $this->option_name . '_' . $name . '">' . $label .'</label>';
|
||||
if ( $shortcode_args ) {
|
||||
$formatted_label .= '<code class="sbspf_shortcode"> ' . $shortcode_args['key'] . "\n";
|
||||
$formatted_label .= 'Eg: ' . $shortcode_args['key'] . '=' . $shortcode_args['example'] . '</code><br>';
|
||||
}
|
||||
$formatted_label .= $after;
|
||||
|
||||
return $formatted_label;
|
||||
}
|
||||
|
||||
public function validate_options( $input, $tab ) {
|
||||
$updated_options = get_option( $this->option_name, array() );
|
||||
$false_if_empty_keys = $this->get_false_fields( $tab );
|
||||
$textarea_keys = $this->get_textarea_fields( $tab );
|
||||
|
||||
foreach ( $false_if_empty_keys as $false_key ) {
|
||||
$updated_options[ $false_key ] = false;
|
||||
}
|
||||
|
||||
foreach ( $input as $key => $val ) {
|
||||
if ( 'custom_js' === $key ) {
|
||||
$updated_options[ $key ] = $val;
|
||||
} else if ( in_array( $key, $false_if_empty_keys ) ) {
|
||||
$updated_options[ $key ] = ($val === 'on');
|
||||
} elseif ( in_array( $key, $textarea_keys ) ) {
|
||||
$updated_options[ $key ] = sanitize_textarea_field( $val );
|
||||
} elseif ( is_array( $val ) ) {
|
||||
$updated_options[ $key ] = array();
|
||||
foreach ( $val as $key2 => $val2 ) {
|
||||
$updated_options[ $key ][ $key2 ] = sanitize_text_field( $val2 );
|
||||
}
|
||||
} else {
|
||||
$updated_options[ $key ] = sanitize_text_field( $val );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $tab === 'configure' ) {
|
||||
do_action( $this->option_name . '_after_configure_save', $updated_options );
|
||||
}
|
||||
|
||||
return $updated_options;
|
||||
}
|
||||
|
||||
|
||||
public function update_options( $new_settings ) {
|
||||
update_option( $this->get_option_name(), $new_settings );
|
||||
$this->settings = $new_settings;
|
||||
}
|
||||
|
||||
public function get_sections( $tab ) {
|
||||
if ( isset( $this->settings_sections[ $tab ] ) ) {
|
||||
return $this->settings_sections[ $tab ];
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
public function set_active_tab( $active_tab ) {
|
||||
foreach ( $this->tabs as $tab ) {
|
||||
if ( $tab['slug'] === $active_tab ) {
|
||||
$this->active_tab = $tab['slug'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get_tabs() {
|
||||
return $this->tabs;
|
||||
}
|
||||
|
||||
public function get_active_tab() {
|
||||
return $this->active_tab;
|
||||
}
|
||||
|
||||
public function get_slug() {
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function get_plugin_name() {
|
||||
return $this->plugin_name;
|
||||
}
|
||||
|
||||
public function get_path( $view ) {
|
||||
return trailingslashit( $this->base_path ) . $view . '.php';
|
||||
}
|
||||
|
||||
public function create_options_page() {
|
||||
require_once trailingslashit( $this->base_path ) . 'main.php';
|
||||
}
|
||||
|
||||
public function next_step() {
|
||||
$return = array();
|
||||
$i = 0;
|
||||
foreach ( $this->tabs as $tab ) {
|
||||
if ( $this->active_tab === $tab['slug'] && isset( $tab['next_step_instructions'] ) ) {
|
||||
$next_tab_slug = isset( $this->tabs[ $i + 1 ]['slug'] ) ? $this->tabs[ $i + 1 ]['slug'] : $tab['slug'];
|
||||
$return = array(
|
||||
'instructions' => $tab['next_step_instructions'],
|
||||
'next_tab' => $next_tab_slug
|
||||
);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function get_connected_accounts() {
|
||||
global $sbspf_settings;
|
||||
|
||||
if ( isset( $sbspf_settings['connected_accounts'] ) ) {
|
||||
return $sbspf_settings['connected_accounts'];
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
public static function connect_account( $args ) {
|
||||
global $sbspf_settings;
|
||||
|
||||
// do connection
|
||||
|
||||
// random fake data
|
||||
$account_id = time();
|
||||
|
||||
$sbspf_settings['connected_accounts'][ $account_id ] = array(
|
||||
'access_token' => 'at_' . str_shuffle( $account_id ),
|
||||
'channel_id' => $account_id,
|
||||
'username' => 'test' . $account_id,
|
||||
'is_valid' => true,
|
||||
'last_checked' => time(),
|
||||
'profile_picture' => $args['profile_picture']
|
||||
);
|
||||
|
||||
update_option( 'sbspf_settings', $sbspf_settings );
|
||||
|
||||
return $sbspf_settings['connected_accounts'][ $account_id ];
|
||||
}
|
||||
|
||||
public function default_tooltip_text() {
|
||||
return '<span class="screen-reader-text">' . __( 'What does this mean?', 'feeds-for-youtube' ) . '</span>' . sby_admin_icon( 'question-circle' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* SBY Admin Notice.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Admin;
|
||||
|
||||
// Exit if accessed directly
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SBY_Admin_Notice {
|
||||
|
||||
public function register() {
|
||||
add_action( 'sby_admin_header_notices', array( $this, 'header_notices' ) );
|
||||
add_action( 'wp_ajax_sby_dismiss_upgrade_notice', array( $this, 'dismiss_upgrade_notice' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Header Notices
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function header_notices() {
|
||||
if ( sby_is_pro() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$lite_notice_dismissed = get_transient( 'youtube_feed_dismiss_lite' );
|
||||
if ( $lite_notice_dismissed ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$output = '';
|
||||
|
||||
$upgrade_url = 'https://smashballoon.com/youtube-feed/demo/?utm_campaign='. sby_utm_campaign() .'&utm_source=lite-upgrade-bar';
|
||||
$output .= '<div id="sbc-notice-bar" class="sbc-header-notice">';
|
||||
$output .= sprintf(
|
||||
'<span class="sbc-notice-bar-message">%s <a href="%s" target="_blank" rel="noopener noreferrer">%s</a></span>',
|
||||
__('You\'re using YouTube Feeds Lite. To unlock more features consider', 'feeds-for-youtube'),
|
||||
$upgrade_url,
|
||||
__('upgrading to Pro', 'feeds-for-youtube')
|
||||
);
|
||||
|
||||
$output .= sprintf(
|
||||
'<button type="button" class="sbc-dismiss" id="sbc-dismiss-header-notice" title="%s" data-page="overview">%s</button>',
|
||||
__('Dismiss this message', 'feeds-for-youtube'),
|
||||
'<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15.8327 5.34175L14.6577 4.16675L9.99935 8.82508L5.34102 4.16675L4.16602 5.34175L8.82435 10.0001L4.16602 14.6584L5.34102 15.8334L9.99935 11.1751L14.6577 15.8334L15.8327 14.6584L11.1744 10.0001L15.8327 5.34175Z" fill="white"/></svg>'
|
||||
);
|
||||
|
||||
$output .= '</div>';
|
||||
|
||||
echo $output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dismiss Upgrade Notice
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function dismiss_upgrade_notice() {
|
||||
// Run a security check.
|
||||
check_ajax_referer( 'sby-admin' , 'nonce');
|
||||
|
||||
if ( ! sby_current_user_can( 'manage_youtube_feed_options' ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
// set the transient so it will hide for next 7 days
|
||||
set_transient( 'youtube_feed_dismiss_lite', 'dismiss', 2 * WEEK_IN_SECONDS );
|
||||
|
||||
wp_send_json_success();
|
||||
wp_die();
|
||||
}
|
||||
|
||||
}
|
||||
532
wp-content/plugins/youtube-feed-pro/inc/Admin/SBY_New_User.php
Normal file
532
wp-content/plugins/youtube-feed-pro/inc/Admin/SBY_New_User.php
Normal file
@@ -0,0 +1,532 @@
|
||||
<?php
|
||||
/**
|
||||
* SBY_New_User.
|
||||
*
|
||||
* @since 2.18
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Admin;
|
||||
|
||||
class SBY_New_User extends SBY_Notifications {
|
||||
/**
|
||||
* Source of notifications content.
|
||||
*
|
||||
* @since 2.18
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SOURCE_URL = 'https://plugin.smashballoon.com/newuser.json';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const OPTION_NAME = 'sby_newuser_notifications';
|
||||
|
||||
/**
|
||||
* Register hooks.
|
||||
*
|
||||
* @since 2.18
|
||||
*/
|
||||
public function hooks() {
|
||||
add_action( 'admin_notices', array( $this, 'output' ), 8 );
|
||||
|
||||
add_action( 'admin_init', array( $this, 'dismiss' ) );
|
||||
add_action( 'wp_ajax_sby_review_notice_consent_update', array( $this, 'review_notice_consent' ) );
|
||||
}
|
||||
|
||||
public function option_name() {
|
||||
return self::OPTION_NAME;
|
||||
}
|
||||
|
||||
public function source_url() {
|
||||
return self::SOURCE_URL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify notification data before it is saved.
|
||||
*
|
||||
* @param array $notifications Array of notifications items to verify.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 2.18
|
||||
*/
|
||||
public function verify( $notifications ) {
|
||||
$data = array();
|
||||
|
||||
if ( ! is_array( $notifications ) || empty( $notifications ) ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$option = $this->get_option();
|
||||
|
||||
foreach ( $notifications as $key => $notification ) {
|
||||
|
||||
// The message should never be empty, if they are, ignore.
|
||||
if ( empty( $notification['content'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore if notification has already been dismissed.
|
||||
if ( ! empty( $option['dismissed'] ) && in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
|
||||
continue;
|
||||
}
|
||||
|
||||
$data[ $key ] = $notification;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify saved notification data for active notifications.
|
||||
*
|
||||
* @since 2.18
|
||||
*
|
||||
* @param array $notifications Array of notifications items to verify.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function verify_active( $notifications ) {
|
||||
if ( ! is_array( $notifications ) || empty( $notifications ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$sby_statuses_option = get_option( 'sby_statuses', array() );
|
||||
$current_time = sby_get_current_time();
|
||||
|
||||
// rating notice logic
|
||||
$sby_rating_notice_option = get_option( 'sby_rating_notice', false );
|
||||
$sby_rating_notice_waiting = get_transient( 'feeds_for_youtube_rating_notice_waiting' );
|
||||
$should_show_rating_notice = ($sby_rating_notice_waiting !== 'waiting' && $sby_rating_notice_option !== 'dismissed');
|
||||
|
||||
// new user discount logic
|
||||
$in_new_user_month_range = true;
|
||||
$should_show_new_user_discount = false;
|
||||
$has_been_one_month_since_rating_dismissal = isset( $sby_statuses_option['rating_notice_dismissed'] ) ? ((int)$sby_statuses_option['rating_notice_dismissed'] + ((int)$notifications['review']['wait'] * DAY_IN_SECONDS)) < $current_time + 1: true;
|
||||
|
||||
if ( isset( $sby_statuses_option['first_install'] ) && $sby_statuses_option['first_install'] === 'from_update' ) {
|
||||
global $current_user;
|
||||
$user_id = $current_user->ID;
|
||||
$ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'sby_ignore_new_user_sale_notice' );
|
||||
$ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
|
||||
if ( $ignore_new_user_sale_notice_meta !== 'always' ) {
|
||||
$should_show_new_user_discount = true;
|
||||
}
|
||||
} elseif ( $in_new_user_month_range && $has_been_one_month_since_rating_dismissal && $sby_rating_notice_waiting !== 'waiting' ) {
|
||||
global $current_user;
|
||||
$user_id = $current_user->ID;
|
||||
$ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'sby_ignore_new_user_sale_notice' );
|
||||
$ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
|
||||
|
||||
if ( $ignore_new_user_sale_notice_meta !== 'always'
|
||||
&& isset( $sby_statuses_option['first_install'] )
|
||||
&& $current_time > (int)$sby_statuses_option['first_install'] + ((int)$notifications['discount']['wait'] * DAY_IN_SECONDS) ) {
|
||||
$should_show_new_user_discount = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( sby_is_pro_version() ) {
|
||||
$should_show_new_user_discount = false;
|
||||
}
|
||||
|
||||
if ( isset( $notifications['review'] ) && $should_show_rating_notice ) {
|
||||
return array( $notifications['review'] );
|
||||
} elseif ( isset( $notifications['discount'] ) && $should_show_new_user_discount ) {
|
||||
return array( $notifications['discount'] );
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get notification data.
|
||||
*
|
||||
* @since 2.18
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get() {
|
||||
if ( ! $this->has_access() ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$option = $this->get_option();
|
||||
|
||||
// Only update if does not exist.
|
||||
if ( empty( $option['update'] ) ) {
|
||||
$this->update();
|
||||
}
|
||||
|
||||
$events = ! empty( $option['events'] ) ? $this->verify_active( $option['events'] ) : array();
|
||||
$feed = ! empty( $option['feed'] ) ? $this->verify_active( $option['feed'] ) : array();
|
||||
|
||||
return array_merge( $events, $feed );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a manual notification event.
|
||||
*
|
||||
* @since 2.18
|
||||
*
|
||||
* @param array $notification Notification data.
|
||||
*/
|
||||
public function add( $notification ) {
|
||||
if ( empty( $notification['id'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$option = $this->get_option();
|
||||
|
||||
if ( in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $option['events'] as $item ) {
|
||||
if ( $item['id'] === $notification['id'] ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$notification = $this->verify( array( $notification ) );
|
||||
|
||||
update_option(
|
||||
$this->option_name(),
|
||||
array(
|
||||
'update' => $option['update'],
|
||||
'feed' => $option['feed'],
|
||||
'events' => array_merge( $notification, $option['events'] ),
|
||||
'dismissed' => $option['dismissed'],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update notification data from feed.
|
||||
*
|
||||
* @since 2.18
|
||||
*/
|
||||
public function update() {
|
||||
$feed = $this->fetch_feed();
|
||||
$option = $this->get_option();
|
||||
|
||||
update_option(
|
||||
$this->option_name(),
|
||||
array(
|
||||
'update' => time(),
|
||||
'feed' => $feed,
|
||||
'events' => $option['events'],
|
||||
'dismissed' => $option['dismissed'],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not enqueue anything extra.
|
||||
*
|
||||
* @since 2.18
|
||||
*/
|
||||
public function enqueues() {
|
||||
|
||||
}
|
||||
|
||||
public function review_notice_consent() {
|
||||
//Security Checks
|
||||
check_ajax_referer( 'sby-admin', 'sby_nonce' );
|
||||
$cap = current_user_can( 'manage_youtube_feed_options' ) ? 'manage_youtube_feed_options' : 'manage_options';
|
||||
|
||||
$cap = apply_filters( 'sby_settings_pages_capability', $cap );
|
||||
if ( ! current_user_can( $cap ) ) {
|
||||
wp_send_json_error(); // This auto-dies.
|
||||
}
|
||||
|
||||
$consent = isset( $_POST[ 'consent' ] ) ? sanitize_text_field( $_POST[ 'consent' ] ) : '';
|
||||
|
||||
update_option( 'sby_review_consent', $consent );
|
||||
|
||||
if ( $consent == 'no' ) {
|
||||
$sby_statuses_option = get_option( 'sby_statuses', array() );
|
||||
update_option( 'sby_rating_notice', 'dismissed', false );
|
||||
$sby_statuses_option['rating_notice_dismissed'] = sby_get_current_time();
|
||||
update_option( 'sby_statuses', $sby_statuses_option, false );
|
||||
}
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Output notifications on Form Overview admin area.
|
||||
*
|
||||
* @since 2.18
|
||||
*/
|
||||
public function output() {
|
||||
// If the Instagram Feed plugin is active, notices only shown on SBY Settings pages
|
||||
if ( function_exists( 'sb_instagram_activate' )
|
||||
&& ! function_exists( 'sb_instagram_feed_pro_init' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( function_exists( 'cff_check_for_db_updates' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( function_exists( 'ctf_check_for_db_updates' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$notifications = $this->get();
|
||||
|
||||
if ( empty( $notifications ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// new user notices included in regular settings page notifications so this
|
||||
// checks to see if user is one of those pages
|
||||
if ( ! empty( $_GET['page'] )
|
||||
&& ( strpos( $_GET['page'], 'sby' ) !== false || strpos( $_GET['page'], 'youtube-feed' ) !== false ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$content_allowed_tags = array(
|
||||
'em' => array(),
|
||||
'strong' => array(),
|
||||
'span' => array(
|
||||
'style' => array(),
|
||||
),
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'target' => array(),
|
||||
'rel' => array(),
|
||||
),
|
||||
);
|
||||
$image_overlay = '';
|
||||
|
||||
foreach ( $notifications as $notification ) {
|
||||
$img_src = SBY_PLUGIN_URL . 'img/' . sanitize_text_field( $notification['image'] );
|
||||
$type = sanitize_text_field( $notification['id'] );
|
||||
// check if this is a review notice
|
||||
if( $type == 'review' ) {
|
||||
$review_consent = get_option( 'sby_review_consent' );
|
||||
$sby_open_feedback_url = 'https://smashballoon.com/feedback/?plugin=youtube-free';
|
||||
// step #1 for the review notice
|
||||
if ( ! $review_consent ) {
|
||||
?>
|
||||
<div class="sby_notice sby_review_notice_step_1">
|
||||
<div class="sby_thumb">
|
||||
<img src="<?php echo esc_url( str_replace( array( 'sbi', 'png' ), array( 'sby', 'svg' ), $img_src ) ); ?>" alt="notice">
|
||||
</div>
|
||||
<div class="sby-notice-text">
|
||||
<p class="sby-notice-text-p"><?php echo __( 'Are you enjoying the YouTube Feeds Plugin?', 'feeds-for-youtube' ); ?></p>
|
||||
</div>
|
||||
<div class="sby-notice-consent-btns">
|
||||
<?php
|
||||
printf(
|
||||
'<button class="sby-btn-link" id="sby_review_consent_yes">%s</button>',
|
||||
__( 'Yes', 'feeds-for-youtube' )
|
||||
);
|
||||
|
||||
printf(
|
||||
'<a href="%s" target="_blank" rel="nofollow noopener" class="sby-btn-link" id="sby_review_consent_no">%s</a>',
|
||||
$sby_open_feedback_url,
|
||||
__( 'No', 'feeds-for-youtube' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
$close_href = add_query_arg( array( 'sby_dismiss' => $type ) );
|
||||
|
||||
$title = $this->get_notice_title( $notification );
|
||||
$content = $this->get_notice_content( $notification, $content_allowed_tags );
|
||||
|
||||
$buttons = array();
|
||||
if ( ! empty( $notification['btns'] ) && is_array( $notification['btns'] ) ) {
|
||||
foreach ( $notification['btns'] as $btn_type => $btn ) {
|
||||
if ( ! is_array( $btn['url'] ) ) {
|
||||
$buttons[ $btn_type ]['url'] = $this->replace_merge_fields( $btn['url'], $notification );
|
||||
} elseif ( is_array( $btn['url'] ) ) {
|
||||
$buttons[ $btn_type ]['url'] = add_query_arg( $btn['url'] );
|
||||
}
|
||||
|
||||
$buttons[ $btn_type ]['attr'] = '';
|
||||
if ( ! empty( $btn['attr'] ) ) {
|
||||
$buttons[ $btn_type ]['attr'] = ' target="_blank" rel="noopener noreferrer"';
|
||||
}
|
||||
|
||||
$buttons[ $btn_type ]['class'] = '';
|
||||
if ( ! empty( $btn['class'] ) ) {
|
||||
$buttons[ $btn_type ]['class'] = ' ' . $btn['class'];
|
||||
}
|
||||
|
||||
$buttons[ $btn_type ]['text'] = '';
|
||||
if ( ! empty( $btn['text'] ) ) {
|
||||
$buttons[ $btn_type ]['text'] = wp_kses( $btn['text'], $content_allowed_tags );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$review_consent = get_option( 'sby_review_consent' );
|
||||
$review_step2_style = '';
|
||||
if ( $type == 'review' && ! $review_consent ) {
|
||||
$review_step2_style = 'style="display: none;"';
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="sby_notice_op sby_notice sby_<?php echo esc_attr( $type ); ?>_notice" <?php echo !empty( $review_step2_style ) ? $review_step2_style : ''; ?>>
|
||||
<div class="sby_thumb">
|
||||
<img src="<?php echo esc_url( str_replace( array( 'sbi', 'png' ), array( 'sby', 'svg' ), $img_src ) ); ?>" alt="notice">
|
||||
<?php echo $image_overlay; ?>
|
||||
</div>
|
||||
<div class="sby-notice-text">
|
||||
<div class="sby-notice-text-inner">
|
||||
<h3 class="sby-notice-text-header"><?php echo $title; ?></h3>
|
||||
<p class="sby-notice-text-p"><?php echo $content; ?></p>
|
||||
</div>
|
||||
<div class="sby-notice-btns-wrap">
|
||||
<p class="sby-notice-links">
|
||||
<?php
|
||||
foreach ( $buttons as $type => $button ) :
|
||||
$btn_classes = array('sby-btn');
|
||||
$btn_classes[] = esc_attr( $button['class'] );
|
||||
if ( $type == 'primary' ) {
|
||||
$btn_classes[] = 'sby-btn-blue';
|
||||
} else {
|
||||
$btn_classes[] = 'sby-btn-grey';
|
||||
}
|
||||
?>
|
||||
<a class="<?php echo implode(' ', $btn_classes); ?>" href="<?php echo esc_attr( str_replace( 'sbi_', 'sby_', $button['url'] ) ); ?>"<?php echo $button['attr']; ?>><?php echo $button['text']; ?></a>
|
||||
<?php endforeach; ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sby-notice-dismiss">
|
||||
<a href="<?php echo esc_url( $close_href ); ?>">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14 1.41L12.59 0L7 5.59L1.41 0L0 1.41L5.59 7L0 12.59L1.41 14L7 8.41L12.59 14L14 12.59L8.41 7L14 1.41Z" fill="#141B38"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* SBY Get Notice Title depending on the notice type
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $notification
|
||||
*
|
||||
* @return string $title
|
||||
*/
|
||||
public function get_notice_title( $notification ) {
|
||||
$type = $notification['id'];
|
||||
$title = '';
|
||||
|
||||
// Notice title depending on notice type
|
||||
if ( $type == 'review' ) {
|
||||
$title = __( 'Glad to hear you are enjoying it. Would you consider leaving a positive review?', 'feeds-for-youtube' );
|
||||
} else if ( $type == 'discount' ) {
|
||||
$title = __( 'Exclusive Offer! 60% OFF', 'feeds-for-youtube' );
|
||||
} else {
|
||||
$title = $this->replace_merge_fields( $notification['title'], $notification );
|
||||
}
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* SBY Get Notice Content depending on the notice type
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $notification
|
||||
* @param array $content_allowed_tags
|
||||
*
|
||||
* @return string $content
|
||||
*/
|
||||
public function get_notice_content( $notification, $content_allowed_tags ) {
|
||||
$type = $notification['id'];
|
||||
$content = '';
|
||||
|
||||
// Notice content depending on notice type
|
||||
if ( $type == 'review' ) {
|
||||
$content = __( 'It really helps to support the plugin and help others to discover it too!', 'feeds-for-youtube' );
|
||||
} else if ( $type == 'discount' ) {
|
||||
$content = __( 'We don’t run promotions very often, but for a limited time we’re offering 60% Off our Pro version to all users of our free YouTube Feeds.', 'feeds-for-youtube' );
|
||||
} else {
|
||||
if ( ! empty( $notification['content'] ) ) {
|
||||
$content = wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags );
|
||||
}
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide messages permanently or some can be dismissed temporarily
|
||||
*
|
||||
* @since 2.18
|
||||
*/
|
||||
public function dismiss() {
|
||||
global $current_user;
|
||||
$user_id = $current_user->ID;
|
||||
$sby_statuses_option = get_option( 'sby_statuses', array() );
|
||||
|
||||
if ( isset( $_GET['sby_ignore_rating_notice_nag'] ) ) {
|
||||
if ( (int)$_GET['sby_ignore_rating_notice_nag'] === 1 ) {
|
||||
update_option( 'sby_rating_notice', 'dismissed', false );
|
||||
$sby_statuses_option['rating_notice_dismissed'] = sby_get_current_time();
|
||||
update_option( 'sby_statuses', $sby_statuses_option, false );
|
||||
|
||||
} elseif ( $_GET['sby_ignore_rating_notice_nag'] === 'later' ) {
|
||||
set_transient( 'feeds_for_youtube_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS );
|
||||
update_option( 'sby_rating_notice', 'pending', false );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $_GET['sby_ignore_new_user_sale_notice'] ) ) {
|
||||
$response = sanitize_text_field( $_GET['sby_ignore_new_user_sale_notice'] );
|
||||
if ( $response === 'always' ) {
|
||||
update_user_meta( $user_id, 'sby_ignore_new_user_sale_notice', 'always' );
|
||||
|
||||
$current_month_number = (int)date('n', sby_get_current_time() );
|
||||
$not_early_in_the_year = ($current_month_number > 5);
|
||||
|
||||
if ( $not_early_in_the_year ) {
|
||||
update_user_meta( $user_id, 'sby_ignore_bfcm_sale_notice', date( 'Y', sby_get_current_time() ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $_GET['sby_ignore_bfcm_sale_notice'] ) ) {
|
||||
$response = sanitize_text_field( $_GET['sby_ignore_bfcm_sale_notice'] );
|
||||
if ( $response === 'always' ) {
|
||||
update_user_meta( $user_id, 'sby_ignore_bfcm_sale_notice', 'always' );
|
||||
} elseif ( $response === date( 'Y', sby_get_current_time() ) ) {
|
||||
update_user_meta( $user_id, 'sby_ignore_bfcm_sale_notice', date( 'Y', sby_get_current_time() ) );
|
||||
}
|
||||
update_user_meta( $user_id, 'sby_ignore_new_user_sale_notice', 'always' );
|
||||
}
|
||||
|
||||
if ( isset( $_GET['sby_dismiss'] ) ) {
|
||||
if ( $_GET['sby_dismiss'] === 'review' ) {
|
||||
update_option( 'sby_rating_notice', 'dismissed', false );
|
||||
$sby_statuses_option['rating_notice_dismissed'] = sby_get_current_time();
|
||||
update_option( 'sby_statuses', $sby_statuses_option, false );
|
||||
} elseif ( $_GET['sby_dismiss'] === 'discount' ) {
|
||||
update_user_meta( $user_id, 'sby_ignore_new_user_sale_notice', 'always' );
|
||||
|
||||
$current_month_number = (int)date('n', sby_get_current_time() );
|
||||
$not_early_in_the_year = ($current_month_number > 5);
|
||||
|
||||
if ( $not_early_in_the_year ) {
|
||||
update_user_meta( $user_id, 'sby_ignore_bfcm_sale_notice', date( 'Y', sby_get_current_time() ) );
|
||||
}
|
||||
}
|
||||
update_user_meta( $user_id, 'sby_ignore_new_user_sale_notice', 'always' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,832 @@
|
||||
<?php
|
||||
/**
|
||||
* SBY_Notifications.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Admin;
|
||||
|
||||
// Exit if accessed directly
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SBY_Notifications {
|
||||
|
||||
/**
|
||||
* Source of notifications content.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SOURCE_URL = 'https://plugin.smashballoon.com/notifications.json';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const OPTION_NAME = 'sby_notifications';
|
||||
|
||||
/**
|
||||
* JSON data contains notices for all plugins. This is used
|
||||
* to select messages only meant for this plugin
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const PLUGIN = 'youtube';
|
||||
|
||||
/**
|
||||
* Option value.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*
|
||||
* @var bool|array
|
||||
*/
|
||||
public $option = false;
|
||||
|
||||
/**
|
||||
* Initialize class.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*/
|
||||
public function init() {
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this function to get the option name to allow
|
||||
* inheritance for the New_User class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function option_name() {
|
||||
return self::OPTION_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this function to get the source URL to allow
|
||||
* inheritance for the New_User class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function source_url() {
|
||||
return self::SOURCE_URL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register hooks.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*/
|
||||
public function hooks() {
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueues' ) );
|
||||
|
||||
add_action( 'sby_admin_notices', array( $this, 'output' ) );
|
||||
|
||||
// on cron. Once a week?
|
||||
add_action( 'sby_notification_update', array( $this, 'update' ) );
|
||||
|
||||
add_action( 'wp_ajax_sby_dashboard_notification_dismiss', array( $this, 'dismiss' ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if user has access and is enabled.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_access() {
|
||||
$access = false;
|
||||
|
||||
if ( current_user_can( 'manage_youtube_feed_options' ) || current_user_can( 'manage_options' ) ) {
|
||||
$access = true;
|
||||
}
|
||||
|
||||
return apply_filters( 'sby_admin_notifications_has_access', $access );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get option value.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*
|
||||
* @param bool $cache Reference property cache if available.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_option( $cache = true ) {
|
||||
if ( $this->option && $cache ) {
|
||||
return $this->option;
|
||||
}
|
||||
|
||||
$option = get_option( $this->option_name(), array() );
|
||||
|
||||
$this->option = array(
|
||||
'update' => ! empty( $option['update'] ) ? $option['update'] : 0,
|
||||
'events' => ! empty( $option['events'] ) ? $option['events'] : array(),
|
||||
'feed' => ! empty( $option['feed'] ) ? $option['feed'] : array(),
|
||||
'dismissed' => ! empty( $option['dismissed'] ) ? $option['dismissed'] : array(),
|
||||
);
|
||||
|
||||
return $this->option;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch notifications from feed.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fetch_feed() {
|
||||
$res = wp_remote_get( $this->source_url() );
|
||||
|
||||
if ( is_wp_error( $res ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$body = wp_remote_retrieve_body( $res );
|
||||
|
||||
if ( empty( $body ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return $this->verify( json_decode( $body, true ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify notification data before it is saved.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*
|
||||
* @param array $notifications Array of notifications items to verify.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function verify( $notifications ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
$data = array();
|
||||
|
||||
if ( ! is_array( $notifications ) || empty( $notifications ) ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$option = $this->get_option();
|
||||
|
||||
foreach ( $notifications as $notification ) {
|
||||
|
||||
// Ignore if not a targeted plugin
|
||||
if ( ! empty( $notification['plugin'] ) && is_array( $notification['plugin'] ) && ! in_array( self::PLUGIN, $notification['plugin'], true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore if max wp version detected
|
||||
if ( ! empty( $notification['maxwpver'] ) && version_compare( get_bloginfo( 'version' ), $notification['maxwpver'], '>' ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore if max version has been reached
|
||||
if ( ! empty( $notification['maxver'] ) && version_compare( $notification['maxver'], SBYVER ) < 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore if min version has not been reached
|
||||
if ( ! empty( $notification['minver'] ) && version_compare( $notification['minver'], SBYVER ) > 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore if a specific sby_status is empty or false
|
||||
if ( ! empty( $notification['statuscheck'] ) ) {
|
||||
$status_key = sanitize_key( $notification['statuscheck'] );
|
||||
$sby_statuses_option = get_option( 'sby_statuses', array() );
|
||||
|
||||
if ( empty( $sby_statuses_option[ $status_key ] ) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// The message and license should never be empty, if they are, ignore.
|
||||
if ( empty( $notification['content'] ) || empty( $notification['type'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore if license type does not match.
|
||||
$license = sby_is_pro_version() ? 'pro' : 'free';
|
||||
|
||||
if ( ! in_array( $license, $notification['type'], true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore if expired.
|
||||
if ( ! empty( $notification['end'] ) && time() > strtotime( $notification['end'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore if notification has already been dismissed.
|
||||
if ( ! empty( $option['dismissed'] ) && in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore message "9".
|
||||
if ( in_array( (int)$notification['id'], array( 9 ) ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: Ignore if notification existed before installing SBY.
|
||||
// Prevents bombarding the user with notifications after activation.
|
||||
$activated = false;
|
||||
if ( ! empty( $activated )
|
||||
&& ! empty( $notification['start'] )
|
||||
&& $activated > strtotime( $notification['start'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data[] = $notification;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify saved notification data for active notifications.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*
|
||||
* @param array $notifications Array of notifications items to verify.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function verify_active( $notifications ) {
|
||||
if ( ! is_array( $notifications ) || empty( $notifications ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// Remove notfications that are not active.
|
||||
foreach ( $notifications as $key => $notification ) {
|
||||
if ( ( ! empty( $notification['start'] ) && sby_get_current_time() < strtotime( $notification['start'] ) )
|
||||
|| ( ! empty( $notification['end'] ) && sby_get_current_time() > strtotime( $notification['end'] ) ) ) {
|
||||
unset( $notifications[ $key ] );
|
||||
}
|
||||
|
||||
if ( empty( $notification['recent_install_override'] ) && $this->recently_installed() ) {
|
||||
unset( $notifications[ $key ] );
|
||||
}
|
||||
|
||||
// Ignore if max version has been reached
|
||||
if ( ! empty( $notification['maxver'] ) && version_compare( $notification['maxver'], SBYVER ) < 0 ) {
|
||||
unset( $notifications[ $key ] );
|
||||
}
|
||||
|
||||
// Ignore if max wp version detected
|
||||
if ( ! empty( $notification['maxwpver'] ) && version_compare( get_bloginfo( 'version' ), $notification['maxwpver'], '>' ) ) {
|
||||
unset( $notifications[ $key ] );
|
||||
}
|
||||
|
||||
// Ignore if min version has not been reached
|
||||
if ( ! empty( $notification['minver'] ) && version_compare( $notification['minver'], SBYVER ) > 0 ) {
|
||||
unset( $notifications[ $key ] );
|
||||
}
|
||||
|
||||
// Ignore if a specific sby_status is empty or false
|
||||
if ( ! empty( $notification['statuscheck'] ) ) {
|
||||
$status_key = sanitize_key( $notification['statuscheck'] );
|
||||
$sby_statuses_option = get_option( 'sby_statuses', array() );
|
||||
|
||||
if ( empty( $sby_statuses_option[ $status_key ] ) ) {
|
||||
unset( $notifications[ $key ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $notifications;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.4.5/1.4.2
|
||||
*/
|
||||
public function recently_installed() {
|
||||
$sby_statuses_option = get_option( 'sby_statuses', array() );
|
||||
|
||||
if ( ! isset( $sby_statuses_option['first_install'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Plugin was installed less than a week ago
|
||||
if ( (int) $sby_statuses_option['first_install'] > time() - WEEK_IN_SECONDS ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get notification data.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get() {
|
||||
if ( ! $this->has_access() ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$option = $this->get_option();
|
||||
|
||||
// Update notifications using async task.
|
||||
if ( empty( $option['update'] ) || sby_get_current_time() > $option['update'] + DAY_IN_SECONDS ) {
|
||||
$this->update();
|
||||
}
|
||||
|
||||
$events = ! empty( $option['events'] ) ? $this->verify_active( $option['events'] ) : array();
|
||||
$feed = ! empty( $option['feed'] ) ? $this->verify_active( $option['feed'] ) : array();
|
||||
|
||||
// If there is a new user notification, add it to the beginning of the notification list
|
||||
$sby_newuser = new SBY_New_User();
|
||||
$newuser_notifications = $sby_newuser->get();
|
||||
|
||||
if ( ! empty( $newuser_notifications ) ) {
|
||||
return $newuser_notifications;
|
||||
}
|
||||
|
||||
return array_merge( $events, $feed );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get notification count.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_count() {
|
||||
return count( $this->get() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a manual notification event.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*
|
||||
* @param array $notification Notification data.
|
||||
*/
|
||||
public function add( $notification ) {
|
||||
if ( empty( $notification['id'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$option = $this->get_option();
|
||||
|
||||
if ( in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $option['events'] as $item ) {
|
||||
if ( $item['id'] === $notification['id'] ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$notification = $this->verify( array( $notification ) );
|
||||
|
||||
update_option(
|
||||
'sby_notifications',
|
||||
array(
|
||||
'update' => $option['update'],
|
||||
'feed' => $option['feed'],
|
||||
'events' => array_merge( $notification, $option['events'] ),
|
||||
'dismissed' => $option['dismissed'],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update notification data from feed.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*/
|
||||
public function update() {
|
||||
$feed = $this->fetch_feed();
|
||||
$option = $this->get_option();
|
||||
|
||||
update_option(
|
||||
'sby_notifications',
|
||||
array(
|
||||
'update' => sby_get_current_time(),
|
||||
'feed' => $feed,
|
||||
'events' => $option['events'],
|
||||
'dismissed' => $option['dismissed'],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin area Form Overview enqueues.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*/
|
||||
public function enqueues() {
|
||||
if ( ! $this->has_access() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$notifications = $this->get();
|
||||
|
||||
if ( empty( $notifications ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$min = '';
|
||||
|
||||
wp_enqueue_style(
|
||||
'sby-admin-notifications',
|
||||
SBY_PLUGIN_URL . "css/admin-notifications{$min}.css",
|
||||
array(),
|
||||
SBYVER
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'sby-admin-notifications',
|
||||
SBY_PLUGIN_URL . "js/admin-notifications{$min}.js",
|
||||
array( 'jquery' ),
|
||||
SBYVER,
|
||||
true
|
||||
);
|
||||
wp_localize_script( 'sby-admin-notifications', 'sby_admin', array(
|
||||
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
||||
'nonce' => wp_create_nonce( 'sby-admin' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fields from the remote source contain placeholders to allow
|
||||
* some messages to be used for multiple plugins.
|
||||
*
|
||||
* @param $content string
|
||||
* @param $notification array
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*/
|
||||
public function replace_merge_fields( $content, $notification ) {
|
||||
$merge_fields = array(
|
||||
'{plugin}' => 'YouTube Feeds',
|
||||
'{amount}' => isset( $notification['amount'] ) ? $notification['amount'] : '',
|
||||
'{platform}' => 'YouTube',
|
||||
'{lowerplatform}' => 'youtube',
|
||||
'{review-url}' => 'https://wordpress.org/support/plugin/feeds-for-youtube/reviews/',
|
||||
'{slug}' => 'feeds-for-youtube',
|
||||
'{campaign}' => sby_utm_campaign()
|
||||
);
|
||||
|
||||
if ( sby_is_pro_version() ) {
|
||||
$merge_fields['{campaign}'] = 'youtube-pro';
|
||||
$merge_fields['{plugin}'] = 'YouTube Feeds Pro';
|
||||
}
|
||||
|
||||
foreach ( $merge_fields as $find => $replace ) {
|
||||
$content = str_replace( $find, $replace, $content );
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output notifications on YouTube Feeds admin area.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*/
|
||||
public function output() {
|
||||
// if we are one single feed page then return
|
||||
if ( isset( $_GET['feed_id'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$notifications = $this->get();
|
||||
|
||||
if ( empty( $notifications ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$is_review_notice = ! empty( $notifications[0] ) && ! empty( $notifications[0]['id'] ) && $notifications[0]['id'] === 'review';
|
||||
|
||||
if ( ! $is_review_notice && ! empty( $_GET['feed_id'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$notifications_html = '';
|
||||
$current_class = ' current';
|
||||
$content_allowed_tags = array(
|
||||
'em' => array(),
|
||||
'strong' => array(),
|
||||
'span' => array(
|
||||
'style' => array(),
|
||||
),
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'target' => array(),
|
||||
'rel' => array(),
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( $notifications as $notification ) {
|
||||
$type = $notification['id'];
|
||||
// Buttons HTML.
|
||||
$buttons_html = '';
|
||||
if ( ! empty( $notification['btns'] ) && is_array( $notification['btns'] ) ) {
|
||||
foreach ( $notification['btns'] as $btn_type => $btn ) {
|
||||
if ( $type == 'review' || $type == 'discount' ) {
|
||||
$btn_class = $btn_type === 'primary' ? 'sby-btn-blue' : 'sby-btn-grey';
|
||||
} else {
|
||||
$btn_class = $btn_type === 'primary' ? 'sby-btn-orange' : 'sby-btn-grey';
|
||||
}
|
||||
if ( is_array( $btn['url'] ) ) {
|
||||
$args = array();
|
||||
foreach ( $btn['url'] as $key => $value ) {
|
||||
$args[ sanitize_key( $key ) ] = sanitize_key( $value );
|
||||
}
|
||||
$btn['url'] = add_query_arg( $args );
|
||||
}
|
||||
if ( ! empty( $btn['attr'] ) ) {
|
||||
$btn['target'] = '_blank';
|
||||
}
|
||||
if ( empty( $btn['class'] ) ) {
|
||||
$btn['class'] = '';
|
||||
}
|
||||
$buttons_html .= sprintf(
|
||||
'<a href="%1$s" class="sby-btn %2$s %3$s"%4$s>%5$s</a>',
|
||||
! empty( $btn['url'] ) ? esc_url( $this->replace_merge_fields( str_replace( 'sbi_', 'sby_', $btn['url'] ), $notification ) ) : '',
|
||||
esc_attr( $btn['class'] ),
|
||||
esc_attr( $btn_class ),
|
||||
! empty( $btn['target'] ) && $btn['target'] === '_blank' ? ' target="_blank" rel="noopener noreferrer"' : '',
|
||||
! empty( $btn['text'] ) ? sanitize_text_field( $btn['text'] ) : ''
|
||||
);
|
||||
}
|
||||
$buttons_html = ! empty( $buttons_html ) ? '<div class="buttons">' . $buttons_html . '</div>' : '';
|
||||
}
|
||||
|
||||
if ( empty( $notification['image'] ) ) {
|
||||
$image_html = '<div class="bell">';
|
||||
|
||||
$image_html .= '<svg xmlns="http://www.w3.org/2000/svg" width="42" height="48" viewBox="0 0 42 48"><defs><style>.a{fill:#777;}.b{fill:#ca4a1f;}</style></defs><path class="a" d="M23-79a6.005,6.005,0,0,1-6-6h10.06a12.066,12.066,0,0,0,1.791,1.308,6.021,6.021,0,0,1-2.077,3.352A6.008,6.008,0,0,1,23-79Zm1.605-9H5.009a2.955,2.955,0,0,1-2.173-.923A3.088,3.088,0,0,1,2-91a2.919,2.919,0,0,1,.807-2.036c.111-.12.229-.243.351-.371a14.936,14.936,0,0,0,3.126-4.409A23.283,23.283,0,0,0,8.007-107.5a14.846,14.846,0,0,1,.906-5.145,14.5,14.5,0,0,1,2.509-4.324A15.279,15.279,0,0,1,20-122.046V-124a3,3,0,0,1,3-3,3,3,0,0,1,3,3v1.954a15.28,15.28,0,0,1,8.58,5.078,14.5,14.5,0,0,1,2.509,4.324,14.846,14.846,0,0,1,.906,5.145c0,.645.016,1.281.047,1.888A12.036,12.036,0,0,0,35-106a11.921,11.921,0,0,0-8.485,3.515A11.923,11.923,0,0,0,23-94a12,12,0,0,0,1.6,6Z" transform="translate(-2 127)"/><circle class="b" cx="9" cy="9" r="9" transform="translate(24 24)"/></svg>';
|
||||
$image_html .= '</div>';
|
||||
} else {
|
||||
if ( $notification['image'] === 'balloon' ) {
|
||||
$image_html = sprintf(
|
||||
'<div class="bell"><img src="%s" alt="notice">',
|
||||
SBY_PLUGIN_URL . 'img/balloon.svg' );
|
||||
} else if ( $notification['id'] === 'review' || $notification['id'] === 'discount' ) {
|
||||
$image_html = sprintf(
|
||||
'<div class="bell"><img src="%s" alt="notice">',
|
||||
SBY_PLUGIN_URL . 'img/' . sanitize_text_field( str_replace( array( 'sbi', '.png' ), array( 'sby', '.svg' ), $notification['image'] ) )
|
||||
);
|
||||
} else {
|
||||
$image_html = '<div class="thumb">';
|
||||
$img_src = SBY_PLUGIN_URL . 'img/' . sanitize_text_field( $notification['image'] );
|
||||
$image_html .= '<img src="'.esc_url( $img_src ).'" alt="notice">';
|
||||
|
||||
if ( isset( $notification['image_overlay'] ) ) {
|
||||
$image_html .= '<div class="img-overlay">'. esc_html( str_replace( '%', '%%', $notification['image_overlay'] ) ).'</div>';
|
||||
}
|
||||
}
|
||||
$image_html .= '</div>';
|
||||
|
||||
}
|
||||
|
||||
// Check if it's review notice then show step #1
|
||||
if ( $type == 'review' ) {
|
||||
$step1_img = SBY_PLUGIN_URL . 'img/' . sanitize_text_field( str_replace( array( 'sbi', 'png' ), array( 'sby', 'svg' ), $notification['image'] ) );
|
||||
$step1_img_html = sprintf('<div class="bell"><img src="%s" alt="notice"></div>', $step1_img);
|
||||
|
||||
$review_consent = get_option( 'sby_review_consent' );
|
||||
$sby_open_feedback_url = 'https://smashballoon.com/feedback/?plugin=' . sby_utm_campaign();
|
||||
// step #1 for the review notice
|
||||
if ( ! $review_consent ) {
|
||||
$step1_btns = sprintf(
|
||||
'<button class="sby-btn-link" id="sby_review_consent_yes">%s</button>',
|
||||
__( 'Yes', 'feeds-for-youtube' )
|
||||
);
|
||||
$step1_btns .= sprintf(
|
||||
'<a href="%s" target="_blank" rel="nofollow noopener" class="sby-btn-link" id="sby_review_consent_no">%s</a>',
|
||||
$sby_open_feedback_url,
|
||||
__( 'No', 'feeds-for-youtube' )
|
||||
);
|
||||
$notifications_html .= sprintf(
|
||||
'<div class="sby_review_step1_notice" data-message-id="%3$s">' . $step1_img_html . '
|
||||
<h3 class="title">%1$s</h3>
|
||||
<div class="review-step-1-btns">%2$s</div>
|
||||
</div>',
|
||||
__( 'Are you enjoying the YouTube Feeds Plugin?', 'feeds-for-youtube' ),
|
||||
$step1_btns,
|
||||
! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$review_consent = get_option( 'sby_review_consent' );
|
||||
$review_step2_style = '';
|
||||
if ( $type == 'review' && ! $review_consent ) {
|
||||
$review_step2_style = 'style="display: none;"';
|
||||
}
|
||||
|
||||
// Build the notification HTML for review notice
|
||||
if ( $type == 'review' ) {
|
||||
$notifications_html .= sprintf(
|
||||
'<div class="message%5$s %7$s" data-message-id="%4$s" %6$s>' . $image_html . '
|
||||
<h3 class="title">%1$s</h3>
|
||||
<p class="content">%2$s</p>
|
||||
%3$s
|
||||
</div>',
|
||||
__( 'Glad to hear you are enjoying it. Would you consider leaving a positive review?', 'feeds-for-youtube' ),
|
||||
__( 'It really helps to support the plugin and help others to discover it too!', 'feeds-for-youtube' ),
|
||||
$buttons_html,
|
||||
! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0,
|
||||
$current_class,
|
||||
( $notification['id'] == 'review' && ! empty( $review_step2_style ) ) ? $review_step2_style : '',
|
||||
( $type == 'review' ) ? 'rn_step_2' : ''
|
||||
);
|
||||
} else if ( $type == 'discount' ) {
|
||||
// Notification HTML for other notices
|
||||
$notifications_html .= sprintf(
|
||||
'<div class="message%5$s" data-message-id="%4$s" %6$s>' . $image_html . '
|
||||
<h3 class="title">%1$s</h3>
|
||||
<p class="content">%2$s</p>
|
||||
%3$s
|
||||
</div>',
|
||||
! empty( $notification['title'] ) ? $this->get_notice_title( $notification ) : '',
|
||||
! empty( $notification['content'] ) ? $this->get_notice_content( $notification, $content_allowed_tags ) : '',
|
||||
$buttons_html,
|
||||
! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0,
|
||||
$current_class,
|
||||
( $notification['id'] == 'review' && ! empty( $review_step2_style ) ) ? $review_step2_style : ''
|
||||
);
|
||||
} else {
|
||||
// Notification HTML for other notices
|
||||
$notifications_html .= sprintf(
|
||||
'<div class="message%5$s" data-message-id="%4$s" %6$s>' . $image_html . '
|
||||
<h3 class="title">%1$s</h3>
|
||||
<p class="content">%2$s</p>
|
||||
%3$s
|
||||
</div>',
|
||||
! empty( $notification['title'] ) ? $this->replace_merge_fields( sanitize_text_field( $notification['title'] ), $notification ) : '',
|
||||
! empty( $notification['content'] ) ? wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags ) : '',
|
||||
$buttons_html,
|
||||
! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0,
|
||||
$current_class,
|
||||
( $notification['id'] == 'review' && ! empty( $review_step2_style ) ) ? $review_step2_style : ''
|
||||
);
|
||||
}
|
||||
|
||||
// Only first notification is current.
|
||||
$current_class = '';
|
||||
}
|
||||
|
||||
$close_href = add_query_arg( array( 'sby_dismiss' => $type ) );
|
||||
$type_class = '';
|
||||
if ( $type === 'review' || $type == 'discount' ) {
|
||||
$type_class = $type === 'review' ? 'sby_review_notice' : 'sby_discount_notice';
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div id="sby-notifications" class="<?php echo esc_attr( $type_class ); ?>">
|
||||
<a
|
||||
class="dismiss"
|
||||
title="<?php echo esc_attr__( 'Dismiss this message', 'feeds-for-youtube' ); ?>"
|
||||
<?php echo ( $type == 'review' || $type == 'discount' ) ? 'href="'. esc_attr( $close_href ) .'"' : '' ?>
|
||||
>
|
||||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.66683 1.27325L8.72683 0.333252L5.00016 4.05992L1.2735 0.333252L0.333496 1.27325L4.06016 4.99992L0.333496 8.72659L1.2735 9.66659L5.00016 5.93992L8.72683 9.66659L9.66683 8.72659L5.94016 4.99992L9.66683 1.27325Z" fill="white"/>
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<?php if ( count( $notifications ) > 1 ) : ?>
|
||||
<div class="navigation">
|
||||
<a class="prev disabled" title="<?php echo esc_attr__( 'Previous message', 'feeds-for-youtube' ); ?>"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chevron-left" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="svg-inline--fa fa-chevron-left fa-w-10"><path fill="currentColor" d="M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z" class=""></path></svg></a>
|
||||
<a class="next disabled" title="<?php echo esc_attr__( 'Next message', 'feeds-for-youtube' ); ?>"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chevron-right" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="svg-inline--fa fa-chevron-right fa-w-10"><path fill="currentColor" d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z" class=""></path></svg></a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="messages">
|
||||
<?php echo $notifications_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* SBY Get Notice Title depending on the notice type
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $notification
|
||||
*
|
||||
* @return string $title
|
||||
*/
|
||||
public function get_notice_title( $notification ) {
|
||||
$type = $notification['id'];
|
||||
$title = '';
|
||||
|
||||
// Notice title depending on notice type
|
||||
if ( $type == 'review' ) {
|
||||
$title = __( 'Glad to hear you are enjoying it. Would you consider leaving a positive review?', 'feeds-for-youtube' );
|
||||
} else if ( $type == 'discount' ) {
|
||||
$title = __( 'Exclusive Offer! 60% OFF', 'feeds-for-youtube' );
|
||||
} else {
|
||||
$title = $this->replace_merge_fields( $notification['title'], $notification );
|
||||
}
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* SBY Get Notice Content depending on the notice type
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $notification
|
||||
* @param array $content_allowed_tags
|
||||
*
|
||||
* @return string $content
|
||||
*/
|
||||
public function get_notice_content( $notification, $content_allowed_tags ) {
|
||||
$type = $notification['id'];
|
||||
$content = '';
|
||||
|
||||
// Notice content depending on notice type
|
||||
if ( $type == 'review' ) {
|
||||
$content = __( 'It really helps to support the plugin and help others to discover it too!', 'feeds-for-youtube' );
|
||||
} else if ( $type == 'discount' ) {
|
||||
$content = __( 'We don’t run promotions very often, but for a limited time we’re offering 60% Off our Pro version to all users of our free YouTube Feeds.', 'feeds-for-youtube' );
|
||||
} else {
|
||||
if ( ! empty( $notification['content'] ) ) {
|
||||
$content = wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags );
|
||||
}
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismiss notification via AJAX. If it's a new user message, also dismiss it
|
||||
* on all admin pages.
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*/
|
||||
public function dismiss() {
|
||||
// Run a security check.
|
||||
check_ajax_referer( 'sby-admin', 'nonce' );
|
||||
|
||||
// Check for access and required param.
|
||||
if ( ! $this->has_access() || empty( $_POST['id'] ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$id = sanitize_text_field( wp_unslash( $_POST['id'] ) );
|
||||
|
||||
if ( $id === 'review' ) {
|
||||
$sby_statuses_option = get_option( 'sby_statuses', array() );
|
||||
|
||||
update_option( 'sby_rating_notice', 'dismissed', false );
|
||||
$sby_statuses_option['rating_notice_dismissed'] = sby_get_current_time();
|
||||
update_option( 'sby_statuses', $sby_statuses_option, false );
|
||||
} elseif ( $id === 'discount' ) {
|
||||
update_user_meta( get_current_user_id(), 'sby_ignore_new_user_sale_notice', 'always' );
|
||||
|
||||
$current_month_number = (int)date('n', sby_get_current_time() );
|
||||
$not_early_in_the_year = ($current_month_number > 5);
|
||||
|
||||
if ( $not_early_in_the_year ) {
|
||||
update_user_meta( get_current_user_id(), 'sby_ignore_bfcm_sale_notice', date( 'Y', sby_get_current_time() ) );
|
||||
}
|
||||
}
|
||||
|
||||
$option = $this->get_option();
|
||||
$type = is_numeric( $id ) ? 'feed' : 'events';
|
||||
|
||||
$option['dismissed'][] = $id;
|
||||
$option['dismissed'] = array_unique( $option['dismissed'] );
|
||||
|
||||
// Remove notification.
|
||||
if ( is_array( $option[ $type ] ) && ! empty( $option[ $type ] ) ) {
|
||||
foreach ( $option[ $type ] as $key => $notification ) {
|
||||
if ( $notification['id'] == $id ) { // phpcs:ignore WordPress.PHP.StrictComparisons
|
||||
unset( $option[ $type ][ $key ] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_option( 'sby_notifications', $option );
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
public function output_return() {
|
||||
ob_start();
|
||||
$this->output();
|
||||
return ob_get_clean();
|
||||
}
|
||||
}
|
||||
371
wp-content/plugins/youtube-feed-pro/inc/Admin/SBY_Tracking.php
Normal file
371
wp-content/plugins/youtube-feed-pro/inc/Admin/SBY_Tracking.php
Normal file
@@ -0,0 +1,371 @@
|
||||
<?php
|
||||
/**
|
||||
* Tracking functions for reporting plugin usage to the Smash Balloon site for users that have opted in
|
||||
*
|
||||
* @copyright Copyright (c) 2018, Chris Christoff
|
||||
* @since
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Admin;
|
||||
|
||||
use Smashballoon\Customizer\DB;
|
||||
use Smashballoon\Framework\Utilities\UsageTracking;
|
||||
use SmashBalloon\YouTubeFeed\Builder\SBY_Db;
|
||||
use SmashBalloon\YouTubeFeed\Builder\SBY_Feed_Saver;
|
||||
|
||||
/**
|
||||
* Usage tracking
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*@since 5.6
|
||||
*/
|
||||
class SBY_Tracking {
|
||||
|
||||
protected $DB;
|
||||
|
||||
public function __construct( DB $DB) {
|
||||
add_action( 'init', array( $this, 'schedule_send' ) );
|
||||
add_filter( 'cron_schedules', array( $this, 'add_schedules' ) );
|
||||
add_filter( 'sb_usage_tracking_data', [ $this, 'filter_usage_tracking_data' ], 10, 2 );
|
||||
add_action( 'sby_usage_tracking_cron', array( $this, 'send_checkin' ) );
|
||||
|
||||
$this->DB = $DB;
|
||||
}
|
||||
|
||||
private function normalize_and_format( $key, $value ) {
|
||||
$normal_bools = array(
|
||||
'widthresp',
|
||||
'disablemobile',
|
||||
'showheader',
|
||||
'showdescription',
|
||||
'headerchannel',
|
||||
'customsearch',
|
||||
'showbutton',
|
||||
'headeroutside',
|
||||
'showsubscribe',
|
||||
'backup_cache_enabled',
|
||||
'disable_resize',
|
||||
'favor_local',
|
||||
'disable_js_image_loading',
|
||||
'ajax_post_load',
|
||||
'ajaxtheme',
|
||||
'enqueue_css_in_shortcode',
|
||||
'customtemplates',
|
||||
'eagerload',
|
||||
|
||||
// pro only
|
||||
'usecustomsearch',
|
||||
'showlikes',
|
||||
'carouselarrows',
|
||||
'carouselpag',
|
||||
'carouselautoplay',
|
||||
'userelative',
|
||||
'showsubscribers',
|
||||
);
|
||||
$custom_text_settings = array(
|
||||
'class',
|
||||
'buttontext',
|
||||
'subscribetext',
|
||||
'customheadertext',
|
||||
|
||||
// pro only
|
||||
'customdate',
|
||||
'subscriberstext',
|
||||
'viewstext',
|
||||
'agotext',
|
||||
'beforedatetext',
|
||||
'beforestreamtimetext',
|
||||
'minutetext',
|
||||
'minutestext',
|
||||
'hourstext',
|
||||
'thousandstext',
|
||||
'millionstext',
|
||||
'watchnowtext',
|
||||
'linktext',
|
||||
'linkurl',
|
||||
'custom_css',
|
||||
'custom_js'
|
||||
);
|
||||
$comma_separate_counts_settings = array(
|
||||
'channel',
|
||||
'playlist',
|
||||
'favorites',
|
||||
'search',
|
||||
'live',
|
||||
'single',
|
||||
'includewords',
|
||||
'excludewords',
|
||||
'includewords',
|
||||
'hidevideos',
|
||||
);
|
||||
$defaults = sby_settings_defaults();
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
if ( empty( $value ) ) {
|
||||
return 0;
|
||||
}
|
||||
return count( $value );
|
||||
// 0 for anything that might be false, 1 for everything else
|
||||
} elseif ( in_array( $key, $normal_bools, true ) ) {
|
||||
if ( in_array( $value, array( false, 0, '0', 'false', '' ), true ) ) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
// if a custom text setting, we just want to know if it's different than the default
|
||||
} elseif ( in_array( $key, $custom_text_settings, true ) ) {
|
||||
if ( $defaults[ $key ] === $value ) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
} elseif ( in_array( $key, $comma_separate_counts_settings, true ) ) {
|
||||
if ( str_replace( ' ', '', $value ) === '' ) {
|
||||
return 0;
|
||||
}
|
||||
$split_at_comma = explode( ',', $value );
|
||||
return count( $split_at_comma );
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
||||
}
|
||||
|
||||
private function get_data() {
|
||||
$data = array();
|
||||
|
||||
// Retrieve current theme info
|
||||
$theme_data = wp_get_theme();
|
||||
|
||||
$count_b = 1;
|
||||
if ( is_multisite() ) {
|
||||
if ( function_exists( 'get_blog_count' ) ) {
|
||||
$count_b = get_blog_count();
|
||||
} else {
|
||||
$count_b = 'Not Set';
|
||||
}
|
||||
}
|
||||
|
||||
$php_version = rtrim( ltrim( sanitize_text_field( phpversion() ) ) );
|
||||
$php_version = ! empty( $php_version ) ? substr( $php_version, 0, strpos( $php_version, '.', strpos( $php_version, '.' ) + 1 ) ) : phpversion();
|
||||
|
||||
global $wp_version;
|
||||
$data['this_plugin'] = 'yt';
|
||||
$data['php_version'] = $php_version;
|
||||
$data['mi_version'] = SBYVER;
|
||||
$data['wp_version'] = $wp_version;
|
||||
$data['server'] = isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : '';
|
||||
$data['multisite'] = is_multisite();
|
||||
$data['url'] = 'f'.home_url();
|
||||
$data['themename'] = $theme_data->Name;
|
||||
$data['themeversion'] = $theme_data->Version;
|
||||
$data['settings'] = array();
|
||||
$data['pro'] = sby_is_pro_version() ? '1' : '';
|
||||
$data['sites'] = $count_b;
|
||||
$data['usagetracking'] = get_option( 'sby_usage_tracking_config', false );
|
||||
$num_users = function_exists( 'count_users' ) ? count_users() : 'Not Set';
|
||||
$data['usercount'] = is_array( $num_users ) ? $num_users['total_users'] : 1;
|
||||
$data['timezoneoffset']= date('P');
|
||||
|
||||
$settings_to_send = array();
|
||||
$raw_settings = get_option( 'sby_settings', array() );
|
||||
|
||||
foreach ( $raw_settings as $key => $value ) {
|
||||
$combine_arrays = array(
|
||||
'include',
|
||||
'hoverinclude',
|
||||
);
|
||||
|
||||
if ( $key === 'api_key' ) {
|
||||
// do not sent
|
||||
} elseif ( $key === 'connected_accounts' ) {
|
||||
if ( is_array( $raw_settings['connected_accounts'] ) ) {
|
||||
$settings_to_send['connected_accounts'] = count( $raw_settings['connected_accounts'] );
|
||||
} else {
|
||||
$settings_to_send['connected_accounts'] = 0;
|
||||
}
|
||||
} elseif ( in_array( $key, $combine_arrays, true ) && is_array( $value ) ) {
|
||||
foreach ( $value as $item ) {
|
||||
$settings_to_send[ $key . '_' . $item ] = 1;
|
||||
}
|
||||
} else {
|
||||
$value = $this->normalize_and_format( $key, $value );
|
||||
if ( $value !== false ) {
|
||||
$settings_to_send[ $key ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$feed_settings = array();
|
||||
$settings_to_send = array_merge( $settings_to_send, $feed_settings );
|
||||
|
||||
global $wpdb;
|
||||
$feed_caches = array();
|
||||
|
||||
$results = $wpdb->get_results( "
|
||||
SELECT option_name
|
||||
FROM $wpdb->options
|
||||
WHERE `option_name` LIKE ('%\_transient\_sby\_%')
|
||||
AND `option_name` NOT LIKE ('%\_transient\_sby\_header%');", ARRAY_A );
|
||||
|
||||
if ( isset( $results[0] ) ) {
|
||||
$feed_caches = $results;
|
||||
}
|
||||
$settings_to_send['num_found_feed_caches'] = count( $feed_caches );
|
||||
|
||||
$settings_to_send['custom_header_template'] = '' !== locate_template( 'sby/header.php', false, false ) ? 1 : 0;
|
||||
$settings_to_send['custom_player_template'] = '' !== locate_template( 'sby/player.php', false, false ) ? 1 : 0;
|
||||
$settings_to_send['custom_info_template'] = '' !== locate_template( 'sby/info.php', false, false ) ? 1 : 0;
|
||||
$settings_to_send['custom_cta_template'] = '' !== locate_template( 'sby/cta.php', false, false ) ? 1 : 0;
|
||||
$settings_to_send['custom_header_generic_template'] = '' !== locate_template( 'sby/header-generic.php', false, false ) ? 1 : 0;
|
||||
$settings_to_send['custom_item_template'] = '' !== locate_template( 'sby/item.php', false, false ) ? 1 : 0;
|
||||
$settings_to_send['custom_footer_template'] = '' !== locate_template( 'sby/footer.php', false, false ) ? 1 : 0;
|
||||
$settings_to_send['custom_feed_template'] = '' !== locate_template( 'sby/feed.php', false, false ) ? 1 : 0;
|
||||
|
||||
// Retrieve current plugin information
|
||||
if( ! function_exists( 'get_plugins' ) ) {
|
||||
include ABSPATH . '/wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
$plugins = get_plugins();
|
||||
$active_plugins = get_option( 'active_plugins', array() );
|
||||
$plugins_to_send = array();
|
||||
|
||||
foreach ( $plugins as $plugin_path => $plugin ) {
|
||||
// If the plugin isn't active, don't show it.
|
||||
if ( ! in_array( $plugin_path, $active_plugins ) )
|
||||
continue;
|
||||
|
||||
$plugins_to_send[] = $plugin['Name'];
|
||||
}
|
||||
|
||||
$data['active_plugins'] = $plugins_to_send;
|
||||
$data['locale'] = get_locale();
|
||||
if ( isset( $data['settings']['api_key'] ) ) {
|
||||
unset( $data['settings']['api_key'] );
|
||||
}
|
||||
if ( isset( $data['settings']['access_token'] ) ) {
|
||||
unset( $data['settings']['access_token'] );
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function send_checkin( $override = false, $ignore_last_checkin = false ) {
|
||||
|
||||
$home_url = trailingslashit( home_url() );
|
||||
|
||||
if ( strpos( $home_url, 'smashballoon.com' ) !== false ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( ! $this->tracking_allowed() && ! $override ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return UsageTracking::send_usage_update($this->get_data(), 'sby');
|
||||
}
|
||||
|
||||
private function tracking_allowed() {
|
||||
$usage_tracking = get_option( 'sby_usage_tracking', array( 'last_send' => 0, 'enabled' => sby_is_pro_version() ) );
|
||||
$tracking_allowed = isset( $usage_tracking['enabled'] ) ? $usage_tracking['enabled'] : sby_is_pro_version();
|
||||
|
||||
return $tracking_allowed;
|
||||
}
|
||||
|
||||
public function schedule_send() {
|
||||
if ( ! wp_next_scheduled( 'sby_usage_tracking_cron' ) ) {
|
||||
$tracking = array();
|
||||
$tracking['day'] = rand( 0, 6 );
|
||||
$tracking['hour'] = rand( 0, 23 );
|
||||
$tracking['minute'] = rand( 0, 59 );
|
||||
$tracking['second'] = rand( 0, 59 );
|
||||
$tracking['offset'] = ( $tracking['day'] * DAY_IN_SECONDS ) +
|
||||
( $tracking['hour'] * HOUR_IN_SECONDS ) +
|
||||
( $tracking['minute'] * MINUTE_IN_SECONDS ) +
|
||||
$tracking['second'];
|
||||
$last_sunday = strtotime("next sunday") - (7 * DAY_IN_SECONDS);
|
||||
if ( ($last_sunday + $tracking['offset']) > time() + 6 * HOUR_IN_SECONDS ) {
|
||||
$tracking['initsend'] = $last_sunday + $tracking['offset'];
|
||||
} else {
|
||||
$tracking['initsend'] = strtotime("next sunday") + $tracking['offset'];
|
||||
}
|
||||
|
||||
wp_schedule_event( $tracking['initsend'], 'weekly', 'sby_usage_tracking_cron' );
|
||||
update_option( 'sby_usage_tracking_config', $tracking );
|
||||
}
|
||||
}
|
||||
|
||||
public function add_schedules( $schedules = array() ) {
|
||||
// Adds once weekly to the existing schedules.
|
||||
$schedules['weekly'] = array(
|
||||
'interval' => 604800,
|
||||
'display' => __( 'Once Weekly', 'feeds-for-youtube' )
|
||||
);
|
||||
return $schedules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the usage tracking data
|
||||
*
|
||||
* @param array $data
|
||||
* @param string $plugin_slug
|
||||
*
|
||||
* @handles sb_usage_tracking_data
|
||||
*
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function filter_usage_tracking_data( $data, $plugin_slug ) {
|
||||
if ( 'sby' !== $plugin_slug ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
if ( ! is_array( $data ) ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
if ( ! isset( $data['settings'] ) ) {
|
||||
$data['settings'] = [];
|
||||
}
|
||||
|
||||
$tracked_boolean_settings = explode( ',',
|
||||
'widthresp,class,height,heightunit,disablemobile,itemspacing,itemspacingunit,
|
||||
background,headercolor,subscribecolor,subscribetextcolor,buttoncolor,buttontextcolor,
|
||||
showheader,showdescription,showbutton,headersize,headeroutside,showsubscribe,buttontext,
|
||||
subscribetext,backup_cache_enabled,resizeprocess,disable_resize,storage_process,
|
||||
favor_local,disable_js_image_loading,ajax_post_load,ajaxtheme,enqueue_css_in_shortcode,
|
||||
customtemplates,gallerycols,gallerycolsmobile,gridcols,gridcolsmobile,eagerload,custom_css,
|
||||
custom_js,disablecdn,allowcookies,usecustomsearch,headerchannel,customsearch,showpast,showlikes,
|
||||
carouselarrows,carouselpag,carouselautoplay,include,hoverinclude,descriptionlength,userelative,
|
||||
dateformat,customdate,showsubscribers,descriptiontextsize,subscriberstext,viewstext,agotext,
|
||||
beforedatetext,beforestreamtimetext,minutetext,minutestext,hourstext,thousandstext,millionstext,
|
||||
watchnowtext,cta,linktext,linkurl,linkopentype,linkcolor,linktextcolor'
|
||||
);
|
||||
$tracked_string_settings = explode( ',',
|
||||
'type,num,nummobile,layout,playvideo,sortby,cache_time,cache_time_unit,playerratio,gdpr,carouselcols,carouselcolsmobile,infoposition'
|
||||
);
|
||||
|
||||
$feeds = SBY_Db::feeds_query();
|
||||
$settings_defaults = SBY_Feed_Saver::settings_defaults();
|
||||
|
||||
// Track settings of the first feed
|
||||
if ( ! empty( $feeds ) ) {
|
||||
$feed = $feeds[0];
|
||||
$feed_settings = ( new SBY_Feed_Saver( $feed['id'] ) )->get_feed_settings();
|
||||
|
||||
if(!is_array($feed_settings)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$booleans = UsageTracking::tracked_settings_to_booleans($tracked_boolean_settings, $settings_defaults, $feed_settings);
|
||||
$strings = UsageTracking::tracked_settings_to_strings($tracked_string_settings, $feed_settings);
|
||||
|
||||
if ( is_array( $booleans ) && is_array( $strings ) ) {
|
||||
$data['settings'] = array_merge( $data['settings'], $booleans, $strings );
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
396
wp-content/plugins/youtube-feed-pro/inc/Admin/SBY_Upgrader.php
Normal file
396
wp-content/plugins/youtube-feed-pro/inc/Admin/SBY_Upgrader.php
Normal file
@@ -0,0 +1,396 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrade to the Pro version
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Admin;
|
||||
|
||||
|
||||
class SBY_Upgrader {
|
||||
|
||||
/**
|
||||
* URL where licensing is done
|
||||
*/
|
||||
const STORE_URL = 'https://smashballoon.com/';
|
||||
|
||||
/**
|
||||
* URL to connect to Smash Balloon App and upgrade to Pro
|
||||
*/
|
||||
const UPGRADE_URL = 'https://connect.smashballoon.com/activate/index.php';
|
||||
|
||||
/**
|
||||
* Check the license key URL
|
||||
*/
|
||||
const CHECK_URL = 'https://connect.smashballoon.com/activate/check.php';
|
||||
|
||||
const NAME = 'youtube';
|
||||
|
||||
const SLUG = 'youtube-feed-pro/youtube-feed-pro.php';
|
||||
|
||||
const REDIRECT = 'youtube-feed-settings';
|
||||
|
||||
const INSTALL_INSTRUCTIONS = 'https://smashballoon.com/doc/setting-up-the-feeds-for-youtube-pro-wordpress-plugin/?youtube&utm_campaign=youtube-free&utm_source=settings&utm_medium=freetopro&utm_content=Upgrade Manually';
|
||||
|
||||
|
||||
/**
|
||||
* AJAX hooks for creating the redirect
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public function hooks() {
|
||||
add_action( 'wp_ajax_nopriv_sby_run_one_click_upgrade', array( 'SmashBalloon\YouTubeFeed\Admin\SBY_Upgrader', 'install_upgrade' ) );
|
||||
add_action( 'wp_ajax_sby_maybe_upgrade_redirect', array( 'SmashBalloon\YouTubeFeed\Admin\SBY_Upgrader', 'maybe_upgrade_redirect' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to licensing API to get download URL for Pro version
|
||||
*
|
||||
* @param $license_data
|
||||
*
|
||||
* @return bool|mixed|null
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public static function get_version_info( $license_data, $license_key ) {
|
||||
$api_params = array(
|
||||
'edd_action' => 'get_version',
|
||||
'license' => $license_key,
|
||||
'item_name' => isset( $license_data['item_name'] ) ? $license_data['item_name'] : false,
|
||||
'item_id' => isset( $license_data['item_id'] ) ? $license_data['item_id'] : false,
|
||||
'version' => '0',
|
||||
'slug' => self::SLUG,
|
||||
'author' => 'SmashBalloon',
|
||||
'url' => home_url(),
|
||||
'beta' => false,
|
||||
'nocache' => '1'
|
||||
);
|
||||
|
||||
$api_url = trailingslashit( self::STORE_URL );
|
||||
|
||||
$request = wp_remote_post(
|
||||
$api_url,
|
||||
array(
|
||||
'timeout' => 15,
|
||||
'sslverify' => true,
|
||||
'body' => $api_params,
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! is_wp_error( $request ) ) {
|
||||
$version_info = json_decode( wp_remote_retrieve_body( $request ) );
|
||||
return $version_info;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax handler for grabbing the upgrade url.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public static function maybe_upgrade_redirect() {
|
||||
$home_url = home_url();
|
||||
check_ajax_referer( 'sby-admin', 'nonce' );
|
||||
if ( ! sby_current_user_can( 'manage_youtube_feed_options' ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
// Check for permissions.
|
||||
if ( ! current_user_can( 'install_plugins' ) ) {
|
||||
wp_send_json_error( array( 'message' => esc_html__( 'You are not allowed to install plugins.', 'feeds-for-youtube' ) ) );
|
||||
}
|
||||
if ( self::is_dev_url( home_url() ) ) {
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'url' => self::INSTALL_INSTRUCTIONS,
|
||||
)
|
||||
);
|
||||
}
|
||||
// Check license key.
|
||||
$license = ! empty( $_POST['license_key'] ) ? sanitize_key( $_POST['license_key'] ) : '';
|
||||
if ( empty( $license ) ) {
|
||||
wp_send_json_error( array( 'message' => esc_html__( 'You are not licensed.', 'feeds-for-youtube' ) ) );
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'edd_action' => 'check_license',
|
||||
'license' => $license,
|
||||
'item_name' => urlencode( SBY_PLUGIN_EDD_NAME ), // the name of our product in EDD
|
||||
);
|
||||
$url = add_query_arg( $args, SBY_STORE_URL );
|
||||
|
||||
$remote_request_args = array(
|
||||
'timeout' => '20',
|
||||
'headers' => array(
|
||||
'referer' => home_url(),
|
||||
)
|
||||
);
|
||||
|
||||
$response = wp_remote_get( $url, $remote_request_args );
|
||||
|
||||
if ( ! is_wp_error( $response ) ) {
|
||||
$body = wp_remote_retrieve_body( $response );
|
||||
|
||||
$license_data = json_decode( $body, true );
|
||||
|
||||
if ( empty( $license_data ) ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'message' => esc_html( self::get_error_message( $license_data ) ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( isset( $license_data['error'] ) && ! empty( $license_data['error'] ) ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'message' => self::get_error_message( $license_data ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( $license_data['license'] !== 'valid' ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'message' => self::get_error_message( $license_data ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
update_option( 'sby_license_key', $license );
|
||||
update_option( 'sby_license_data', $license_data );
|
||||
update_option( 'sby_license_status', $license_data['license'] );
|
||||
|
||||
// Redirect.
|
||||
$oth = hash( 'sha512', wp_rand() );
|
||||
$hashed_oth = hash_hmac( 'sha512', $oth, wp_salt() );
|
||||
|
||||
update_option( 'sby_one_click_upgrade', $oth );
|
||||
$version = '1.0';
|
||||
$version_info = self::get_version_info( $license_data, $license );
|
||||
$file = '';
|
||||
if ( isset( $version_info->package ) ) {
|
||||
$file = $version_info->package;
|
||||
}
|
||||
$siteurl = admin_url();
|
||||
$endpoint = admin_url( 'admin-ajax.php' );
|
||||
$redirect = admin_url( 'admin.php?page=' . self::REDIRECT );
|
||||
$url = add_query_arg(
|
||||
array(
|
||||
'key' => $license,
|
||||
'oth' => $hashed_oth,
|
||||
'endpoint' => $endpoint,
|
||||
'version' => $version,
|
||||
'siteurl' => $siteurl,
|
||||
'homeurl' => $home_url,
|
||||
'redirect' => rawurldecode( base64_encode( $redirect ) ),
|
||||
'file' => rawurldecode( base64_encode( $file ) ),
|
||||
'plugin_name' => self::NAME,
|
||||
),
|
||||
self::UPGRADE_URL
|
||||
);
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'url' => $url,
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
wp_send_json_error( array( 'message' => esc_html__( 'Could not connect.', 'feeds-for-youtube' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Endpoint for one-click upgrade.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public function install_upgrade() {
|
||||
$error = esc_html__( 'Could not install upgrade. Please download from smashballoon.com and install manually.', 'feeds-for-youtube' );
|
||||
// verify params present (oth & download link).
|
||||
$post_oth = ! empty( $_REQUEST['oth'] ) ? sanitize_text_field( $_REQUEST['oth'] ) : '';
|
||||
$post_url = ! empty( $_REQUEST['file'] ) ? $_REQUEST['file'] : '';
|
||||
|
||||
if ( empty( $post_oth ) || empty( $post_url ) ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
// Verify oth.
|
||||
$oth = get_option( 'sby_one_click_upgrade' );
|
||||
|
||||
if ( empty( $oth ) ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
if ( hash_hmac( 'sha512', $oth, wp_salt() ) !== $post_oth ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
// Delete so cannot replay.
|
||||
delete_option( 'sby_one_click_upgrade' );
|
||||
// Set the current screen to avoid undefined notices.
|
||||
set_current_screen( self::REDIRECT );
|
||||
// Prepare variables.
|
||||
$url = esc_url_raw(
|
||||
add_query_arg(
|
||||
array(
|
||||
'page' => self::REDIRECT,
|
||||
),
|
||||
admin_url( 'admin.php' )
|
||||
)
|
||||
);
|
||||
|
||||
// Verify pro not installed.
|
||||
$active = activate_plugin( self::SLUG, $url, false, true );
|
||||
if ( ! is_wp_error( $active ) ) {
|
||||
deactivate_plugins( plugin_basename( SBY_PLUGIN_DIR ) );
|
||||
wp_send_json_success( esc_html__( 'Plugin installed & activated.', 'feeds-for-youtube' ) );
|
||||
}
|
||||
|
||||
$creds = request_filesystem_credentials( $url, '', false, false, null );
|
||||
// Check for file system permissions.
|
||||
if ( false === $creds ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
if ( ! WP_Filesystem( $creds ) ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
// We do not need any extra credentials if we have gotten this far, so let's install the plugin.
|
||||
$license = get_option( 'sby_license_key' );
|
||||
if ( empty( $license ) ) {
|
||||
wp_send_json_error( new \WP_Error( '403', esc_html__( 'You are not licensed.', 'feeds-for-youtube' ) ) );
|
||||
}
|
||||
|
||||
// Do not allow WordPress to search/download translations, as this will break JS output.
|
||||
remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
|
||||
// Create the plugin upgrader with our custom skin.
|
||||
require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/Admin/PluginSilentUpgrader.php';
|
||||
require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/Admin/PluginSilentUpgraderSkin.php';
|
||||
require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/Admin/class-install-skin.php';
|
||||
$installer = new \SBY\Helpers\PluginSilentUpgrader( new \SBY_Install_Skin() );
|
||||
|
||||
// Error check.
|
||||
if ( ! method_exists( $installer, 'install' ) || empty( $post_url ) ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
$license_data = get_option( 'sby_license_data' );
|
||||
|
||||
if ( ! empty( $license_data ) ) {
|
||||
$version_info = self::get_version_info( $license_data );
|
||||
|
||||
$file = '';
|
||||
if ( isset( $version_info->package ) ) {
|
||||
$file = $version_info->package;
|
||||
}
|
||||
} else {
|
||||
wp_send_json_error( new \WP_Error( '403', esc_html__( 'You are not licensed.', 'feeds-for-youtube' ) ) );
|
||||
}
|
||||
|
||||
if ( ! empty( $file ) ) {
|
||||
|
||||
$installer->install( $file ); // phpcs:ignore
|
||||
// Check license key.
|
||||
// Flush the cache and return the newly installed plugin basename.
|
||||
wp_cache_flush();
|
||||
|
||||
$plugin_basename = $installer->plugin_info();
|
||||
|
||||
if ( $plugin_basename ) {
|
||||
deactivate_plugins( plugin_basename( SBY_PLUGIN_BASENAME ), true );
|
||||
|
||||
// Activate the plugin silently.
|
||||
$activated = activate_plugin( $plugin_basename );
|
||||
|
||||
if ( ! is_wp_error( $activated ) ) {
|
||||
wp_send_json_success( esc_html__( 'Plugin installed & activated.', 'feeds-for-youtube' ) );
|
||||
} else {
|
||||
// Reactivate the lite plugin if pro activation failed.
|
||||
$activated = activate_plugin( plugin_basename( SBY_PLUGIN_BASENAME ), '', false, true );
|
||||
wp_send_json_error( esc_html__( 'Pro version installed but needs to be activated from the Plugins page inside your WordPress admin.', 'feeds-for-youtube' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not it's likely to be a reachable URL for upgrade
|
||||
*
|
||||
* @param string $url
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public static function is_dev_url( $url = '' ) {
|
||||
$is_local_url = false;
|
||||
// Trim it up
|
||||
$url = strtolower( trim( $url ) );
|
||||
// Need to get the host...so let's add the scheme so we can use parse_url
|
||||
if ( false === strpos( $url, 'http://' ) && false === strpos( $url, 'https://' ) ) {
|
||||
$url = 'http://' . $url;
|
||||
}
|
||||
$url_parts = parse_url( $url );
|
||||
$host = ! empty( $url_parts['host'] ) ? $url_parts['host'] : false;
|
||||
if ( ! empty( $url ) && ! empty( $host ) ) {
|
||||
if ( false !== ip2long( $host ) ) {
|
||||
if ( ! filter_var( $host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
|
||||
$is_local_url = true;
|
||||
}
|
||||
} elseif ( 'localhost' === $host ) {
|
||||
$is_local_url = true;
|
||||
}
|
||||
|
||||
$tlds_to_check = array( '.local', ':8888', ':8080', ':8081', '.invalid', '.example', '.test' );
|
||||
foreach ( $tlds_to_check as $tld ) {
|
||||
if ( false !== strpos( $host, $tld ) ) {
|
||||
$is_local_url = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( substr_count( $host, '.' ) > 1 ) {
|
||||
$subdomains_to_check = array();
|
||||
foreach ( $subdomains_to_check as $subdomain ) {
|
||||
$subdomain = str_replace( '.', '(.)', $subdomain );
|
||||
$subdomain = str_replace( array( '*', '(.)' ), '(.*)', $subdomain );
|
||||
if ( preg_match( '/^(' . $subdomain . ')/', $host ) ) {
|
||||
$is_local_url = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $is_local_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle API Response and check for an error.
|
||||
*
|
||||
* @param array $response
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public static function get_error_message( $response ) {
|
||||
$message = '';
|
||||
if ( isset( $response['error'] ) ) {
|
||||
$error = sanitize_text_field( $response['error'] );
|
||||
switch ( $error ) {
|
||||
case 'expired':
|
||||
$message = __( 'This license is expired.', 'feeds-for-youtube' );
|
||||
break;
|
||||
default:
|
||||
$message = __( 'We encountered a problem unlocking the PRO features. Please install the PRO version manually.', 'feeds-for-youtube' );
|
||||
}
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
336
wp-content/plugins/youtube-feed-pro/inc/Blocks/SBY_Blocks.php
Normal file
336
wp-content/plugins/youtube-feed-pro/inc/Blocks/SBY_Blocks.php
Normal file
@@ -0,0 +1,336 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Blocks;
|
||||
|
||||
use Smashballoon\Customizer\DB;
|
||||
use Smashballoon\Customizer\Feed_Builder;
|
||||
use SmashBalloon\YouTubeFeed\Helpers\Util;
|
||||
use SmashBalloon\YouTubeFeed\Services\AssetsService;
|
||||
use SmashBalloon\YouTubeFeed\Services\LicenseNotification;
|
||||
use Smashballoon\Framework\Packages\Blocks\RecommendedBlocks;
|
||||
|
||||
/**
|
||||
* Instagram Feed block with live preview.
|
||||
*
|
||||
* @since 1.7.1
|
||||
*/
|
||||
class SBY_Blocks {
|
||||
|
||||
protected $db;
|
||||
protected $feed_builder;
|
||||
protected $license_service;
|
||||
|
||||
public function __construct( Feed_Builder $feed_builder, DB $db ) {
|
||||
$this->db = $db;
|
||||
$this->feed_builder = $feed_builder;
|
||||
$this->license_service = new LicenseNotification();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if current integration is allowed to load.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function allow_load() {
|
||||
return function_exists( 'register_block_type' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an integration.
|
||||
*
|
||||
* @since 1.7.1
|
||||
*/
|
||||
public function load() {
|
||||
$this->hooks();
|
||||
$recommended_blocks = new RecommendedBlocks();
|
||||
$recommended_blocks->setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Integration hooks.
|
||||
*
|
||||
* @since 1.7.1
|
||||
*/
|
||||
protected function hooks() {
|
||||
add_action( 'init', array( $this, 'register_block' ) );
|
||||
add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Instagram Feed Gutenberg block on the backend.
|
||||
*
|
||||
* @since 1.7.1
|
||||
*/
|
||||
public function register_block() {
|
||||
|
||||
wp_register_style(
|
||||
'sby-blocks-styles',
|
||||
trailingslashit( SBY_PLUGIN_URL ) . 'css/sby-blocks.css',
|
||||
array( 'wp-edit-blocks' ),
|
||||
SBYVER
|
||||
);
|
||||
|
||||
$attributes = array(
|
||||
'shortcodeSettings' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
'noNewChanges' => array(
|
||||
'type' => 'boolean',
|
||||
),
|
||||
'executed' => array(
|
||||
'type' => 'boolean',
|
||||
)
|
||||
);
|
||||
|
||||
register_block_type(
|
||||
'sby/sby-feed-block',
|
||||
array(
|
||||
'attributes' => $attributes,
|
||||
'render_callback' => array( $this, 'get_feed_html' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Instagram Feed Gutenberg block scripts.
|
||||
*
|
||||
* @since 1.7.1
|
||||
*/
|
||||
public function enqueue_block_editor_assets() {
|
||||
do_action('sby_enqueue_scripts', true);
|
||||
|
||||
wp_enqueue_style( 'sby-blocks-styles' );
|
||||
wp_enqueue_script(
|
||||
'sby-feed-block',
|
||||
trailingslashit( SBY_PLUGIN_URL ) . 'js/sby-blocks.js',
|
||||
array( 'wp-blocks', 'wp-i18n', 'wp-element' ),
|
||||
SBYVER,
|
||||
true
|
||||
);
|
||||
|
||||
$shortcode_settings = '';
|
||||
|
||||
$i18n = array(
|
||||
'addSettings' => esc_html__( 'Add Settings', 'feeds-for-youtube' ),
|
||||
'shortcodeSettings' => esc_html__( 'Shortcode Settings', 'feeds-for-youtube' ),
|
||||
'example' => esc_html__( 'Example', 'feeds-for-youtube' ),
|
||||
'preview' => esc_html__( 'Apply Changes', 'feeds-for-youtube' ),
|
||||
|
||||
);
|
||||
|
||||
if ( ! empty( $_GET['sby_wizard'] ) ) {
|
||||
$shortcode_settings = 'feed="' . (int) $_GET['sby_wizard'] . '"';
|
||||
}
|
||||
|
||||
wp_localize_script(
|
||||
'sby-feed-block',
|
||||
'sby_block_editor',
|
||||
array(
|
||||
'wpnonce' => wp_create_nonce( 'sby-blocks' ),
|
||||
'canShowFeed' => true,
|
||||
'shortcodeSettings' => $shortcode_settings,
|
||||
'i18n' => $i18n,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get form HTML to display in a Instagram Feed Gutenberg block.
|
||||
*
|
||||
* @param array $attr Attributes passed by Instagram Feed Gutenberg block.
|
||||
*
|
||||
* @since 1.7.1
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_feed_html( $attr ) {
|
||||
$feeds_count = $this->db->feeds_count();
|
||||
$shortcode_settings = isset( $attr['shortcodeSettings'] ) ? $attr['shortcodeSettings'] : '';
|
||||
|
||||
if ( $feeds_count <= 0 ) {
|
||||
return $this->plain_block_design( empty( Util::get_license_key() ) ? 'inactive' : 'expired' );
|
||||
}
|
||||
|
||||
$return = '';
|
||||
$return .= $this->get_license_expired_notice();
|
||||
|
||||
$statuses = get_option( 'sby_statuses', array() );
|
||||
|
||||
if ( empty( $statuses['support_legacy_shortcode'] ) ) {
|
||||
if ( empty( $shortcode_settings ) || strpos( $shortcode_settings, 'feed=' ) === false ) {
|
||||
$feeds = $this->feed_builder->get_feed_list();
|
||||
if ( ! empty( $feeds[0]['id'] ) ) {
|
||||
$shortcode_settings = 'feed="' . (int) $feeds[0]['id'] . '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$shortcode_settings = str_replace(array( '[youtube-feed', ']' ), '', $shortcode_settings );
|
||||
|
||||
$return .= do_shortcode( '[youtube-feed '.$shortcode_settings.']' );
|
||||
|
||||
return $return;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Plain block design when theres no feeds.
|
||||
*
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public function plain_block_design( $license_state = 'expired' ) {
|
||||
if ( !is_admin() && !defined( 'REST_REQUEST' ) ) {
|
||||
return;
|
||||
}
|
||||
$other_plugins = $this->get_others_plugins();
|
||||
|
||||
$icons = sby_builder_pro()->builder_svg_icons();
|
||||
$output = '<div class="sby-license-expired-plain-block-wrapper '. $license_state .'">
|
||||
<div class="sby-lepb-header">
|
||||
<div class="sb-left">';
|
||||
$output .= $icons['info'];
|
||||
|
||||
if ( $license_state == 'expired' ) {
|
||||
$output .= sprintf('<p>%s</p>', __('Your license has expired! Renew it to reactivate Pro features.', 'feeds-for-youtube'));
|
||||
} else {
|
||||
$output .= sprintf('<p>%s</p>', __('Your license key is inactive. Activate it to enable Pro features.', 'feeds-for-youtube'));
|
||||
}
|
||||
|
||||
$output .= '</div>
|
||||
<div class="sb-right">
|
||||
<a href="'. $this->license_service->get_renew_url() .'">
|
||||
Resolve Now
|
||||
'. $icons['chevronRight'] .'
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sby-lepb-body">
|
||||
'. $icons['blockEditorSBYLogo'] .'
|
||||
<p class="sby-block-body-title">Get started with your first feed from <br/> your YouTube Channel</p>';
|
||||
|
||||
$output .= sprintf(
|
||||
'<a href="%s" class="sby-btn sby-btn-blue">%s '. $icons['chevronRight'] .'</a>',
|
||||
admin_url('admin.php?page=sby-feed-builder'),
|
||||
__('Create a YouTube Feeds', 'feeds-for-youtube')
|
||||
);
|
||||
$output .= '</div>
|
||||
<div class="sby-lepd-footer">
|
||||
<p class="sby-lepd-footer-title">Did you know? </p>
|
||||
<p>You can add posts from '. $other_plugins .' using our free plugins</p>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get other Smash Balloon plugins list
|
||||
*
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public function get_others_plugins() {
|
||||
$active_plugins = sby_get_active_plugins_info();
|
||||
|
||||
$other_plugins = array(
|
||||
'is_instagram_installed' => array(
|
||||
'title' => 'Instagram',
|
||||
'url' => 'https://smashballoon.com/instagram-feed/?utm_campaign=youtube-pro&utm_source=block-feed-embed&utm_medium=did-you-know',
|
||||
),
|
||||
'is_facebook_installed' => array(
|
||||
'title' => 'Facebook',
|
||||
'url' => 'https://smashballoon.com/custom-facebook-feed/?utm_campaign=youtube-pro&utm_source=block-feed-embed&utm_medium=did-you-know',
|
||||
),
|
||||
'is_twitter_installed' => array(
|
||||
'title' => 'Twitter',
|
||||
'url' => 'https://smashballoon.com/custom-twitter-feeds/?utm_campaign=youtube-pro&utm_source=block-feed-embed&utm_medium=did-you-know',
|
||||
),
|
||||
'is_youtube_installed' => array(
|
||||
'title' => 'YouTube',
|
||||
'url' => 'https://smashballoon.com/youtube-feed/?utm_campaign=youtube-pro&utm_source=block-feed-embed&utm_medium=did-you-know',
|
||||
),
|
||||
);
|
||||
|
||||
if ( ! empty( $active_plugins ) ) {
|
||||
foreach ( $active_plugins as $name => $plugin ) {
|
||||
if ( $plugin != false ) {
|
||||
unset( $other_plugins[$name] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$other_plugins_html = array();
|
||||
foreach( $other_plugins as $plugin ) {
|
||||
$other_plugins_html[] = '<a href="'. $plugin['url'] .'">'. $plugin['title'] .'</a>';
|
||||
}
|
||||
|
||||
return \implode(", ", $other_plugins_html);
|
||||
}
|
||||
|
||||
public function get_license_expired_notice() {
|
||||
// Check that the license exists and the user hasn't already clicked to ignore the message
|
||||
if ( empty( Util::get_license_key() ) ) {
|
||||
return $this->get_license_expired_notice_content( 'inactive' );
|
||||
}
|
||||
// If license not expired then return;
|
||||
if ( !Util::is_license_expired() ) {
|
||||
return;
|
||||
}
|
||||
// Grace period ended?
|
||||
if ( !Util::is_license_grace_period_ended( true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->get_license_expired_notice_content();
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the license expired notice content on top of the embed block
|
||||
*
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public function get_license_expired_notice_content( $license_state = 'expired' ) {
|
||||
if ( !is_admin() && !defined( 'REST_REQUEST' ) ) {
|
||||
return;
|
||||
}
|
||||
$icons = sby_builder_pro()->builder_svg_icons();
|
||||
|
||||
$output = '<div class="sby-block-license-expired-notice-ctn sby-bln-license-state-'. $license_state .'">';
|
||||
$output .= '<div class="sby-blen-header">';
|
||||
$output .= $icons['eye2'];
|
||||
$output .= '<span>' . __('Only Visible to WordPress Admins', 'feeds-for-youtube') . '</span>';
|
||||
$output .= '</div>';
|
||||
$output .= '<div class="sby-blen-resolve">';
|
||||
$output .= '<div class="sby-left">';
|
||||
$output .= $icons['info'];
|
||||
if ( $license_state == 'inactive' ) {
|
||||
$output .= '<span>' . __('Your license key is inactive. Activate it to enable Pro features.', 'feeds-for-youtube') . '</span>';
|
||||
} else {
|
||||
$output .= '<span>' . __('Your license has expired! Renew it to reactivate Pro features.', 'feeds-for-youtube') . '</span>';
|
||||
}
|
||||
$output .= '</div>';
|
||||
$output .= '<div class="sby-right">';
|
||||
$output .= '<a href="'. $this->license_service->get_renew_url() .'" target="_blank">'. __('Resolve Now', 'feeds-for-youtube') .'</a>';
|
||||
$output .= $icons['chevronRight'];
|
||||
$output .= '</div>';
|
||||
$output .= '</div>';
|
||||
$output .= '</div>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking if is Gutenberg REST API call.
|
||||
*
|
||||
* @since 1.7.1
|
||||
*
|
||||
* @return bool True if is Gutenberg REST API call.
|
||||
*/
|
||||
public static function is_gb_editor() {
|
||||
|
||||
// TODO: Find a better way to check if is GB editor API call.
|
||||
return defined( 'REST_REQUEST' ) && REST_REQUEST && ! empty( $_REQUEST['context'] ) && 'edit' === $_REQUEST['context']; // phpcs:ignore
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Action Button Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Actionbutton_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'actionbutton';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<button class="sb-control-action-button sb-btn sby-yt-fs sb-btn-grey">
|
||||
<div v-if="control.buttonIcon" v-html="svgIcons[control.buttonIcon]"></div>
|
||||
<span class="sb-small-p sb-bold sb-dark-text">{{control.label}}</span>
|
||||
</button>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* CheckBox Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Checkbox_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'checkbox';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-checkbox-ctn sby-yt-fs" @click.prevent.default="(control.custom != undefined && control.custom == 'feedtype') ? changeCheckboxSectionValue('type', control.value, 'feedFlyPreview') : changeSwitcherSettingValue(control.id, control.options.enabled, control.options.disabled, control.ajaxAction != undefined ? control.ajaxAction : false)">
|
||||
<div class="sb-control-checkbox" :data-active="(control.custom != undefined && control.custom == 'feedtype') ? <?php echo $controlEditingTypeModel; ?>['type'].includes(control.value) : <?php echo $controlEditingTypeModel; ?>[control.id] == control.options.enabled"></div>
|
||||
<div class="sb-control-label">{{control.label}}</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* CheckBox List Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Checkboxlist_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'checkboxlist';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-checkbox-ctn sby-yt-fs" v-for="option in control.options" @click.prevent.default="changeCheckboxListValue(control.id, option.value)">
|
||||
<div class="sb-control-checkbox" :data-active="<?php echo $controlEditingTypeModel; ?>[control.id].includes(option.value)"></div>
|
||||
<div class="sb-control-label sb-small-p sb-dark-text" v-html="option.label"></div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* CheckBox Section Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Checkboxsection_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'checkboxsection';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return HTML
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-checkboxsection-header" v-if="control.header">
|
||||
<div class="sb-control-checkboxsection-name">
|
||||
<div v-html="svgIcons['preview']"></div>
|
||||
<strong class="">{{genericText.name}}</strong>
|
||||
</div>
|
||||
<strong>{{genericText.edit}}</strong>
|
||||
</div>
|
||||
<div class="sb-control-checkbox-ctn sby-yt-fs" @click.prevent.default="switchNestedSection(control.section.id, control.section)">
|
||||
<div class="sb-control-checkbox-hover sb-tr-2"></div>
|
||||
<div class="sb-control-checkbox" @click.stop.prevent.default="changeCheckboxSectionValue(control.id, control.value)" :data-active="checkboxSectionValueExists(control.id, control.value)"></div>
|
||||
<div class="sby-yt-fs" :data-active="checkboxSectionValueExists(control.id, control.value)">
|
||||
<strong class="sb-control-label">{{control.label}}</strong>
|
||||
</div>
|
||||
<div class="sb-control-checkboxsection-btn"></div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Color Override Field Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Coloroverride_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'coloroverride';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-input-ctn sby-yt-fs sb-control-coloroverride-ctn">
|
||||
<div class="sb-control-coloroverride-content">
|
||||
<div class="sb-control-coloroverride-txt" v-html="<?php echo $controlEditingTypeModel; ?>[control.id]"></div>
|
||||
<div class="sb-control-coloroverride-swatch" :style="'background:'+<?php echo $controlEditingTypeModel; ?>[control.id]"></div>
|
||||
</div>
|
||||
<div class="sb-control-colorpicker-btn" @click.prevent.default="resetColorOverride(control.id)">{{genericText.reset}}</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Color Picker Field Control
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Colorpicker_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 4.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'colorpicker';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 4.0
|
||||
* @access public
|
||||
*
|
||||
* @return HTML
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-input-ctn sby-yt-fs sb-control-colorpicker-ctn" :data-picker-style="control.pickerType ? control.pickerType : 'default'" @click.stop="showColorPickerPospup(control.id)" v-on-clickaway="hideColorPickerPopup()">
|
||||
<!--<sbi-colorpicker :color="<?php echo $controlEditingTypeModel; ?>[control.id]" v-on:change="changeSettingValue(control.id,...arguments)" :control-id="control.id"></sbi-colorpicker>-->
|
||||
<input class="sb-control-input" placeholder="Select" type="text" v-model="<?php echo $controlEditingTypeModel; ?>[control.id]">
|
||||
<div class="sb-control-colorpicker-swatch" :style="'background:'+<?php echo $controlEditingTypeModel; ?>[control.id]+';'"></div>
|
||||
<div class="sb-control-colorpicker-popup" v-show="customizerScreens.activeColorPicker == control.id">
|
||||
<sketch-picker
|
||||
@input="updateColorValue(control.id)"
|
||||
v-model="<?php echo $controlEditingTypeModel; ?>[control.id]"
|
||||
:value="<?php echo $controlEditingTypeModel; ?>[control.id]"
|
||||
:preset-colors="['#fff','#000','#e92b2b','#ffc104','#31e92b','#2b4ee9','#a72be9','#e92b82']"
|
||||
></sketch-picker>
|
||||
<button class="sb-control-action-button sb-colorpicker-reset-btn sb-btn sby-yt-fs sb-btn-grey" @click.prevent.default="resetColor(control.id)">
|
||||
<div v-html="svgIcons['update']"></div>
|
||||
<span>{{genericText.reset}}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="sb-control-colorpicker-btn" v-if="control.pickerType == 'reset'">{{genericText.reset}}</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder Control Base
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
abstract class SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get control info.
|
||||
*
|
||||
* Getting the Control information []
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_info() {
|
||||
return array(
|
||||
'id' => '',
|
||||
'type' => '',
|
||||
'modelname' => '',
|
||||
'layout' => 'full',
|
||||
'reverse' => 'false',
|
||||
'default' => '',
|
||||
'seperator' => 'none',
|
||||
'heading' => '',
|
||||
'description' => '',
|
||||
'tooltip' => '',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Control Output
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {}
|
||||
|
||||
/**
|
||||
* Getting Editing Control Type
|
||||
*
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public function get_control_edit_type( $editingType ) {
|
||||
switch ( $editingType ) {
|
||||
case 'settings':
|
||||
return 'customizerFeedData.settings';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Control HTML.
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return HTML
|
||||
*/
|
||||
public function print_control_wrapper( $editingType ) {
|
||||
$control_type = $this->get_type();
|
||||
$controlEditingTypeModel = $this->get_control_edit_type( $editingType );
|
||||
?>
|
||||
|
||||
<div class="sb-control-elem-ctn sby-yt-fs" v-if="control.type == '<?php echo $control_type; ?>'"
|
||||
v-show="isControlShown(control)"
|
||||
:data-child="control.child ? 'true' : false"
|
||||
:data-separator="control.separator != undefined ? control.separator : 'none'"
|
||||
:data-type="control.type" :data-layout="control.layout == undefined ? 'block' : 'half'"
|
||||
:data-reverse="control.reverse != undefined ? 'true' : 'false'" :data-stacked="control.stacked ? 'true' : 'false'"
|
||||
:data-heading="control.strongHeading != undefined && control.strongHeading != 'true' ? '' : 'strong'"
|
||||
:data-disabled="control.disabledInput != undefined ? isControlShown(control) : false"
|
||||
:data-switcher-top="control.switcherTop != undefined ? 'true' : false"
|
||||
>
|
||||
|
||||
<div class="sb-control-elem-overlay"
|
||||
v-show="control.condition != undefined || control.checkExtension != undefined || control.checkExtensionDimmed != undefined ? !checkControlCondition(control.condition, control.checkExtension, control.checkExtensionDimmed) : false"
|
||||
@click.prevent.default="control.checkExtensionPopup != undefined && !checkExtensionActive(control.checkExtensionPopup) ? viewsActive.extensionsPopupElement = control.checkExtensionPopup : false"
|
||||
:class="control.checkExtensionPopup != undefined && !checkExtensionActive(control.checkExtensionPopup) ? 'sb-cursor-pointer' : ''"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="sb-control-elem-label" v-if="(control.heading == undefined && control.description == undefined) ? false : true && control.type != 'customview'">
|
||||
<div class="sb-control-elem-label-title sby-yt-fs">
|
||||
<div v-if="control.icon != undefined" class="sb-control-elem-icon" v-html="svgIcons[control.icon]"></div>
|
||||
<div class="sb-control-elem-heading sb-small-p sb-dark-text" :data-underline="control.underline" :class="control.enableViewAction != undefined && control.enableViewAction != false ? 'sb-cursor-pointer' : ''" v-html="control.heading" @click.prevent.default="control.enableViewAction != undefined && control.enableViewAction != false ? switchNestedSection(control.enableViewAction, null ) : false"></div>
|
||||
<div class="sb-control-elem-tltp" v-if="control.tooltip != undefined" @mouseover.prevent.default="toggleElementTooltip(control.tooltip, 'show', control.tooltipAlign ? control.tooltipAlign : 'center' )" @mouseleave.prevent.default="toggleElementTooltip('', 'hide')">
|
||||
<div class="sb-control-elem-tltp-icon" v-html="svgIcons['info']"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sb-control-elem-description" v-if="control.descriptionPosition != 'bottom'" v-html="control.description"></div>
|
||||
</div>
|
||||
<div class="sb-control-elem-output">
|
||||
<?php $this->get_control_output( $controlEditingTypeModel ); ?>
|
||||
<div class="sb-control-elem-description" v-if="control.descriptionPosition != undefined && control.descriptionPosition == 'bottom'" v-html="control.description"></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Custom View
|
||||
* This control will used for custom HTMlL controls like (source, feed type...)
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Customview_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'customview';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
$this->get_control_sources_output( $controlEditingTypeModel );
|
||||
$this->get_control_shoppable_disabled_output( $controlEditingTypeModel );
|
||||
$this->get_control_shoppable_enabled_output( $controlEditingTypeModel );
|
||||
$this->get_control_shoppable_selected_post_output( $controlEditingTypeModel );
|
||||
$this->get_control_moderation_mode_output( $controlEditingTypeModel );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shoppable Feed Disabled Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_shoppable_disabled_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-shoppbale-disabled-ctn sb-control-imginfo-ctn" v-if="control.viewId == 'shoppabledisabled'">
|
||||
<div class="sb-control-imginfo-elem sby-yt-fs">
|
||||
<div class="sb-control-imginfo-icon sby-yt-fs" v-html="svgIcons['shoppableDisabled']"></div>
|
||||
<div class="sb-control-imginfo-text sby-yt-fs" data-textalign="left">
|
||||
<strong class="sb-bold sb-dark-text " v-html="customizeScreensText.shoppableFeedScreen.heading1"></strong>
|
||||
<span v-html="customizeScreensText.shoppableFeedScreen.description1"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shoppable Feed Enabled Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_shoppable_enabled_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-shoppbale-enbaled-ctn sb-control-imginfo-ctn" v-if="control.viewId == 'shoppableenabled'">
|
||||
<div class="sb-control-imginfo-elem sby-yt-fs">
|
||||
<div class="sb-control-imginfo-icon sby-yt-fs" v-html="svgIcons['shoppableEnabled']"></div>
|
||||
<div class="sb-control-imginfo-text sby-yt-fs" data-textalign="center">
|
||||
<strong class="sb-bold sb-dark-text " v-html="customizeScreensText.shoppableFeedScreen.heading2"></strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shoppable Feed Selected Post
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_shoppable_selected_post_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-shoppbale-selectedpost-ctn" v-if="control.viewId == 'shoppableselectedpost' && shoppableFeed.postId != null">
|
||||
<strong v-html="genericText.selectedPost"></strong>
|
||||
<div class="sb-control-selectedpost-info sby-yt-fs">
|
||||
<img :src="shoppableFeed.postMedia" alt="Selected Shoppable">
|
||||
<span v-html="shoppableFeed.postCaption"></span>
|
||||
</div>
|
||||
<div class="sb-control-selectedpost-input sby-yt-fs">
|
||||
<span class="sby-yt-fs" v-html="genericText.productLink"></span>
|
||||
<input type="text" class="sb-control-input sby-yt-fs" v-model="shoppableFeed.postShoppableUrl" :placeholder="genericText.enterProductLink">
|
||||
</div>
|
||||
<div class="sb-control-selectedpost-btns sby-yt-fs">
|
||||
<button class="sb-shoppable-selectedpost-btn sbi-btn-grey" @click.prevent.default="addPostShoppableFeed()">
|
||||
<div v-html="svgIcons['checkmark']"></div>
|
||||
<span v-html="genericText.add"></span>
|
||||
</button>
|
||||
<button class="sb-shoppable-selectedpost-btn sbi-btn-grey" @click.prevent.default="cancelPostShoppableFeed()">
|
||||
<span v-html="genericText.cancel"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sources Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return HTML
|
||||
*/
|
||||
public function get_control_sources_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-feedtype-ctn" v-if="control.viewId == 'sources'">
|
||||
|
||||
<div class="sb-control-feedtype-item sby-yt-fs" v-for="(feedType, feedTypeID) in selectSourceScreen.multipleTypes" v-if="checkMultipleFeedTypeActiveCustomizer(feedTypeID)">
|
||||
|
||||
<div class="sb-control-elem-label-title sby-yt-fs">
|
||||
<div class="sb-control-elem-heading sb-small-p sb-dark-text" v-html="feedType.heading"></div>
|
||||
<div class="sb-control-elem-tltp" @mouseover.prevent.default="toggleElementTooltip(feedType.description, 'show', 'center' )" @mouseleave.prevent.default="toggleElementTooltip('', 'hide')">
|
||||
<div class="sb-control-elem-tltp-icon" v-html="svgIcons['info']"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-control-feedtype-list sby-yt-fs">
|
||||
<div class="sb-control-feedtype-list-item" v-for="selectedSource in returnSelectedSourcesByTypeCustomizer(feedTypeID)">
|
||||
<div class="sb-control-feedtype-list-item-icon" v-html="feedTypeID == 'hashtag' ? svgIcons['hashtag'] : svgIcons['user']"></div>
|
||||
<span v-html="feedTypeID == 'hashtag' ? selectedSource : selectedSource.username"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<button class="sb-control-action-button sb-btn sb-btn-grey sby-yt-fs" @click.prevent.default="openFeedTypesPopupCustomizer()">
|
||||
<div v-html="svgIcons['edit']"></div>
|
||||
<span>{{genericText.editSources}}</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Moderation Mode Ouptut
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_moderation_mode_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-moderationmode-ctn" v-if="control.viewId == 'moderationmode'">
|
||||
<button class="sb-control-moderationmode-btn sb-btn sb-btn-right-icon sb-btn-grey sby-yt-fs" v-if="!viewsActive.moderationMode" @click.prevent.default="openModerationMode()">
|
||||
<div class="sb-btn-right-txt">
|
||||
<div v-html="svgIcons['eye1']"></div>
|
||||
<span>{{genericText.moderateFeed}}</span>
|
||||
</div>
|
||||
<div class="sb-btn-right-chevron"></div>
|
||||
</button>
|
||||
|
||||
<div class="sb-control-moderationmode-elements sby-yt-fs" v-if="viewsActive.moderationMode">
|
||||
|
||||
<div class="sb-control-switcher-ctn" :data-active="<?php echo $controlEditingTypeModel; ?>[control.switcher.id] === control.switcher.options.enabled" @click.prevent.default="changeSwitcherSettingValue(control.switcher.id, control.switcher.options.enabled, control.switcher.options.disabled, control.switcher.ajaxAction ? control.switcher.ajaxAction : false)">
|
||||
<div class="sb-control-switcher sb-tr-2"></div>
|
||||
<div class="sb-control-label" v-if="control.switcher.label" :data-title="control.switcher.labelStrong ? 'true' : false">{{control.switcher.label}}</div>
|
||||
</div>
|
||||
|
||||
<div v-if="<?php echo $controlEditingTypeModel; ?>[control.switcher.id] == control.switcher.options.enabled">
|
||||
<div class="sb-control-moderatiomode-selement sby-yt-fs sb-control-before-brd">
|
||||
<div class="sb-control-elem-label-title sby-yt-fs">
|
||||
<div class="sb-control-elem-heading sb-small-p sb-dark-text">{{genericText.moderationMode}}</div>
|
||||
</div>
|
||||
<div class="sb-control-toggle-set-ctn sb-control-toggle-set-desc-ctn sby-yt-fs">
|
||||
<div class="sb-control-toggle-elm sby-yt-fs sb-tr-2" v-for="(moderationItem, moderationId) in control.moderationTypes " @click.prevent.default="switchModerationListType(moderationId)" :data-active="moderationSettings.list_type_selected == moderationId">
|
||||
<div class="sb-control-toggle-deco sb-tr-1"></div>
|
||||
<div class="sb-control-content">
|
||||
<div class="sb-control-label">{{moderationItem.label}}</div>
|
||||
<div class="sb-control-toggle-description">{{moderationItem.description}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-control-moderatiomode-selement sby-yt-fs sb-control-before-brd">
|
||||
<div class="sb-control-elem-label-title sby-yt-fs">
|
||||
<div class="sb-control-elem-heading sb-small-p sb-dark-text">{{genericText.moderationModeEnterPostId}}</div>
|
||||
</div>
|
||||
<div class="sby-yt-fs">
|
||||
<textarea class="sb-control-input-textrea sby-yt-fs" v-model="customBlockModerationlistTemp" :placeholder="genericText.moderationModeTextareaPlaceholder"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-control-moderationmode-action-btns sb-control-before-brd sby-yt-fs">
|
||||
<button class="sb-btn sb-btn-blue sby-yt-fs" @click.prevent.default="saveModerationSettings()">
|
||||
<div class="sbi-fb-icon-success"></div>
|
||||
{{genericText.moderateFeedSaveExit}}
|
||||
</button>
|
||||
<button class="sb-btn sb-btn-grey sby-yt-fs" @click.prevent.default="activateView('moderationMode'); moderationShoppableMode = false;">
|
||||
<div class="sbi-fb-icon-cancel"></div>
|
||||
{{genericText.cancel}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Date Picker Field Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Datepicker_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'datepicker';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-input-ctn sby-yt-fs">
|
||||
<input type="date" class="sb-control-input sby-yt-fs" v-model="<?php echo $controlEditingTypeModel; ?>[control.id]" @change.prevent.default="changeSettingValue(control.id, false,false, control.ajaxAction ? control.ajaxAction : false)" :placeholder="control.placeholder ? control.placeholder : ''">
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Heading Text Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Heading_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'heading';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Hidden Field Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Hidden_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'hidden';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-input-ctn sby-yt-fs">
|
||||
<input type="hidden" v-model="<?php echo $controlEditingTypeModel; ?>[control.id]">
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Image Chooser Field Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Imagechooser_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'imagechooser';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-imagechooser-ctn sby-yt-fs">
|
||||
<div class="sby-yt-fs">
|
||||
<input type="text" class="sb-control-imagechooser-input sby-yt-fs" :class="checkNotEmpty(<?php echo $controlEditingTypeModel; ?>[control.id]) ? 'sb-control-imagechooser-padding' : ''" v-model="<?php echo $controlEditingTypeModel; ?>[control.id]" :placeholder="control.placeholder ? control.placeholder : <?php echo $controlEditingTypeModel; ?>[control.id]" disabled>
|
||||
<div class="sb-control-imagechooser-clear sbi-fb-tltp-parent" v-if="checkNotEmpty(<?php echo $controlEditingTypeModel; ?>[control.id])">
|
||||
<div class="sb-control-imagechooser-clear-icon" @click.prevent.default="changeSettingValue(control.id, '')"></div>
|
||||
<div class="sbi-fb-tltp-elem"><span>{{genericText.clear.replace(/ /g," ")}}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sb-control-imagechooser-btn" @click.prevent.default="imageChooser( control.id )">
|
||||
<div v-html="svgIcons['imageChooser']"></div>
|
||||
<span v-html="checkNotEmpty(<?php echo $controlEditingTypeModel ?>[control.id]) ? genericText.change : genericText.addImage.replace(/ /g,' ')"></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Number Field Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Number_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'number';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-input-ctn sby-yt-fs" :data-contains-suffix="control.fieldSuffix !== undefined ? 'true' : 'false'">
|
||||
<div class="sb-control-input-info" :class="control.fieldPrefixAction != undefined ? 'sb-cursor-pointer' : ''" v-if="control.fieldPrefix" @click.prevent.default="control.fieldPrefixAction != undefined ? fieldCustomClickAction(control.fieldPrefixAction) : false">{{control.fieldPrefix.replace(/ /g," ")}}</div>
|
||||
<input type="number" class="sb-control-input sby-yt-fs" :placeholder="control.placeholder ? control.placeholder : ''" :step="control.step ? control.step : 1" :max="control.max ? control.max : 1000" :min="control.min ? control.min : 0" v-model="<?php echo $controlEditingTypeModel; ?>[control.id]" @change.prevent.default="changeSettingValue(control.id,false,false, control.ajaxAction ? control.ajaxAction : false)">
|
||||
<div class="sb-control-input-info" :class="control.fieldSuffixAction != undefined ? 'sb-cursor-pointer' : ''" v-if="control.fieldSuffix" @click.prevent.default="control.fieldSuffixAction != undefined ? fieldCustomClickAction(control.fieldSuffixAction) : false">{{control.fieldSuffix.replace(/ /g," ")}}</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Select Field Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Select_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'select';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-input-ctn sby-yt-fs">
|
||||
<select class="sb-control-input sby-yt-fs" v-model="<?php echo $controlEditingTypeModel; ?>[control.id]" @change.prevent.default="changeSettingValue(control.id,false,false, control.ajaxAction ? control.ajaxAction : false)">
|
||||
<option v-for="(opName, opValue) in control.options" :value="opValue">{{opName}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Separator Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Separator_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'separator';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-elem-separator sby-yt-fs" :style="'margin-top:'+ (control.top ? control.top : 0) +'px;margin-bottom:'+ (control.bottom ? control.bottom : 0) +'px;'"></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Switcher Field Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Switcher_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'switcher';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-switcher-ctn" :data-active="<?php echo $controlEditingTypeModel; ?>[control.id] == control.options.enabled" @click.prevent.default="changeSwitcherSettingValue(control.id, control.options.enabled, control.options.disabled, control.ajaxAction ? control.ajaxAction : false)">
|
||||
<div class="sb-control-switcher sb-tr-2"></div>
|
||||
<div class="sb-control-label" v-if="control.label" :data-title="control.labelStrong ? 'true' : false">{{control.label}}</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Text Field Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Text_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-input-ctn sby-yt-fs">
|
||||
<div class="sb-control-input-info" v-if="control.fieldPrefix">{{control.fieldPrefix.replace(/ /g," ")}}</div>
|
||||
<input type="text" class="sb-control-input sby-yt-fs" v-model="<?php echo $controlEditingTypeModel; ?>[control.id]" @change.prevent.default="changeSettingValue(control.id, false,false, control.ajaxAction ? control.ajaxAction : false)" :placeholder="control.placeholder ? control.placeholder : ''">
|
||||
<div class="sb-control-input-info" v-if="control.fieldSuffix">{{control.fieldSuffix.replace(/ /g," ")}}</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* TextArea Field Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Textarea_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'textarea';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-textarea-ctn sby-yt-fs">
|
||||
<textarea class="sb-control-input-textrea sby-yt-fs" v-model="<?php echo $controlEditingTypeModel; ?>[control.id]" :placeholder="control.placeholder ? control.placeholder : ''" @focusout.prevent.default="changeSettingValue(false,false,false, control.ajaxAction ? control.ajaxAction : false)"></textarea>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Toggle Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Toggle_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'toggle';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-toggle-ctn sby-yt-fs">
|
||||
<div class="sb-control-toggle-elm sby-yt-fs sb-tr-2" data-active="true">
|
||||
<div class="sb-control-toggle-deco sb-tr-1"></div>
|
||||
<div class="sb-control-toggle-icon" v-if="control.toggle.icon" v-html="svgIcons[control.toggle.icon]"></div>
|
||||
<div class="sb-control-label">{{control.toggle.label}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Toggle Buttons
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Togglebutton_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'togglebutton';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-togglebutton-ctn sby-yt-fs">
|
||||
<div class="sb-control-togglebutton-elm sby-yt-fs sb-tr-1" v-for="toggle in control.options" :data-active="<?php echo $controlEditingTypeModel; ?>[control.id] == toggle.value" v-show="toggle.condition != undefined ? checkControlCondition(toggle.condition) : true" @click.prevent.default="changeSettingValue(control.id,toggle.value, true)" >
|
||||
{{toggle.label}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
* Toggle Set Control
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Controls;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Toggleset_Control extends SB_Controls_Base {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Getting the Control Type
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'toggleset';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Control
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_control_output( $controlEditingTypeModel ) {
|
||||
?>
|
||||
<div class="sb-control-toggle-set-ctn sby-yt-fs">
|
||||
<div class="sb-control-toggle-elm sby-yt-fs sb-tr-2" v-for="toggle in control.options" :data-active="<?php echo $controlEditingTypeModel; ?>[control.id] == toggle.value" @click.prevent.default="changeSettingValue(control.id,toggle.value, toggle.checkExtension != undefined ? checkExtensionActive(toggle.checkExtension) : true, control.ajaxAction != undefined ? control.ajaxAction : false)" v-show="toggle.condition != undefined ? checkControlCondition(toggle.condition) : true" :data-disabled="toggle.checkExtension != undefined ? !checkExtensionActive(toggle.checkExtension) : false">
|
||||
<div class="sb-control-toggle-extension-cover" v-show="toggle.checkExtension != undefined && !checkExtensionActive(toggle.checkExtension)"></div>
|
||||
<div class="sb-control-toggle-deco sb-tr-1"></div>
|
||||
<div class="sb-control-toggle-icon" v-if="toggle.icon" v-html="svgIcons[toggle.icon]"></div>
|
||||
<div class="sb-control-label">{{toggle.label}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
935
wp-content/plugins/youtube-feed-pro/inc/Builder/SBY_Db.php
Normal file
935
wp-content/plugins/youtube-feed-pro/inc/Builder/SBY_Db.php
Normal file
@@ -0,0 +1,935 @@
|
||||
<?php
|
||||
/**
|
||||
* YouTube Feeds Database
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Builder;
|
||||
|
||||
class SBY_Db {
|
||||
|
||||
const RESULTS_PER_PAGE = 20;
|
||||
|
||||
const RESULTS_PER_CRON_UPDATE = 14;
|
||||
|
||||
/**
|
||||
* Query the sbi_sources table
|
||||
*
|
||||
* @param array $args
|
||||
*
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function source_query( $args = array() ) {
|
||||
global $wpdb;
|
||||
$sources_table_name = $wpdb->prefix . 'sbi_sources';
|
||||
$feeds_table_name = $wpdb->prefix . 'sby_feeds';
|
||||
|
||||
$page = 0;
|
||||
if ( isset( $args['page'] ) ) {
|
||||
$page = (int) $args['page'] - 1;
|
||||
unset( $args['page'] );
|
||||
}
|
||||
|
||||
$offset = max( 0, $page * self::RESULTS_PER_PAGE );
|
||||
|
||||
if ( empty( $args ) ) {
|
||||
|
||||
$limit = (int) self::RESULTS_PER_PAGE;
|
||||
$sql = "SELECT s.id, s.account_id, s.account_type, s.privilege, s.access_token, s.username, s.info, s.error, s.expires, count(f.id) as used_in
|
||||
FROM $sources_table_name s
|
||||
LEFT JOIN $feeds_table_name f ON f.settings LIKE CONCAT('%', s.account_id, '%')
|
||||
GROUP BY s.id, s.account_id
|
||||
LIMIT $limit
|
||||
OFFSET $offset;
|
||||
";
|
||||
|
||||
$results = $wpdb->get_results( $sql, ARRAY_A );
|
||||
|
||||
if ( empty( $results ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
foreach ( $results as $result ) {
|
||||
if ( (int) $result['used_in'] > 0 ) {
|
||||
$account_id = sanitize_key( $result['account_id'] );
|
||||
$sql = "SELECT *
|
||||
FROM $feeds_table_name
|
||||
WHERE settings LIKE CONCAT('%', $account_id, '%')
|
||||
GROUP BY id
|
||||
LIMIT 100;
|
||||
";
|
||||
|
||||
$results[ $i ]['instances'] = $wpdb->get_results( $sql, ARRAY_A );
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
if ( ! empty( $args['expiring'] ) ) {
|
||||
$sql = $wpdb->prepare(
|
||||
"
|
||||
SELECT * FROM $sources_table_name
|
||||
WHERE account_type = 'personal'
|
||||
AND expires < %s
|
||||
AND last_updated < %s
|
||||
ORDER BY expires ASC
|
||||
LIMIT 5;
|
||||
",
|
||||
gmdate( 'Y-m-d H:i:s', time() + SBI_REFRESH_THRESHOLD_OFFSET ),
|
||||
gmdate( 'Y-m-d H:i:s', time() - SBI_MINIMUM_INTERVAL )
|
||||
);
|
||||
|
||||
return $wpdb->get_results( $sql, ARRAY_A );
|
||||
}
|
||||
|
||||
if ( ! empty( $args['username'] ) ) {
|
||||
return $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"
|
||||
SELECT * FROM $sources_table_name
|
||||
WHERE username = %s;
|
||||
",
|
||||
$args['username']
|
||||
),
|
||||
ARRAY_A
|
||||
);
|
||||
}
|
||||
|
||||
if ( isset( $args['access_token'] ) && ! isset( $args['id'] ) ) {
|
||||
return $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"
|
||||
SELECT * FROM $sources_table_name
|
||||
WHERE access_token = %s;
|
||||
",
|
||||
$args['access_token']
|
||||
),
|
||||
ARRAY_A
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! isset( $args['id'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( is_array( $args['id'] ) ) {
|
||||
$id_array = array();
|
||||
foreach ( $args['id'] as $id ) {
|
||||
$id_array[] = esc_sql( $id );
|
||||
}
|
||||
} elseif ( strpos( $args['id'], ',' ) !== false ) {
|
||||
$id_array = explode( ',', str_replace( ' ', '', esc_sql( $args['id'] ) ) );
|
||||
}
|
||||
if ( isset( $id_array ) ) {
|
||||
$id_string = "'" . implode( "' , '", array_map( 'esc_sql', $id_array ) ) . "'";
|
||||
}
|
||||
|
||||
if ( ! empty( $args['all_business'] ) ) {
|
||||
$id_string = empty( $id_string ) ? '0' : $id_string;
|
||||
$sql = "
|
||||
SELECT * FROM $sources_table_name
|
||||
WHERE account_id IN ($id_string)
|
||||
OR account_type = 'business'
|
||||
";
|
||||
|
||||
return $wpdb->get_results( $sql, ARRAY_A );
|
||||
}
|
||||
|
||||
$privilege = '';
|
||||
|
||||
if ( ! empty( $privilege ) ) {
|
||||
if ( isset( $id_string ) ) {
|
||||
$sql = $wpdb->prepare(
|
||||
"
|
||||
SELECT * FROM $sources_table_name
|
||||
WHERE account_id IN ($id_string)
|
||||
AND privilege = %s;
|
||||
",
|
||||
$privilege
|
||||
);
|
||||
|
||||
} else {
|
||||
$sql = $wpdb->prepare(
|
||||
"
|
||||
SELECT * FROM $sources_table_name
|
||||
WHERE account_id = %s
|
||||
AND privilege = %s;
|
||||
",
|
||||
$args['id'],
|
||||
$privilege
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if ( isset( $id_string ) ) {
|
||||
$sql = "
|
||||
SELECT * FROM $sources_table_name
|
||||
WHERE account_id IN ($id_string);
|
||||
";
|
||||
|
||||
} else {
|
||||
$sql = $wpdb->prepare(
|
||||
"
|
||||
SELECT * FROM $sources_table_name
|
||||
WHERE account_id = %s;
|
||||
",
|
||||
$args['id']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $wpdb->get_results( $sql, ARRAY_A );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a source (connected account)
|
||||
*
|
||||
* @param array $to_update
|
||||
* @param array $where_data
|
||||
*
|
||||
* @return false|int
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function source_update( $to_update, $where_data ) {
|
||||
global $wpdb;
|
||||
$sources_table_name = $wpdb->prefix . 'sbi_sources';
|
||||
$encryption = new \SB_YouTube_Data_Encryption();
|
||||
|
||||
$data = array();
|
||||
$where = array();
|
||||
$format = array();
|
||||
$where_format = array();
|
||||
if ( isset( $to_update['type'] ) ) {
|
||||
$data['account_type'] = $to_update['type'];
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_update['privilege'] ) ) {
|
||||
$data['privilege'] = $to_update['privilege'];
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_update['id'] ) ) {
|
||||
$where['account_id'] = $to_update['id'];
|
||||
$where_format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_update['access_token'] ) ) {
|
||||
$data['access_token'] = $encryption->maybe_encrypt( $to_update['access_token'] );
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_update['username'] ) ) {
|
||||
$data['username'] = $to_update['username'];
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_update['info'] ) ) {
|
||||
$data['info'] = $encryption->maybe_encrypt( $to_update['info'] );
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_update['error'] ) ) {
|
||||
$data['error'] = $to_update['error'];
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_update['expires'] ) ) {
|
||||
$data['expires'] = $to_update['expires'];
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_update['last_updated'] ) ) {
|
||||
$data['last_updated'] = $to_update['last_updated'];
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_update['author'] ) ) {
|
||||
$data['author'] = $to_update['author'];
|
||||
$format[] = '%d';
|
||||
}
|
||||
|
||||
if ( isset( $where_data['type'] ) ) {
|
||||
$where['account_type'] = $where_data['type'];
|
||||
$where_format[] = '%s';
|
||||
}
|
||||
if ( isset( $where_data['privilege'] ) ) {
|
||||
$where['privilege'] = $where_data['privilege'];
|
||||
$where_format[] = '%s';
|
||||
}
|
||||
if ( isset( $where_data['author'] ) ) {
|
||||
$where['author'] = $where_data['author'];
|
||||
$where_format[] = '%d';
|
||||
}
|
||||
if ( isset( $where_data['id'] ) ) {
|
||||
$where['account_id'] = $where_data['id'];
|
||||
$where_format[] = '%s';
|
||||
}
|
||||
if ( isset( $where_data['record_id'] ) ) {
|
||||
$where['id'] = $where_data['record_id'];
|
||||
$where_format[] = '%d';
|
||||
}
|
||||
$affected = $wpdb->update( $sources_table_name, $data, $where, $format, $where_format );
|
||||
|
||||
return $affected;
|
||||
}
|
||||
|
||||
/**
|
||||
* New source (connected account) data is added to the
|
||||
* sbi_sources table and the new insert ID is returned
|
||||
*
|
||||
* @param array $to_insert
|
||||
*
|
||||
* @return false|int
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function source_insert( $to_insert ) {
|
||||
global $wpdb;
|
||||
$sources_table_name = $wpdb->prefix . 'sbi_sources';
|
||||
$encryption = new \SB_Instagram_Data_Encryption();
|
||||
|
||||
$data = array();
|
||||
$format = array();
|
||||
if ( isset( $to_insert['id'] ) ) {
|
||||
$data['account_id'] = $to_insert['id'];
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_insert['type'] ) ) {
|
||||
$data['account_type'] = $to_insert['type'];
|
||||
$format[] = '%s';
|
||||
} else {
|
||||
$data['account_type'] = 'page';
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_insert['privilege'] ) ) {
|
||||
$data['privilege'] = $to_insert['privilege'];
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_insert['access_token'] ) ) {
|
||||
$data['access_token'] = $encryption->maybe_encrypt( $to_insert['access_token'] );
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_insert['username'] ) ) {
|
||||
$data['username'] = $to_insert['username'];
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_insert['info'] ) ) {
|
||||
$data['info'] = $encryption->maybe_encrypt( $to_insert['info'] );
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_insert['error'] ) ) {
|
||||
$data['error'] = $to_insert['error'];
|
||||
$format[] = '%s';
|
||||
}
|
||||
if ( isset( $to_insert['expires'] ) ) {
|
||||
$data['expires'] = $to_insert['expires'];
|
||||
$format[] = '%s';
|
||||
} else {
|
||||
$data['expires'] = '2100-12-30 00:00:00';
|
||||
$format[] = '%s';
|
||||
}
|
||||
$data['last_updated'] = gmdate( 'Y-m-d H:i:s' );
|
||||
$format[] = '%s';
|
||||
if ( isset( $to_insert['author'] ) ) {
|
||||
$data['author'] = $to_insert['author'];
|
||||
$format[] = '%d';
|
||||
} else {
|
||||
$data['author'] = get_current_user_id();
|
||||
$format[] = '%d';
|
||||
}
|
||||
|
||||
return $wpdb->insert( $sources_table_name, $data, $format );
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the to get feeds list for Elementor
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function elementor_feeds_query() {
|
||||
global $wpdb;
|
||||
$feeds_elementor = array();
|
||||
$feeds_table_name = $wpdb->prefix . 'sby_feeds';
|
||||
$feeds_list = $wpdb->get_results(
|
||||
"
|
||||
SELECT id, feed_name FROM $feeds_table_name;
|
||||
"
|
||||
);
|
||||
if ( ! empty( $feeds_list ) ) {
|
||||
foreach ( $feeds_list as $feed ) {
|
||||
$feeds_elementor[ $feed->id ] = $feed->feed_name;
|
||||
}
|
||||
}
|
||||
return $feeds_elementor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Count the sby_feeds table
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function feeds_count() {
|
||||
global $wpdb;
|
||||
$feeds_table_name = $wpdb->prefix . 'sby_feeds';
|
||||
$results = $wpdb->get_results(
|
||||
"SELECT COUNT(*) AS num_entries FROM $feeds_table_name",
|
||||
ARRAY_A
|
||||
);
|
||||
return isset( $results[0]['num_entries'] ) ? (int) $results[0]['num_entries'] : 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Query the sby_feeds table
|
||||
*
|
||||
* @param array $args
|
||||
*
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function feeds_query( $args = array() ) {
|
||||
global $wpdb;
|
||||
$feeds_table_name = $wpdb->prefix . 'sby_feeds';
|
||||
$page = 0;
|
||||
if ( isset( $args['page'] ) ) {
|
||||
$page = (int) $args['page'] - 1;
|
||||
unset( $args['page'] );
|
||||
}
|
||||
|
||||
$offset = max( 0, $page * self::RESULTS_PER_PAGE );
|
||||
|
||||
if ( isset( $args['id'] ) ) {
|
||||
$sql = $wpdb->prepare(
|
||||
"
|
||||
SELECT * FROM $feeds_table_name
|
||||
WHERE id = %d;
|
||||
",
|
||||
$args['id']
|
||||
);
|
||||
} else {
|
||||
$sql = $wpdb->prepare(
|
||||
"
|
||||
SELECT * FROM $feeds_table_name
|
||||
LIMIT %d
|
||||
OFFSET %d;",
|
||||
self::RESULTS_PER_PAGE,
|
||||
$offset
|
||||
);
|
||||
}
|
||||
|
||||
return $wpdb->get_results( $sql, ARRAY_A );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update feed data in the sbi_feed table
|
||||
*
|
||||
* @param array $to_update
|
||||
* @param array $where_data
|
||||
*
|
||||
* @return false|int
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function feeds_update( $to_update, $where_data ) {
|
||||
global $wpdb;
|
||||
$feeds_table_name = $wpdb->prefix . 'sby_feeds';
|
||||
|
||||
$data = array();
|
||||
$where = array();
|
||||
$format = array();
|
||||
foreach ( $to_update as $single_insert ) {
|
||||
if ( $single_insert['key'] ) {
|
||||
$data[ $single_insert['key'] ] = $single_insert['values'][0];
|
||||
$format[] = '%s';
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $where_data['id'] ) ) {
|
||||
$where['id'] = $where_data['id'];
|
||||
$where_format = array( '%d' );
|
||||
} elseif ( isset( $where_data['feed_name'] ) ) {
|
||||
$where['feed_name'] = $where_data['feed_name'];
|
||||
$where_format = array( '%s' );
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data['last_modified'] = gmdate( 'Y-m-d H:i:s' );
|
||||
$format[] = '%s';
|
||||
|
||||
$affected = $wpdb->update( $feeds_table_name, $data, $where, $format, $where_format );
|
||||
|
||||
return $affected;
|
||||
}
|
||||
|
||||
/**
|
||||
* New feed data is added to the sby_feeds table and
|
||||
* the new insert ID is returned
|
||||
*
|
||||
* @param array $to_insert
|
||||
*
|
||||
* @return false|int
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function feeds_insert( $to_insert ) {
|
||||
global $wpdb;
|
||||
$feeds_table_name = $wpdb->prefix . 'sby_feeds';
|
||||
|
||||
$data = array();
|
||||
$format = array();
|
||||
foreach ( $to_insert as $single_insert ) {
|
||||
if ( $single_insert['key'] ) {
|
||||
$data[ $single_insert['key'] ] = $single_insert['values'][0];
|
||||
$format[] = '%s';
|
||||
}
|
||||
}
|
||||
|
||||
$data['last_modified'] = gmdate( 'Y-m-d H:i:s' );
|
||||
$format[] = '%s';
|
||||
|
||||
$data['author'] = get_current_user_id();
|
||||
$format[] = '%d';
|
||||
|
||||
$wpdb->insert( $feeds_table_name, $data, $format );
|
||||
return $wpdb->insert_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the sby_feeds table
|
||||
* Porcess to define the name of the feed when adding new
|
||||
*
|
||||
* @param string $sourcename
|
||||
*
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function feeds_query_name( $sourcename ) {
|
||||
global $wpdb;
|
||||
$feeds_table_name = $wpdb->prefix . 'sby_feeds';
|
||||
$sql = $wpdb->prepare(
|
||||
"SELECT * FROM $feeds_table_name
|
||||
WHERE feed_name LIKE %s;",
|
||||
$wpdb->esc_like( $sourcename ) . '%'
|
||||
);
|
||||
$count = count( $wpdb->get_results( $sql, ARRAY_A ) );
|
||||
return ( $count === 0 ) ? $sourcename : $sourcename . ' (' . ( $count + 1 ) . ')';
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Query to Remove Feeds from Database
|
||||
*
|
||||
* @param array $feed_ids_array
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function delete_feeds_query( $feed_ids_array ) {
|
||||
global $wpdb;
|
||||
$feeds_table_name = $wpdb->prefix . 'sby_feeds';
|
||||
$feed_caches_table_name = $wpdb->prefix . 'sbi_feed_caches';
|
||||
$feed_ids_array = implode( ',', array_map( 'absint', $feed_ids_array ) );
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $feeds_table_name WHERE id IN ($feed_ids_array)"
|
||||
)
|
||||
);
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $feed_caches_table_name WHERE feed_id IN ($feed_ids_array)"
|
||||
)
|
||||
);
|
||||
|
||||
echo json_encode( SBI_Feed_Builder::get_feed_list() );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to Remove Source from Database
|
||||
*
|
||||
* @param array $source_id
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function delete_source_query( $source_id ) {
|
||||
global $wpdb;
|
||||
$sources_table_name = $wpdb->prefix . 'sbi_sources';
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $sources_table_name WHERE id = %d; ",
|
||||
$source_id
|
||||
)
|
||||
);
|
||||
|
||||
echo json_encode( SBI_Feed_Builder::get_source_list() );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to Remove Source from Database
|
||||
*
|
||||
* @param array $source_id
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function delete_source_by_account_id( $source_id ) {
|
||||
global $wpdb;
|
||||
$sources_table_name = $wpdb->prefix . 'sbi_sources';
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $sources_table_name WHERE account_id = %s; ",
|
||||
$source_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to Duplicate a Single Feed
|
||||
*
|
||||
* @param int $feed_id
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function duplicate_feed_query( $feed_id ) {
|
||||
global $wpdb;
|
||||
$feeds_table_name = $wpdb->prefix . 'sby_feeds';
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"INSERT INTO $feeds_table_name (feed_name, settings, author, status)
|
||||
SELECT CONCAT(feed_name, ' (copy)'), settings, author, status
|
||||
FROM $feeds_table_name
|
||||
WHERE id = %d; ",
|
||||
$feed_id
|
||||
)
|
||||
);
|
||||
|
||||
echo json_encode( SBI_Feed_Builder::get_feed_list() );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get cache records in the sbi_feed_caches table
|
||||
*
|
||||
* @param array $args
|
||||
*
|
||||
* @return array|object|null
|
||||
*/
|
||||
public static function feed_caches_query( $args ) {
|
||||
global $wpdb;
|
||||
$feed_cache_table_name = $wpdb->prefix . 'sbi_feed_caches';
|
||||
|
||||
if ( ! isset( $args['cron_update'] ) ) {
|
||||
$sql = "
|
||||
SELECT * FROM $feed_cache_table_name;";
|
||||
} else {
|
||||
if ( ! isset( $args['additional_batch'] ) ) {
|
||||
$sql = $wpdb->prepare(
|
||||
"
|
||||
SELECT * FROM $feed_cache_table_name
|
||||
WHERE cron_update = 'yes'
|
||||
ORDER BY last_updated ASC
|
||||
LIMIT %d;",
|
||||
self::RESULTS_PER_CRON_UPDATE
|
||||
);
|
||||
} else {
|
||||
$sql = $wpdb->prepare(
|
||||
"
|
||||
SELECT * FROM $feed_cache_table_name
|
||||
WHERE cron_update = 'yes'
|
||||
AND last_updated < %s
|
||||
ORDER BY last_updated ASC
|
||||
LIMIT %d;",
|
||||
gmdate( 'Y-m-d H:i:s', time() - HOUR_IN_SECONDS ),
|
||||
self::RESULTS_PER_CRON_UPDATE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $wpdb->get_results( $sql, ARRAY_A );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates all database tables used in the new admin area in
|
||||
* the 6.0 update.
|
||||
*
|
||||
* TODO: Add error reporting
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function create_tables( $include_charset_collate = true ) {
|
||||
if ( ! function_exists( 'dbDelta' ) ) {
|
||||
require_once ABSPATH . '/wp-admin/includes/upgrade.php';
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$max_index_length = 191;
|
||||
$charset_collate = '';
|
||||
if ( $include_charset_collate && method_exists( $wpdb, 'get_charset_collate' ) ) { // get_charset_collate introduced in WP 3.5
|
||||
$charset_collate = $wpdb->get_charset_collate();
|
||||
}
|
||||
|
||||
$feeds_table_name = $wpdb->prefix . 'sby_feeds';
|
||||
|
||||
if ( $wpdb->get_var( "show tables like '$feeds_table_name'" ) !== $feeds_table_name ) {
|
||||
$sql = "
|
||||
CREATE TABLE $feeds_table_name (
|
||||
id bigint(20) unsigned NOT NULL auto_increment,
|
||||
feed_name text NOT NULL default '',
|
||||
feed_title text NOT NULL default '',
|
||||
settings longtext NOT NULL default '',
|
||||
author bigint(20) unsigned NOT NULL default '1',
|
||||
status varchar(255) NOT NULL default '',
|
||||
last_modified datetime NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY author (author)
|
||||
) $charset_collate;
|
||||
";
|
||||
$wpdb->query( $sql );
|
||||
}
|
||||
$error = $wpdb->last_error;
|
||||
$query = $wpdb->last_query;
|
||||
$had_error = false;
|
||||
if ( $wpdb->get_var( "show tables like '$feeds_table_name'" ) !== $feeds_table_name ) {
|
||||
$had_error = true;
|
||||
}
|
||||
|
||||
if ( ! $had_error ) {
|
||||
}
|
||||
|
||||
$feed_caches_table_name = $wpdb->prefix . 'sby_feed_caches';
|
||||
|
||||
if ( $wpdb->get_var( "show tables like '$feed_caches_table_name'" ) !== $feed_caches_table_name ) {
|
||||
$sql = '
|
||||
CREATE TABLE ' . $feed_caches_table_name . " (
|
||||
id bigint(20) unsigned NOT NULL auto_increment,
|
||||
feed_id varchar(255) NOT NULL default '',
|
||||
cache_key varchar(255) NOT NULL default '',
|
||||
cache_value longtext NOT NULL default '',
|
||||
cron_update varchar(20) NOT NULL default 'yes',
|
||||
last_updated datetime NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY feed_id (feed_id($max_index_length))
|
||||
) $charset_collate;";
|
||||
$wpdb->query( $sql );
|
||||
}
|
||||
$error = $wpdb->last_error;
|
||||
$query = $wpdb->last_query;
|
||||
$had_error = false;
|
||||
if ( $wpdb->get_var( "show tables like '$feed_caches_table_name'" ) !== $feed_caches_table_name ) {
|
||||
$had_error = true;
|
||||
}
|
||||
|
||||
if ( ! $had_error ) {
|
||||
}
|
||||
|
||||
$sources_table_name = $wpdb->prefix . 'sby_sources';
|
||||
|
||||
if ( $wpdb->get_var( "show tables like '$sources_table_name'" ) !== $sources_table_name ) {
|
||||
$sql = '
|
||||
CREATE TABLE ' . $sources_table_name . " (
|
||||
id bigint(20) unsigned NOT NULL auto_increment,
|
||||
account_id varchar(255) NOT NULL default '',
|
||||
account_type varchar(255) NOT NULL default '',
|
||||
privilege varchar(255) NOT NULL default '',
|
||||
access_token varchar(1000) NOT NULL default '',
|
||||
username varchar(255) NOT NULL default '',
|
||||
info text NOT NULL default '',
|
||||
error text NOT NULL default '',
|
||||
expires datetime NOT NULL,
|
||||
last_updated datetime NOT NULL,
|
||||
author bigint(20) unsigned NOT NULL default '1',
|
||||
PRIMARY KEY (id),
|
||||
KEY account_type (account_type($max_index_length)),
|
||||
KEY author (author)
|
||||
) $charset_collate;";
|
||||
$wpdb->query( $sql );
|
||||
}
|
||||
$error = $wpdb->last_error;
|
||||
$query = $wpdb->last_query;
|
||||
$had_error = false;
|
||||
if ( $wpdb->get_var( "show tables like '$sources_table_name'" ) !== $sources_table_name ) {
|
||||
$had_error = true;
|
||||
}
|
||||
|
||||
if ( ! $had_error ) {
|
||||
}
|
||||
}
|
||||
|
||||
public static function create_sources_database() {
|
||||
// not needed
|
||||
}
|
||||
|
||||
public static function clear_sbi_feed_caches() {
|
||||
global $wpdb;
|
||||
$feed_caches_table_name = $wpdb->prefix . 'sbi_feed_caches';
|
||||
|
||||
if ( $wpdb->get_var( "show tables like '$feed_caches_table_name'" ) === $feed_caches_table_name ) {
|
||||
$wpdb->query( "DELETE FROM $feed_caches_table_name" );
|
||||
}
|
||||
}
|
||||
|
||||
public static function clear_sbi_sources() {
|
||||
global $wpdb;
|
||||
$sources_table_name = $wpdb->prefix . 'sbi_sources';
|
||||
|
||||
if ( $wpdb->get_var( "show tables like '$sources_table_name'" ) === $sources_table_name ) {
|
||||
$wpdb->query( "DELETE FROM $sources_table_name" );
|
||||
}
|
||||
}
|
||||
|
||||
public static function reset_tables() {
|
||||
global $wpdb;
|
||||
$feeds_table_name = $wpdb->prefix . 'sby_feeds';
|
||||
|
||||
$wpdb->query( "DROP TABLE IF EXISTS $feeds_table_name" );
|
||||
$feed_caches_table_name = $wpdb->prefix . 'sbi_feed_caches';
|
||||
|
||||
$wpdb->query( "DROP TABLE IF EXISTS $feed_caches_table_name" );
|
||||
|
||||
$sources_table_name = $wpdb->prefix . 'sbi_sources';
|
||||
$wpdb->query( "DROP TABLE IF EXISTS $sources_table_name" );
|
||||
}
|
||||
|
||||
public static function reset_db_update() {
|
||||
update_option( 'sbi_db_version', 1.9 );
|
||||
delete_option( 'sbi_legacy_feed_settings' );
|
||||
|
||||
// are there existing feeds to toggle legacy onboarding?
|
||||
$sbi_statuses_option = get_option( 'sbi_statuses', array() );
|
||||
|
||||
if ( isset( $sbi_statuses_option['legacy_onboarding'] ) ) {
|
||||
unset( $sbi_statuses_option['legacy_onboarding'] );
|
||||
}
|
||||
if ( isset( $sbi_statuses_option['support_legacy_shortcode'] ) ) {
|
||||
unset( $sbi_statuses_option['support_legacy_shortcode'] );
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$table_name = $wpdb->prefix . 'usermeta';
|
||||
$wpdb->query(
|
||||
"
|
||||
DELETE
|
||||
FROM $table_name
|
||||
WHERE `meta_key` LIKE ('sbi\_%')
|
||||
"
|
||||
);
|
||||
|
||||
$feed_locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR;
|
||||
|
||||
$results = $wpdb->query(
|
||||
"
|
||||
DELETE
|
||||
FROM $feed_locator_table_name
|
||||
WHERE feed_id LIKE '*%';"
|
||||
);
|
||||
|
||||
update_option( 'sbi_statuses', $sbi_statuses_option );
|
||||
}
|
||||
|
||||
public static function reset_legacy() {
|
||||
|
||||
//Settings
|
||||
delete_option( 'sbi_statuses' );
|
||||
delete_option( 'sb_instagram_settings' );
|
||||
delete_option( 'sbi_ver' );
|
||||
delete_option( 'sb_expired_tokens' );
|
||||
delete_option( 'sbi_cron_report' );
|
||||
delete_option( 'sb_instagram_errors' );
|
||||
delete_option( 'sb_instagram_ajax_status' );
|
||||
delete_option( 'sbi_db_version' );
|
||||
|
||||
// Clear backup caches
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'options';
|
||||
$wpdb->query(
|
||||
"
|
||||
DELETE
|
||||
FROM $table_name
|
||||
WHERE `option_name` LIKE ('%!sbi\_%')
|
||||
"
|
||||
);
|
||||
$wpdb->query(
|
||||
"
|
||||
DELETE
|
||||
FROM $table_name
|
||||
WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')
|
||||
"
|
||||
);
|
||||
$wpdb->query(
|
||||
"
|
||||
DELETE
|
||||
FROM $table_name
|
||||
WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')
|
||||
"
|
||||
);
|
||||
$wpdb->query(
|
||||
"
|
||||
DELETE
|
||||
FROM $table_name
|
||||
WHERE `option_name` LIKE ('%sb_wlupdated_%')
|
||||
"
|
||||
);
|
||||
|
||||
//image resizing
|
||||
$upload = wp_upload_dir();
|
||||
$posts_table_name = $wpdb->prefix . 'sbi_instagram_posts';
|
||||
$feeds_posts_table_name = $wpdb->prefix . 'sbi_instagram_feeds_posts';
|
||||
|
||||
$image_files = glob( trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . '*' ); // get all file names
|
||||
foreach ( $image_files as $file ) { // iterate files
|
||||
if ( is_file( $file ) ) {
|
||||
unlink( $file );
|
||||
} // delete file
|
||||
}
|
||||
|
||||
//global $wp_filesystem;
|
||||
|
||||
//$wp_filesystem->delete( trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) , true );
|
||||
//Delete tables
|
||||
$wpdb->query( "DROP TABLE IF EXISTS $posts_table_name" );
|
||||
$wpdb->query( "DROP TABLE IF EXISTS $feeds_posts_table_name" );
|
||||
$locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR;
|
||||
$wpdb->query( "DROP TABLE IF EXISTS $locator_table_name" );
|
||||
|
||||
$table_name = $wpdb->prefix . 'options';
|
||||
$wpdb->query(
|
||||
"
|
||||
DELETE
|
||||
FROM $table_name
|
||||
WHERE `option_name` LIKE ('%\_transient\_\$sbi\_%')
|
||||
"
|
||||
);
|
||||
$wpdb->query(
|
||||
"
|
||||
DELETE
|
||||
FROM $table_name
|
||||
WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sbi\_%')
|
||||
"
|
||||
);
|
||||
delete_option( 'sbi_hashtag_ids' );
|
||||
delete_option( 'sb_instagram_errors' );
|
||||
delete_option( 'sbi_usage_tracking_config' );
|
||||
delete_option( 'sbi_usage_tracking' );
|
||||
delete_option( 'sbi_oembed_token' );
|
||||
delete_option( 'sbi_top_api_calls' );
|
||||
delete_option( 'sbi_rating_notice' );
|
||||
delete_option( 'sbi_refresh_report' );
|
||||
delete_option( 'sbi_welcome_seen' );
|
||||
delete_option( 'sbi_notifications' );
|
||||
delete_option( 'sbi_newuser_notifications' );
|
||||
|
||||
global $wp_roles;
|
||||
$wp_roles->remove_cap( 'administrator', 'manage_instagram_feed_options' );
|
||||
wp_clear_scheduled_hook( 'sbi_feed_update' );
|
||||
wp_clear_scheduled_hook( 'sbi_usage_tracking_cron' );
|
||||
}
|
||||
}
|
||||
1655
wp-content/plugins/youtube-feed-pro/inc/Builder/SBY_Feed_Builder.php
Normal file
1655
wp-content/plugins/youtube-feed-pro/inc/Builder/SBY_Feed_Builder.php
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,667 @@
|
||||
<?php
|
||||
/**
|
||||
* YouTube Feed Database
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Builder;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\Customizer\ProxyProvider;
|
||||
|
||||
class SBY_Feed_Saver {
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
private $insert_id;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
private $sanitized_and_sorted_data;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
private $feed_db_data;
|
||||
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
private $feed_name;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
private $is_legacy;
|
||||
|
||||
/**
|
||||
* @var ProxyProvider
|
||||
*/
|
||||
private $proxy_provider;
|
||||
|
||||
/**
|
||||
* SBY_Feed_Saver constructor.
|
||||
*
|
||||
* @param int $insert_id
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __construct( $insert_id ) {
|
||||
$this->proxy_provider = new ProxyProvider;
|
||||
|
||||
if ( $insert_id === 'legacy' ) {
|
||||
$this->is_legacy = true;
|
||||
$this->insert_id = 0;
|
||||
} else {
|
||||
$this->is_legacy = false;
|
||||
$this->insert_id = $insert_id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Feed insert ID if it exists
|
||||
*
|
||||
* @return bool|int
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function get_feed_id() {
|
||||
if ( $this->is_legacy ) {
|
||||
return 'legacy';
|
||||
}
|
||||
if ( ! empty( $this->insert_id ) ) {
|
||||
return $this->insert_id;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function set_data( $data ) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $feed_name
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function set_feed_name( $feed_name ) {
|
||||
$this->feed_name = $feed_name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function get_feed_db_data() {
|
||||
return $this->feed_db_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new feed if there is no associated feed
|
||||
* found. Otherwise updates the exiting feed.
|
||||
*
|
||||
* @return false|int
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function update_or_insert() {
|
||||
$this->sanitize_and_sort_data();
|
||||
|
||||
if ( $this->exists_in_database() ) {
|
||||
return $this->update();
|
||||
} else {
|
||||
return $this->insert();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not a feed exists with the
|
||||
* associated insert ID
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function exists_in_database() {
|
||||
if ( $this->is_legacy ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $this->insert_id === false ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'id' => $this->insert_id,
|
||||
);
|
||||
|
||||
$results = SBY_Db::feeds_query( $args );
|
||||
|
||||
return isset( $results[0] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new feed from sanitized and sorted data.
|
||||
* Some data is saved in the sbi_feeds table and some is
|
||||
* saved in the sbi_feed_settings table.
|
||||
*
|
||||
* @return false|int
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function insert() {
|
||||
if ( $this->is_legacy ) {
|
||||
return $this->update();
|
||||
}
|
||||
|
||||
if ( ! isset( $this->sanitized_and_sorted_data ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$settings_array = self::format_settings( $this->sanitized_and_sorted_data['feed_settings'] );
|
||||
|
||||
$this->sanitized_and_sorted_data['feeds'][] = array(
|
||||
'key' => 'settings',
|
||||
'values' => array( json_encode( $settings_array ) ),
|
||||
);
|
||||
|
||||
if ( ! empty( $this->feed_name ) ) {
|
||||
$this->sanitized_and_sorted_data['feeds'][] = array(
|
||||
'key' => 'feed_name',
|
||||
'values' => array( $this->feed_name ),
|
||||
);
|
||||
}
|
||||
|
||||
$this->sanitized_and_sorted_data['feeds'][] = array(
|
||||
'key' => 'status',
|
||||
'values' => array( 'publish' ),
|
||||
);
|
||||
|
||||
$insert_id = SBY_Db::feeds_insert( $this->sanitized_and_sorted_data['feeds'] );
|
||||
|
||||
if ( $insert_id ) {
|
||||
$this->insert_id = $insert_id;
|
||||
|
||||
return $insert_id;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing feed and related settings from
|
||||
* sanitized and sorted data.
|
||||
*
|
||||
* @return false|int
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function update() {
|
||||
if ( ! isset( $this->sanitized_and_sorted_data ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'id' => $this->insert_id,
|
||||
);
|
||||
|
||||
$settings_array = self::format_settings( $this->sanitized_and_sorted_data['feed_settings'] );
|
||||
|
||||
if ( $this->is_legacy ) {
|
||||
|
||||
$to_save_json = json_encode( $settings_array );
|
||||
update_option( 'sby_legacy_feed_settings', $to_save_json, false );
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->sanitized_and_sorted_data['feeds'][] = array(
|
||||
'key' => 'settings',
|
||||
'values' => array( json_encode( $settings_array ) ),
|
||||
);
|
||||
|
||||
$this->sanitized_and_sorted_data['feeds'][] = array(
|
||||
'key' => 'feed_name',
|
||||
'values' => array( sanitize_text_field( $this->feed_name ) ),
|
||||
);
|
||||
|
||||
$success = SBY_Db::feeds_update( $this->sanitized_and_sorted_data['feeds'], $args );
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts settings that have been sanitized into an associative array
|
||||
* that can be saved as JSON in the database
|
||||
*
|
||||
* @param $raw_settings
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function format_settings( $raw_settings ) {
|
||||
$settings_array = array();
|
||||
foreach ( $raw_settings as $single_setting ) {
|
||||
if ( count( $single_setting['values'] ) > 1 ) {
|
||||
$settings_array[ $single_setting['key'] ] = $single_setting['values'];
|
||||
|
||||
} else {
|
||||
$settings_array[ $single_setting['key'] ] = isset( $single_setting['values'][0] ) ? $single_setting['values'][0] : '';
|
||||
}
|
||||
}
|
||||
|
||||
return $settings_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Preview Settings
|
||||
* for the Feed Fly Preview
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function get_feed_preview_settings( $preview_settings ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves and organizes feed setting data for easy use in
|
||||
* the builder
|
||||
*
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function get_feed_settings() {
|
||||
if ( $this->is_legacy ) {
|
||||
$feed_settings = $this->proxy_provider->get_settings_class();
|
||||
|
||||
$feed_settings->set_feed_type_and_terms();
|
||||
$feed_settings->set_transient_name();
|
||||
$return = $feed_settings->get_settings();
|
||||
|
||||
$this->feed_db_data = array(
|
||||
'id' => 'legacy',
|
||||
'feed_name' => __( 'Legacy Feeds', 'feeds-for-youtube' ),
|
||||
'feed_title' => __( 'Legacy Feeds', 'feeds-for-youtube' ),
|
||||
'status' => 'publish',
|
||||
'last_modified' => date( 'Y-m-d H:i:s' ),
|
||||
);
|
||||
} elseif ( empty( $this->insert_id ) ) {
|
||||
return false;
|
||||
} else {
|
||||
$args = array(
|
||||
'id' => $this->insert_id,
|
||||
);
|
||||
$settings_db_data = SBY_Db::feeds_query( $args );
|
||||
if ( false === $settings_db_data || sizeof( $settings_db_data ) === 0 ) {
|
||||
return false;
|
||||
}
|
||||
$this->feed_db_data = array(
|
||||
'id' => $settings_db_data[0]['id'],
|
||||
'feed_name' => $settings_db_data[0]['feed_name'],
|
||||
'feed_title' => $settings_db_data[0]['feed_title'],
|
||||
'status' => $settings_db_data[0]['status'],
|
||||
'last_modified' => $settings_db_data[0]['last_modified'],
|
||||
);
|
||||
|
||||
$return = json_decode( $settings_db_data[0]['settings'], true );
|
||||
$return['feed_name'] = $settings_db_data[0]['feed_name'];
|
||||
}
|
||||
|
||||
$return = wp_parse_args( $return, self::settings_defaults() );
|
||||
|
||||
if ( empty( $return['id'] ) ) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
if ( ! is_array( $return['id'] ) ) {
|
||||
$return['id'] = explode( ',', str_replace( ' ', '', $return['id'] ) );
|
||||
}
|
||||
if ( ! is_array( $return['tagged'] ) ) {
|
||||
$return['tagged'] = explode( ',', str_replace( ' ', '', $return['tagged'] ) );
|
||||
}
|
||||
if ( ! is_array( $return['hashtag'] ) ) {
|
||||
$return['hashtag'] = explode( ',', str_replace( ' ', '', $return['hashtag'] ) );
|
||||
}
|
||||
$args = array( 'id' => $return['id'] );
|
||||
|
||||
$source_query = SBY_Db::source_query( $args );
|
||||
|
||||
$return['sources'] = array();
|
||||
|
||||
if ( ! empty( $source_query ) ) {
|
||||
|
||||
foreach ( $source_query as $source ) {
|
||||
$user_id = $source['account_id'];
|
||||
$return['sources'][ $user_id ] = self::get_processed_source_data( $source );
|
||||
}
|
||||
} else {
|
||||
$found_sources = array();
|
||||
|
||||
foreach ( $return['id'] as $id_or_slug ) {
|
||||
$maybe_source_from_connected = SBY_Source::maybe_one_off_connected_account_update( $id_or_slug );
|
||||
|
||||
if ( $maybe_source_from_connected ) {
|
||||
$found_sources[] = $maybe_source_from_connected;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $found_sources ) ) {
|
||||
foreach ( $found_sources as $source ) {
|
||||
$user_id = $source['account_id'];
|
||||
$return['sources'][ $user_id ] = self::get_processed_source_data( $source );
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
$source_query = SBY_Db::source_query( $args );
|
||||
|
||||
if ( isset( $source_query[0] ) ) {
|
||||
$source = $source_query[0];
|
||||
|
||||
$user_id = $source['account_id'];
|
||||
|
||||
$return['sources'][ $user_id ] = self::get_processed_source_data( $source );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public static function get_processed_source_data( $source ) {
|
||||
$encryption = new \SB_Instagram_Data_Encryption();
|
||||
$user_id = $source['account_id'];
|
||||
$info = ! empty( $source['info'] ) ? json_decode( $encryption->decrypt( $source['info'] ), true ) : array();
|
||||
|
||||
$cdn_avatar_url = \SB_Instagram_Parse_Pro::get_avatar_url( $info );
|
||||
|
||||
$processed = array(
|
||||
'record_id' => stripslashes( $source['id'] ),
|
||||
'user_id' => $user_id,
|
||||
'type' => stripslashes( $source['account_type'] ),
|
||||
'privilege' => stripslashes( $source['privilege'] ),
|
||||
'access_token' => stripslashes( $encryption->decrypt( $source['access_token'] ) ),
|
||||
'username' => stripslashes( $source['username'] ),
|
||||
'name' => stripslashes( $source['username'] ),
|
||||
'info' => stripslashes( $encryption->decrypt( $source['info'] ) ),
|
||||
'error' => stripslashes( $source['error'] ),
|
||||
'expires' => stripslashes( $source['expires'] ),
|
||||
'profile_picture' => $cdn_avatar_url,
|
||||
'local_avatar_url' => \SB_Instagram_Connected_Account::maybe_local_avatar( $source['username'], $cdn_avatar_url ),
|
||||
);
|
||||
|
||||
return $processed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves and organizes feed setting data for easy use in
|
||||
* the builder
|
||||
* It will NOT get the settings from the DB, but from the Customizer builder
|
||||
* To be used for updating feed preview on the fly
|
||||
*
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function get_feed_settings_preview( $settings_db_data ) {
|
||||
if ( false === $settings_db_data || sizeof( $settings_db_data ) === 0 ) {
|
||||
return false;
|
||||
}
|
||||
$return = $settings_db_data;
|
||||
$return = wp_parse_args( $return, self::settings_defaults() );
|
||||
if ( empty( $return['sources'] ) ) {
|
||||
return $return;
|
||||
}
|
||||
$sources = array();
|
||||
foreach ( $return['sources'] as $single_source ) {
|
||||
array_push( $sources, $single_source['account_id'] );
|
||||
}
|
||||
|
||||
$args = array( 'id' => $sources );
|
||||
$source_query = SBY_Db::source_query( $args );
|
||||
|
||||
$return['sources'] = array();
|
||||
if ( ! empty( $source_query ) ) {
|
||||
foreach ( $source_query as $source ) {
|
||||
$user_id = $source['account_id'];
|
||||
$return['sources'][ $user_id ] = self::get_processed_source_data( $source );
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Default settings, $return_array equalling false will return
|
||||
* the settings in the general way that the "SBI_Shortcode" class,
|
||||
* "sbi_get_processed_options" method does
|
||||
*
|
||||
* @param bool $return_array
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function settings_defaults( $return_array = true ) {
|
||||
{
|
||||
$defaults = array(
|
||||
'connected_accounts' => array(),
|
||||
'type' => 'channel',
|
||||
'channel' => '',
|
||||
'num' => 9,
|
||||
'nummobile' => 9,
|
||||
'widthresp' => true,
|
||||
'class' => '',
|
||||
'height' => '',
|
||||
'heightunit' => '%',
|
||||
'disablemobile' => false,
|
||||
'itemspacing' => 5,
|
||||
'itemspacingunit' => 'px',
|
||||
'background' => '',
|
||||
'headercolor' => '',
|
||||
'subscribecolor' => '',
|
||||
'subscribetextcolor' => '',
|
||||
'buttoncolor' => '',
|
||||
'buttontextcolor' => '',
|
||||
'layout' => 'grid',
|
||||
'playvideo' => 'automatically',
|
||||
'sortby' => 'none',
|
||||
'imageres' => 'auto',
|
||||
'showheader' => true,
|
||||
'showdescription' => true,
|
||||
'showbutton' => true,
|
||||
'headersize' => 'small',
|
||||
'headeroutside' => false,
|
||||
'showsubscribe' => true,
|
||||
'buttontext' => __( 'Load More...', 'feeds-for-youtube' ),
|
||||
'subscribetext' => __( 'Subscribe', 'feeds-for-youtube' ),
|
||||
'caching_type' => 'page',
|
||||
'cache_time' => 1,
|
||||
'cache_time_unit' => 'hours',
|
||||
'backup_cache_enabled' => true,
|
||||
'resizeprocess' => 'background',
|
||||
'disable_resize' => true,
|
||||
'storage_process' => 'background',
|
||||
'favor_local' => false,
|
||||
'disable_js_image_loading' => false,
|
||||
'ajax_post_load' => false,
|
||||
'ajaxtheme' => false,
|
||||
'enqueue_css_in_shortcode' => false,
|
||||
'font_method' => 'svg',
|
||||
'customtemplates' => false,
|
||||
'gallerycols' => 3,
|
||||
'gallerycolsmobile' => 2,
|
||||
'gridcols' => 3,
|
||||
'gridcolsmobile' => 2,
|
||||
'playerratio' => '9:16',
|
||||
'eagerload' => false,
|
||||
'custom_css' => '',
|
||||
'custom_js' => '',
|
||||
'gdpr' => 'auto',
|
||||
'disablecdn' => false,
|
||||
'allowcookies' => false,
|
||||
|
||||
// pro only
|
||||
'usecustomsearch' => false,
|
||||
'headerchannel' => '',
|
||||
'customsearch' => '',
|
||||
'showpast' => true,
|
||||
'showlikes' => true,
|
||||
'carouselcols' => 3,
|
||||
'carouselcolsmobile' => 2,
|
||||
'carouselarrows' => true,
|
||||
'carouselpag' => true,
|
||||
'carouselautoplay' => false,
|
||||
'infoposition' => 'below',
|
||||
'include' => array( 'title', 'icon', 'user', 'date', 'countdown' ),
|
||||
'hoverinclude' => array( 'description', 'stats' ),
|
||||
'descriptionlength' => 150,
|
||||
'userelative' => true,
|
||||
'dateformat' => '0',
|
||||
'customdate' => '',
|
||||
'showsubscribers' => true,
|
||||
'descriptiontextsize' => '13px',
|
||||
|
||||
'subscriberstext' => __( 'subscribers', 'feeds-for-youtube' ),
|
||||
'viewstext' => __( 'views', 'feeds-for-youtube' ),
|
||||
'agotext' => __( 'ago', 'feeds-for-youtube' ),
|
||||
'beforedatetext' => __( 'Streaming live', 'feeds-for-youtube' ),
|
||||
'beforestreamtimetext' => __( 'Streaming live in', 'feeds-for-youtube' ),
|
||||
'minutetext' => __( 'minute', 'feeds-for-youtube' ),
|
||||
'minutestext' => __( 'minutes', 'feeds-for-youtube' ),
|
||||
'hourstext' => __( 'hours', 'feeds-for-youtube' ),
|
||||
'thousandstext' => __( 'K', 'feeds-for-youtube' ),
|
||||
'millionstext' => __( 'M', 'feeds-for-youtube' ),
|
||||
'watchnowtext' => __( 'Watch Now', 'feeds-for-youtube' ),
|
||||
'cta' => 'related',
|
||||
|
||||
// pro comments
|
||||
'numcomments' => 20,
|
||||
'enablecomments' => false,
|
||||
|
||||
'linktext' => __( 'Learn More', 'feeds-for-youtube' ),
|
||||
'linkurl' => '',
|
||||
'linkopentype' => 'same',
|
||||
'linkcolor' => '',
|
||||
'linktextcolor' => '',
|
||||
);
|
||||
|
||||
$defaults = self::filter_defaults( $defaults );
|
||||
|
||||
// some settings are comma separated and not arrays when the feed is created
|
||||
if ( $return_array ) {
|
||||
$settings_with_multiples = array(
|
||||
'sources',
|
||||
);
|
||||
|
||||
foreach ( $settings_with_multiples as $multiple_key ) {
|
||||
if ( isset( $defaults[ $multiple_key ] ) ) {
|
||||
$defaults[ $multiple_key ] = explode( ',', $defaults[ $multiple_key ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides backwards compatibility for extensions
|
||||
*
|
||||
* @param array $defaults
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function filter_defaults( $defaults ) {
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves settings for legacy feeds. Runs on first update automatically.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function set_legacy_feed_settings() {
|
||||
$to_save = SBI_Post_Set::legacy_to_builder_convert();
|
||||
|
||||
$to_save_json = json_encode( $to_save );
|
||||
|
||||
update_option( 'sbi_legacy_feed_settings', $to_save_json, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for taking raw post data related to settings
|
||||
* an sanitizing it and sorting it to easily use in
|
||||
* the database tables
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
private function sanitize_and_sort_data() {
|
||||
$data = $this->data;
|
||||
|
||||
$sanitized_and_sorted = array(
|
||||
'feeds' => array(),
|
||||
'feed_settings' => array(),
|
||||
);
|
||||
|
||||
foreach ( $data as $key => $value ) {
|
||||
|
||||
$data_type = SBY_Feed_Saver_Manager::get_data_type( $key );
|
||||
$sanitized_values = array();
|
||||
if ( is_array( $value ) ) {
|
||||
foreach ( $value as $item ) {
|
||||
$type = SBY_Feed_Saver_Manager::is_boolean( $item ) ? 'boolean' : $data_type['sanitization'];
|
||||
$sanitized_values[] = SBY_Feed_Saver_Manager::sanitize( $type, $item );
|
||||
}
|
||||
} else {
|
||||
$type = SBY_Feed_Saver_Manager::is_boolean( $value ) ? 'boolean' : $data_type['sanitization'];
|
||||
$sanitized_values[] = SBY_Feed_Saver_Manager::sanitize( $type, $value );
|
||||
}
|
||||
|
||||
$single_sanitized = array(
|
||||
'key' => $key,
|
||||
'values' => $sanitized_values,
|
||||
);
|
||||
|
||||
$sanitized_and_sorted[ $data_type['table'] ][] = $single_sanitized;
|
||||
}
|
||||
|
||||
$this->sanitized_and_sorted_data = $sanitized_and_sorted;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,707 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* YouTube Feed Saver Manager
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Builder;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\SBY_Cache;
|
||||
use SmashBalloon\YouTubeFeed\Services\ShortcodeService;
|
||||
use SmashBalloon\YouTubeFeed\Customizer\DB;
|
||||
use Smashballoon\Customizer\Feed_Builder;
|
||||
use SmashBalloon\YouTubeFeed\SBY_Parse;
|
||||
use SmashBalloon\YouTubeFeed\Helpers\Util;
|
||||
|
||||
class SBY_Feed_Saver_Manager
|
||||
{
|
||||
/**
|
||||
* AJAX hooks for various feed data related functionality
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function register()
|
||||
{
|
||||
add_action('wp_ajax_sby_feed_saver_manager_builder_update', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Feed_Saver_Manager', 'builder_update' ));
|
||||
add_action('wp_ajax_sby_feed_saver_manager_get_feed_list_page', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Feed_Saver_Manager', 'get_feed_list_page' ));
|
||||
add_action('wp_ajax_sby_feed_saver_manager_fly_preview', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Feed_Saver_Manager', 'feed_customizer_fly_preview' ));
|
||||
add_action('wp_ajax_sby_feed_handle_saver_manager_fly_preview', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Feed_Saver_Manager', 'feed_customizer_feed_handle_fly_preview' ));
|
||||
add_action('wp_ajax_sby_feed_saver_manager_clear_single_feed_cache', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Feed_Saver_Manager', 'clear_single_feed_cache' ));
|
||||
add_action('wp_ajax_sby_feed_saver_manager_duplicate_feed', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Feed_Saver_Manager', 'duplicate_feed' ));
|
||||
add_action('wp_ajax_sby_feed_saver_manager_delete_feeds', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Feed_Saver_Manager', 'delete_feed' ));
|
||||
add_action('wp_ajax_sby_dismiss_onboarding', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Feed_Saver_Manager', 'after_dismiss_onboarding' ));
|
||||
add_action('wp_ajax_sby_feed_refresh', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Feed_Saver_Manager', 'feed_refresh' ));
|
||||
add_action('wp_ajax_sby_feed_saver_clear_comments_cache', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Feed_Saver_Manager', 'clear_comments_cache' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in an AJAX call to update settings for a particular feed.
|
||||
* Can also be used to create a new feed if no feed_id sent in
|
||||
* $_POST data.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function builder_update()
|
||||
{
|
||||
check_ajax_referer('sby-admin', 'nonce');
|
||||
|
||||
if (! sby_current_user_can('manage_youtube_feed_options')) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$settings_data = $_POST;
|
||||
|
||||
$feed_id = false;
|
||||
$is_new_feed = isset($settings_data['new_insert']) ? true : false;
|
||||
if (! empty($settings_data['feed_id'])) {
|
||||
$feed_id = sanitize_text_field($settings_data['feed_id']);
|
||||
unset($settings_data['feed_id']);
|
||||
} elseif (isset($settings_data['feed_id'])) {
|
||||
unset($settings_data['feed_id']);
|
||||
}
|
||||
unset($settings_data['action']);
|
||||
unset($settings_data['nonce']);
|
||||
|
||||
if (! isset($settings_data['feed_name'])) {
|
||||
$settings_data['feed_name'] = '';
|
||||
}
|
||||
|
||||
// If all video elements are disabled then store it as an empty array
|
||||
if (empty($settings_data['settings']['include'])) {
|
||||
$settings_data['settings']['include'] = array();
|
||||
}
|
||||
if (empty($settings_data['settings']['hoverinclude'])) {
|
||||
$settings_data['settings']['hoverinclude'] = array();
|
||||
}
|
||||
$update_feed = isset($settings_data['update_feed']) ? true : false;
|
||||
unset($settings_data['update_feed']);
|
||||
|
||||
if ($is_new_feed) {
|
||||
$settings_data = SBY_Feed_Templates_Settings::get_feed_settings_by_feed_templates($settings_data);
|
||||
}
|
||||
|
||||
$selected_feed_model = isset($settings_data['selectedFeedModel']) ? self::filter_feed_model_data($settings_data['selectedFeedModel'], $settings_data['feedtype']) : '';
|
||||
|
||||
// Check if New
|
||||
if (isset($settings_data['new_insert']) && $settings_data['new_insert'] === 'true' && isset($settings_data['feedtype'])) {
|
||||
$feedtype = sanitize_text_field($settings_data['feedtype']);
|
||||
$feed_type_data = self::create_single_feed_type_data($feedtype, $selected_feed_model);
|
||||
$settings_data = array_merge($feed_type_data, $settings_data);
|
||||
|
||||
$settings_data['feed_name'] = self::create_feed_name($settings_data['feedtype'], $selected_feed_model);
|
||||
}
|
||||
|
||||
unset($settings_data['feedtype']);
|
||||
unset($settings_data['selectedFeedModel']);
|
||||
unset($settings_data['new_insert']);
|
||||
unset($settings_data['sourcename']);
|
||||
$feed_name = '';
|
||||
if ($update_feed) {
|
||||
$feed_name = $settings_data['feed_name'];
|
||||
$settings_data = $settings_data['settings'];
|
||||
}
|
||||
|
||||
unset($settings_data['sources']);
|
||||
|
||||
$feed_saver = new SBY_Feed_Saver($feed_id);
|
||||
$feed_saver->set_feed_name($feed_name);
|
||||
$feed_saver->set_data($settings_data);
|
||||
|
||||
$return = array(
|
||||
'success' => false,
|
||||
'feed_id' => false,
|
||||
);
|
||||
|
||||
if ($feed_saver->update_or_insert()) {
|
||||
$return = array(
|
||||
'success' => true,
|
||||
'feed_id' => $feed_saver->get_feed_id(),
|
||||
);
|
||||
if ($is_new_feed) {
|
||||
echo wp_json_encode($return);
|
||||
wp_die();
|
||||
} else {
|
||||
$feed_cache = new SBY_Cache($feed_id);
|
||||
$feed_cache->clear('all');
|
||||
$feed_cache->clear('posts');
|
||||
echo wp_json_encode($return);
|
||||
wp_die();
|
||||
}
|
||||
}
|
||||
echo wp_json_encode($return);
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of feeds with a limit and offset like a page
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function get_feed_list_page()
|
||||
{
|
||||
check_ajax_referer('sby-admin', 'nonce');
|
||||
|
||||
if (! sby_current_user_can('manage_youtube_feed_options')) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$args = array( 'page' => (int)$_POST['page'] );
|
||||
$feeds_data = sby_builder_pro()->get_feed_list($args);
|
||||
|
||||
echo wp_json_encode($feeds_data);
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in an AJAX call to delete a feed cache from the Database
|
||||
* $_POST data.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function clear_single_feed_cache()
|
||||
{
|
||||
check_ajax_referer('sby-admin', 'nonce');
|
||||
|
||||
if (! sby_current_user_can('manage_youtube_feed_options')) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$feed_id = sanitize_key($_POST['feedID']);
|
||||
// clear object cache
|
||||
sby_clear_object_cache();
|
||||
// clear transients
|
||||
sby_clear_cache();
|
||||
self::feed_customizer_fly_preview();
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used To check if it's customizer Screens
|
||||
* Returns Feed info or false!
|
||||
*
|
||||
* @param bool $include_comments
|
||||
*
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function maybe_feed_customizer_data($include_comments = false)
|
||||
{
|
||||
if (isset($_GET['feed_id'])) {
|
||||
$feed_id = sanitize_key($_GET['feed_id']);
|
||||
$feed_saver = new SBY_Feed_Saver($feed_id);
|
||||
$settings = $feed_saver->get_feed_settings();
|
||||
$feed_db_data = $feed_saver->get_feed_db_data();
|
||||
|
||||
if ($settings !== false) {
|
||||
$return = array(
|
||||
'feed_info' => $feed_db_data,
|
||||
'headerData' => $feed_db_data,
|
||||
'settings' => $settings,
|
||||
'posts' => array(),
|
||||
);
|
||||
if (intval($feed_id) > 0) {
|
||||
$instagram_feed_settings = new \SB_Instagram_Settings_Pro(
|
||||
array(
|
||||
'feed' => $feed_id,
|
||||
'customizer' => true,
|
||||
),
|
||||
sbi_defaults()
|
||||
);
|
||||
} else {
|
||||
$instagram_feed_settings = new \SB_Instagram_Settings_Pro($settings, sbi_defaults());
|
||||
}
|
||||
|
||||
$instagram_feed_settings->set_feed_type_and_terms();
|
||||
$instagram_feed_settings->set_transient_name();
|
||||
$transient_name = $instagram_feed_settings->get_transient_name();
|
||||
$settings = $instagram_feed_settings->get_settings();
|
||||
|
||||
$feed_type_and_terms = $instagram_feed_settings->get_feed_type_and_terms();
|
||||
if ($feed_id === 'legacy' && $transient_name === 'sbi_false') {
|
||||
$transient_name = 'sbi_legacy';
|
||||
}
|
||||
$instagram_feed = new \SB_Instagram_Feed_Pro($transient_name);
|
||||
|
||||
$instagram_feed->set_cache($instagram_feed_settings->get_cache_time_in_seconds(), $settings);
|
||||
|
||||
if ($instagram_feed->regular_cache_exists()) {
|
||||
$instagram_feed->set_post_data_from_cache();
|
||||
|
||||
if ($instagram_feed->need_posts($settings['num']) && $instagram_feed->can_get_more_posts()) {
|
||||
while ($instagram_feed->need_posts($settings['num']) && $instagram_feed->can_get_more_posts()) {
|
||||
$instagram_feed->add_remote_posts($settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed());
|
||||
}
|
||||
|
||||
$instagram_feed->cache_feed_data($instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled']);
|
||||
}
|
||||
} else {
|
||||
while ($instagram_feed->need_posts($settings['num']) && $instagram_feed->can_get_more_posts()) {
|
||||
$instagram_feed->add_remote_posts($settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed());
|
||||
}
|
||||
|
||||
if ($instagram_feed->out_of_next_pages() || $instagram_feed->should_look_for_db_only_posts($settings, $feed_type_and_terms)) {
|
||||
$instagram_feed->add_db_only_posts($transient_name, $settings, $feed_type_and_terms);
|
||||
}
|
||||
|
||||
if (! $instagram_feed->should_use_backup()) {
|
||||
$instagram_feed->cache_feed_data($instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled']);
|
||||
} elseif ($instagram_feed->should_cache_error()) {
|
||||
$cache_time = min($instagram_feed_settings->get_cache_time_in_seconds(), 15 * 60);
|
||||
$instagram_feed->cache_feed_data($cache_time, false);
|
||||
}
|
||||
}
|
||||
$return['posts'] = $instagram_feed->get_post_data();
|
||||
|
||||
$header_data = array();
|
||||
|
||||
$instagram_feed->set_remote_header_data($settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed());
|
||||
$header_data = $instagram_feed->get_header_data();
|
||||
if ($settings['stories'] && ! empty($header_data)) {
|
||||
$instagram_feed->set_remote_stories_data($settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed());
|
||||
}
|
||||
$instagram_feed->cache_header_data($instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled']);
|
||||
if (! empty($header_data) && \SB_Instagram_Connected_Account::local_avatar_exists($header_data['username'])) {
|
||||
$header_data['local_avatar_url'] = \SB_Instagram_Connected_Account::get_local_avatar_url($header_data['username']);
|
||||
$header_data['local_avatar'] = \SB_Instagram_Connected_Account::get_local_avatar_url($header_data['username']);
|
||||
} else {
|
||||
$header_data['local_avatar'] = false;
|
||||
}
|
||||
$header_data['local_avatar'] = false;
|
||||
$return['header'] = $header_data;
|
||||
$return['headerData'] = $header_data;
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get single feed type create data
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function create_single_feed_type_data($feedtype, $model)
|
||||
{
|
||||
$feed_data = array();
|
||||
$feed_data['usecustomsearch'] = '';
|
||||
$feed_data['showpast'] = '';
|
||||
$feed_data['customsearch'] = '';
|
||||
$feed_data['api_key'] = '';
|
||||
$feed_data['type'] = $feedtype;
|
||||
$feed_data['channel'] = $model['channel'];
|
||||
$feed_data['playlist'] = $model['playlist'];
|
||||
$feed_data['favorites'] = $model['favorites'];
|
||||
$feed_data['search'] = $model['search'];
|
||||
$feed_data['live'] = $model['live'];
|
||||
$feed_data['single'] = $model['single'];
|
||||
|
||||
$feed_data['caching_type'] = 'page';
|
||||
$feed_data['caching_time'] = 1;
|
||||
$feed_data['caching_time_unit'] = 'hours';
|
||||
$feed_data['cache_cron_interval'] = '30mins';
|
||||
$feed_data['cache_cron_time'] = 0;
|
||||
$feed_data['cache_cron_am_pm'] = 'am';
|
||||
|
||||
return $feed_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to retrieve Feed Posts for preview screen
|
||||
* Returns Feed info or false!
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function feed_customizer_fly_preview()
|
||||
{
|
||||
check_ajax_referer('sby-admin', 'nonce');
|
||||
|
||||
if (! sby_current_user_can('manage_youtube_feed_options')) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
if (isset($_POST['feedID']) && isset($_POST['previewSettings'])) {
|
||||
$feed_id = $_POST['feedID'];
|
||||
$preview_settings = SBY_Parse::parse_quoted_string_as_boolean($_POST['previewSettings']);
|
||||
$feed_name = $_POST['feedName'];
|
||||
|
||||
$preview_settings = isset($_POST['isFeedTemplatesPopup']) ? SBY_Feed_Templates_Settings::get_feed_settings_by_feed_templates($preview_settings) + $preview_settings : $preview_settings;
|
||||
|
||||
$feed_saver = new SBY_Feed_Saver($feed_id);
|
||||
$feed_saver->set_feed_name($feed_name);
|
||||
$feed_saver->set_data($preview_settings);
|
||||
|
||||
if (isset($_POST['clearCache']) && $_POST['clearCache'] == true) {
|
||||
sby_clear_cache();
|
||||
}
|
||||
|
||||
$atts = Feed_Builder::add_customizer_att(
|
||||
array(
|
||||
'feed' => $feed_id,
|
||||
'customizer' => true,
|
||||
)
|
||||
);
|
||||
|
||||
//Fixes Carousel preview issue.
|
||||
$only_preview = self::carousel_column_preview($_POST['previewScreen'],$preview_settings);
|
||||
|
||||
$shortcode = new ShortcodeService();
|
||||
$feed_output = $shortcode->sby_youtube_feed($atts, $only_preview);
|
||||
$return['feed_html'] = $feed_output['feedInitOutput'];
|
||||
;
|
||||
$return['customizerDataSettings'] = $preview_settings;
|
||||
|
||||
echo json_encode($return);
|
||||
}
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to feed handle for preview screen
|
||||
* Returns Feed info or false!
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function feed_customizer_feed_handle_fly_preview()
|
||||
{
|
||||
check_ajax_referer('sby-admin', 'nonce');
|
||||
|
||||
if (! sby_current_user_can('manage_youtube_feed_options')) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
if (isset($_POST['feedID']) && isset($_POST['previewSettings'])) {
|
||||
$feed_id = $_POST['feedID'];
|
||||
$preview_settings = SBY_Parse::parse_quoted_string_as_boolean($_POST['previewSettings']);
|
||||
$feed_name = $_POST['feedName'];
|
||||
$feed_type = $_POST['feedType'];
|
||||
|
||||
$preview_settings = isset($_POST['isFeedTemplatesPopup']) ? SBY_Feed_Templates_Settings::get_feed_settings_by_feed_templates($preview_settings) + $preview_settings : $preview_settings;
|
||||
$preview_settings = self::filter_feed_model_data($preview_settings, $feed_type);
|
||||
|
||||
$feed_saver = new SBY_Feed_Saver($feed_id);
|
||||
$feed_saver->set_feed_name($feed_name);
|
||||
$feed_saver->set_data($preview_settings);
|
||||
|
||||
if (isset($_POST['clearCache']) && $_POST['clearCache'] == true) {
|
||||
sby_clear_cache();
|
||||
}
|
||||
|
||||
$atts = Feed_Builder::add_customizer_att(
|
||||
array(
|
||||
'feed' => $feed_id,
|
||||
'customizer' => true,
|
||||
)
|
||||
);
|
||||
|
||||
$shortcode = new ShortcodeService();
|
||||
$feed_output = $shortcode->sby_youtube_feed($atts, $preview_settings);
|
||||
$return['feed_html'] = $feed_output['feedInitOutput'];
|
||||
;
|
||||
$return['customizerDataSettings'] = $preview_settings;
|
||||
|
||||
echo json_encode($return);
|
||||
}
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in an AJAX call to duplicate a Feed
|
||||
* $_POST data.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function duplicate_feed()
|
||||
{
|
||||
check_ajax_referer('sby-admin', 'nonce');
|
||||
|
||||
if (! sby_current_user_can('manage_youtube_feed_options')) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
if (! empty($_POST['feed_id'])) {
|
||||
DB::duplicate_feed_query($_POST['feed_id']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in an AJAX call to delete feeds from the Database
|
||||
* $_POST data.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function delete_feed()
|
||||
{
|
||||
check_ajax_referer('sby-admin', 'nonce');
|
||||
|
||||
if (! sby_current_user_can('manage_youtube_feed_options')) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
if (! empty($_POST['feeds_ids']) && is_array($_POST['feeds_ids'])) {
|
||||
DB::delete_feeds_query($_POST['feeds_ids']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Feed Name
|
||||
* This will create the feed name when creating new Feeds
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function create_feed_name($selected_feed, $selected_feed_models)
|
||||
{
|
||||
$feed_name = 'YouTube Feed';
|
||||
if ($selected_feed) {
|
||||
$feed_name .= ' - ' . ucfirst($selected_feed);
|
||||
}
|
||||
|
||||
return DB::feeds_query_name($feed_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to dismiss onboarding using AJAX
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function after_dismiss_onboarding()
|
||||
{
|
||||
check_ajax_referer('sby-admin', 'nonce');
|
||||
|
||||
if (! sby_current_user_can('manage_youtube_feed_options')) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$type = 'newuser';
|
||||
if (isset($_POST['was_active'])) {
|
||||
$type = sanitize_text_field($_POST['was_active']);
|
||||
}
|
||||
|
||||
Feed_Builder::update_onboarding_meta('dismissed', $type);
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in an AJAX call to delete a feed cache from the Database
|
||||
* $_POST data.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function feed_refresh()
|
||||
{
|
||||
check_ajax_referer('sby-admin', 'nonce');
|
||||
|
||||
if (! sby_current_user_can('manage_youtube_feed_options')) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$feed_id = sanitize_key($_POST['feedID']);
|
||||
|
||||
sby_clear_cache();
|
||||
self::feed_customizer_fly_preview();
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter feed model data
|
||||
*
|
||||
* @since 2.2
|
||||
*/
|
||||
public static function filter_feed_model_data($feed_data, $feedtype)
|
||||
{
|
||||
if ($feedtype == 'channel') {
|
||||
$channel = $feed_data['channel'];
|
||||
} elseif ($feedtype == 'favorites') {
|
||||
$channel = $feed_data['favorites'];
|
||||
} elseif ($feedtype == 'live') {
|
||||
$channel = $feed_data['live'];
|
||||
}
|
||||
|
||||
$channel_id = '';
|
||||
$channel_url = '';
|
||||
if (strpos($channel, '@') !== false && ( strpos($channel, 'https://') !== false || strpos($channel, 'http://') !== false )) {
|
||||
$channel_url = $channel;
|
||||
} elseif (strpos($channel, '@') !== false) {
|
||||
$channel_url = 'https://www.youtube.com/' . $channel;
|
||||
}
|
||||
if ($channel_url) {
|
||||
$saved_channel_id = Util::get_saved_channel_id($channel);
|
||||
if (! $saved_channel_id) {
|
||||
$channel_id = Util::get_channel_id_by_api_request($channel_url);
|
||||
} else {
|
||||
$channel_id = $saved_channel_id;
|
||||
}
|
||||
} else {
|
||||
$channel_id = $channel;
|
||||
}
|
||||
|
||||
if ($feedtype == 'channel') {
|
||||
$feed_data['channel'] = $channel_id;
|
||||
} elseif ($feedtype == 'favorites') {
|
||||
$feed_data['favorites'] = $channel_id;
|
||||
} elseif ($feedtype == 'live') {
|
||||
$feed_data['live'] = $channel_id;
|
||||
}
|
||||
|
||||
return $feed_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines what table and sanitization should be used
|
||||
* when handling feed setting data.
|
||||
*
|
||||
* TODO: Add settings that need something other than sanitize_text_field
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function get_data_type($key)
|
||||
{
|
||||
switch ($key) {
|
||||
case 'sources':
|
||||
$return = array(
|
||||
'table' => 'feed_settings',
|
||||
'sanitization' => 'sanitize_text_field',
|
||||
);
|
||||
break;
|
||||
case 'feed_title':
|
||||
$return = array(
|
||||
'table' => 'feeds',
|
||||
'sanitization' => 'sanitize_text_field',
|
||||
);
|
||||
break;
|
||||
case 'feed_name':
|
||||
$return = array(
|
||||
'table' => 'feeds',
|
||||
'sanitization' => 'sanitize_text_field',
|
||||
);
|
||||
break;
|
||||
case 'status':
|
||||
$return = array(
|
||||
'table' => 'feeds',
|
||||
'sanitization' => 'sanitize_text_field',
|
||||
);
|
||||
break;
|
||||
case 'author':
|
||||
$return = array(
|
||||
'table' => 'feeds',
|
||||
'sanitization' => 'int',
|
||||
);
|
||||
break;
|
||||
default:
|
||||
$return = array(
|
||||
'table' => 'feed_settings',
|
||||
'sanitization' => 'sanitize_text_field',
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if boolean
|
||||
* for a value
|
||||
*
|
||||
* @param string $type
|
||||
* @param int|string $value
|
||||
*
|
||||
* @return int|string
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function is_boolean($value)
|
||||
{
|
||||
return ( $value === 'true' || $value === 'false' || is_bool($value) ) ? true : false;
|
||||
}
|
||||
|
||||
public static function cast_boolean($value)
|
||||
{
|
||||
if ($value === 'true' || $value === true || $value === 'on') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the appropriate sanitization function and returns the result
|
||||
* for a value
|
||||
*
|
||||
* @param string $type
|
||||
* @param int|string $value
|
||||
*
|
||||
* @return int|string
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function sanitize($type, $value)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'int':
|
||||
$return = intval($value);
|
||||
break;
|
||||
case 'boolean':
|
||||
$return = self::cast_boolean($value);
|
||||
break;
|
||||
default:
|
||||
$return = sanitize_text_field(wp_unslash($value));
|
||||
break;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear comments cache AJAX call
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 2.3.3
|
||||
*/
|
||||
public static function clear_comments_cache()
|
||||
{
|
||||
check_ajax_referer('sby-admin', 'nonce');
|
||||
|
||||
if (! current_user_can('manage_youtube_feed_options')) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
delete_transient('sby_comment_cache');
|
||||
echo 'success';
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Carousel Column Preview.
|
||||
*
|
||||
* @param string $preview_screen
|
||||
* @param array $preview_settings
|
||||
* @return array
|
||||
*
|
||||
* @since 2.3.4
|
||||
*/
|
||||
public static function carousel_column_preview($preview_screen, $preview_settings) {
|
||||
// Return if preview_settings does not exist.
|
||||
if(empty($preview_settings)) {
|
||||
return $preview_settings;
|
||||
}
|
||||
|
||||
$layout = !empty($preview_settings['layout']) ? $preview_settings['layout'] : '';
|
||||
|
||||
// As we do not use iframe owl slider still thinks that it's in desktop mode ( on mobile view inside preview ). So we just intercepted the desktop value with the mobile one to simulate the desired behavior.
|
||||
if( !empty( $preview_screen ) && 'mobile' === $preview_screen && 'carousel' === $layout ) {
|
||||
$preview_settings['cols'] = $preview_settings['colsmobile'];
|
||||
}
|
||||
|
||||
return $preview_settings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,359 @@
|
||||
<?php
|
||||
/**
|
||||
* The Feed Templates Settings Class
|
||||
*
|
||||
* It has the default settings for the feed templates for various feed types
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Builder;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
class SBY_Feed_Templates_Settings {
|
||||
|
||||
/**
|
||||
* Add feed settings depending on feed templates
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public static function get_feed_settings_by_feed_templates( $settings ) {
|
||||
// Check if the feedtype is timelime/posts
|
||||
if ( $settings['feedtemplate'] == 'default' ) {
|
||||
$settings = self::get_default_feedtemplate_settings( $settings );
|
||||
}
|
||||
|
||||
if ( $settings['feedtemplate'] == 'carousel' ) {
|
||||
$settings = self::get_carousel_feedtemplate_settings( $settings );
|
||||
}
|
||||
|
||||
if ( $settings['feedtemplate'] == 'cards' ) {
|
||||
$settings = self::get_cards_feedtemplate_settings( $settings );
|
||||
}
|
||||
|
||||
if ( $settings['feedtemplate'] == 'list' ) {
|
||||
$settings = self::get_list_feedtemplate_settings( $settings );
|
||||
}
|
||||
|
||||
if ( $settings['feedtemplate'] == 'gallery' ) {
|
||||
$settings = self::get_gallery_feedtemplate_settings( $settings );
|
||||
}
|
||||
|
||||
if ( $settings['feedtemplate'] == 'latest_video' ) {
|
||||
$settings = self::get_latest_video_feedtemplate_settings( $settings );
|
||||
}
|
||||
|
||||
if ( $settings['feedtemplate'] == 'showcase_carousel' ) {
|
||||
$settings = self::get_showcase_carousel_feedtemplate_settings( $settings );
|
||||
}
|
||||
|
||||
if ( $settings['feedtemplate'] == 'widget' ) {
|
||||
$settings = self::get_widget_feedtemplate_settings( $settings );
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Feed settings for default template type
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array $settings
|
||||
*/
|
||||
public static function get_default_feedtemplate_settings( $settings ) {
|
||||
$settings['layout'] = 'grid';
|
||||
$settings['cols'] = '3';
|
||||
$settings['colsmobile'] = '1';
|
||||
$settings['num'] = '9';
|
||||
$settings['itemspacing'] = '5';
|
||||
|
||||
$settings['colorpalette'] = 'inherit';
|
||||
|
||||
$settings['showheader'] = false;
|
||||
$settings['videocardstyle'] = 'regular';
|
||||
|
||||
$settings = self::enable_comments_for_template( $settings, true );
|
||||
$settings = self::get_default_loadmore_button_settings( $settings );
|
||||
$settings = self::get_default_subscribe_button_settings( $settings );
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Feed settings for carousel template type
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array $settings
|
||||
*/
|
||||
public static function get_carousel_feedtemplate_settings( $settings ) {
|
||||
$settings = self::get_default_carousel_settings( $settings );
|
||||
|
||||
$settings['cols'] = '3';
|
||||
$settings['colsmobile'] = '1';
|
||||
|
||||
$settings['num'] = '9';
|
||||
$settings['itemspacing'] = '5';
|
||||
|
||||
$settings['colorpalette'] = 'inherit';
|
||||
|
||||
$settings['showheader'] = true;
|
||||
$settings['headerstyle'] = 'text';
|
||||
$settings['customheadertext'] = 'We are on YouTube';
|
||||
$settings['customheadersize'] = 'medium';
|
||||
$settings = self::get_default_loadmore_button_settings( $settings );
|
||||
$settings = self::get_default_subscribe_button_settings( $settings );
|
||||
|
||||
$settings['videocardstyle'] = 'regular';
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Feed settings for cards template type
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array $settings
|
||||
*/
|
||||
public static function get_cards_feedtemplate_settings( $settings ) {
|
||||
$settings['layout'] = 'grid';
|
||||
$settings['cols'] = '3';
|
||||
$settings['colsmobile'] = '1';
|
||||
|
||||
$settings['num'] = '9';
|
||||
$settings['itemspacing'] = '8';
|
||||
|
||||
$settings['colorpalette'] = 'inherit';
|
||||
|
||||
$settings['showheader'] = true;
|
||||
$settings['headerstyle'] = 'text';
|
||||
$settings['customheadertext'] = 'We are on YouTube';
|
||||
$settings['customheadersize'] = 'medium';
|
||||
|
||||
$settings['videocardstyle'] = 'boxed';
|
||||
$settings['boxedbgcolor'] = '#ffffff';
|
||||
$settings['boxborderradius'] = '4';
|
||||
$settings['enableboxshadow'] = true;
|
||||
|
||||
$settings = self::enable_comments_for_template( $settings, true );
|
||||
$settings = self::get_default_loadmore_button_settings( $settings );
|
||||
$settings = self::get_default_subscribe_button_settings( $settings );
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Feed settings for lists template type
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array $settings
|
||||
*/
|
||||
public static function get_list_feedtemplate_settings( $settings ) {
|
||||
$settings['layout'] = 'list';
|
||||
|
||||
$settings['num'] = '2';
|
||||
$settings['itemspacing'] = '5';
|
||||
|
||||
$settings['colorpalette'] = 'inherit';
|
||||
|
||||
$settings['showheader'] = true;
|
||||
$settings['headerstyle'] = 'standard';
|
||||
|
||||
$settings['videocardstyle'] = 'regular';
|
||||
|
||||
$settings = self::enable_comments_for_template( $settings, false );
|
||||
$settings = self::get_default_loadmore_button_settings( $settings );
|
||||
$settings = self::get_default_subscribe_button_settings( $settings );
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Feed settings for gallery template type
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array $settings
|
||||
*/
|
||||
public static function get_gallery_feedtemplate_settings( $settings ) {
|
||||
$settings['layout'] = 'gallery';
|
||||
$settings['cols'] = '3';
|
||||
$settings['colsmobile'] = '1';
|
||||
$settings['num'] = '6';
|
||||
$settings['itemspacing'] = '5';
|
||||
|
||||
$settings['colorpalette'] = 'inherit';
|
||||
|
||||
$settings['showheader'] = false;
|
||||
$settings['videocardstyle'] = 'regular';
|
||||
|
||||
$settings = self::enable_comments_for_template( $settings, false );
|
||||
$settings = self::get_default_loadmore_button_settings( $settings );
|
||||
$settings = self::get_default_subscribe_button_settings( $settings );
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Feed settings for latest_video template type
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array $settings
|
||||
*/
|
||||
public static function get_latest_video_feedtemplate_settings( $settings ) {
|
||||
$settings['layout'] = 'list';
|
||||
|
||||
$settings['num'] = '1';
|
||||
$settings['itemspacing'] = '5';
|
||||
|
||||
$settings['colorpalette'] = 'inherit';
|
||||
|
||||
$settings['showheader'] = true;
|
||||
|
||||
$settings['videocardstyle'] = 'regular';
|
||||
|
||||
$settings = self::enable_comments_for_template( $settings, true );
|
||||
$settings = self::get_default_loadmore_button_settings( $settings );
|
||||
$settings = self::get_default_subscribe_button_settings( $settings );
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Feed settings for showcase carousel template type
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array $settings
|
||||
*/
|
||||
public static function get_showcase_carousel_feedtemplate_settings( $settings ) {
|
||||
$settings = self::get_default_carousel_settings( $settings );
|
||||
|
||||
$settings['cols'] = '1';
|
||||
$settings['colsmobile'] = '1';
|
||||
|
||||
$settings['num'] = '3';
|
||||
$settings['itemspacing'] = '5';
|
||||
|
||||
$settings['colorpalette'] = 'inherit';
|
||||
|
||||
$settings['showheader'] = true;
|
||||
|
||||
$settings = self::get_default_loadmore_button_settings( $settings );
|
||||
$settings = self::get_default_subscribe_button_settings( $settings );
|
||||
|
||||
$settings['videocardstyle'] = 'regular';
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Feed settings for widget template type
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array $settings
|
||||
*/
|
||||
public static function get_widget_feedtemplate_settings( $settings ) {
|
||||
$settings['layout'] = 'list';
|
||||
|
||||
$settings['num'] = '2';
|
||||
$settings['itemspacing'] = '5';
|
||||
|
||||
$settings['colorpalette'] = 'inherit';
|
||||
|
||||
$settings['showheader'] = false;
|
||||
|
||||
$settings['videocardstyle'] = 'regular';
|
||||
|
||||
$settings = self::get_default_loadmore_button_settings( $settings );
|
||||
$settings = self::get_default_subscribe_button_settings( $settings );
|
||||
$settings = self::enable_comments_for_template( $settings, false );
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default settings for carousel settings
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array $settings
|
||||
*/
|
||||
public static function get_default_carousel_settings( $settings ) {
|
||||
$settings['layout'] = 'carousel';
|
||||
$settings['carouselrows'] = 1;
|
||||
$settings['carouselloop'] = 'rewind';
|
||||
$settings['carouseltime'] = '3000';
|
||||
$settings['carouselarrows'] = true;
|
||||
$settings['carouselpag'] = true;
|
||||
$settings['carouselautoplay'] = true;
|
||||
$settings = self::enable_comments_for_template( $settings, true );
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default settings for load more button
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array $settings
|
||||
*/
|
||||
public static function get_default_loadmore_button_settings( $settings ) {
|
||||
$settings['showbutton'] = true;
|
||||
$settings['buttoncolor'] = '';
|
||||
$settings['buttonhovercolor'] = '';
|
||||
$settings['buttontextcolor'] = '';
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default settings for subscribe button
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array $settings
|
||||
*/
|
||||
public static function get_default_subscribe_button_settings( $settings ) {
|
||||
$settings['showsubscribe'] = true;
|
||||
$settings['subscribecolor'] = '';
|
||||
$settings['subscribehovercolor'] = 'rgb(255, 255, 255, .25)';
|
||||
$settings['subscribetextcolor'] = '';
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables comments for the template settings if the conditions are met.
|
||||
*
|
||||
* @since 2.3.3
|
||||
*
|
||||
* @param array $settings
|
||||
* @param bool $flag
|
||||
* @return array $settings
|
||||
*/
|
||||
private static function enable_comments_for_template($settings, $flag) {
|
||||
if( sby_is_pro() && !sby_license_notices_active()) {
|
||||
$settings['enablecomments'] = $flag;
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
846
wp-content/plugins/youtube-feed-pro/inc/Builder/SBY_Source.php
Normal file
846
wp-content/plugins/youtube-feed-pro/inc/Builder/SBY_Source.php
Normal file
@@ -0,0 +1,846 @@
|
||||
<?php
|
||||
/**
|
||||
* YouTube Feed Source
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* Current Connected Account Data Example
|
||||
*
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Builder;
|
||||
|
||||
use function DI\value;
|
||||
|
||||
class SBY_Source {
|
||||
|
||||
const BATCH_SIZE = 10;
|
||||
|
||||
/**
|
||||
* AJAX hooks for various feed data related functionality
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function hooks() {
|
||||
add_action( 'wp_ajax_sbi_source_builder_update', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Source', 'builder_update' ) );
|
||||
add_action( 'wp_ajax_sbi_source_builder_update_multiple', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Source', 'builder_update_multiple' ) );
|
||||
add_action( 'wp_ajax_sbi_source_get_page', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Source', 'get_page' ) );
|
||||
add_action( 'wp_ajax_sbi_source_get_featured_post_preview', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Source', 'get_featured_post_preview' ) );
|
||||
add_action( 'wp_ajax_sbi_source_get_playlist_post_preview', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Source', 'get_playlist_post_preview' ) );
|
||||
add_action( 'admin_init', array( 'SmashBalloon\YouTubeFeed\Builder\SBY_Source', 'batch_process_legacy_source_queue' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in an AJAX call to update sources based on selections or
|
||||
* input from a user. Makes an API request to add additiona info
|
||||
* about the connected source.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function builder_update() {
|
||||
if ( ! check_ajax_referer( 'sbi_admin_nonce' , 'nonce', false ) && ! check_ajax_referer( 'sby-admin' , 'nonce', false ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
if ( ! sby_current_user_can( 'manage_instagram_feed_options' ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$source_data = array(
|
||||
'access_token' => sanitize_text_field( $_POST['access_token'] ),
|
||||
'id' => sanitize_text_field( $_POST['id'] ),
|
||||
'type' => sanitize_text_field( $_POST['type'] ),
|
||||
'username' => isset( $_POST['username'] ) ? sanitize_text_field( $_POST['username'] ) : '',
|
||||
);
|
||||
|
||||
$return = sbi_connect_new_account( $source_data['access_token'], $source_data['id'] );
|
||||
|
||||
if ( empty( $return['error'] ) ) {
|
||||
wp_send_json_success( SBI_Feed_Builder::get_source_list() );
|
||||
}
|
||||
wp_send_json_error( array( 'message' => $return['error'] ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add our update a source from raw API data.
|
||||
*
|
||||
* @param $source_data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function process_connecting_source_data( $source_data ) {
|
||||
$connected_account = array(
|
||||
'id' => $source_data['id'],
|
||||
'user_id' => $source_data['id'],
|
||||
'type' => $source_data['type'],
|
||||
'account_type' => $source_data['type'],
|
||||
'username' => $source_data['username'],
|
||||
'access_token' => $source_data['access_token'],
|
||||
'privilege' => $source_data['privilege'],
|
||||
);
|
||||
$single_source = self::update_single_source( $connected_account, false );
|
||||
|
||||
if ( ! empty( $single_source['error'] ) ) {
|
||||
$message = ! empty( $single_source['error']['error']['message'] ) ? esc_html( $single_source['error']['error']['message'] ) : '';
|
||||
$code = ! empty( $single_source['error']['error']['code'] ) ? esc_html( $single_source['error']['error']['code'] ) : '';
|
||||
if ( isset( $single_source['error']['response'] ) && is_wp_error( $single_source['error']['response'] ) ) {
|
||||
$response = $single_source['error']['response'];
|
||||
$message = sprintf( __( 'Error connecting to %s.', 'feeds-for-youtube' ), $single_source['error']['url'] );
|
||||
if ( isset( $response ) && isset( $response->errors ) ) {
|
||||
foreach ( $response->errors as $key => $item ) {
|
||||
$code = $key;
|
||||
$message .= $item[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
$message .= ' <a href="https://smashballoon.com/instagram-feed/docs/errors/" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'feeds-for-youtube' ) . '</a>';
|
||||
|
||||
$return_html = '<div class="sb-alerts-wrap"><div class="sb-alert">';
|
||||
$return_html .= '<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">';
|
||||
$return_html .= '<path d="M8.99935 0.666504C4.39935 0.666504 0.666016 4.39984 0.666016 8.99984C0.666016 13.5998 4.39935 17.3332 8.99935 17.3332C13.5993 17.3332 17.3327 13.5998 17.3327 8.99984C17.3327 4.39984 13.5993 0.666504 8.99935 0.666504ZM9.83268 13.1665H8.16602V11.4998H9.83268V13.1665ZM9.83268 9.83317H8.16602V4.83317H9.83268V9.83317Z" fill="#995C00"/>';
|
||||
$return_html .= '</svg>';
|
||||
$return_html .= '<span><strong>' . sprintf( __( 'Connection Error: %s ', 'feeds-for-youtube' ), $code ) . '</strong></span><br>' . $message . '</div></div>';
|
||||
|
||||
$return = array(
|
||||
'success' => false,
|
||||
'message' => $return_html,
|
||||
);
|
||||
return json_encode( $return );
|
||||
} else {
|
||||
global $sb_instagram_posts_manager;
|
||||
$sb_instagram_posts_manager->remove_error( 'connection' );
|
||||
}
|
||||
|
||||
$manager = new \SB_Instagram_Data_Manager();
|
||||
$manager->update_last_used();
|
||||
|
||||
return json_encode( SBI_Feed_Builder::get_source_list() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in an AJAX call to update Multiple sources based on selections or
|
||||
* input from a user. Makes an API request to add additiona info
|
||||
* about the connected source.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function builder_update_multiple() {
|
||||
if ( ! check_ajax_referer( 'sbi_admin_nonce' , 'nonce', false ) && ! check_ajax_referer( 'sby-admin' , 'nonce', false ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
if ( ! sby_current_user_can( 'manage_instagram_feed_options' ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
if ( isset( $_POST['sourcesList'] ) && ! empty( $_POST['sourcesList'] ) && is_array( $_POST['sourcesList'] ) ) {
|
||||
foreach ( $_POST['sourcesList'] as $single_source ) :
|
||||
$source_data = array(
|
||||
'access_token' => sanitize_text_field( $single_source['access_token'] ),
|
||||
'id' => sanitize_text_field( $single_source['id'] ),
|
||||
'type' => sanitize_text_field( $single_source['type'] ),
|
||||
'username' => isset( $single_source['username'] ) ? sanitize_text_field( $single_source['username'] ) : '',
|
||||
);
|
||||
|
||||
if ( $single_source['type'] === 'business' ) {
|
||||
$source_data['privilege'] = 'tagged';
|
||||
}
|
||||
|
||||
if ( ! empty( $single_source['name'] ) ) {
|
||||
$source_data['name'] = sanitize_text_field( $single_source['name'] );
|
||||
}
|
||||
|
||||
self::process_connecting_source_data( $source_data );
|
||||
endforeach;
|
||||
}
|
||||
echo json_encode( SBI_Feed_Builder::get_source_list() );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of sources with a limit and offset like a page
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function get_page() {
|
||||
if ( ! check_ajax_referer( 'sbi_admin_nonce' , 'nonce', false ) && ! check_ajax_referer( 'sby-admin' , 'nonce', false ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
if ( ! sby_current_user_can( 'manage_instagram_feed_options' ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$args = array( 'page' => $_POST['page'] );
|
||||
$source_data = SBI_Db::source_query( $args );
|
||||
|
||||
echo json_encode( $source_data );
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection URLs are based on the website connecting accounts so that is
|
||||
* configured here and returned
|
||||
*
|
||||
* @param bool $is_settings
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function get_connection_urls( $is_settings = false ) {
|
||||
$urls = array();
|
||||
$admin_url_state = $is_settings ? admin_url( 'admin.php?page=sby-feed-builder-settings' ) : admin_url( 'admin.php?page=sbi-feed-builder' );
|
||||
//If the admin_url isn't returned correctly then use a fallback
|
||||
if ( $admin_url_state === '/wp-admin/admin.php?page=sbi-feed-builder'
|
||||
|| $admin_url_state === '/wp-admin/admin.php?page=sbi-feed-builder&tab=configuration' ) {
|
||||
$admin_url_state = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
|
||||
}
|
||||
#$urls['personal'] ='https://connect.smashballoon.com/auth/ig/?wordpress_user=&v=pro&vn=' . SBYVER . '&state=';
|
||||
#$urls['business'] = 'https://connect.smashballoon.com/auth/ig/?wordpress_user=&v=pro&vn=' . SBYVER . '&state=';
|
||||
|
||||
$urls['personal'] ='https://connect.smashballoon.com/auth/ig/?wordpress_user=&v=pro&vn=' . SBYVER;
|
||||
$urls['business'] = 'https://connect.smashballoon.com/auth/ig/?wordpress_user=&v=pro&vn=' . SBYVER;
|
||||
|
||||
$urls['stateURL'] = $admin_url_state;
|
||||
|
||||
return $urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used as a listener for the account connection process. If
|
||||
* data is returned from the account connection processed it's used
|
||||
* to generate the list of possible sources to chose from.
|
||||
*
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function maybe_source_connection_data() {
|
||||
if ( isset( $_GET['sbi_access_token'] ) && isset( $_GET['sbi_graph_api'] ) ) {
|
||||
$return = self::retrieve_available_business_accounts();
|
||||
return $return;
|
||||
|
||||
} elseif ( isset( $_GET['sbi_access_token'] ) && isset( $_GET['sbi_account_type'] ) ) {
|
||||
$return = self::retrieve_available_personal_accounts();
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the Instagram Basic Display API to get available personal
|
||||
* accounts
|
||||
*
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function retrieve_available_personal_accounts() {
|
||||
$encryption = new \SB_Instagram_Data_Encryption();
|
||||
$return = array(
|
||||
'type' => 'personal',
|
||||
'unconnectedAccounts' => array(),
|
||||
'matchingExistingAccounts' => array(),
|
||||
'didQuickUpdate' => false,
|
||||
);
|
||||
|
||||
$access_token = sanitize_text_field( $_GET['sbi_access_token'] );
|
||||
if ( empty( $access_token ) ) {
|
||||
return array();
|
||||
}
|
||||
$user_id = sanitize_text_field( $_GET['sbi_id'] );
|
||||
$user_name = sanitize_text_field( $_GET['sbi_username'] );
|
||||
$expires_in = (int) $_GET['sbi_expires_in'];
|
||||
$expires_timestamp = time() + $expires_in;
|
||||
|
||||
$source_data = array(
|
||||
'access_token' => $access_token,
|
||||
'id' => $user_id,
|
||||
'user_id' => $user_id,
|
||||
'type' => 'basic',
|
||||
'username' => $user_name,
|
||||
'privilege' => '',
|
||||
'expires' => date( 'Y-m-d H:i:s', $expires_timestamp ),
|
||||
);
|
||||
|
||||
$connection = new \SB_Instagram_API_Connect( $source_data, 'header', array() );
|
||||
$connection->connect();
|
||||
$header_details = '{}';
|
||||
$source_data['error'] = '';
|
||||
if ( ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) {
|
||||
$header_details_array = $connection->get_data();
|
||||
|
||||
$header_details_array = self::merge_account_details( $header_details_array, $source_data );
|
||||
$source_data['username'] = $header_details_array['username'];
|
||||
$header_details = json_encode( $header_details_array );
|
||||
} else {
|
||||
$source_data['error'] = $connection;
|
||||
if ( $connection->is_wp_error() ) {
|
||||
$page_error = $connection->get_wp_error();
|
||||
if ( ! empty( $page_error ) && isset( $page_error['response']->errors ) ) {
|
||||
$error_message = '';
|
||||
foreach ( $page_error['response']->errors as $key => $item ) {
|
||||
$error_message .= $key . ': ' . $item[0] . ' ';
|
||||
}
|
||||
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => 'HTTP Request',
|
||||
'message' => $error_message,
|
||||
'details' => $error_message,
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$error = $connection->get_data();
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => $error['error']['code'],
|
||||
'message' => $error['error']['message'],
|
||||
'details' => $error['error']['message'],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$source_data['info'] = $header_details;
|
||||
$return['unconnectedAccounts'][] = $source_data;
|
||||
|
||||
$args = array(
|
||||
'id' => $user_id,
|
||||
);
|
||||
$results = SBI_Db::source_query( $args );
|
||||
$already_connected_as_business_account = ( isset( $results[0] ) && $results[0]['account_type'] === 'business' );
|
||||
$matches_existing_personal = ( isset( $results[0] ) && $results[0]['account_type'] === 'personal' );
|
||||
|
||||
if ( $already_connected_as_business_account ) {
|
||||
$return['matchingExistingAccounts'] = $results[0];
|
||||
$instagram_account_data = json_decode( $encryption->decrypt( $results[0]['info'] ), true );
|
||||
$return['matchingExistingAccounts']['avatar'] = isset( $instagram_account_data['profile_picture_url'] ) ? $instagram_account_data['profile_picture_url'] : false;
|
||||
|
||||
$return['notice'] = __( 'The Instagram account you are logged into is already connected as a "business" account. Remove the business account if you\'d like to connect as a basic account instead (not recommended).', 'feeds-for-youtube' );
|
||||
} elseif ( $matches_existing_personal ) {
|
||||
$return['matchingExistingAccounts'] = $results[0];
|
||||
self::update_or_insert( $source_data );
|
||||
$return['notice'] = '';
|
||||
$return['didQuickUpdate'] = true;
|
||||
} else {
|
||||
self::update_or_insert( $source_data );
|
||||
$return['didQuickUpdate'] = true;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the Facebook API to retrieve a list of business accounts
|
||||
*
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function retrieve_available_business_accounts() {
|
||||
|
||||
$return = array(
|
||||
'type' => 'business',
|
||||
'unconnectedAccounts' => array(),
|
||||
'matchingExistingAccounts' => array(),
|
||||
'didQuickUpdate' => false,
|
||||
);
|
||||
|
||||
$access_token = sbi_maybe_clean( urldecode( $_GET['sbi_access_token'] ) );
|
||||
if ( empty( $access_token ) ) {
|
||||
return array();
|
||||
}
|
||||
$url = 'https://graph.facebook.com/me/accounts?fields=instagram_business_account,access_token&limit=500&access_token=' . $access_token;
|
||||
|
||||
$args = array(
|
||||
'timeout' => 60,
|
||||
);
|
||||
$result = wp_remote_get( $url, $args );
|
||||
$pages_data = '{}';
|
||||
if ( ! is_wp_error( $result ) ) {
|
||||
$pages_data = $result['body'];
|
||||
} else {
|
||||
$page_error = $result;
|
||||
}
|
||||
|
||||
if ( isset( $page_error ) && isset( $page_error->errors ) ) {
|
||||
$error_message = '';
|
||||
foreach ( $page_error->errors as $key => $item ) {
|
||||
$error_message .= $key . ': ' . $item[0] . ' ';
|
||||
}
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => 'HTTP Request',
|
||||
'message' => __( 'Your server could not complete a remote request to Facebook\'s API. Your host may be blocking access or there may be a problem with your server.', 'feeds-for-youtube' ),
|
||||
'details' => $error_message,
|
||||
),
|
||||
);
|
||||
}
|
||||
$pages_data_arr = json_decode( $pages_data, true );
|
||||
|
||||
if ( empty( $pages_data_arr['data'] ) ) {
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => 'No Accounts Found',
|
||||
'message' => __( 'Couldn\'t find Business Profile', 'feeds-for-youtube' ),
|
||||
'details' => sprintf( __( 'Uh oh. It looks like this Facebook account is not currently connected to an Instagram Business profile. Please check that you are logged into the %1$sFacebook account%2$s in this browser which is associated with your Instagram Business Profile.', 'feeds-for-youtube' ), '<a href="https://www.facebook.com/" target="_blank" rel="noopener noreferrer">', '</a>' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
$user_url = 'https://graph.facebook.com/me?fields=name,id,picture&access_token=' . $access_token;
|
||||
$args = array(
|
||||
'timeout' => 60,
|
||||
);
|
||||
$result = wp_remote_get( $user_url, $args );
|
||||
if ( ! is_wp_error( $result ) ) {
|
||||
$user_data = $result['body'];
|
||||
$user_data_arr = json_decode( $user_data, true );
|
||||
|
||||
$return['user'] = $user_data_arr;
|
||||
}
|
||||
$return['numFound'] = count( $pages_data_arr['data'] );
|
||||
|
||||
foreach ( $pages_data_arr['data'] as $page_data ) {
|
||||
if ( isset( $page_data['instagram_business_account'] ) ) {
|
||||
$instagram_business_id = $page_data['instagram_business_account']['id'];
|
||||
$page_access_token = isset( $page_data['access_token'] ) ? $page_data['access_token'] : '';
|
||||
$instagram_account_url = 'https://graph.facebook.com/' . $instagram_business_id . '?fields=name,username,profile_picture_url&access_token=' . $access_token;
|
||||
|
||||
$args = array(
|
||||
'timeout' => 60,
|
||||
);
|
||||
$result = wp_remote_get( $instagram_account_url, $args );
|
||||
if ( ! is_wp_error( $result ) ) {
|
||||
$instagram_account_info = $result['body'];
|
||||
|
||||
$instagram_account_data = json_decode( $instagram_account_info, true );
|
||||
|
||||
$instagram_biz_img = isset( $instagram_account_data['profile_picture_url'] ) ? $instagram_account_data['profile_picture_url'] : false;
|
||||
$source_data = array(
|
||||
'access_token' => $access_token,
|
||||
'id' => $instagram_business_id,
|
||||
'user_id' => $instagram_business_id,
|
||||
'type' => 'business',
|
||||
'username' => $instagram_account_data['username'],
|
||||
'avatar' => $instagram_biz_img,
|
||||
'privilege' => 'tagged',
|
||||
);
|
||||
|
||||
$source_data['info'] = json_encode( $instagram_account_data );
|
||||
$return['unconnectedAccounts'][] = $source_data;
|
||||
|
||||
$args = array(
|
||||
'id' => $instagram_business_id,
|
||||
);
|
||||
$results = SBI_Db::source_query( $args );
|
||||
$already_connected_as_business_account = ( isset( $results[0] ) && $results[0]['account_type'] === 'business' );
|
||||
$matches_existing_personal = ( isset( $results[0] ) && $results[0]['account_type'] === 'personal' );
|
||||
|
||||
if ( $already_connected_as_business_account ) {
|
||||
self::update_or_insert( $source_data );
|
||||
} elseif ( $matches_existing_personal && $return['numFound'] === 1 ) {
|
||||
$return['didQuickUpdate'] = true;
|
||||
self::update_or_insert( $source_data );
|
||||
}
|
||||
} else {
|
||||
$page_error = $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $return['unconnectedAccounts'] ) ) {
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => 'No Accounts Found',
|
||||
'message' => __( 'Couldn\'t find Business Profile', 'feeds-for-youtube' ),
|
||||
'details' => sprintf( __( 'Uh oh. It looks like this Facebook account is not currently connected to an Instagram Business profile. Please check that you are logged into the %1$sFacebook account%2$s in this browser which is associated with your Instagram Business Profile. If you are, in fact, logged-in to the correct account please make sure you have Instagram accounts connected with your Facebook account by following %3$sthis FAQ%4$s', 'feeds-for-youtube' ), '<a href="https://www.facebook.com/" target="_blank" rel="noopener noreferrer">', '</a>', '<a href="https://smashballoon.com/reconnecting-an-instagram-business-profile/" target="_blank" rel="noopener noreferrer">', '</a>' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to update or insert connected accounts (sources)
|
||||
*
|
||||
* @param array $source_data
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function update_or_insert( $source_data ) {
|
||||
if ( ! isset( $source_data['id'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( isset( $source_data['info'] ) ) {
|
||||
// data from an API request related to the source is saved as a JSON string
|
||||
if ( is_object( $source_data['info'] ) || is_array( $source_data['info'] ) ) {
|
||||
$source_data['info'] = json_encode( $source_data['info'] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( self::exists_in_database( $source_data ) ) {
|
||||
$source_data['last_updated'] = date( 'Y-m-d H:i:s' );
|
||||
self::update( $source_data, false );
|
||||
} else {
|
||||
if ( ! isset( $source_data['access_token'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
self::insert( $source_data );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the source exists in the database
|
||||
*
|
||||
* @param array $args
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function exists_in_database( $args ) {
|
||||
$results = SBI_Db::source_query( $args );
|
||||
|
||||
return isset( $results[0] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new source as a row in the sbi_sources table
|
||||
*
|
||||
* @param array $source_data
|
||||
*
|
||||
* @return false|int
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function insert( $source_data ) {
|
||||
if ( isset( $source_data['name'] ) ) {
|
||||
$source_data['username'] = $source_data['name'];
|
||||
}
|
||||
$data = $source_data;
|
||||
|
||||
return SBI_Db::source_insert( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update info in rows that match the source data
|
||||
*
|
||||
* @param array $source_data
|
||||
*
|
||||
* @return false|int
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function update( $source_data, $where_privilige = true ) {
|
||||
$where = array( 'id' => $source_data['id'] );
|
||||
unset( $source_data['id'] );
|
||||
|
||||
if ( $where_privilige && isset( $source_data['privilege'] ) ) {
|
||||
$where['privilege'] = $source_data['privilege'];
|
||||
}
|
||||
|
||||
// usernames are more common in the other plugins so
|
||||
// that is the name of the column that is used as the
|
||||
// page or group "name" data
|
||||
if ( isset( $source_data['name'] ) ) {
|
||||
$source_data['username'] = $source_data['name'];
|
||||
}
|
||||
$data = $source_data;
|
||||
|
||||
return SBI_Db::source_update( $data, $where );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a queue of connected accounts that need to be added to
|
||||
* the sources table
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function set_legacy_source_queue() {
|
||||
$sbi_statuses_option = get_option( 'sbi_statuses', array() );
|
||||
$options = get_option( 'sb_instagram_settings', array() );
|
||||
|
||||
$connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
|
||||
|
||||
$sbi_statuses_option['legacy_source_queue'] = array_chunk( array_keys( $connected_accounts ), self::BATCH_SIZE );
|
||||
|
||||
update_option( 'sbi_statuses', $sbi_statuses_option );
|
||||
|
||||
return $sbi_statuses_option['legacy_source_queue'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not there are still sources in the queue and
|
||||
* this isn't disabled
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function should_do_source_updates() {
|
||||
$sbi_statuses_option = get_option( 'sbi_statuses', array() );
|
||||
|
||||
$should_do_source_updates = isset( $sbi_statuses_option['legacy_source_queue'] ) ? ! empty( $sbi_statuses_option['legacy_source_queue'] ) : false;
|
||||
|
||||
return apply_filters( 'should_do_source_updates', $should_do_source_updates );
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes one set of connected accounts
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function batch_process_legacy_source_queue() {
|
||||
if ( ! self::should_do_source_updates() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sbi_statuses_option = get_option( 'sbi_statuses', array() );
|
||||
$batch = array_shift( $sbi_statuses_option['legacy_source_queue'] );
|
||||
update_option( 'sbi_statuses', $sbi_statuses_option ); // updated early just in case there is a fatal error
|
||||
|
||||
if ( empty( $batch ) ) {
|
||||
return;
|
||||
}
|
||||
$options = get_option( 'sb_instagram_settings', array() );
|
||||
|
||||
$connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
|
||||
|
||||
foreach ( $batch as $account_key ) {
|
||||
$connected_account = isset( $connected_accounts[ $account_key ] ) ? $connected_accounts[ $account_key ] : false;
|
||||
|
||||
if ( $connected_account ) {
|
||||
self::update_single_source( $connected_account );
|
||||
}
|
||||
}
|
||||
|
||||
return $sbi_statuses_option['legacy_source_queue'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer data from a connected account to the sources table
|
||||
* after it's been validated with an API call
|
||||
*
|
||||
* @param array $connected_account
|
||||
* @param bool $connect_if_error
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function update_single_source( $connected_account, $connect_if_error = true ) {
|
||||
$account_type = isset( $connected_account['account_type'] ) ? $connected_account['account_type'] : 'business';
|
||||
|
||||
$connection = new \SB_Instagram_API_Connect( $connected_account, 'header', array() );
|
||||
|
||||
$connection->connect();
|
||||
if ( isset( $connected_account['privilege'] ) && $connected_account['privilege'] === 'tagged' ) {
|
||||
$connected_account['use_tagged'] = true;
|
||||
}
|
||||
|
||||
$source_data = array(
|
||||
'access_token' => $connected_account['access_token'],
|
||||
'id' => $connected_account['user_id'],
|
||||
'type' => $account_type,
|
||||
'username' => $connected_account['username'],
|
||||
'privilege' => ! empty( $connected_account['use_tagged'] ) ? 'tagged' : '',
|
||||
);
|
||||
|
||||
if ( ! empty( $connected_account['expires_timestamp'] ) ) {
|
||||
$source_data['expires'] = date( 'Y-m-d H:i:s', $connected_account['expires_timestamp'] );
|
||||
}
|
||||
|
||||
if ( $connected_account['local_avatar'] ) {
|
||||
\SB_Instagram_Connected_Account::update_local_avatar_status( $connected_account['username'], true );
|
||||
}
|
||||
|
||||
$header_details = '{}';
|
||||
$source_data['error'] = '';
|
||||
if ( ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) {
|
||||
$header_details_array = $connection->get_data();
|
||||
$header_details_array = self::merge_account_details( $header_details_array, $connected_account );
|
||||
|
||||
$cdn_avatar_url = \SB_Instagram_Parse::get_avatar( $header_details_array, array(), true );
|
||||
if ( ! empty( $cdn_avatar_url ) ) {
|
||||
$created = \SB_Instagram_Connected_Account::create_local_avatar( $header_details_array['username'], $cdn_avatar_url );
|
||||
\SB_Instagram_Connected_Account::update_local_avatar_status( $header_details_array['username'], $created );
|
||||
}
|
||||
|
||||
$source_data['username'] = $header_details_array['username'];
|
||||
$header_details = json_encode( $header_details_array );
|
||||
} else {
|
||||
$source_data['error'] = $connection;
|
||||
if ( $connection->is_wp_error() ) {
|
||||
$source_data['error'] = $connection->get_wp_error();
|
||||
} else {
|
||||
$source_data['error'] = $connection->get_data();
|
||||
}
|
||||
}
|
||||
|
||||
$source_data['info'] = $header_details;
|
||||
|
||||
if ( ! empty( $connected_account['private'] ) ) {
|
||||
$source_data['info']['private'] = $connected_account['private'];
|
||||
}
|
||||
|
||||
if ( empty( $source_data['error'] ) || $connect_if_error ) {
|
||||
self::update_or_insert( $source_data );
|
||||
}
|
||||
|
||||
$source_data['record_id'] = 0;
|
||||
$source_data['account_id'] = $connected_account['user_id'];
|
||||
$source_data['account_type'] = $account_type;
|
||||
|
||||
return $source_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a source from the access token and
|
||||
* source ID saved in 3.x settings
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function update_source_from_legacy_settings() {
|
||||
// not needed
|
||||
}
|
||||
|
||||
public static function merge_account_details( $header_details_array, $connected_account ) {
|
||||
$header_details_array['local_avatar'] = ! empty( $connected_account['local_avatar'] );
|
||||
$header_details_array['name'] = ! empty( $connected_account['name'] ) ? $connected_account['name'] : '{}';
|
||||
$header_details_array['page_access_token'] = ! empty( $connected_account['page_access_token'] ) ? $connected_account['page_access_token'] : '';
|
||||
|
||||
return $header_details_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the plugin is still updating legacy sources this function
|
||||
* can be used to udpate a single source if needed before
|
||||
* the update is done.
|
||||
*
|
||||
* @param string $slug_or_id
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
public static function maybe_one_off_connected_account_update( $slug_or_id ) {
|
||||
if ( ! self::should_do_source_updates() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$connected_accounts = (array) json_decode( stripcslashes( get_option( 'sbi_connected_accounts' ) ), true );
|
||||
$connected_account = isset( $connected_accounts[ $slug_or_id ] ) ? $connected_accounts[ $slug_or_id ] : false;
|
||||
|
||||
if ( $connected_account ) {
|
||||
return self::update_single_source( $connected_account );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the "error" column in the sbi_sources table for a specific
|
||||
* account
|
||||
*
|
||||
* @param string $account_id
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function clear_error( $account_id ) {
|
||||
$source_data = array(
|
||||
'id' => $account_id,
|
||||
'error' => '',
|
||||
);
|
||||
return self::update_or_insert( $source_data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the error table by account ID
|
||||
*
|
||||
* @param string $account_id
|
||||
* @param string|object|array $error
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function add_error( $account_id, $error ) {
|
||||
$source_data = array(
|
||||
'id' => $account_id,
|
||||
'error' => is_string( $error ) ? $error : json_encode( $error ),
|
||||
);
|
||||
return self::update_or_insert( $source_data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses query results from the sbi_sources table to convert them
|
||||
* into connected account data and return them as a connected account
|
||||
* array as would be used in versions 5.x and below
|
||||
*
|
||||
* @param array $source_data
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function convert_sources_to_connected_accounts( $source_data ) {
|
||||
$encryption = new \SB_Instagram_Data_Encryption();
|
||||
|
||||
$connected_accounts = array();
|
||||
|
||||
foreach ( $source_data as $source_datum ) {
|
||||
$info = ! empty( $source_datum['info'] ) ? json_decode( $encryption->decrypt( $source_datum['info'] ), true ) : array();
|
||||
$settings = array( 'gdpr' => 'no' );
|
||||
$avatar = \SB_Instagram_Parse::get_avatar( $info, $settings, true );
|
||||
$connected_account = array(
|
||||
'id' => $source_datum['account_id'],
|
||||
'user_id' => $source_datum['account_id'],
|
||||
'type' => $source_datum['account_type'],
|
||||
'account_type' => $source_datum['account_type'],
|
||||
'username' => $source_datum['username'],
|
||||
'access_token' => sbi_maybe_clean( $source_datum['access_token'] ),
|
||||
'privilege' => $source_datum['privilege'],
|
||||
'expires_timestamp' => strtotime( $source_datum['expires'] ),
|
||||
'is_valid' => empty( $source_datum['error'] ),
|
||||
'profile_picture' => $avatar,
|
||||
'last_checked' => isset( $source_datum['last_updated'] ) ? strtotime( $source_datum['last_updated'] ) : time(),
|
||||
);
|
||||
if ( ! empty( $info['private'] ) ) {
|
||||
$connected_account['private'] = $info['private'];
|
||||
}
|
||||
|
||||
$connected_account['local_avatar_url'] = \SB_Instagram_Connected_Account::maybe_local_avatar( $source_datum['username'], $avatar );
|
||||
|
||||
$connected_accounts[ $source_datum['account_id'] ] = $connected_account;
|
||||
}
|
||||
|
||||
return $connected_accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a batch of accounts that have expiring access tokens
|
||||
*
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function get_expiring() {
|
||||
$args = array( 'expiring' => true );
|
||||
$results = SBI_Db::source_query( $args );
|
||||
|
||||
return $results;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Builder
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Builder;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SB_Builder_Customizer {
|
||||
|
||||
/**
|
||||
* Controls Classes Array
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $controls_classes = array();
|
||||
|
||||
|
||||
/**
|
||||
* Get controls list.
|
||||
*
|
||||
* Getting controls list
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_controls_list() {
|
||||
return array(
|
||||
'actionbutton',
|
||||
'checkbox',
|
||||
'checkboxsection',
|
||||
'datepicker',
|
||||
'colorpicker',
|
||||
'number',
|
||||
'select',
|
||||
'switcher',
|
||||
'text',
|
||||
'textarea',
|
||||
'toggle',
|
||||
'toggleset',
|
||||
'heading',
|
||||
'separator',
|
||||
'customview',
|
||||
'coloroverride',
|
||||
'togglebutton',
|
||||
'hidden',
|
||||
'imagechooser',
|
||||
'checkboxlist',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Controls
|
||||
*
|
||||
* Including Control
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public static function register_controls() {
|
||||
$controls_list = self::get_controls_list();
|
||||
foreach ( $controls_list as $control ) {
|
||||
$controlClassName = 'SB_' . ucfirst( $control ) . '_Control';
|
||||
$cls_name = __NAMESPACE__ . '\Controls\\' . $controlClassName;
|
||||
$control_class = new $cls_name();
|
||||
self::$controls_classes[ $control ] = $control_class;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print Controls Vue JS Tempalte
|
||||
*
|
||||
* Including Control
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public static function get_controls_templates( $editingType ) {
|
||||
$controls_list = self::get_controls_list();
|
||||
foreach ( $controls_list as $control ) {
|
||||
self::$controls_classes[ $control ]->print_control_wrapper( $editingType );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
/**
|
||||
* Builder Customizer Tab
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Tabs;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
class SBY_Builder_Customizer_Tab {
|
||||
|
||||
/**
|
||||
* Get Tabs Data
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_customizer_tabs() {
|
||||
return array(
|
||||
'customize' => array(
|
||||
'id' => 'customize',
|
||||
'heading' => __( 'Customize', 'feeds-for-youtube' ),
|
||||
'sections' => SBY_Customize_Tab::get_sections(),
|
||||
),
|
||||
'settings' => array(
|
||||
'id' => 'settings',
|
||||
'heading' => __( 'Settings', 'feeds-for-youtube' ),
|
||||
'sections' => SBY_Settings_Tab::get_sections(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Text Size Options
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_text_size_options() {
|
||||
return array(
|
||||
'inherit' => __( 'Inherit', 'feeds-for-youtube' ),
|
||||
'10' => '10px',
|
||||
'11' => '11px',
|
||||
'12' => '12px',
|
||||
'13' => '13px',
|
||||
'14' => '14px',
|
||||
'15' => '15px',
|
||||
'16' => '16px',
|
||||
'18' => '18px',
|
||||
'20' => '20px',
|
||||
'24' => '24px',
|
||||
'28' => '28px',
|
||||
'32' => '32px',
|
||||
'36' => '36px',
|
||||
'42' => '42px',
|
||||
'48' => '48px',
|
||||
'54' => '54px',
|
||||
'60' => '60px',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* header Icons Options
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_header_icons_options() {
|
||||
return array(
|
||||
'facebook-square' => 'Facebook 1',
|
||||
'facebook' => 'Facebook 2',
|
||||
'calendar' => 'Events 1',
|
||||
'calendar-o' => 'Events 2',
|
||||
'picture-o' => 'Photos',
|
||||
'users' => 'People',
|
||||
'thumbs-o-up' => 'Thumbs Up 1',
|
||||
'thumbs-up' => 'Thumbs Up 2',
|
||||
'comment-o' => 'Speech Bubble 1',
|
||||
'comment' => 'Speech Bubble 2',
|
||||
'ticket' => 'Ticket',
|
||||
'list-alt' => 'News List',
|
||||
'file' => 'File 1',
|
||||
'file-o' => 'File 2',
|
||||
'file-text' => 'File 3',
|
||||
'file-text-o' => 'File 4',
|
||||
'youtube-play ' => 'Video',
|
||||
'youtube-play' => 'YouTube',
|
||||
'vimeo-square' => 'Vimeo',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Date Format Options
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_date_format_options() {
|
||||
$original = strtotime( '2016-07-25T17:30:00+0000' );
|
||||
return array(
|
||||
'1' => __( '2 days ago', 'feeds-for-youtube' ),
|
||||
'2' => gmdate( 'F jS, g:i a', $original ),
|
||||
'3' => gmdate( 'F jS', $original ),
|
||||
'4' => gmdate( 'D F jS', $original ),
|
||||
'5' => gmdate( 'l F jS', $original ),
|
||||
'6' => gmdate( 'D M jS, Y', $original ),
|
||||
'7' => gmdate( 'l F jS, Y', $original ),
|
||||
'8' => gmdate( 'l F jS, Y - g:i a', $original ),
|
||||
'9' => gmdate( "l M jS, 'y", $original ),
|
||||
'10' => gmdate( 'm.d.y', $original ),
|
||||
'18' => gmdate( 'm.d.y - G:i', $original ),
|
||||
'11' => gmdate( 'm/d/y', $original ),
|
||||
'12' => gmdate( 'd.m.y', $original ),
|
||||
'19' => gmdate( 'd.m.y - G:i', $original ),
|
||||
'13' => gmdate( 'd/m/y', $original ),
|
||||
'14' => gmdate( 'd-m-Y, G:i', $original ),
|
||||
'15' => gmdate( 'jS F Y, G:i', $original ),
|
||||
'16' => gmdate( 'd M Y, G:i', $original ),
|
||||
'17' => gmdate( 'l jS F Y, G:i', $original ),
|
||||
'18' => gmdate( 'Y-m-d', $original ),
|
||||
'custom' => __( 'Custom', 'feeds-for-youtube' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,318 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Tab
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder\Tabs;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\Builder\SBY_Feed_Builder;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
class SBY_Settings_Tab {
|
||||
|
||||
|
||||
/**
|
||||
* Get Customize Tab Sections
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_sections() {
|
||||
return array(
|
||||
'settings_feedtype' => array(
|
||||
'heading' => __( 'Sources', 'feeds-for-youtube' ),
|
||||
'icon' => 'source',
|
||||
'controls' => self::get_settings_sources_controls(),
|
||||
),
|
||||
'settings_filters_moderation' => array(
|
||||
'heading' => __( 'Filters and Moderation', 'feeds-for-youtube' ),
|
||||
'icon' => 'filter',
|
||||
'separator' => 'none',
|
||||
'controls' => self::get_settings_filters_moderation_controls(),
|
||||
),
|
||||
'settings_sort' => array(
|
||||
'heading' => __( 'Sort', 'feeds-for-youtube' ),
|
||||
'icon' => 'sort',
|
||||
'controls' => self::get_settings_sort_controls(),
|
||||
),
|
||||
'settings_shoppable_feed' => array(
|
||||
'heading' => __( 'Shoppable Feed', 'feeds-for-youtube' ),
|
||||
'icon' => 'shop',
|
||||
'separator' => 'none',
|
||||
'controls' => self::get_settings_shoppable_feed_controls(),
|
||||
),
|
||||
'empty_sections' => array(
|
||||
'heading' => '',
|
||||
'isHeader' => true,
|
||||
),
|
||||
'settings_advanced' => array(
|
||||
'heading' => __( 'Advanced', 'feeds-for-youtube' ),
|
||||
'icon' => 'cog',
|
||||
'controls' => self::get_settings_advanced_controls(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Settings Tab Filters & Moderation Section
|
||||
* @since 4.0
|
||||
* @return array
|
||||
*/
|
||||
public static function get_settings_filters_moderation_controls() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'customview',
|
||||
'viewId' => 'moderationmode',
|
||||
'switcher' => array(
|
||||
'id' => 'enablemoderationmode',
|
||||
'label' => __( 'Enable', 'feeds-for-youtube' ),
|
||||
'reverse' => 'true',
|
||||
'stacked' => 'true',
|
||||
'labelStrong' => true,
|
||||
'options' => array(
|
||||
'enabled' => true,
|
||||
'disabled' => false,
|
||||
),
|
||||
),
|
||||
'moderationTypes' => array(
|
||||
'allow' => array(
|
||||
'label' => __( 'Allow List', 'feeds-for-youtube' ),
|
||||
'description' => __( 'Hides post by default so you can select the ones you want to show', 'feeds-for-youtube' ),
|
||||
),
|
||||
'block' => array(
|
||||
'label' => __( 'Block List', 'feeds-for-youtube' ),
|
||||
'description' => __( 'Show all posts by default so you can select the ones you want to hide', 'feeds-for-youtube' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'separator',
|
||||
'top' => 10,
|
||||
'bottom' => 10,
|
||||
'checkViewDisabled' => 'moderationMode',
|
||||
),
|
||||
array(
|
||||
'type' => 'heading',
|
||||
'strongHeading' => 'true',
|
||||
'heading' => __( 'Filters', 'feeds-for-youtube' ),
|
||||
'checkViewDisabled' => 'moderationMode',
|
||||
),
|
||||
array(
|
||||
'type' => 'textarea',
|
||||
'id' => 'includewords',
|
||||
'heading' => __( 'Only show posts containing', 'feeds-for-youtube' ),
|
||||
'tooltip' => __( 'Only show posts which contain certain words or hashtags in the caption. For example, adding "sheep, cow, dog" will show any photos which contain either the word sheep, cow, or dog. You can separate multiple words or hashtags using commas.', 'feeds-for-youtube' ),
|
||||
'placeholder' => __( 'Add words here to only show posts containing these words', 'feeds-for-youtube' ),
|
||||
'checkViewDisabled' => 'moderationMode',
|
||||
),
|
||||
|
||||
array(
|
||||
'type' => 'textarea',
|
||||
'id' => 'excludewords',
|
||||
'disabledInput' => true,
|
||||
'heading' => __( 'Do not show posts containing', 'feeds-for-youtube' ),
|
||||
'tooltip' => __( 'Remove any posts containing these text strings, separating multiple strings using commas.', 'feeds-for-youtube' ),
|
||||
'placeholder' => __( 'Add words here to hide any posts containing these words', 'feeds-for-youtube' ),
|
||||
'checkViewDisabled' => 'moderationMode',
|
||||
),
|
||||
|
||||
array(
|
||||
'type' => 'heading',
|
||||
'strongHeading' => 'true',
|
||||
'stacked' => 'true',
|
||||
'heading' => __( 'Show specific types of posts', 'feeds-for-youtube' ),
|
||||
'checkViewDisabled' => 'moderationMode',
|
||||
),
|
||||
|
||||
array(
|
||||
'type' => 'checkbox',
|
||||
'id' => 'photosposts',
|
||||
'label' => __( 'Photos', 'feeds-for-youtube' ),
|
||||
'reverse' => 'true',
|
||||
'stacked' => 'true',
|
||||
'checkViewDisabled' => 'moderationMode',
|
||||
'ajaxAction' => 'feedFlyPreview',
|
||||
'options' => array(
|
||||
'enabled' => true,
|
||||
'disabled' => false,
|
||||
),
|
||||
),
|
||||
|
||||
array(
|
||||
'type' => 'checkbox',
|
||||
'id' => 'videosposts',
|
||||
'label' => __( 'Feed Videos', 'feeds-for-youtube' ),
|
||||
'reverse' => 'true',
|
||||
'stacked' => 'true',
|
||||
'checkViewDisabled' => 'moderationMode',
|
||||
'ajaxAction' => 'feedFlyPreview',
|
||||
'options' => array(
|
||||
'enabled' => true,
|
||||
'disabled' => false,
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'checkbox',
|
||||
'id' => 'igtvposts',
|
||||
'label' => __( 'IGTV Videos', 'feeds-for-youtube' ),
|
||||
'reverse' => 'true',
|
||||
'stacked' => 'true',
|
||||
'checkViewDisabled' => 'moderationMode',
|
||||
'ajaxAction' => 'feedFlyPreview',
|
||||
'options' => array(
|
||||
'enabled' => true,
|
||||
'disabled' => false,
|
||||
),
|
||||
),
|
||||
|
||||
array(
|
||||
'type' => 'separator',
|
||||
'top' => 26,
|
||||
'bottom' => 15,
|
||||
'checkViewDisabled' => 'moderationMode',
|
||||
),
|
||||
|
||||
array(
|
||||
'type' => 'number',
|
||||
'id' => 'offset',
|
||||
'strongHeading' => 'true',
|
||||
'stacked' => 'true',
|
||||
'placeholder' => '0',
|
||||
'fieldSuffix' => 'posts',
|
||||
'heading' => __( 'Post Offset', 'feeds-for-youtube' ),
|
||||
'description' => __( 'This will skip the specified number of posts from displaying in the feed', 'feeds-for-youtube' ),
|
||||
'checkViewDisabled' => 'moderationMode',
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Settings Tab Sort Section
|
||||
* @since 4.0
|
||||
* @return array
|
||||
*/
|
||||
public static function get_settings_sort_controls() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'toggleset',
|
||||
'id' => 'sortby',
|
||||
'heading' => __( 'Sort Posts by', 'feeds-for-youtube' ),
|
||||
'strongHeading' => 'true',
|
||||
'ajaxAction' => 'feedFlyPreview',
|
||||
'options' => array(
|
||||
array(
|
||||
'value' => 'none',
|
||||
'label' => __( 'Newest', 'feeds-for-youtube' ),
|
||||
),
|
||||
array(
|
||||
'value' => 'likes',
|
||||
'label' => __( 'Likes', 'feeds-for-youtube' ),
|
||||
),
|
||||
array(
|
||||
'value' => 'random',
|
||||
'label' => __( 'Random', 'feeds-for-youtube' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Settings Tab Shoppable Feed Section
|
||||
* @since 4.0
|
||||
* @return array
|
||||
*/
|
||||
public static function get_settings_shoppable_feed_controls() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'switcher',
|
||||
'id' => 'shoppablefeed',
|
||||
'label' => __( 'Enable', 'feeds-for-youtube' ),
|
||||
'reverse' => 'true',
|
||||
'stacked' => 'true',
|
||||
'options' => array(
|
||||
'enabled' => true,
|
||||
'disabled' => false,
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'customview',
|
||||
'condition' => array( 'shoppablefeed' => array( false ) ),
|
||||
'conditionHide' => true,
|
||||
'viewId' => 'shoppabledisabled',
|
||||
),
|
||||
array(
|
||||
'type' => 'customview',
|
||||
'condition' => array( 'shoppablefeed' => array( true ) ),
|
||||
'conditionHide' => true,
|
||||
'viewId' => 'shoppableenabled',
|
||||
),
|
||||
array(
|
||||
'type' => 'customview',
|
||||
'condition' => array( 'shoppablefeed' => array( true ) ),
|
||||
'conditionHide' => true,
|
||||
'viewId' => 'shoppableselectedpost',
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Settings Tab Advanced Section
|
||||
* @since 4.0
|
||||
* @return array
|
||||
*/
|
||||
public static function get_settings_advanced_controls() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'number',
|
||||
'id' => 'maxrequests',
|
||||
'strongHeading' => 'true',
|
||||
'heading' => __( 'Max Concurrent API Requests', 'feeds-for-youtube' ),
|
||||
'description' => __( 'Change the number of maximum concurrent API requests. Not recommended unless directed by the support team.', 'feeds-for-youtube' ),
|
||||
),
|
||||
array(
|
||||
'type' => 'switcher',
|
||||
'id' => 'customtemplates',
|
||||
'label' => __( 'Custom Templates', 'feeds-for-youtube' ),
|
||||
'description' => sprintf( __( 'The default HTML for the feed can be replaced with custom templates added to your theme\'s folder. Enable this setting to use these templates. Custom templates are not used in the feed editor. %1$sLearn More%2$s', 'feeds-for-youtube' ), '<a href="https://smashballoon.com/guide-to-creating-custom-templates/?utm_source=plugin-pro&utm_campaign=sbi&utm_medium=customizer" target="_blank">', '</a>' ),
|
||||
'descriptionPosition' => 'bottom',
|
||||
'reverse' => 'true',
|
||||
'strongHeading' => 'true',
|
||||
'labelStrong' => 'true',
|
||||
'options' => array(
|
||||
'enabled' => true,
|
||||
'disabled' => false,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Settings TabSources Section
|
||||
* @since 2.0
|
||||
* @return array
|
||||
*/
|
||||
public static function get_settings_sources_controls() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'customview',
|
||||
'viewId' => 'sources',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/**
|
||||
* SBY Tooltip Wizard
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Builder;
|
||||
|
||||
class Tooltip_Wizard {
|
||||
|
||||
/**
|
||||
* Register component
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function register() {
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register hooks.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function hooks() {
|
||||
add_action( 'admin_enqueue_scripts', [ $this, 'enqueues' ] );
|
||||
add_action( 'admin_footer', [ $this, 'output' ] );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enqueue assets.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function enqueues() {
|
||||
|
||||
wp_enqueue_style(
|
||||
'sby_tooltipster',
|
||||
SBY_PLUGIN_URL . 'css/tooltipster.css',
|
||||
null,
|
||||
SBYVER
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'tooltipster',
|
||||
SBY_PLUGIN_URL . 'js/jquery.tooltipster.min.js',
|
||||
[ 'jquery' ],
|
||||
SBYVER,
|
||||
true
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'sby-admin-tooltip-wizard',
|
||||
SBY_PLUGIN_URL . 'js/tooltip-wizard.js',
|
||||
[ 'jquery' ],
|
||||
SBYVER
|
||||
);
|
||||
|
||||
$wp_localize_data = [];
|
||||
if( $this->check_gutenberg_wizard() ){
|
||||
$wp_localize_data['sby_wizard_gutenberg'] = true;
|
||||
}
|
||||
|
||||
wp_localize_script(
|
||||
'sby-admin-tooltip-wizard',
|
||||
'sby_admin_tooltip_wizard',
|
||||
$wp_localize_data
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output HTML.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function output() {
|
||||
if( $this->check_gutenberg_wizard() ){
|
||||
$this->gutenberg_tooltip_output();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gutenberg Tooltip Output HTML.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function check_gutenberg_wizard() {
|
||||
global $pagenow;
|
||||
return ( ( $pagenow == 'post.php' ) || (get_post_type() == 'page') )
|
||||
&& ! empty( $_GET['sby_wizard'] );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gutenberg Tooltip Output HTML.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function gutenberg_tooltip_output() {
|
||||
?>
|
||||
<div id="sby-gutenberg-tooltip-content">
|
||||
<div class="sby-tlp-wizard-cls sby-tlp-wizard-close"></div>
|
||||
<div class="sby-tlp-wizard-content">
|
||||
<strong class="sby-tooltip-wizard-head"><?php echo __('Add a Block','feeds-for-youtube') ?></strong>
|
||||
<p class="sby-tooltip-wizard-txt"><?php echo __('Click the plus button, search for Feeds for YouTube','feeds-for-youtube'); ?>
|
||||
<br/><?php echo __('Feed, and click the block to embed it.','feeds-for-youtube') ?> <a href="https://smashballoon.com/doc/wordpress-5-block-page-editor-gutenberg/?youtube" rel="noopener" target="_blank" rel="nofollow noopener"><?php echo __('Learn More','feeds-for-youtube') ?></a></p>
|
||||
<div class="sby-tooltip-wizard-actions">
|
||||
<button class="sby-tlp-wizard-close"><?php echo __('Done','feeds-for-youtube') ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
31
wp-content/plugins/youtube-feed-pro/inc/Container.php
Normal file
31
wp-content/plugins/youtube-feed-pro/inc/Container.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
|
||||
use Smashballoon\Customizer\Config;
|
||||
use Smashballoon\Customizer\DB;
|
||||
use Smashballoon\Customizer\PreviewProvider;
|
||||
use Smashballoon\Customizer\ProxyProvider;
|
||||
use Smashballoon\Stubs\Traits\Singleton;
|
||||
use SmashBalloon\YouTubeFeed\Customizer\ShortcodePreviewProvider;
|
||||
|
||||
class Container {
|
||||
use Singleton;
|
||||
|
||||
/**
|
||||
* @return \SmashBalloon\YouTubeFeed\Vendor\DI\Container
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if(null === self::$instance) {
|
||||
self::$instance = ( new \SmashBalloon\YouTubeFeed\Vendor\DI\ContainerBuilder() )->build();
|
||||
|
||||
self::$instance->set(Config::class, new \SmashBalloon\YouTubeFeed\Customizer\Config());
|
||||
self::$instance->set(DB::class, new \SmashBalloon\YouTubeFeed\Customizer\DB());
|
||||
self::$instance->set(ProxyProvider::class, new \SmashBalloon\YouTubeFeed\Customizer\ProxyProvider());
|
||||
self::$instance->set( PreviewProvider::class, new ShortcodePreviewProvider());
|
||||
self::$instance->set(SBY_Settings::class, new SBY_Settings([], sby_get_database_settings()));
|
||||
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Customizer;
|
||||
|
||||
class Config extends \Smashballoon\Customizer\Config {
|
||||
public $plugin_slug = 'sby';
|
||||
public $statuses_option = 'sby_statuses';
|
||||
|
||||
public function isPro() {
|
||||
return sby_is_pro_version();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Customizer;
|
||||
|
||||
use Smashballoon\Stubs\Services\ServiceProvider;
|
||||
use SmashBalloon\YouTubeFeed\Helpers\Util;
|
||||
|
||||
class Customizer_Compatibility extends ServiceProvider {
|
||||
|
||||
public function register() {
|
||||
add_action('admin_enqueue_scripts', [$this, 'register_scripts']);
|
||||
}
|
||||
|
||||
public function register_scripts() {
|
||||
$asset_url = trailingslashit( SBY_PLUGIN_URL ) . 'js/customizer.min.js';
|
||||
|
||||
if ( isset( $_GET['sb_debug'] ) ) {
|
||||
$asset_url = trailingslashit( SBY_PLUGIN_URL ) . 'js/customizer-debug.js';
|
||||
}
|
||||
|
||||
if(!Util::isProduction()) {
|
||||
$asset_url = 'http://localhost:9005/customizer.min.js';
|
||||
}
|
||||
|
||||
// only enqueue the below scripts on allowed pages; YouTube plugin All Feeds page
|
||||
if ( !$this->is_allowed_screens() ) {
|
||||
return;
|
||||
}
|
||||
wp_enqueue_script( 'sby_builder_extension', $asset_url, [], SBYVER );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for allowed screens
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function is_allowed_screens() {
|
||||
global $current_user;
|
||||
$current_screen = get_current_screen();
|
||||
$allowed_screens = array(
|
||||
'toplevel_page_sby-feed-builder',
|
||||
);
|
||||
if ( in_array( $current_screen->base, $allowed_screens ) ) {
|
||||
return true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
90
wp-content/plugins/youtube-feed-pro/inc/Customizer/DB.php
Normal file
90
wp-content/plugins/youtube-feed-pro/inc/Customizer/DB.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Customizer;
|
||||
|
||||
use Smashballoon\Customizer\Feed_Builder;
|
||||
|
||||
class DB extends \Smashballoon\Customizer\DB {
|
||||
protected $feeds_table = 'sby_feeds';
|
||||
protected $sources_table = 'sby_sources';
|
||||
|
||||
/**
|
||||
* Query the feeds table
|
||||
* Porcess to define the name of the feed when adding new
|
||||
*
|
||||
* @param array $args
|
||||
*
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function feeds_query_name( $feedname ) {
|
||||
global $wpdb;
|
||||
$feeds_table_name = $wpdb->prefix . 'sby_feeds';
|
||||
$sql = $wpdb->prepare(
|
||||
"SELECT * FROM $feeds_table_name
|
||||
WHERE feed_name LIKE %s;",
|
||||
$wpdb->esc_like($feedname) . '%'
|
||||
);
|
||||
$count = sizeof($wpdb->get_results( $sql, ARRAY_A ));
|
||||
return ($count == 0) ? $feedname : $feedname .' ('. ($count+1) .')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to Duplicate a Single Feed
|
||||
*
|
||||
* @param array $args
|
||||
*
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function duplicate_feed_query( $feed_id ){
|
||||
global $wpdb;
|
||||
$feeds_table_name = $wpdb->prefix . 'sby_feeds';
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"INSERT INTO $feeds_table_name (feed_name, settings, author, status)
|
||||
SELECT CONCAT(feed_name, ' (copy)'), settings, author, status
|
||||
FROM $feeds_table_name
|
||||
WHERE id = %d; ", $feed_id
|
||||
)
|
||||
);
|
||||
|
||||
$builder = Feed_Builder::instance();
|
||||
echo sby_json_encode($builder->get_feed_list());
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to Remove Feeds from Database
|
||||
*
|
||||
* @param array $args
|
||||
*
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function delete_feeds_query( $feed_ids_array ) {
|
||||
global $wpdb;
|
||||
$feeds_table_name = $wpdb->prefix . 'sby_feeds';
|
||||
$feed_caches_table_name = $wpdb->prefix . 'sby_feed_caches';
|
||||
$feed_ids_array = array_map('intval', $feed_ids_array);
|
||||
$feed_ids_array = implode(',', $feed_ids_array);
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $feeds_table_name WHERE id IN ($feed_ids_array)"
|
||||
)
|
||||
);
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $feed_caches_table_name WHERE feed_id IN ($feed_ids_array)"
|
||||
)
|
||||
);
|
||||
|
||||
$builder = Feed_Builder::instance();
|
||||
echo sby_json_encode($builder->get_feed_list());
|
||||
wp_die();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Customizer;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\Pro\SBY_Settings_Pro;
|
||||
use SmashBalloon\YouTubeFeed\SBY_Settings;
|
||||
|
||||
class ProxyProvider extends \Smashballoon\Customizer\ProxyProvider {
|
||||
public function get_settings_class() {
|
||||
if(!sby_is_pro_version()) {
|
||||
return new SBY_Settings([], sby_get_database_settings());
|
||||
}
|
||||
return new SBY_Settings_Pro([], sby_get_database_settings());
|
||||
}
|
||||
|
||||
public function get_db_settings() {
|
||||
return sby_get_database_settings();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Customizer;
|
||||
|
||||
use Smashballoon\Customizer\PreviewProvider;
|
||||
|
||||
class ShortcodePreviewProvider implements PreviewProvider {
|
||||
public function render( $attr, $settings ) {
|
||||
return apply_filters( 'sby_render_shortcode', $attr, $settings );
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Tab
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Customizer\Tabs;
|
||||
|
||||
use Smashballoon\Customizer\Tabs\Tab;
|
||||
use Smashballoon\Customizer\YouTube_License_Tier;
|
||||
|
||||
class Settings_Tab extends Tab {
|
||||
protected $id = 'settings';
|
||||
protected $heading = "";
|
||||
protected $license_tier_features;
|
||||
|
||||
public function __construct() {
|
||||
$this->heading = __('Settings', 'feeds-for-youtube');
|
||||
// init license tier
|
||||
$license_tier = new YouTube_License_Tier;
|
||||
$this->license_tier_features = $license_tier->tier_features();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Settings Tab Sections
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
* @access public
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_sections() {
|
||||
$learn_more = 'https://smashballoon.com/pricing/youtube-feed?utm_campaign=youtube-free&utm_source=moderation&utm_medium=learn-more';
|
||||
return array(
|
||||
'settings_feedtype' => array(
|
||||
'heading' => __( 'Feed Type', 'feeds-for-youtube' ),
|
||||
'icon' => 'feedtype',
|
||||
'controls' => $this->get_settings_feedtype_controls(),
|
||||
),
|
||||
'settings_filters' => array(
|
||||
'heading' => !sby_is_pro() ? __( 'Filters and Moderation', 'feeds-for-youtube' ) . '<span class="sb-breadcrumb-pro-label">PRO</span>' : __( 'Filters and Moderation', 'feeds-for-youtube' ),
|
||||
'description' => sprintf( __('Hide one or more videos individually or with the help of Pro features. <a href="%s" target="_blank">Learn More</a>', 'feeds-for-youtube'), $learn_more ),
|
||||
'icon' => 'filters',
|
||||
'controls' => $this->get_settings_filters_controls(),
|
||||
),
|
||||
'empty_sections' => array(
|
||||
'heading' => '',
|
||||
'isHeader' => true,
|
||||
),
|
||||
'settings_advanced' => array(
|
||||
'heading' => __( 'Advanced', 'feeds-for-youtube' ),
|
||||
'icon' => 'cog',
|
||||
'controls' => $this->get_settings_advanced_controls(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Settings Tab Feed Type Section
|
||||
*
|
||||
* @since 2.0
|
||||
* @return array
|
||||
*/
|
||||
public static function get_settings_feedtype_controls() {
|
||||
return [
|
||||
[
|
||||
'type' => 'customview',
|
||||
'viewId' => 'feedtype'
|
||||
],
|
||||
[
|
||||
'type' => 'switcher',
|
||||
'id' => 'showpast',
|
||||
'label' => __( 'Show Past Live Streams', 'feeds-for-youtube' ),
|
||||
'strongHeading' => 'true',
|
||||
'labelStrong' => 'true',
|
||||
'condition' => array( 'type' => array( 'live' ) ),
|
||||
'conditionHide' => true,
|
||||
'options' => array(
|
||||
'enabled' => true,
|
||||
'disabled' => false,
|
||||
),
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Settings Tab Filters Section
|
||||
*
|
||||
* @since 2.0
|
||||
* @return array
|
||||
*/
|
||||
private function get_settings_filters_controls() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'textarea',
|
||||
'id' => 'includewords',
|
||||
'heading' => __( 'Allowed Words or Hashtags', 'feeds-for-youtube' ),
|
||||
'tooltip' => __( 'Allowed Words or Hashtags', 'feeds-for-youtube' ),
|
||||
'checkExtensionPopup' => sby_is_pro() && !sby_license_notices_active() && in_array('video_filtering', $this->license_tier_features) ? null : 'advancedFilters',
|
||||
'placeholder' => __( 'Show videos containing these words or hashtags. Separate multiple words with comma, and include “#” for hashtags.', 'feeds-for-youtube' ),
|
||||
'ajaxAction' => 'filtersAndModeration'
|
||||
),
|
||||
array(
|
||||
'type' => 'textarea',
|
||||
'id' => 'excludewords',
|
||||
'heading' => __( 'Blocked Words or Hashtags', 'feeds-for-youtube' ),
|
||||
'placeholder' => __( 'Hide videos containing these words or hashtags. Separate multiple words with comma, and include “#” for hashtags.', 'feeds-for-youtube' ),
|
||||
'tooltip' => __( 'Blocked Words or Hashtags', 'feeds-for-youtube' ),
|
||||
'checkExtensionPopup' => sby_is_pro() && !sby_license_notices_active() && in_array('video_filtering', $this->license_tier_features) ? null : 'advancedFilters',
|
||||
'separator' => 'bottom',
|
||||
'ajaxAction' => 'filtersAndModeration',
|
||||
),
|
||||
array(
|
||||
'type' => 'textarea',
|
||||
'id' => 'hidevideos',
|
||||
'heading' => __( 'Hide specific Videos', 'feeds-for-youtube' ),
|
||||
'tooltip' => __( 'Hide specific Videos', 'feeds-for-youtube' ),
|
||||
'placeholder' => __( 'Enter video IDs. Separate multiple IDs with comma', 'feeds-for-youtube' ),
|
||||
'checkExtensionPopup' => sby_is_pro() && !sby_license_notices_active() && in_array('video_filtering', $this->license_tier_features) ? null : 'advancedFilters',
|
||||
'ajaxAction' => 'feedRefresh',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Settings Tab Advanced Section
|
||||
* @since 2.0
|
||||
* @return array
|
||||
*/
|
||||
private function get_settings_advanced_controls() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'select',
|
||||
'id' => 'storage_process',
|
||||
'strongHeading' => 'true',
|
||||
'heading' => __( 'Local Storage Process', 'feeds-for-youtube' ),
|
||||
'options' => array(
|
||||
'background' => 'Background',
|
||||
'page' => 'Page',
|
||||
'none' => 'None',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'switcher',
|
||||
'id' => 'ajax_post_load',
|
||||
'label' => __( 'Load Initial Posts with AJAX', 'feeds-for-youtube' ),
|
||||
'strongHeading' => 'true',
|
||||
'labelStrong' => 'true',
|
||||
'options' => array(
|
||||
'enabled' => true,
|
||||
'disabled' => false,
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'switcher',
|
||||
'id' => 'eagerload',
|
||||
'label' => __( 'Load iFrames on Page Load', 'feeds-for-youtube' ),
|
||||
'strongHeading' => 'true',
|
||||
'labelStrong' => 'true',
|
||||
'options' => array(
|
||||
'enabled' => true,
|
||||
'disabled' => false,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Settings TabSources Section
|
||||
* @since 6.0
|
||||
* @return array
|
||||
*/
|
||||
private function get_settings_sources_controls() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'customview',
|
||||
'viewId' => 'sources',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,408 @@
|
||||
<?php
|
||||
/**
|
||||
* Styling Tab
|
||||
* Contains different controls for the individual Elements
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Customizer\Tabs;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\SBY_Display_Elements;
|
||||
|
||||
class Styling_Tab{
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 2.0
|
||||
* @return array
|
||||
*/
|
||||
public static function empty_style(){
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Customize Tab Individual Elements Nested Section
|
||||
* @since 2.0
|
||||
* @return array
|
||||
*/
|
||||
public static function playicon_styling_title(){
|
||||
return [
|
||||
[
|
||||
'type' => 'separator',
|
||||
'top' => 20,
|
||||
'bottom' => 5,
|
||||
],
|
||||
[
|
||||
'type' => 'heading',
|
||||
'heading' => __( 'Text', 'feeds-for-youtube' ),
|
||||
],
|
||||
[
|
||||
'type' => 'colorpicker',
|
||||
'id' => 'playiconcolor',
|
||||
'layout' => 'half',
|
||||
'strongHeading' => 'false',
|
||||
'heading' => __( 'Color', 'feeds-for-youtube' ),
|
||||
'style' => array( '[id^=sb_youtube_].sb_youtube .sby_video_title' => 'color:{{value}};' ),
|
||||
'stacked' => 'true'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Customize Tab Individual Elements Nested Section
|
||||
* @since 2.0
|
||||
* @return array
|
||||
*/
|
||||
public static function video_styling_title(){
|
||||
return [
|
||||
[
|
||||
'type' => 'separator',
|
||||
'top' => 20,
|
||||
'bottom' => 5,
|
||||
],
|
||||
[
|
||||
'type' => 'heading',
|
||||
'heading' => __( 'Text', 'feeds-for-youtube' ),
|
||||
],
|
||||
[
|
||||
'type' => 'colorpicker',
|
||||
'id' => 'videotitlecolor',
|
||||
'layout' => 'half',
|
||||
'strongHeading' => 'false',
|
||||
'heading' => __( 'Color', 'feeds-for-youtube' ),
|
||||
'style' => array( '[id^=sb_youtube_].sb_youtube .sby_video_title' => 'color:{{value}} !important;' ),
|
||||
'stacked' => 'true'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Customize Tab Individual Elements Nested Section
|
||||
* @since 2.0
|
||||
* @return array
|
||||
*/
|
||||
public static function user_styling_title(){
|
||||
return [
|
||||
[
|
||||
'type' => 'separator',
|
||||
'top' => 20,
|
||||
'bottom' => 5,
|
||||
],
|
||||
[
|
||||
'type' => 'heading',
|
||||
'heading' => __( 'Text', 'feeds-for-youtube' ),
|
||||
],
|
||||
[
|
||||
'type' => 'colorpicker',
|
||||
'id' => 'videouserecolor',
|
||||
'layout' => 'half',
|
||||
'strongHeading' => 'false',
|
||||
'heading' => __( 'Color', 'feeds-for-youtube' ),
|
||||
'style' => array( '[id^=sb_youtube_].sb_youtube .sby_meta span.sby_username_wrap' => 'color:{{value}} !important;' ),
|
||||
'stacked' => 'true'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Customize Tab Individual Elements Nested Section
|
||||
* @since 2.0
|
||||
* @return array
|
||||
*/
|
||||
public static function views_styling_title(){
|
||||
return [
|
||||
[
|
||||
'type' => 'separator',
|
||||
'top' => 20,
|
||||
'bottom' => 5,
|
||||
],
|
||||
[
|
||||
'type' => 'heading',
|
||||
'heading' => __( 'Text', 'feeds-for-youtube' ),
|
||||
],
|
||||
[
|
||||
'type' => 'colorpicker',
|
||||
'id' => 'videoviewsecolor',
|
||||
'layout' => 'half',
|
||||
'strongHeading' => 'false',
|
||||
'heading' => __( 'Color', 'feeds-for-youtube' ),
|
||||
'style' => array( '[id^=sb_youtube_].sb_youtube .sby_meta span.sby_view_count_wrap' => 'color:{{value}} !important;' ),
|
||||
'stacked' => 'true'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Customize Tab Individual Elements Nested Section
|
||||
* @since 2.0
|
||||
* @return array
|
||||
*/
|
||||
public static function countdown_styling_title(){
|
||||
return [
|
||||
[
|
||||
'type' => 'separator',
|
||||
'top' => 20,
|
||||
'bottom' => 5,
|
||||
],
|
||||
[
|
||||
'type' => 'heading',
|
||||
'heading' => __( 'Text', 'feeds-for-youtube' ),
|
||||
],
|
||||
[
|
||||
'type' => 'colorpicker',
|
||||
'id' => 'videocountdowncolor',
|
||||
'layout' => 'half',
|
||||
'strongHeading' => 'false',
|
||||
'heading' => __( 'Color', 'feeds-for-youtube' ),
|
||||
'style' => array( '[id^=sb_youtube_].sb_youtube .sby_ls_message_wrap .sby_ls_message' => 'background-color:{{value}} !important;' ),
|
||||
'stacked' => 'true'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Customize Tab Individual Elements Nested Section
|
||||
* @since 2.0
|
||||
* @return array
|
||||
*/
|
||||
public static function stats_styling_title(){
|
||||
return [
|
||||
[
|
||||
'type' => 'separator',
|
||||
'top' => 20,
|
||||
'bottom' => 5,
|
||||
],
|
||||
[
|
||||
'type' => 'heading',
|
||||
'heading' => __( 'Text', 'feeds-for-youtube' ),
|
||||
],
|
||||
[
|
||||
'type' => 'colorpicker',
|
||||
'id' => 'videostatscolor',
|
||||
'layout' => 'half',
|
||||
'strongHeading' => 'false',
|
||||
'heading' => __( 'Color', 'feeds-for-youtube' ),
|
||||
'style' => array( '[id^=sb_youtube_].sb_youtube .sby_info .sby_stats' => 'color:{{value}}!important;' ),
|
||||
'stacked' => 'true'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Customize Tab Individual Elements Nested Section
|
||||
* @since 2.0
|
||||
* @return array
|
||||
*/
|
||||
public static function date_styling_title(){
|
||||
$full_date = SBY_Display_Elements::full_date( strtotime( 'July 25th, 5:30 pm' ), array( 'dateformat' => '0', 'customdate' => '' ), $include_time = true );
|
||||
return [
|
||||
[
|
||||
'type' => 'separator',
|
||||
'top' => 20,
|
||||
'bottom' => 5,
|
||||
],
|
||||
[
|
||||
'type' => 'heading',
|
||||
'heading' => __( 'Format', 'feeds-for-youtube' ),
|
||||
],
|
||||
[
|
||||
'type' => 'select',
|
||||
'id' => 'dateformat',
|
||||
'stacked' => 'true',
|
||||
'options' => array(
|
||||
'0' => sprintf( __( 'WordPress Default (%s)', 'feeds-for-youtube' ), $full_date ),
|
||||
'1' => __( 'July 25th, 5:30 pm', 'feeds-for-youtube'),
|
||||
'2' => __( 'July 25th', 'feeds-for-youtube'),
|
||||
'3' => __( 'Mon July 25th', 'feeds-for-youtube'),
|
||||
'4' => __( 'Monday July 25th', 'feeds-for-youtube'),
|
||||
'5' => __( 'Mon Jul 25th, 2020', 'feeds-for-youtube'),
|
||||
'6' => __( 'Monday July 25th, 2020 - 5:30 pm', 'feeds-for-youtube'),
|
||||
'7' => __( '07.25.20', 'feeds-for-youtube'),
|
||||
'8' => __( '07.25.20 - 17:30', 'feeds-for-youtube'),
|
||||
'9' => __( '07/25/20', 'feeds-for-youtube'),
|
||||
'10' => __( '25.07.20', 'feeds-for-youtube'),
|
||||
'11' => __( '25/07/20', 'feeds-for-youtube'),
|
||||
'12' => __( '25th July 2020, 17:30', 'feeds-for-youtube'),
|
||||
'custom' => __( 'Custom', 'feeds-for-youtube'),
|
||||
),
|
||||
'default' => 'automatically',
|
||||
'ajaxAction' => 'feedFlyPreview',
|
||||
],
|
||||
[
|
||||
'type' => 'text',
|
||||
'id' => 'customdate',
|
||||
'condition' => array( 'dateformat' => array( 'custom' ) ),
|
||||
'conditionHide' => true,
|
||||
'strongHeading' => 'false',
|
||||
'stacked' => 'true',
|
||||
'placeholder' => 'Enter custom format (F j, Y g:i a)',
|
||||
'ajaxAction' => 'feedFlyPreview',
|
||||
],
|
||||
[
|
||||
'type' => 'checkbox',
|
||||
'id' => 'userelative',
|
||||
'label' => __( 'Use relative time (for example: 5 hours ago) when the video is less than 2 days old', 'feeds-for-youtube' ),
|
||||
'reverse' => 'true',
|
||||
'stacked' => 'true',
|
||||
'options' => array(
|
||||
'enabled' => true,
|
||||
'disabled' => false,
|
||||
)
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Customize Tab Individual Elements Nested Section
|
||||
* @since 2.0
|
||||
* @return array
|
||||
*/
|
||||
public static function description_styling_title(){
|
||||
return [
|
||||
[
|
||||
'type' => 'separator',
|
||||
'top' => 20,
|
||||
'bottom' => 5,
|
||||
],
|
||||
[
|
||||
'type' => 'number',
|
||||
'id' => 'descriptionlength',
|
||||
'stacked' => 'true',
|
||||
'fieldSuffix' => 'characters',
|
||||
'heading' => __( 'Maximum Text Length', 'feeds-for-youtube' ),
|
||||
'description' => __( 'Description will truncate after reaching the length', 'feeds-for-youtube' ),
|
||||
],
|
||||
[
|
||||
'type' => 'heading',
|
||||
'heading' => __( 'Text', 'feeds-for-youtube' ),
|
||||
],
|
||||
[
|
||||
'type' => 'select',
|
||||
'id' => 'descriptiontextsize',
|
||||
'heading' => __( 'Description Text Size', 'feeds-for-youtube' ),
|
||||
'layout' => 'half',
|
||||
'strongHeading' => 'false',
|
||||
'stacked' => 'true',
|
||||
'options' => array(
|
||||
'12px' => '12px',
|
||||
'13px' => '13px',
|
||||
'14px' => '14px',
|
||||
'15px' => '15px',
|
||||
'16px' => '16px',
|
||||
'18px' => '18px',
|
||||
'20px' => '20px',
|
||||
),
|
||||
'default' => '13px',
|
||||
'style' => array( '[id^=sb_youtube_].sb_youtube .sby_caption_wrap .sby_caption' => 'font-size:{{value}} !important;' ),
|
||||
],
|
||||
[
|
||||
'type' => 'colorpicker',
|
||||
'id' => 'videodescriptioncolor',
|
||||
'layout' => 'half',
|
||||
'strongHeading' => 'false',
|
||||
'heading' => __( 'Color', 'feeds-for-youtube' ),
|
||||
'style' => array( '[id^=sb_youtube_].sb_youtube .sby_caption_wrap.sby_item_caption_wrap .sby_caption' => 'color:{{value}}!important;' ),
|
||||
'stacked' => 'true'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Customize Tab Individual Elements Nested Section
|
||||
* @since 2.0
|
||||
* @return array
|
||||
*/
|
||||
public static function call_to_action( $feed_id ){
|
||||
return array(
|
||||
array(
|
||||
'type' => 'separator',
|
||||
'top' => 0,
|
||||
'bottom' => 10,
|
||||
),
|
||||
array(
|
||||
'type' => 'select',
|
||||
'id' => 'cta',
|
||||
'heading' => __( 'Type', 'feeds-for-youtube' ),
|
||||
'description' => __( 'What the user sees when a video pauses or ends', 'feeds-for-youtube' ),
|
||||
'strongHeading' => 'true',
|
||||
'stacked' => 'true',
|
||||
'options' => array(
|
||||
'related' => 'Related Videos',
|
||||
'link' => 'Custom Link',
|
||||
'default' => 'YouTube Default',
|
||||
),
|
||||
'default' => 'related'
|
||||
),
|
||||
array(
|
||||
'type' => 'separator',
|
||||
'condition' => array( 'cta' => array( 'link' ) ),
|
||||
'conditionHide' => true,
|
||||
'top' => 20,
|
||||
'bottom' => 5,
|
||||
),
|
||||
array(
|
||||
'type' => 'heading',
|
||||
'heading' => __( 'Settings', 'feeds-for-youtube' ),
|
||||
'condition' => array( 'cta' => array( 'link' ) ),
|
||||
'conditionHide' => true,
|
||||
),
|
||||
array(
|
||||
'type' => 'text',
|
||||
'id' => 'linktext',
|
||||
'layout' => 'half',
|
||||
'condition' => array( 'cta' => array( 'link' ) ),
|
||||
'conditionHide' => true,
|
||||
'strongHeading' => 'false',
|
||||
'stacked' => 'true',
|
||||
'heading' => __( 'Button Text', 'feeds-for-youtube' ),
|
||||
),
|
||||
array(
|
||||
'type' => 'colorpicker',
|
||||
'id' => 'linkcolor',
|
||||
'condition' => array( 'cta' => array( 'link' ) ),
|
||||
'conditionHide' => true,
|
||||
'layout' => 'half',
|
||||
'strongHeading' => 'false',
|
||||
'heading' => __( 'Button Background', 'feeds-for-youtube' ),
|
||||
'style' => array( '[id^=sb_youtube_].sb_youtube.sby_palette_custom_' . $feed_id . ' .sby_video_title' => 'color:{{value}}!important;' ),
|
||||
'stacked' => 'true',
|
||||
),
|
||||
array(
|
||||
'type' => 'colorpicker',
|
||||
'id' => 'linktextcolor',
|
||||
'condition' => array( 'cta' => array( 'link' ) ),
|
||||
'conditionHide' => true,
|
||||
'layout' => 'half',
|
||||
'strongHeading' => 'false',
|
||||
'heading' => __( 'Button Text Color', 'feeds-for-youtube' ),
|
||||
'style' => array( '[id^=sb_youtube_].sb_youtube.sby_palette_custom_' . $feed_id . ' .sby_video_title' => 'color:{{value}}!important;' ),
|
||||
'stacked' => 'true',
|
||||
),
|
||||
array(
|
||||
'type' => 'select',
|
||||
'id' => 'linkopentype',
|
||||
'heading' => __( 'Open link in', 'feeds-for-youtube' ),
|
||||
'condition' => array( 'cta' => array( 'link' ) ),
|
||||
'conditionHide' => true,
|
||||
'layout' => 'half',
|
||||
'strongHeading' => 'false',
|
||||
'stacked' => 'true',
|
||||
'options' => array(
|
||||
'same' => 'Same Window',
|
||||
'newwindow' => 'New Window',
|
||||
),
|
||||
'default' => 'same'
|
||||
),
|
||||
array(
|
||||
'type' => 'textarea',
|
||||
'id' => 'linkurl',
|
||||
'heading' => __( 'Default Link', 'feeds-for-youtube' ),
|
||||
'placeholder' => __( 'https://', 'feeds-for-youtube' ),
|
||||
'condition' => array( 'cta' => array( 'link' ) ),
|
||||
'conditionHide' => true,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Customizer\Tabs;
|
||||
|
||||
use Smashballoon\Customizer\Tabs\Manager;
|
||||
use Smashballoon\Stubs\Services\ServiceProvider;
|
||||
|
||||
class TabsService extends ServiceProvider {
|
||||
|
||||
/**
|
||||
* @var Customize_Tab
|
||||
*/
|
||||
private $customize_tab;
|
||||
/**
|
||||
* @var Settings_Tab
|
||||
*/
|
||||
private $settings_tab;
|
||||
|
||||
public function __construct(Customize_Tab $customize_tab, Settings_Tab $settings_tab) {
|
||||
$this->customize_tab = $customize_tab;
|
||||
$this->settings_tab = $settings_tab;
|
||||
}
|
||||
|
||||
public function register() {
|
||||
$tabs_manager = Manager::getInstance();
|
||||
$tabs_manager->register_tab($this->customize_tab);
|
||||
$tabs_manager->register_tab($this->settings_tab);
|
||||
}
|
||||
}
|
||||
12
wp-content/plugins/youtube-feed-pro/inc/Data/DataFactory.php
Normal file
12
wp-content/plugins/youtube-feed-pro/inc/Data/DataFactory.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Data;
|
||||
|
||||
|
||||
use SmashBalloon\YouTubeFeed\Container;
|
||||
|
||||
class DataFactory {
|
||||
public function create($class) {
|
||||
return Container::get_instance()->get($class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Data;
|
||||
|
||||
class GoogleAPIResponseStruct {
|
||||
public $data;
|
||||
public $response;
|
||||
public $status;
|
||||
}
|
||||
487
wp-content/plugins/youtube-feed-pro/inc/Feed_Locator.php
Normal file
487
wp-content/plugins/youtube-feed-pro/inc/Feed_Locator.php
Normal file
@@ -0,0 +1,487 @@
|
||||
<?php
|
||||
/**
|
||||
* Class SBY_Feed_Locator
|
||||
*
|
||||
* Locates feeds on the site and logs information about them in the database.
|
||||
*
|
||||
* @since 1.14
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
|
||||
use Smashballoon\Customizer\DB;
|
||||
|
||||
class Feed_Locator
|
||||
{
|
||||
private $feed_details;
|
||||
|
||||
private $expiration_time;
|
||||
|
||||
private $matching_entries;
|
||||
|
||||
public function __construct( $feed_details ) {
|
||||
/**
|
||||
* Example of how $feed_details is structured
|
||||
*
|
||||
* $feed_details = array(
|
||||
* 'feed_id' => $transient_name,
|
||||
* 'atts' => $atts,
|
||||
* 'location' => array(
|
||||
* 'post_id' => get_the_ID(),
|
||||
* 'html' => 'unknown'
|
||||
* )
|
||||
* );
|
||||
*/
|
||||
$this->feed_details = $feed_details;
|
||||
|
||||
$this->matching_entries = array();
|
||||
|
||||
$this->expiration_time = time() - 2 * WEEK_IN_SECONDS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns records that match the post ID and feed ID
|
||||
* of the feed being located
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.14
|
||||
*/
|
||||
public function retrieve_matching_entries() {
|
||||
global $wpdb;
|
||||
$feed_locator_table_name = esc_sql( $wpdb->prefix . SBY_FEED_LOCATOR );
|
||||
|
||||
$results = $wpdb->get_results( $wpdb->prepare("
|
||||
SELECT *
|
||||
FROM $feed_locator_table_name
|
||||
WHERE post_id = %d
|
||||
AND feed_id = %s", $this->feed_details['location']['post_id'], $this->feed_details['feed_id'] ),ARRAY_A );
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add feed being located to the database
|
||||
*
|
||||
* @since 1.14
|
||||
*/
|
||||
public function insert_entry() {
|
||||
global $wpdb;
|
||||
|
||||
$feed_locator_table_name = esc_sql( $wpdb->prefix . SBY_FEED_LOCATOR );
|
||||
|
||||
$affected = $wpdb->query( $wpdb->prepare( "INSERT INTO $feed_locator_table_name
|
||||
(feed_id,
|
||||
post_id,
|
||||
html_location,
|
||||
shortcode_atts,
|
||||
last_update)
|
||||
VALUES (
|
||||
%s,
|
||||
%d,
|
||||
%s,
|
||||
%s,
|
||||
%s);",
|
||||
$this->feed_details['atts']['feed'],
|
||||
$this->feed_details['location']['post_id'],
|
||||
$this->feed_details['location']['html'],
|
||||
$this->sby_json_encode( $this->feed_details['atts'] ),
|
||||
date( 'Y-m-d H:i:s' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a record based on the existing "id" column. Location can change
|
||||
* from "unknown" to one of footer, content, header, or sidebar.
|
||||
*
|
||||
* @param $id
|
||||
* @param $location
|
||||
*
|
||||
* @since 1.14
|
||||
*/
|
||||
public function update_entry( $id, $location ) {
|
||||
global $wpdb;
|
||||
|
||||
$feed_locator_table_name = esc_sql( $wpdb->prefix . SBY_FEED_LOCATOR );
|
||||
|
||||
$query = $wpdb->query( $wpdb->prepare( "
|
||||
UPDATE $feed_locator_table_name
|
||||
SET last_update = %s, html_location = %s
|
||||
WHERE id = %d;", date( 'Y-m-d H:i:s' ), $location, $id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a feed being located based on whether or not the record
|
||||
* exists as well as whether or not an unknown location needs to be
|
||||
* updated.
|
||||
*
|
||||
* @since 1.14
|
||||
*/
|
||||
public function add_or_update_entry() {
|
||||
if ( empty( $this->feed_details['feed_id'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->matching_entries = $this->retrieve_matching_entries();
|
||||
|
||||
if ( empty( $this->matching_entries ) ) {
|
||||
$this->insert_entry();
|
||||
} else {
|
||||
$matching_indices = array();
|
||||
$matched_location = false;
|
||||
$non_unknown_match = false;
|
||||
$unknown_match = false;
|
||||
|
||||
foreach ( $this->matching_entries as $index => $matching_entry ) {
|
||||
$details_atts = is_array( $this->feed_details['atts'] ) ? $this->feed_details['atts'] : array();
|
||||
$matching_atts = json_decode( $matching_entry['shortcode_atts'], true );
|
||||
if ( ! is_array( $matching_atts ) ) {
|
||||
$matching_atts = array();
|
||||
}
|
||||
$atts_diff = array_diff( $matching_atts, $details_atts ); // determines if the shortcode settings match the shortcode settings of an existing feed
|
||||
if ( empty( $atts_diff ) ) {
|
||||
$matching_indices[] = $matching_entry['id'];
|
||||
if ( $matching_entry['html_location'] === $this->feed_details['location']['html'] ) {
|
||||
$matched_location = $index;
|
||||
$this->update_entry( $matching_entry['id'], $matching_entry['html_location'] );
|
||||
}
|
||||
if ( $matching_entry['html_location'] !== 'unknown' ) {
|
||||
$non_unknown_match = $index;
|
||||
} else {
|
||||
$unknown_match = $index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( false === $matched_location ) {
|
||||
// if there is no matched location, there is only one feed on the page, and the feed being checked has an unknown location, update the known location
|
||||
if ( count( $matching_indices ) === 1
|
||||
&& $this->feed_details['location']['html'] === 'unknown'
|
||||
&& false !== $non_unknown_match ) {
|
||||
$this->update_entry( $this->matching_entries[ $non_unknown_match ]['id'], $this->matching_entries[ $non_unknown_match ]['html_location'] );
|
||||
} else {
|
||||
if ( $this->feed_details['location']['html'] !== 'unknown'
|
||||
&& false !== $unknown_match ) {
|
||||
$this->update_entry( $this->matching_entries[ $unknown_match ]['id'], $this->feed_details['location']['html'] );
|
||||
} else {
|
||||
$this->insert_entry();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Old feeds are only detected once a day to keep load on the server low.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.14
|
||||
*/
|
||||
public static function should_clear_old_locations() {
|
||||
$sby_statuses_option = get_option( 'sby_statuses', array() );
|
||||
$last_old_feed_check = isset( $sby_statuses_option['feed_locator']['last_check'] ) ? $sby_statuses_option['feed_locator']['last_check'] : 0;
|
||||
|
||||
return $last_old_feed_check < time() - DAY_IN_SECONDS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Old feeds are removed if they haven't been updated in two weeks.
|
||||
*
|
||||
* @since 1.14
|
||||
*/
|
||||
public static function delete_old_locations() {
|
||||
global $wpdb;
|
||||
|
||||
$feed_locator_table_name = esc_sql( $wpdb->prefix . SBY_FEED_LOCATOR );
|
||||
$two_weeks_ago = date( 'Y-m-d H:i:s', time() - 2 * WEEK_IN_SECONDS );
|
||||
|
||||
$affected = $wpdb->query( $wpdb->prepare(
|
||||
"DELETE FROM $feed_locator_table_name WHERE last_update < %s;", $two_weeks_ago ) );
|
||||
|
||||
$sby_statuses_option = get_option( 'sby_statuses', array() );
|
||||
$sby_statuses_option['feed_locator']['last_check'] = time();
|
||||
if ( ! isset( $sby_statuses_option['feed_locator']['initialized'] ) ) {
|
||||
$sby_statuses_option['feed_locator']['initialized'] = time();
|
||||
}
|
||||
|
||||
update_option( 'sby_statuses', $sby_statuses_option, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Feeds are located with the page load randomly (5% or 1/30 loads)
|
||||
* to decrease load on the server.
|
||||
*
|
||||
* If the locating just started (within 5 minutes) it is run more often
|
||||
* to collect feed locations quickly.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.14
|
||||
*/
|
||||
public static function should_do_locating() {
|
||||
$sby_statuses_option = get_option( 'sby_statuses', array() );
|
||||
if ( isset( $sby_statuses_option['feed_locator']['initialized'] )
|
||||
&& $sby_statuses_option['feed_locator']['initialized'] < (time() - 300) ) {
|
||||
$should_do_locating = rand( 1, 10 ) === 10;
|
||||
} else {
|
||||
$should_do_locating = rand( 1, 30 ) === 30;
|
||||
}
|
||||
$should_do_locating = apply_filters( 'sby_should_do_locating', $should_do_locating );
|
||||
|
||||
return $should_do_locating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simliar to the should_do_locating method but will add an additional
|
||||
* database query to see if there is a feed with an unknown location that
|
||||
* matches the details of the feed in question.
|
||||
*
|
||||
* @param $feed_id
|
||||
* @param $post_id
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.14
|
||||
*/
|
||||
public static function should_do_ajax_locating( $feed_id, $post_id ) {
|
||||
|
||||
$should_do_locating = rand( 1, 50 ) === 50;
|
||||
|
||||
$should_do_locating = apply_filters( 'sby_should_do_ajax_locating', $should_do_locating );
|
||||
|
||||
return $should_do_locating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Feeds are located with the page load randomly (1/30 loads)
|
||||
* to decrease load on the server.
|
||||
*
|
||||
* If the locating just started (within 5 minutes) it is run more often
|
||||
* to collect feed locations quickly.
|
||||
*
|
||||
* @param $feed_id
|
||||
* @param $post_id
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.14
|
||||
*/
|
||||
public static function entries_need_locating( $feed_id, $post_id ) {
|
||||
global $wpdb;
|
||||
$feed_locator_table_name = esc_sql( $wpdb->prefix . SBY_FEED_LOCATOR );
|
||||
|
||||
$one_day_ago = date( 'Y-m-d H:i:s', time() - DAY_IN_SECONDS );
|
||||
|
||||
$results = $wpdb->get_results( $wpdb->prepare("
|
||||
SELECT id
|
||||
FROM $feed_locator_table_name
|
||||
WHERE html_location = 'unknown'
|
||||
AND last_update < %s
|
||||
AND feed_id = %s
|
||||
AND post_id = %d
|
||||
LIMIT 1;", $one_day_ago, $feed_id, $post_id ),ARRAY_A );
|
||||
|
||||
return isset( $results[0] );
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom table stores locations
|
||||
*
|
||||
* @since 1.14
|
||||
*/
|
||||
public static function create_table() {
|
||||
global $wpdb;
|
||||
|
||||
$feed_locator_table_name = esc_sql( $wpdb->prefix . SBY_FEED_LOCATOR );
|
||||
|
||||
if ( $wpdb->get_var( "show tables like '$feed_locator_table_name'" ) != $feed_locator_table_name ) {
|
||||
$sql = "CREATE TABLE " . $feed_locator_table_name . " (
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
feed_id VARCHAR(50) DEFAULT '' NOT NULL,
|
||||
post_id BIGINT(20) UNSIGNED NOT NULL,
|
||||
html_location VARCHAR(50) DEFAULT 'unknown' NOT NULL,
|
||||
shortcode_atts LONGTEXT NOT NULL,
|
||||
last_update DATETIME
|
||||
);";
|
||||
$wpdb->query( $sql );
|
||||
}
|
||||
$error = $wpdb->last_error;
|
||||
$query = $wpdb->last_query;
|
||||
$had_error = false;
|
||||
if ( $wpdb->get_var( "show tables like '$feed_locator_table_name'" ) != $feed_locator_table_name ) {
|
||||
$had_error = true;
|
||||
}
|
||||
|
||||
if ( ! $had_error ) {
|
||||
$wpdb->query( "ALTER TABLE $feed_locator_table_name ADD INDEX feed_id (feed_id)" );
|
||||
$wpdb->query( "ALTER TABLE $feed_locator_table_name ADD INDEX post_id (post_id)" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of unique feeds in the database.
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @since 1.14
|
||||
*/
|
||||
public static function count_unique() {
|
||||
global $wpdb;
|
||||
|
||||
$feed_locator_table_name = esc_sql( $wpdb->prefix . SBY_FEED_LOCATOR );
|
||||
$results_content = $wpdb->get_results( "
|
||||
SELECT COUNT(*) AS num_entries
|
||||
FROM $feed_locator_table_name
|
||||
WHERE html_location = 'content'
|
||||
", ARRAY_A );
|
||||
|
||||
|
||||
$results_other = $wpdb->get_results( "
|
||||
SELECT COUNT(*) AS num_entries
|
||||
FROM $feed_locator_table_name
|
||||
WHERE html_location != 'content'
|
||||
AND html_location != 'unknown'
|
||||
GROUP BY feed_id
|
||||
", ARRAY_A );
|
||||
|
||||
$total = 0;
|
||||
if ( isset( $results_content[0]['num_entries'] ) ) {
|
||||
$total += (int)$results_content[0]['num_entries'];
|
||||
}
|
||||
if ( isset( $results_other[0]['num_entries'] ) ) {
|
||||
$total += (int)$results_other[0]['num_entries'];
|
||||
}
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a summary of the located feeds in an array
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.14
|
||||
*/
|
||||
public static function summary() {
|
||||
global $wpdb;
|
||||
|
||||
$feed_locator_table_name = esc_sql( $wpdb->prefix . SBY_FEED_LOCATOR );
|
||||
|
||||
$locations = array(
|
||||
array(
|
||||
'label' => __( 'Content', 'feeds-for-youtube' ),
|
||||
'html_locations' => array( 'content', 'unknown' )
|
||||
),
|
||||
array(
|
||||
'label' => __( 'Header', 'feeds-for-youtube' ),
|
||||
'html_locations' => array( 'header' ),
|
||||
'group_by' => 'feed_id'
|
||||
),
|
||||
array(
|
||||
'label' => __( 'Sidebar', 'feeds-for-youtube' ),
|
||||
'html_locations' => array( 'sidebar' ),
|
||||
'group_by' => 'feed_id'
|
||||
),
|
||||
array(
|
||||
'label' => __( 'Footer', 'feeds-for-youtube' ),
|
||||
'html_locations' => array( 'footer' ),
|
||||
'group_by' => 'feed_id'
|
||||
)
|
||||
);
|
||||
|
||||
$one_result_found = false;
|
||||
|
||||
foreach ( $locations as $key => $location ) {
|
||||
$in = implode( "', '", $location['html_locations'] );
|
||||
$group_by = isset( $location['group_by'] ) ? "GROUP BY " . $location['group_by'] : "";
|
||||
$results = $wpdb->get_results("
|
||||
SELECT *
|
||||
FROM $feed_locator_table_name
|
||||
WHERE html_location IN ('$in')
|
||||
$group_by
|
||||
ORDER BY last_update ASC",ARRAY_A );
|
||||
|
||||
if ( isset( $results[0] ) ) {
|
||||
$one_result_found = true;
|
||||
}
|
||||
|
||||
$locations[ $key ]['results'] = $results;
|
||||
}
|
||||
|
||||
if ( ! $one_result_found ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return $locations;
|
||||
}
|
||||
|
||||
private function sby_json_encode( $thing ) {
|
||||
if ( function_exists( 'wp_json_encode' ) ) {
|
||||
return wp_json_encode( $thing );
|
||||
} else {
|
||||
return json_encode( $thing );
|
||||
}
|
||||
}
|
||||
|
||||
public static function legacy_feed_locator_query( $args ) {
|
||||
global $wpdb;
|
||||
$feed_locator_table_name = $wpdb->prefix . SBY_FEED_LOCATOR;
|
||||
|
||||
$group_by = '';
|
||||
if ( isset( $args['group_by'] ) ) {
|
||||
$group_by = 'GROUP BY ' . esc_sql( $args['group_by'] );
|
||||
}
|
||||
|
||||
$location_string = 'content';
|
||||
if ( isset( $args['html_location'] ) ) {
|
||||
$locations = array_map( 'esc_sql', $args['html_location'] );
|
||||
$location_string = implode( "', '", $locations );
|
||||
}
|
||||
|
||||
$page = 0;
|
||||
if ( isset( $args['page'] ) ) {
|
||||
$page = (int) $args['page'] - 1;
|
||||
unset( $args['page'] );
|
||||
}
|
||||
|
||||
$offset = max( 0, $page * DB::RESULTS_PER_PAGE );
|
||||
$limit = DB::RESULTS_PER_PAGE;
|
||||
|
||||
$results = $wpdb->get_results(
|
||||
"
|
||||
SELECT *
|
||||
FROM $feed_locator_table_name
|
||||
WHERE feed_id NOT LIKE '*%'
|
||||
AND html_location IN ( '$location_string' )
|
||||
$group_by
|
||||
LIMIT $limit
|
||||
OFFSET $offset;",
|
||||
ARRAY_A
|
||||
);
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public static function update_legacy_to_builder( $args ) {
|
||||
global $wpdb;
|
||||
$feed_locator_table_name = $wpdb->prefix . SBY_FEED_LOCATOR;
|
||||
|
||||
$data = array(
|
||||
'feed_id' => '*' . $args['new_feed_id'],
|
||||
'shortcode_atts' => '{"feed":"' . $args['new_feed_id'] . '"}',
|
||||
);
|
||||
|
||||
$affected = $wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"UPDATE $feed_locator_table_name
|
||||
SET feed_id = %s, shortcode_atts = %s",
|
||||
$data['feed_id'],
|
||||
$data['shortcode_atts']
|
||||
)
|
||||
);
|
||||
|
||||
return $affected;
|
||||
}
|
||||
}
|
||||
99
wp-content/plugins/youtube-feed-pro/inc/HTTP_Request.php
Normal file
99
wp-content/plugins/youtube-feed-pro/inc/HTTP_Request.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* Class HTTP_Request
|
||||
*
|
||||
* This class with make remote request
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class HTTP_Request {
|
||||
|
||||
/**
|
||||
* Make the HTTP remote request
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $url
|
||||
* @param array|null $data
|
||||
*
|
||||
* @since 6.0
|
||||
*
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public static function request( $method, $url, $data = null ) {
|
||||
$args = array(
|
||||
'headers' => array(
|
||||
'Content-Type' => 'application/json',
|
||||
),
|
||||
);
|
||||
|
||||
$args = array_merge( $args, $data );
|
||||
|
||||
if ( 'GET' === $method ) {
|
||||
$request = wp_remote_get( $url, $args );
|
||||
} elseif ( 'DELETE' === $method ) {
|
||||
$args['method'] = 'DELETE';
|
||||
$request = wp_remote_request( $url, $args );
|
||||
} elseif ( 'PATCH' === $method ) {
|
||||
$args['method'] = 'PATCH';
|
||||
$request = wp_remote_request( $url, $args );
|
||||
} elseif ( 'PUT' === $method ) {
|
||||
$args['method'] = 'PUT';
|
||||
$request = wp_remote_request( $url, $args );
|
||||
} else {
|
||||
$args['method'] = 'POST';
|
||||
$request = wp_remote_post( $url, $args );
|
||||
}
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if WP_Error returned
|
||||
*
|
||||
* @param array|WP_Error $request
|
||||
*
|
||||
* @since 6.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_error( $request ) {
|
||||
return is_wp_error( $request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the remote call status code
|
||||
*
|
||||
* @param array|WP_Error $request
|
||||
*
|
||||
* @since 6.0
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public static function status( $request ) {
|
||||
if ( is_wp_error( $request ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
return wp_remote_retrieve_response_code( $request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the remote call body data
|
||||
*
|
||||
* @param array|WP_Error $request
|
||||
*
|
||||
* @since 6.0
|
||||
*
|
||||
* @return array $response
|
||||
*/
|
||||
public static function data( $request ) {
|
||||
$response = wp_remote_retrieve_body( $request );
|
||||
return json_decode( $response );
|
||||
}
|
||||
}
|
||||
357
wp-content/plugins/youtube-feed-pro/inc/Helpers/Util.php
Normal file
357
wp-content/plugins/youtube-feed-pro/inc/Helpers/Util.php
Normal file
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Helpers;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\Pro\SBY_API_Connect_Pro;
|
||||
use SmashBalloon\YouTubeFeed\SBY_API_Connect;
|
||||
|
||||
class Util {
|
||||
public static function isPro() {
|
||||
return defined( 'SBY_PRO' ) && SBY_PRO === true;
|
||||
}
|
||||
|
||||
public static function isProduction() {
|
||||
return empty($_ENV['SBY_DEVELOPMENT']) || $_ENV['SBY_DEVELOPMENT'] !== 'true';
|
||||
}
|
||||
|
||||
public static function ajaxPreflightChecks() {
|
||||
check_ajax_referer( 'sby-admin', 'nonce' );
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_send_json_error(); // This auto-dies.
|
||||
}
|
||||
}
|
||||
|
||||
public static function sby_capability_check() {
|
||||
$cap = current_user_can( 'manage_youtube_feed_options' ) ? 'manage_youtube_feed_options' : 'manage_options';
|
||||
$cap = apply_filters( 'sby_settings_pages_capability', $cap );
|
||||
return $cap;
|
||||
}
|
||||
|
||||
public static function isCurrentScreenAllowed() {
|
||||
$allowed_screens = array(
|
||||
'dashboard',
|
||||
'toplevel_page_sby-feed-builder',
|
||||
'youtube-feed_page_youtube-feed-setup',
|
||||
'youtube-feed_page_youtube-feed-settings',
|
||||
'youtube-feed_page_youtube-feed-single-videos',
|
||||
'youtube-feed_page_youtube-feed-support',
|
||||
'youtube-feed_page_youtube-feed-about',
|
||||
);
|
||||
$allowed_screens = apply_filters( 'sby_settings_pages_allowed_screens', $allowed_screens );
|
||||
$current_screen = get_current_screen();
|
||||
$current_screen = $current_screen->id;
|
||||
$is_allowed = in_array( $current_screen, $allowed_screens );
|
||||
return $is_allowed;
|
||||
}
|
||||
|
||||
public static function get_license_key() {
|
||||
$license_key = get_option( 'sby_license_key' );
|
||||
$license_key = apply_filters( 'sby_license_key', $license_key );
|
||||
return $license_key;
|
||||
}
|
||||
|
||||
public static function get_license_data() {
|
||||
if ( get_option( 'sby_license_data' ) ) {
|
||||
// Get license data from the db and convert the object to an array
|
||||
return (array) get_option( 'sby_license_data' );
|
||||
}
|
||||
|
||||
$sby_license_data = self::sby_check_license( self::get_license_key() );
|
||||
|
||||
return $sby_license_data;
|
||||
}
|
||||
|
||||
public static function is_license_expired() {
|
||||
// Get license data
|
||||
$sby_license_data = (array) Util::get_license_data();
|
||||
//If expires param isn't set yet then set it to be a date to avoid PHP notice
|
||||
$sby_license_expires_date = isset( $sby_license_data['expires'] ) ? $sby_license_data['expires'] : '2036-12-31 23:59:59';
|
||||
if ( $sby_license_expires_date == 'lifetime' ) {
|
||||
$sby_license_expires_date = '2036-12-31 23:59:59';
|
||||
}
|
||||
$sby_todays_date = date('Y-m-d');
|
||||
$sby_interval = round( abs( strtotime( $sby_todays_date ) - strtotime( $sby_license_expires_date ) ) / 86400 );
|
||||
//Is license expired?
|
||||
if( $sby_interval == 0 || strtotime( $sby_license_expires_date ) < strtotime( $sby_todays_date ) ) {
|
||||
// If we haven't checked the API again one last time before displaying the expired notice then check it to make sure the license hasn't been renewed
|
||||
if ( get_option( 'sby_check_license_api_when_expires' ) !== 'false' ) {
|
||||
$sby_license_expired = self::sby_check_license( self::get_license_key(), true );
|
||||
} else {
|
||||
$sby_license_expired = true;
|
||||
}
|
||||
} else {
|
||||
$sby_license_expired = false;
|
||||
//License is not expired so change the check_api setting to be true so the next time it expires it checks again
|
||||
update_option( 'sby_check_license_api_when_expires', 'true' );
|
||||
update_option( 'sby_check_license_api_post_grace_period', 'true' );
|
||||
}
|
||||
|
||||
$sby_license_expires_date_arr = str_split($sby_license_expires_date);
|
||||
// If expired date is returned as 1970 (or any other 20th century year) then it means that the correct expired date was not returned and so don't show the renewal notice
|
||||
if( $sby_license_expires_date_arr[0] == '1' ) $sby_license_expired = false;
|
||||
|
||||
// If there's no expired date then don't show the expired notification
|
||||
if( empty($sby_license_expires_date) || !isset($sby_license_expires_date) ) {
|
||||
$sby_license_expired = false;
|
||||
}
|
||||
|
||||
// Is license missing - ie. on very first check
|
||||
if ( isset( $sby_license_data['error'] ) ) {
|
||||
if ( $sby_license_data['error'] == 'missing' ) {
|
||||
$sby_license_expired = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $sby_license_expired;
|
||||
}
|
||||
|
||||
public static function is_license_grace_period_ended( $post_grace_period = false ) {
|
||||
// Get license data
|
||||
$sby_license_data = (array) Util::get_license_data();
|
||||
//If expires param isn't set yet then set it to be a date to avoid PHP notice
|
||||
$sby_license_expires_date = isset( $sby_license_data['expires'] ) ? $sby_license_data['expires'] : '2036-12-31 23:59:59';
|
||||
if ( $sby_license_expires_date == 'lifetime' ) {
|
||||
$sby_license_expires_date = '2036-12-31 23:59:59';
|
||||
}
|
||||
|
||||
$sby_todays_date = date('Y-m-d');
|
||||
$sby_grace_period_date = strtotime( $sby_license_expires_date . '+14 days');
|
||||
$sby_grace_period_interval = round( abs( strtotime( $sby_todays_date ) - $sby_grace_period_date ) / 86400 );
|
||||
|
||||
if ( $post_grace_period && strtotime( $sby_todays_date ) > $sby_grace_period_date ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $sby_grace_period_interval == 0 || $sby_grace_period_date < strtotime( $sby_todays_date ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remote check for license status
|
||||
*
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public static function sby_check_license( $sby_license, $check_license_status = false, $license_api_second_check = false ) {
|
||||
//Set a flag so it doesn't check the API again until the next time it expires
|
||||
if ( $license_api_second_check ) {
|
||||
update_option( 'sby_check_license_api_post_grace_period', 'false' );
|
||||
} else {
|
||||
update_option( 'sby_check_license_api_when_expires', 'false' );
|
||||
}
|
||||
|
||||
// data to send in our API request
|
||||
$sby_api_params = array(
|
||||
'edd_action'=> 'check_license',
|
||||
'license' => $sby_license,
|
||||
'item_name' => urlencode( SBY_PLUGIN_NAME ) // the name of our product in EDD
|
||||
);
|
||||
$api_url = add_query_arg( $sby_api_params, SBY_STORE_URL );
|
||||
$args = array(
|
||||
'timeout' => 60,
|
||||
'sslverify' => false
|
||||
);
|
||||
// Call the custom API.
|
||||
$request = wp_remote_get( $api_url, $args );
|
||||
if ( is_wp_error( $request ) ) {
|
||||
return;
|
||||
}
|
||||
// decode the license data
|
||||
$sby_license_data = json_decode( wp_remote_retrieve_body( $request ) );
|
||||
$sby_license_data_arr = (array) $sby_license_data;
|
||||
//Store license data in db
|
||||
update_option( 'sby_license_data', $sby_license_data );
|
||||
update_option( 'sby_license_status', $sby_license_data->license );
|
||||
$sby_todays_date = date('Y-m-d');
|
||||
if ( $check_license_status ) {
|
||||
//Check whether it's active
|
||||
if( $sby_license_data_arr['license'] !== 'expired' && ( strtotime( $sby_license_data_arr['expires'] ) > strtotime( $sby_todays_date ) ) ){
|
||||
$sby_license_status = false;
|
||||
} else {
|
||||
$sby_license_status = true;
|
||||
}
|
||||
|
||||
return $sby_license_status;
|
||||
}
|
||||
|
||||
return $sby_license_data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update License Data
|
||||
*
|
||||
*/
|
||||
public static function update_recheck_license_data( $license_data ) {
|
||||
$license_changed = false;
|
||||
// compare the old stored license status with new license status
|
||||
if ( get_option( 'sby_license_status' ) !== $license_data->license ) {
|
||||
$license_changed = true;
|
||||
// make license check_api true so next time it expires it checks again
|
||||
update_option( 'sby_check_license_api_when_expires', 'true' );
|
||||
update_option( 'sby_check_license_api_post_grace_period', 'true' );
|
||||
}
|
||||
update_option( 'sby_license_status', $license_data->license );
|
||||
|
||||
return $license_changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if licese expired/inactive notices needs to show
|
||||
*
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public static function expiredLicenseWithGracePeriodEnded() {
|
||||
return !empty( self::get_license_key() ) &&
|
||||
self::is_license_expired() &&
|
||||
self::is_license_grace_period_ended( true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Make API request to get channel ID from YouTube handle
|
||||
*/
|
||||
public static function get_channel_id_by_api_request( $url ) {
|
||||
$response = new \stdClass();
|
||||
$path = parse_url($url, PHP_URL_PATH);
|
||||
$basename = basename($path); // This will give you the username part
|
||||
|
||||
if( !empty($basename) ) {
|
||||
$username = strpos($basename, '@') === 0 ? substr($basename, 1) : $basename;
|
||||
|
||||
$params = array(
|
||||
'channel_handle' => $username
|
||||
);
|
||||
|
||||
$connected_account = sby_get_first_connected_account();
|
||||
$sby_api_connect = new SBY_API_Connect($connected_account, 'channels', $params );
|
||||
$sby_api_connect->connect();
|
||||
|
||||
$data = $sby_api_connect->get_data();
|
||||
|
||||
|
||||
if ( ! $sby_api_connect->is_youtube_error() ) {
|
||||
$channelId = !empty($data['items'][0]['id']) ? $data['items'][0]['id'] : '';
|
||||
$response->channel_id = $channelId;
|
||||
}
|
||||
}
|
||||
|
||||
if( empty($response->channel_id)) {
|
||||
$api_register_url = SBY_API_URL . 'auth/register?url=' . get_home_url();
|
||||
$api_url = SBY_API_URL . 'youtube/handle?channel_url=' . $url;
|
||||
|
||||
// Get Authorization Token
|
||||
$request = wp_remote_post( $api_register_url );
|
||||
if ( is_wp_error( $request ) ) {
|
||||
return;
|
||||
}
|
||||
$response = json_decode( wp_remote_retrieve_body( $request ) );
|
||||
if ( $response->success && empty( $response->token ) || ! $response->success && empty( $response->data->token ) ) {
|
||||
error_log('returning due to empty token');
|
||||
return;
|
||||
}
|
||||
if ( $response->success ) {
|
||||
$api_token = $response->token;
|
||||
} else {
|
||||
$api_token = $response->data->token;
|
||||
}
|
||||
|
||||
// Get Channel ID
|
||||
$request = wp_remote_get( $api_url, array(
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $api_token,
|
||||
),
|
||||
));
|
||||
|
||||
if ( is_wp_error( $request ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$response = json_decode( wp_remote_retrieve_body( $request ) );
|
||||
|
||||
}
|
||||
|
||||
self::cache_saved_channel_id( $url, $response );
|
||||
|
||||
return $response->channel_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache saved channel ID to database
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function cache_saved_channel_id( $url, $response ) {
|
||||
$channel_ids = get_option( 'sby_saved_channel_ids' );
|
||||
$channel_ids = json_decode( $channel_ids, true );
|
||||
|
||||
if ( empty( $channel_ids ) ) {
|
||||
$channel_ids = array();
|
||||
}
|
||||
|
||||
// find the channel @handle from the channel string
|
||||
$regex_pattern = '/@(\w+)/';
|
||||
if ( preg_match($regex_pattern, $url, $matches ) ) {
|
||||
$channel_handle = $matches[1];
|
||||
}
|
||||
if ( ! $channel_handle ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel_ids[ '@' . strtolower($channel_handle) ] = $response->channel_id;
|
||||
update_option( 'sby_saved_channel_ids', json_encode( $channel_ids ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get channel ID from saved channel IDs cached in the database
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public static function get_saved_channel_id( $channel ) {
|
||||
$channel_ids = get_option( 'sby_saved_channel_ids' );
|
||||
$channel_ids = json_decode( $channel_ids, true );
|
||||
if ( empty( $channel_ids ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel_id = '';
|
||||
|
||||
// find the channel @handle from the channel string
|
||||
$regex_pattern = '/@(\w+)/';
|
||||
if ( preg_match($regex_pattern, $channel, $matches ) ) {
|
||||
$channel_handle = $matches[1];
|
||||
}
|
||||
if ( ! $channel_handle ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isset( $channel_ids[ '@' . strtolower($channel_handle) ] ) ) {
|
||||
$channel_id = $channel_ids[ '@' . strtolower($channel_handle) ];
|
||||
}
|
||||
|
||||
return $channel_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
* @since 2.1.1
|
||||
*/
|
||||
public static function sby_get_resized_uploads_url() {
|
||||
$upload = wp_upload_dir();
|
||||
|
||||
$base_url = $upload['baseurl'];
|
||||
$home_url = home_url();
|
||||
|
||||
if ( strpos( $home_url, 'https:' ) !== false ) {
|
||||
str_replace( 'http:', 'https:', $base_url );
|
||||
}
|
||||
|
||||
$resize_url = apply_filters( 'sby_resize_url', trailingslashit( $base_url ) . trailingslashit( SBY_UPLOADS_NAME ) );
|
||||
|
||||
return $resize_url;
|
||||
}
|
||||
|
||||
}
|
||||
576
wp-content/plugins/youtube-feed-pro/inc/PluginSilentUpgrader.php
Normal file
576
wp-content/plugins/youtube-feed-pro/inc/PluginSilentUpgrader.php
Normal file
@@ -0,0 +1,576 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
|
||||
use WP_Error;
|
||||
use WP_Upgrader;
|
||||
use WP_Filesystem_Base;
|
||||
|
||||
/** \WP_Upgrader class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
|
||||
|
||||
/** \Plugin_Upgrader class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php';
|
||||
|
||||
/**
|
||||
* In WP 5.3 a PHP 5.6 splat operator (...$args) was added to \WP_Upgrader_Skin::feedback().
|
||||
* We need to remove all calls to *Skin::feedback() method, as we can't override it in own Skins
|
||||
* without breaking support for PHP 5.3-5.5.
|
||||
*
|
||||
* @internal Please do not use this class outside of core WPForms development. May be removed at any time.
|
||||
*
|
||||
* @since 1.5.6.1
|
||||
*/
|
||||
class PluginSilentUpgrader extends \Plugin_Upgrader {
|
||||
|
||||
/**
|
||||
* Run an upgrade/installation.
|
||||
*
|
||||
* Attempts to download the package (if it is not a local file), unpack it, and
|
||||
* install it in the destination folder.
|
||||
*
|
||||
* @since 1.5.6.1
|
||||
*
|
||||
* @param array $options {
|
||||
* Array or string of arguments for upgrading/installing a package.
|
||||
*
|
||||
* @type string $package The full path or URI of the package to install.
|
||||
* Default empty.
|
||||
* @type string $destination The full path to the destination folder.
|
||||
* Default empty.
|
||||
* @type bool $clear_destination Whether to delete any files already in the
|
||||
* destination folder. Default false.
|
||||
* @type bool $clear_working Whether to delete the files form the working
|
||||
* directory after copying to the destination.
|
||||
* Default false.
|
||||
* @type bool $abort_if_destination_exists Whether to abort the installation if the destination
|
||||
* folder already exists. When true, `$clear_destination`
|
||||
* should be false. Default true.
|
||||
* @type bool $is_multi Whether this run is one of multiple upgrade/installation
|
||||
* actions being performed in bulk. When true, the skin
|
||||
* WP_Upgrader::header() and WP_Upgrader::footer()
|
||||
* aren't called. Default false.
|
||||
* @type array $hook_extra Extra arguments to pass to the filter hooks called by
|
||||
* WP_Upgrader::run().
|
||||
* }
|
||||
* @return array|false|WP_error The result from self::install_package() on success, otherwise a WP_Error,
|
||||
* or false if unable to connect to the filesystem.
|
||||
*/
|
||||
public function run( $options ) {
|
||||
|
||||
$defaults = array(
|
||||
'package' => '', // Please always pass this.
|
||||
'destination' => '', // And this
|
||||
'clear_destination' => false,
|
||||
'abort_if_destination_exists' => true, // Abort if the Destination directory exists, Pass clear_destination as false please
|
||||
'clear_working' => true,
|
||||
'is_multi' => false,
|
||||
'hook_extra' => array(), // Pass any extra $hook_extra args here, this will be passed to any hooked filters.
|
||||
);
|
||||
|
||||
$options = wp_parse_args( $options, $defaults );
|
||||
|
||||
/**
|
||||
* Filters the package options before running an update.
|
||||
*
|
||||
* See also {@see 'upgrader_process_complete'}.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param array $options {
|
||||
* Options used by the upgrader.
|
||||
*
|
||||
* @type string $package Package for update.
|
||||
* @type string $destination Update location.
|
||||
* @type bool $clear_destination Clear the destination resource.
|
||||
* @type bool $clear_working Clear the working resource.
|
||||
* @type bool $abort_if_destination_exists Abort if the Destination directory exists.
|
||||
* @type bool $is_multi Whether the upgrader is running multiple times.
|
||||
* @type array $hook_extra {
|
||||
* Extra hook arguments.
|
||||
*
|
||||
* @type string $action Type of action. Default 'update'.
|
||||
* @type string $type Type of update process. Accepts 'plugin', 'theme', or 'core'.
|
||||
* @type bool $bulk Whether the update process is a bulk update. Default true.
|
||||
* @type string $plugin Path to the plugin file relative to the plugins directory.
|
||||
* @type string $theme The stylesheet or template name of the theme.
|
||||
* @type string $language_update_type The language pack update type. Accepts 'plugin', 'theme',
|
||||
* or 'core'.
|
||||
* @type object $language_update The language pack update offer.
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
$options = apply_filters( 'upgrader_package_options', $options );
|
||||
|
||||
if ( ! $options['is_multi'] ) { // call $this->header separately if running multiple times
|
||||
$this->skin->header();
|
||||
}
|
||||
|
||||
// Connect to the Filesystem first.
|
||||
$res = $this->fs_connect( array( WP_CONTENT_DIR, $options['destination'] ) );
|
||||
// Mainly for non-connected filesystem.
|
||||
if ( ! $res ) {
|
||||
if ( ! $options['is_multi'] ) {
|
||||
$this->skin->footer();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->skin->before();
|
||||
|
||||
if ( is_wp_error( $res ) ) {
|
||||
$this->skin->error( $res );
|
||||
$this->skin->after();
|
||||
if ( ! $options['is_multi'] ) {
|
||||
$this->skin->footer();
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Download the package (Note, This just returns the filename
|
||||
* of the file if the package is a local file)
|
||||
*/
|
||||
$download = $this->download_package( $options['package'], true );
|
||||
|
||||
// Allow for signature soft-fail.
|
||||
// WARNING: This may be removed in the future.
|
||||
if ( is_wp_error( $download ) && $download->get_error_data( 'softfail-filename' ) ) {
|
||||
|
||||
// Don't output the 'no signature could be found' failure message for now.
|
||||
if ( 'signature_verification_no_signature' != $download->get_error_code() || WP_DEBUG ) {
|
||||
// Outout the failure error as a normal feedback, and not as an error:
|
||||
//$this->skin->feedback( $download->get_error_message() );
|
||||
|
||||
// Report this failure back to WordPress.org for debugging purposes.
|
||||
wp_version_check(
|
||||
array(
|
||||
'signature_failure_code' => $download->get_error_code(),
|
||||
'signature_failure_data' => $download->get_error_data(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Pretend this error didn't happen.
|
||||
$download = $download->get_error_data( 'softfail-filename' );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $download ) ) {
|
||||
$this->skin->error( $download );
|
||||
$this->skin->after();
|
||||
if ( ! $options['is_multi'] ) {
|
||||
$this->skin->footer();
|
||||
}
|
||||
return $download;
|
||||
}
|
||||
|
||||
$delete_package = ( $download != $options['package'] ); // Do not delete a "local" file
|
||||
|
||||
// Unzips the file into a temporary directory.
|
||||
$working_dir = $this->unpack_package( $download, $delete_package );
|
||||
if ( is_wp_error( $working_dir ) ) {
|
||||
$this->skin->error( $working_dir );
|
||||
$this->skin->after();
|
||||
if ( ! $options['is_multi'] ) {
|
||||
$this->skin->footer();
|
||||
}
|
||||
return $working_dir;
|
||||
}
|
||||
|
||||
// With the given options, this installs it to the destination directory.
|
||||
$result = $this->install_package(
|
||||
array(
|
||||
'source' => $working_dir,
|
||||
'destination' => $options['destination'],
|
||||
'clear_destination' => $options['clear_destination'],
|
||||
'abort_if_destination_exists' => $options['abort_if_destination_exists'],
|
||||
'clear_working' => $options['clear_working'],
|
||||
'hook_extra' => $options['hook_extra'],
|
||||
)
|
||||
);
|
||||
|
||||
$this->skin->set_result( $result );
|
||||
if ( is_wp_error( $result ) ) {
|
||||
$this->skin->error( $result );
|
||||
//$this->skin->feedback( 'process_failed' );
|
||||
} else {
|
||||
// Installation succeeded.
|
||||
//$this->skin->feedback( 'process_success' );
|
||||
}
|
||||
|
||||
$this->skin->after();
|
||||
|
||||
if ( ! $options['is_multi'] ) {
|
||||
|
||||
/**
|
||||
* Fires when the upgrader process is complete.
|
||||
*
|
||||
* See also {@see 'upgrader_package_options'}.
|
||||
*
|
||||
* @since 3.6.0
|
||||
* @since 3.7.0 Added to WP_Upgrader::run().
|
||||
* @since 4.6.0 `$translations` was added as a possible argument to `$hook_extra`.
|
||||
*
|
||||
* @param WP_Upgrader $this WP_Upgrader instance. In other contexts, $this, might be a
|
||||
* Theme_Upgrader, Plugin_Upgrader, Core_Upgrade, or Language_Pack_Upgrader instance.
|
||||
* @param array $hook_extra {
|
||||
* Array of bulk item update data.
|
||||
*
|
||||
* @type string $action Type of action. Default 'update'.
|
||||
* @type string $type Type of update process. Accepts 'plugin', 'theme', 'translation', or 'core'.
|
||||
* @type bool $bulk Whether the update process is a bulk update. Default true.
|
||||
* @type array $plugins Array of the basename paths of the plugins' main files.
|
||||
* @type array $themes The theme slugs.
|
||||
* @type array $translations {
|
||||
* Array of translations update data.
|
||||
*
|
||||
* @type string $language The locale the translation is for.
|
||||
* @type string $type Type of translation. Accepts 'plugin', 'theme', or 'core'.
|
||||
* @type string $slug Text domain the translation is for. The slug of a theme/plugin or
|
||||
* 'default' for core translations.
|
||||
* @type string $version The version of a theme, plugin, or core.
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
do_action( 'upgrader_process_complete', $this, $options['hook_extra'] );
|
||||
|
||||
$this->skin->footer();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle maintenance mode for the site.
|
||||
*
|
||||
* Create/delete the maintenance file to enable/disable maintenance mode.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem Subclass
|
||||
*
|
||||
* @param bool $enable True to enable maintenance mode, false to disable.
|
||||
*/
|
||||
public function maintenance_mode( $enable = false ) {
|
||||
global $wp_filesystem;
|
||||
$file = $wp_filesystem->abspath() . '.maintenance';
|
||||
if ( $enable ) {
|
||||
//$this->skin->feedback( 'maintenance_start' );
|
||||
// Create maintenance file to signal that we are upgrading
|
||||
$maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
|
||||
$wp_filesystem->delete( $file );
|
||||
$wp_filesystem->put_contents( $file, $maintenance_string, FS_CHMOD_FILE );
|
||||
} elseif ( ! $enable && $wp_filesystem->exists( $file ) ) {
|
||||
//$this->skin->feedback( 'maintenance_end' );
|
||||
$wp_filesystem->delete( $file );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a package.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string $package The URI of the package. If this is the full path to an
|
||||
* existing local file, it will be returned untouched.
|
||||
* @param bool $check_signatures Whether to validate file signatures. Default false.
|
||||
* @return string|WP_Error The full path to the downloaded package file, or a WP_Error object.
|
||||
*/
|
||||
public function download_package( $package, $check_signatures = false, $hook_extra = array() ) {
|
||||
|
||||
/**
|
||||
* Filters whether to return the package.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param bool $reply Whether to bail without returning the package.
|
||||
* Default false.
|
||||
* @param string $package The package file name.
|
||||
* @param WP_Upgrader $this The WP_Upgrader instance.
|
||||
*/
|
||||
$reply = apply_filters( 'upgrader_pre_download', false, $package, $this );
|
||||
if ( false !== $reply ) {
|
||||
return $reply;
|
||||
}
|
||||
|
||||
if ( ! preg_match( '!^(http|https|ftp)://!i', $package ) && file_exists( $package ) ) { //Local file or remote?
|
||||
return $package; //must be a local file..
|
||||
}
|
||||
|
||||
if ( empty( $package ) ) {
|
||||
return new WP_Error( 'no_package', $this->strings['no_package'] );
|
||||
}
|
||||
|
||||
//$this->skin->feedback( 'downloading_package', $package );
|
||||
|
||||
$download_file = download_url( $package, 300, $check_signatures );
|
||||
|
||||
if ( is_wp_error( $download_file ) && ! $download_file->get_error_data( 'softfail-filename' ) ) {
|
||||
return new WP_Error( 'download_failed', $this->strings['download_failed'], $download_file->get_error_message() );
|
||||
}
|
||||
|
||||
return $download_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a compressed package file.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
*
|
||||
* @param string $package Full path to the package file.
|
||||
* @param bool $delete_package Optional. Whether to delete the package file after attempting
|
||||
* to unpack it. Default true.
|
||||
* @return string|WP_Error The path to the unpacked contents, or a WP_Error on failure.
|
||||
*/
|
||||
public function unpack_package( $package, $delete_package = true ) {
|
||||
global $wp_filesystem;
|
||||
|
||||
//$this->skin->feedback( 'unpack_package' );
|
||||
|
||||
$upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/';
|
||||
|
||||
//Clean up contents of upgrade directory beforehand.
|
||||
$upgrade_files = $wp_filesystem->dirlist( $upgrade_folder );
|
||||
if ( ! empty( $upgrade_files ) ) {
|
||||
foreach ( $upgrade_files as $file ) {
|
||||
$wp_filesystem->delete( $upgrade_folder . $file['name'], true );
|
||||
}
|
||||
}
|
||||
|
||||
// We need a working directory - Strip off any .tmp or .zip suffixes
|
||||
$working_dir = $upgrade_folder . basename( basename( $package, '.tmp' ), '.zip' );
|
||||
|
||||
// Clean up working directory
|
||||
if ( $wp_filesystem->is_dir( $working_dir ) ) {
|
||||
$wp_filesystem->delete( $working_dir, true );
|
||||
}
|
||||
|
||||
// Unzip package to working directory
|
||||
$result = unzip_file( $package, $working_dir );
|
||||
|
||||
// Once extracted, delete the package if required.
|
||||
if ( $delete_package ) {
|
||||
unlink( $package );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
$wp_filesystem->delete( $working_dir, true );
|
||||
if ( 'incompatible_archive' == $result->get_error_code() ) {
|
||||
return new WP_Error( 'incompatible_archive', $this->strings['incompatible_archive'], $result->get_error_data() );
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $working_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a package.
|
||||
*
|
||||
* Copies the contents of a package form a source directory, and installs them in
|
||||
* a destination directory. Optionally removes the source. It can also optionally
|
||||
* clear out the destination folder if it already exists.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
* @global array $wp_theme_directories
|
||||
*
|
||||
* @param array|string $args {
|
||||
* Optional. Array or string of arguments for installing a package. Default empty array.
|
||||
*
|
||||
* @type string $source Required path to the package source. Default empty.
|
||||
* @type string $destination Required path to a folder to install the package in.
|
||||
* Default empty.
|
||||
* @type bool $clear_destination Whether to delete any files already in the destination
|
||||
* folder. Default false.
|
||||
* @type bool $clear_working Whether to delete the files form the working directory
|
||||
* after copying to the destination. Default false.
|
||||
* @type bool $abort_if_destination_exists Whether to abort the installation if
|
||||
* the destination folder already exists. Default true.
|
||||
* @type array $hook_extra Extra arguments to pass to the filter hooks called by
|
||||
* WP_Upgrader::install_package(). Default empty array.
|
||||
* }
|
||||
*
|
||||
* @return array|WP_Error The result (also stored in `WP_Upgrader::$result`), or a WP_Error on failure.
|
||||
*/
|
||||
public function install_package( $args = array() ) {
|
||||
global $wp_filesystem, $wp_theme_directories;
|
||||
|
||||
$defaults = array(
|
||||
'source' => '', // Please always pass this
|
||||
'destination' => '', // and this
|
||||
'clear_destination' => false,
|
||||
'clear_working' => false,
|
||||
'abort_if_destination_exists' => true,
|
||||
'hook_extra' => array(),
|
||||
);
|
||||
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
// These were previously extract()'d.
|
||||
$source = $args['source'];
|
||||
$destination = $args['destination'];
|
||||
$clear_destination = $args['clear_destination'];
|
||||
|
||||
set_time_limit( 300 );
|
||||
|
||||
if ( empty( $source ) || empty( $destination ) ) {
|
||||
return new WP_Error( 'bad_request', $this->strings['bad_request'] );
|
||||
}
|
||||
//$this->skin->feedback( 'installing_package' );
|
||||
|
||||
/**
|
||||
* Filters the install response before the installation has started.
|
||||
*
|
||||
* Returning a truthy value, or one that could be evaluated as a WP_Error
|
||||
* will effectively short-circuit the installation, returning that value
|
||||
* instead.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param bool|WP_Error $response Response.
|
||||
* @param array $hook_extra Extra arguments passed to hooked filters.
|
||||
*/
|
||||
$res = apply_filters( 'upgrader_pre_install', true, $args['hook_extra'] );
|
||||
|
||||
if ( is_wp_error( $res ) ) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
//Retain the Original source and destinations
|
||||
$remote_source = $args['source'];
|
||||
$local_destination = $destination;
|
||||
|
||||
$source_files = array_keys( $wp_filesystem->dirlist( $remote_source ) );
|
||||
$remote_destination = $wp_filesystem->find_folder( $local_destination );
|
||||
|
||||
//Locate which directory to copy to the new folder, This is based on the actual folder holding the files.
|
||||
if ( 1 == count( $source_files ) && $wp_filesystem->is_dir( trailingslashit( $args['source'] ) . $source_files[0] . '/' ) ) { //Only one folder? Then we want its contents.
|
||||
$source = trailingslashit( $args['source'] ) . trailingslashit( $source_files[0] );
|
||||
} elseif ( count( $source_files ) == 0 ) {
|
||||
return new WP_Error( 'incompatible_archive_empty', $this->strings['incompatible_archive'], $this->strings['no_files'] ); // There are no files?
|
||||
} else { // It's only a single file, the upgrader will use the folder name of this file as the destination folder. Folder name is based on zip filename.
|
||||
$source = trailingslashit( $args['source'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the source file location for the upgrade package.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.4.0 The $hook_extra parameter became available.
|
||||
*
|
||||
* @param string $source File source location.
|
||||
* @param string $remote_source Remote file source location.
|
||||
* @param WP_Upgrader $this WP_Upgrader instance.
|
||||
* @param array $hook_extra Extra arguments passed to hooked filters.
|
||||
*/
|
||||
$source = apply_filters( 'upgrader_source_selection', $source, $remote_source, $this, $args['hook_extra'] );
|
||||
|
||||
if ( is_wp_error( $source ) ) {
|
||||
return $source;
|
||||
}
|
||||
|
||||
// Has the source location changed? If so, we need a new source_files list.
|
||||
if ( $source !== $remote_source ) {
|
||||
$source_files = array_keys( $wp_filesystem->dirlist( $source ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Protection against deleting files in any important base directories.
|
||||
* Theme_Upgrader & Plugin_Upgrader also trigger this, as they pass the
|
||||
* destination directory (WP_PLUGIN_DIR / wp-content/themes) intending
|
||||
* to copy the directory into the directory, whilst they pass the source
|
||||
* as the actual files to copy.
|
||||
*/
|
||||
$protected_directories = array( ABSPATH, WP_CONTENT_DIR, WP_PLUGIN_DIR, WP_CONTENT_DIR . '/themes' );
|
||||
|
||||
if ( is_array( $wp_theme_directories ) ) {
|
||||
$protected_directories = array_merge( $protected_directories, $wp_theme_directories );
|
||||
}
|
||||
|
||||
if ( in_array( $destination, $protected_directories ) ) {
|
||||
$remote_destination = trailingslashit( $remote_destination ) . trailingslashit( basename( $source ) );
|
||||
$destination = trailingslashit( $destination ) . trailingslashit( basename( $source ) );
|
||||
}
|
||||
|
||||
if ( $clear_destination ) {
|
||||
// We're going to clear the destination if there's something there.
|
||||
//$this->skin->feedback( 'remove_old' );
|
||||
|
||||
$removed = $this->clear_destination( $remote_destination );
|
||||
|
||||
/**
|
||||
* Filters whether the upgrader cleared the destination.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param mixed $removed Whether the destination was cleared. true on success, WP_Error on failure
|
||||
* @param string $local_destination The local package destination.
|
||||
* @param string $remote_destination The remote package destination.
|
||||
* @param array $hook_extra Extra arguments passed to hooked filters.
|
||||
*/
|
||||
$removed = apply_filters( 'upgrader_clear_destination', $removed, $local_destination, $remote_destination, $args['hook_extra'] );
|
||||
|
||||
if ( is_wp_error( $removed ) ) {
|
||||
return $removed;
|
||||
}
|
||||
} elseif ( $args['abort_if_destination_exists'] && $wp_filesystem->exists( $remote_destination ) ) {
|
||||
//If we're not clearing the destination folder and something exists there already, Bail.
|
||||
//But first check to see if there are actually any files in the folder.
|
||||
$_files = $wp_filesystem->dirlist( $remote_destination );
|
||||
if ( ! empty( $_files ) ) {
|
||||
$wp_filesystem->delete( $remote_source, true ); //Clear out the source files.
|
||||
return new WP_Error( 'folder_exists', $this->strings['folder_exists'], $remote_destination );
|
||||
}
|
||||
}
|
||||
|
||||
//Create destination if needed
|
||||
if ( ! $wp_filesystem->exists( $remote_destination ) ) {
|
||||
if ( ! $wp_filesystem->mkdir( $remote_destination, FS_CHMOD_DIR ) ) {
|
||||
return new WP_Error( 'mkdir_failed_destination', $this->strings['mkdir_failed'], $remote_destination );
|
||||
}
|
||||
}
|
||||
// Copy new version of item into place.
|
||||
$result = copy_dir( $source, $remote_destination );
|
||||
if ( is_wp_error( $result ) ) {
|
||||
if ( $args['clear_working'] ) {
|
||||
$wp_filesystem->delete( $remote_source, true );
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
//Clear the Working folder?
|
||||
if ( $args['clear_working'] ) {
|
||||
$wp_filesystem->delete( $remote_source, true );
|
||||
}
|
||||
|
||||
$destination_name = basename( str_replace( $local_destination, '', $destination ) );
|
||||
if ( '.' == $destination_name ) {
|
||||
$destination_name = '';
|
||||
}
|
||||
|
||||
$this->result = compact( 'source', 'source_files', 'destination', 'destination_name', 'local_destination', 'remote_destination', 'clear_destination' );
|
||||
|
||||
/**
|
||||
* Filters the installation response after the installation has finished.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param bool $response Installation response.
|
||||
* @param array $hook_extra Extra arguments passed to hooked filters.
|
||||
* @param array $result Installation result data.
|
||||
*/
|
||||
$res = apply_filters( 'upgrader_post_install', true, $args['hook_extra'], $this->result );
|
||||
|
||||
if ( is_wp_error( $res ) ) {
|
||||
$this->result = $res;
|
||||
return $res;
|
||||
}
|
||||
|
||||
//Bombard the calling function will all the info which we've just used.
|
||||
return $this->result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
|
||||
/** \WP_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-skin.php';
|
||||
|
||||
/**
|
||||
* Class PluginSilentUpgraderSkin.
|
||||
*
|
||||
* @internal Please do not use this class outside of core WPForms development. May be removed at any time.
|
||||
*
|
||||
* @since 1.5.6.1
|
||||
*/
|
||||
class PluginSilentUpgraderSkin extends \WP_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Empty out the header of its HTML content and only check to see if it has
|
||||
* been performed or not.
|
||||
*
|
||||
* @since 1.5.6.1
|
||||
*/
|
||||
public function header() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty out the footer of its HTML contents.
|
||||
*
|
||||
* @since 1.5.6.1
|
||||
*/
|
||||
public function footer() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Instead of outputting HTML for errors, just return them.
|
||||
* Ajax request will just ignore it.
|
||||
*
|
||||
* @since 1.5.6.1
|
||||
*
|
||||
* @param array $errors Array of errors with the install process.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function error( $errors ) {
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty out JavaScript output that calls function to decrement the update counts.
|
||||
*
|
||||
* @since 1.5.6.1
|
||||
*
|
||||
* @param string $type Type of update count to decrement.
|
||||
*/
|
||||
public function decrement_update_count( $type ) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
/**
|
||||
* Class SB_Instagram_API_Connect_Pro
|
||||
*
|
||||
* Adds support for additional endpoints:
|
||||
*
|
||||
* - Personal account comments
|
||||
* - Business account top and recent hashtags
|
||||
* - Business account stories
|
||||
* - Business account comments
|
||||
* - Business account hashtag IDs
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Pro;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\SBY_API_Connect;
|
||||
|
||||
class SBY_API_Connect_Pro extends SBY_API_Connect
|
||||
{
|
||||
public function connect() {
|
||||
$url = $this->get_url();
|
||||
|
||||
if ( strpos( $url, 'iframe' ) === 0 ) {
|
||||
$response = $this->get_iframe_response();
|
||||
$response = json_decode( str_replace( '%22', '”', $response ), true );
|
||||
} else {
|
||||
$response = wp_remote_get( esc_url_raw( $url ), $this->get_args() );
|
||||
|
||||
if ( ! is_wp_error( $response ) ) {
|
||||
// certain ways of representing the html for double quotes causes errors so replaced here.
|
||||
$response = json_decode( str_replace( '%22', '”', $response['body'] ), true );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->response = $response;
|
||||
|
||||
}
|
||||
|
||||
private function get_iframe_response() {
|
||||
return '{"kind":"youtube#playlistItemListResponse","nextPageToken":"single","items":[{"iframe":"'.str_replace( 'iframe_', '', $this->get_url() ).'","id":"blank","snippet":{"publishedAt":"2020-04-01T17:45:02.000Z","channelId":"blank","title":"","description":"","thumbnails":{"default":{"url":"'.trailingslashit( SBY_PLUGIN_URL ) . 'img/placeholder.png'.'","width":120,"height":90},"medium":{"url":"'.trailingslashit( SBY_PLUGIN_URL ) . 'img/placeholder.png'.'","width":320,"height":180},"high":{"url":"'.trailingslashit( SBY_PLUGIN_URL ) . 'img/placeholder.png'.'","width":480,"height":360},"standard":{"url":"'.trailingslashit( SBY_PLUGIN_URL ) . 'img/placeholder.png'.'","width":640,"height":480},"maxres":{"url":"'.trailingslashit( SBY_PLUGIN_URL ) . 'img/placeholder.png'.'","width":1280,"height":720}},"channelTitle":"","playlistId":"UU-blank","position":0,"resourceId":{"kind":"youtube#video","videoId":"iframe"},"contentDetails":{"videoId":"iframe","videoPublishedAt":"2020-04-01T17:45:02.000Z"},"status":{"privacyStatus":"public"}}}]}';
|
||||
}
|
||||
|
||||
public function set_response( $response ) {
|
||||
$this->response = $response;
|
||||
}
|
||||
|
||||
|
||||
public function get_next_page( $params = false ) {
|
||||
|
||||
if ( $params && isset( $params['video_ids'] ) ) {
|
||||
if ( isset( $params['nextPageToken'] ) ) {
|
||||
if ( count( $params['nextPageToken'] ) > SBY_MAX_SINGLE_PAGE ) {
|
||||
return array_slice( $params['nextPageToken'], SBY_MAX_SINGLE_PAGE );
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
} elseif ( count( $params['video_ids'] ) > SBY_MAX_SINGLE_PAGE ) {
|
||||
return array_slice( $params['video_ids'], SBY_MAX_SINGLE_PAGE );
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
if ( ! empty( $this->response['nextPageToken'] ) ) {
|
||||
return $this->response['nextPageToken'];
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the url for the API request based on the account information,
|
||||
* type of data needed, and additional parameters
|
||||
*
|
||||
* @param $connected_account
|
||||
* @param $endpoint_slug header or user
|
||||
* @param $params
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function set_url( $connected_account, $endpoint_slug, $params = [], $api_key = null ) {
|
||||
$num = ! empty( $params['num'] ) ? (int)$params['num'] : 50;
|
||||
|
||||
$access_credentials = isset( $connected_account['api_key'] ) ? 'key=' . $connected_account['api_key'] : 'access_token=' . $connected_account['access_token'];
|
||||
$next_page = '';
|
||||
if ( isset( $params['nextPageToken'] ) && ! is_array( $params['nextPageToken'] ) ) {
|
||||
$next_page = '&pageToken=' . $params['nextPageToken'];
|
||||
}
|
||||
|
||||
if ( $endpoint_slug === 'tokeninfo' ) {
|
||||
$url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=' . $connected_account['access_token'];
|
||||
} elseif ( $endpoint_slug === 'channels' ) {
|
||||
$channel_param = 'mine=true';
|
||||
if ( isset( $params['channel_name'] ) ) {
|
||||
$channel_param = 'forUsername=' . $params['channel_name'];
|
||||
} elseif ( isset( $params['channel_id'] ) ) {
|
||||
$channel_param = 'id=' . $params['channel_id'];
|
||||
}
|
||||
|
||||
$url = 'https://www.googleapis.com/youtube/v3/channels?part=id,snippet,statistics,contentDetails&'.$channel_param.'&' . $access_credentials . $next_page;
|
||||
} elseif ( $endpoint_slug === 'live' ) {
|
||||
$url = 'iframe_'.$params['channelId'];
|
||||
} elseif ( $endpoint_slug === 'search' ) {
|
||||
$part = 'snippet';
|
||||
if ( isset( $params['part'] ) ) {
|
||||
$part = $this->formatted_part_param_string( $params['part'] );
|
||||
}
|
||||
if ( ! isset( $params['isCustom'] ) ) {
|
||||
if ( isset( $params['eventType'] ) && $params['eventType'] === 'upcoming' ) {
|
||||
$num = 50; // get max videos so we can reverse sort them to show soonest playing live streams first, default order is by publish date
|
||||
}
|
||||
$params_string = $this->formatted_param_string( $params );
|
||||
|
||||
} else {
|
||||
$params_string = $params['customSearch'];
|
||||
|
||||
if ( isset( $params['nextPageToken'] ) ) {
|
||||
$params_string .= '&pageToken=' . $params['nextPageToken'];
|
||||
}
|
||||
}
|
||||
$num = max( 10, $num );
|
||||
|
||||
$query_var_string= 'type=video&part='.$part.'&maxResults=' . $num . $params_string;
|
||||
|
||||
$url = 'https://www.googleapis.com/youtube/v3/search?'.$query_var_string.'&'.$access_credentials.$next_page;
|
||||
} elseif ( $endpoint_slug === 'playlistItems' ) {
|
||||
$url = 'https://www.googleapis.com/youtube/v3/playlistItems?part=id,snippet,contentDetails,status&maxResults='.$num.'&playlistId='.$params['playlist_id'].'&' . $access_credentials.$next_page;
|
||||
} elseif ( $endpoint_slug === 'single' ) {
|
||||
$part = 'id,statistics,contentDetails,snippet,liveStreamingDetails';
|
||||
|
||||
$vid_ids = empty( $params['nextPageToken'] ) ? $params['video_ids'] : $params['nextPageToken'];
|
||||
$vid_ids = array_slice( $vid_ids, 0, SBY_MAX_SINGLE_PAGE );
|
||||
$vid_id_string = implode( ',', $vid_ids );
|
||||
|
||||
$url = 'https://www.googleapis.com/youtube/v3/videos?part='.$part.'&id='.$vid_id_string.'&maxResults=50&' . $access_credentials;
|
||||
|
||||
} elseif ( $endpoint_slug === 'videos' ) {
|
||||
$params_string = $this->formatted_param_string( $params );
|
||||
$part = 'id,statistics,contentDetails';
|
||||
if ( isset( $params['part'] ) ) {
|
||||
$part = $this->formatted_part_param_string( $params['part'] );
|
||||
}
|
||||
|
||||
$url = 'https://www.googleapis.com/youtube/v3/videos?part='.$part.$params_string.'&maxResults='.$num.'&' . $access_credentials;
|
||||
} elseif ( $endpoint_slug === 'videosDuration' ) {
|
||||
$ids = isset( $params['ids'] ) ? $params['ids'] : [];
|
||||
$part = 'id,statistics,contentDetails';
|
||||
$url = 'https://www.googleapis.com/youtube/v3/videos?part='.$part.'&id='.$ids.'&maxResults='.$num.'&' . $access_credentials;
|
||||
} elseif ( $endpoint_slug === 'comments' ) {
|
||||
$part = 'snippet,replies';
|
||||
$video_id = isset( $params['video_id'] ) ? $params['video_id'] : [];
|
||||
$url = 'https://www.googleapis.com/youtube/v3/commentThreads?part='. $part .'&videoId='.$video_id.'&order=relevance&maxResults='.$num.'&' . $access_credentials;
|
||||
} elseif ( $endpoint_slug === 'livestream' ) {
|
||||
$page_token_param = '';
|
||||
$part = 'id';
|
||||
$channel_id = isset( $params['channel_id'] ) ? $params['channel_id'] : '';
|
||||
$event_type = isset( $params['event_type'] ) ? $params['event_type'] : '';
|
||||
$page_token = isset( $params['page_token'] ) ? $params['page_token'] : '';
|
||||
|
||||
if ( !empty($page_token) ) {
|
||||
$page_token_param = '&pageToken=' . $page_token;
|
||||
}
|
||||
|
||||
$url = 'https://www.googleapis.com/youtube/v3/search?part='. $part .'&channelId='.$channel_id .'&eventType='.$event_type .'&order=date&maxResults=50&type=video&' . $access_credentials . $page_token_param;
|
||||
|
||||
} else {
|
||||
$channel_param = 'mine=true';
|
||||
if ( isset( $params['username'] ) ) {
|
||||
$channel_param = 'forUsername=' . $params['username'];
|
||||
} elseif ( isset( $params['channel_id'] ) ) {
|
||||
$channel_param = 'id=' . $params['channel_id'];
|
||||
}
|
||||
|
||||
$url = 'https://www.googleapis.com/youtube/v3/channels?part=id,snippet&'.$channel_param.'&' . $access_credentials.$next_page;
|
||||
}
|
||||
|
||||
$this->set_url_from_args( $url );
|
||||
}
|
||||
}
|
||||
284
wp-content/plugins/youtube-feed-pro/inc/Pro/SBY_CPT.php
Normal file
284
wp-content/plugins/youtube-feed-pro/inc/Pro/SBY_CPT.php
Normal file
@@ -0,0 +1,284 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Pro;
|
||||
|
||||
class SBY_CPT {
|
||||
public function __construct() {
|
||||
|
||||
add_filter( 'manage_' . SBY_CPT . '_posts_columns', array( $this, 'set_custom_sby_videos_columns' ) );
|
||||
add_filter( 'manage_edit-' . SBY_CPT . '_sortable_columns', array( $this, 'set_custom_sortable_sby_videos_columns' ), 10, 1 );
|
||||
add_action( 'manage_' . SBY_CPT . '_posts_custom_column', array( $this, 'custom_sby_videos_column' ), 10, 2 );
|
||||
add_action( 'pre_get_posts', array( $this, '' . SBY_CPT . '_custom_order' ), 10, 1 );
|
||||
add_action( 'admin_init', array( $this, 'channel_action_listener' ) );
|
||||
|
||||
add_shortcode( 'youtube-feed-single', array( $this, 'youtube_feed_single' ) );
|
||||
}
|
||||
|
||||
public static function set_up_submenus() {
|
||||
add_submenu_page(
|
||||
SBY_SLUG,
|
||||
__( 'Manage Single Videos', 'feeds-for-youtube' ),
|
||||
__( 'Single Video Settings', 'feeds-for-youtube' ),
|
||||
'edit_' . SBY_CPT,
|
||||
'sby_single_settings',
|
||||
array( __CLASS__, 'single_settings_admin_page' )
|
||||
);
|
||||
}
|
||||
|
||||
public static function single_settings_admin_page() {
|
||||
include_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/Admin/templates/single-settings.php';
|
||||
}
|
||||
|
||||
public static function set_custom_sby_videos_columns( $columns ) {
|
||||
|
||||
$columns['channel_title'] = __( 'Channel', 'feeds-for-youtube' );
|
||||
$columns['video_id'] = __( 'Video ID', 'feeds-for-youtube' );
|
||||
$columns['youtube_publish_date'] = __( 'Publish Date', 'feeds-for-youtube' );
|
||||
|
||||
unset( $columns['author'] );
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
public static function custom_sby_videos_column( $column, $post_id ) {
|
||||
switch ( $column ) {
|
||||
|
||||
case 'channel_title' :
|
||||
$channel = get_post_meta( $post_id, 'sby_channel_title', true );
|
||||
if ( ! empty( $channel ) ) {
|
||||
echo esc_html( $channel );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'video_id' :
|
||||
$video_id = get_post_meta( $post_id, 'sby_video_id', true );
|
||||
if ( ! empty( $video_id ) ) {
|
||||
echo esc_html( $video_id );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'youtube_publish_date' :
|
||||
$publish_date = get_post_meta( $post_id, 'sby_youtube_publish_date', true );
|
||||
$date_format = get_option( 'date_format' );
|
||||
$time_format = get_option( 'time_format' );
|
||||
if ( $date_format && $time_format ) {
|
||||
$date_time_format = $date_format . ' ' . $time_format;
|
||||
} else {
|
||||
$date_time_format = 'F j, Y g:i a';
|
||||
}
|
||||
|
||||
if ( ! empty( $publish_date ) ) {
|
||||
echo esc_html( date_i18n( $date_time_format, strtotime( $publish_date ) + sby_get_utc_offset() ) );
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static function set_custom_sortable_sby_videos_columns( $columns ) {
|
||||
$columns['channel_title'] = 'sby_channel_title';
|
||||
$columns['youtube_publish_date'] = 'sby_youtube_publish_date';
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
public function sby_videos_custom_order( $query ) {
|
||||
if ( ! is_admin() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$orderby = $query->get( 'orderby' );
|
||||
|
||||
if ( in_array( $orderby, array( 'sby_channel_title', 'sby_video_id', 'sby_youtube_publish_date' ), true ) ) {
|
||||
$query->set( 'meta_key', $orderby );
|
||||
$query->set( 'orderby', 'meta_value' );
|
||||
}
|
||||
|
||||
if ( isset( $_GET['channel_id'] ) && $query->is_main_query() && $query->query_vars['post_type'] == SBY_CPT ) {
|
||||
//Get original meta query
|
||||
$meta_query = (array) $query->get( 'meta_query' );
|
||||
|
||||
// Add your criteria
|
||||
$meta_query[] = array(
|
||||
'key' => 'sby_channel_id',
|
||||
'value' => sanitize_text_field( $_GET['channel_id'] ),
|
||||
'compare' => '=',
|
||||
);
|
||||
|
||||
// Set the meta query to the complete, altered query
|
||||
$query->set( 'meta_query', $meta_query );
|
||||
}
|
||||
}
|
||||
|
||||
public static function channel_action_listener() {
|
||||
if ( ! isset( $_GET['sby_action'] ) || ! isset( $_GET['channel'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$action = sanitize_text_field( $_GET['sby_action'] );
|
||||
$channel_id = sanitize_text_field( $_GET['channel'] );
|
||||
|
||||
if ( $action === 'publish' ) {
|
||||
|
||||
if ( ! empty( $channel_id ) ) {
|
||||
$args = array(
|
||||
'channel_id' => $channel_id,
|
||||
'post_status' => array( 'draft', 'pending' ),
|
||||
'posts_per_page' => - 1
|
||||
);
|
||||
$draft_posts = new SBY_YT_Query( $args );
|
||||
$draft_posts_arr = $draft_posts->get_posts();
|
||||
|
||||
foreach ( $draft_posts_arr as $post ) {
|
||||
$update_post = array( 'ID' => $post->ID, 'post_status' => 'publish' );
|
||||
wp_update_post( $update_post );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} elseif ( $action === 'trash' ) {
|
||||
if ( ! empty( $channel_id ) ) {
|
||||
$args = array(
|
||||
'channel_id' => $channel_id,
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => - 1
|
||||
);
|
||||
$draft_posts = new SBY_YT_Query( $args );
|
||||
$draft_posts_arr = $draft_posts->get_posts();
|
||||
|
||||
foreach ( $draft_posts_arr as $post ) {
|
||||
wp_trash_post( $post->ID );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
wp_safe_redirect( admin_url( 'admin.php?page=youtube-feed-single-videos' ) );
|
||||
}
|
||||
|
||||
public static function youtube_feed_single( $atts = array() ) {
|
||||
$atts = ! empty( $atts ) ? $atts : array();
|
||||
if ( isset( $atts['postid'] ) ) {
|
||||
$args = array(
|
||||
'p' => $atts['postid'],
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => - 1
|
||||
);
|
||||
$vid_posts = new SBY_YT_Query( $args );
|
||||
$vid_posts_arr = $vid_posts->get_posts();
|
||||
|
||||
if ( isset ( $vid_posts_arr[0] ) ) {
|
||||
$youtube_post = $vid_posts_arr[0];
|
||||
}
|
||||
} elseif ( isset( $atts['videoid'] ) ) {
|
||||
$args = array(
|
||||
'video_id' => $atts['videoid'],
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => - 1
|
||||
);
|
||||
$vid_posts = new SBY_YT_Query( $args );
|
||||
$vid_posts_arr = $vid_posts->get_posts();
|
||||
|
||||
if ( isset ( $vid_posts_arr[0] ) ) {
|
||||
$youtube_post = $vid_posts_arr[0];
|
||||
}
|
||||
} else {
|
||||
global $post;
|
||||
|
||||
if ( $post->post_type === SBY_CPT ) {
|
||||
$youtube_post = $post;
|
||||
}
|
||||
}
|
||||
if ( ! isset( $youtube_post ) ) {
|
||||
return 'Need to add Post ID';
|
||||
}
|
||||
|
||||
global $sby_settings;
|
||||
|
||||
$youtube_post_meta = get_post_meta( $youtube_post->ID );
|
||||
|
||||
$api_data = json_decode( $youtube_post_meta['sby_json'][0], true );
|
||||
$settings = $sby_settings;
|
||||
$shortcode_atts = wp_json_encode( $atts );
|
||||
|
||||
$options_att_arr['cta'] = array(
|
||||
'type' => 'default'
|
||||
);
|
||||
if ( $settings['cta'] === 'link' ) {
|
||||
$options_att_arr['cta']['type'] = 'link';
|
||||
}
|
||||
|
||||
$options_att_arr['cta']['defaultLink'] = $settings['linkurl'];
|
||||
$options_att_arr['cta']['defaultText'] = $settings['linktext'];
|
||||
$options_att_arr['cta']['openType'] = $settings['linkopentype'];
|
||||
$button_color = str_replace( '#', '', $settings['linkcolor'] );
|
||||
$button_text_color = str_replace( '#', '', $settings['linktextcolor'] );
|
||||
$options_att_arr['cta']['color'] = ! empty( $button_color ) ? sby_hextorgb( $button_color ) : '';
|
||||
$options_att_arr['cta']['textColor'] = ! empty( $button_text_color ) ? sby_hextorgb( $button_text_color ) : '';
|
||||
|
||||
if ( ! empty( $settings['descriptionlength'] ) ) {
|
||||
$options_att_arr['descriptionlength'] = (int)$settings['descriptionlength'];
|
||||
}
|
||||
|
||||
$other_atts = ' data-options="'.esc_attr( wp_json_encode( $options_att_arr ) ).'"';
|
||||
$icon_type = $settings['font_method'];
|
||||
|
||||
wp_enqueue_script( 'sby_scripts' );
|
||||
|
||||
include sby_get_feed_template_part( 'shortcode-content', $settings );
|
||||
}
|
||||
|
||||
public static function get_sby_cpt_settings() {
|
||||
$defaults = array(
|
||||
'include' => array( 'description', 'stats' ),
|
||||
'post_status' => 'draft'
|
||||
);
|
||||
$sby_videos_settings = get_option( SBY_CPT . '_settings', $defaults );
|
||||
|
||||
return $sby_videos_settings;
|
||||
}
|
||||
|
||||
public static function setting_name( $name, $is_array = false ) {
|
||||
|
||||
$return = SBY_CPT . '_settings[' . $name . ']';
|
||||
|
||||
if ( $is_array ) {
|
||||
$return .= '[]';
|
||||
}
|
||||
|
||||
return $return;
|
||||
|
||||
}
|
||||
|
||||
public static function validate_options( $input, $option_name ) {
|
||||
$updated_options = get_option( $option_name, array() );
|
||||
|
||||
foreach ( $input as $key => $val ) {
|
||||
if ( is_array( $val ) ) {
|
||||
$updated_options[ $key ] = array();
|
||||
foreach ( $val as $val2 ) {
|
||||
$updated_options[ $key ][] = sanitize_text_field( $val2 );
|
||||
}
|
||||
|
||||
} else {
|
||||
// include in search set to false
|
||||
if ( $val === 'on' ) {
|
||||
$val = true;
|
||||
}
|
||||
if ( $key === 'search_include' ) {
|
||||
$updated_options[ $key ] = false;
|
||||
} else {
|
||||
$updated_options[ $key ] = sanitize_text_field( $val );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$updated_options = apply_filters( 'sby_single_settings_valid_options', $updated_options, $input );
|
||||
|
||||
return $updated_options;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* SBY_Comments_Pro.
|
||||
*
|
||||
* @since 2.3.3
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Pro;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\Pro\SBY_Display_Elements_Pro;
|
||||
|
||||
class SBY_Comments_Pro
|
||||
{
|
||||
/**
|
||||
* Generates base HTML for displaying comments for list and gallery layout
|
||||
*
|
||||
* @return false|string
|
||||
*
|
||||
* @since 2.3.3
|
||||
*/
|
||||
|
||||
public static function comment_html($settings) {
|
||||
$message_icon = '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M13.6693 13.73L11.0026 11.0633H1.66927C1.3026 11.0633 0.988715 10.9327 0.727604 10.6716C0.466493 10.4105 0.335938 10.0966 0.335938 9.72997V1.72997C0.335938 1.3633 0.466493 1.04941 0.727604 0.788304C0.988715 0.527193 1.3026 0.396637 1.66927 0.396637H12.3359C12.7026 0.396637 13.0165 0.527193 13.2776 0.788304C13.5387 1.04941 13.6693 1.3633 13.6693 1.72997V13.73ZM1.66927 9.72997H11.5693L12.3359 10.48V1.72997H1.66927V9.72997Z" fill="currentColor"/></svg>';
|
||||
|
||||
ob_start(); ?>
|
||||
<div class="sby-comment-container" <?php echo SBY_Display_Elements_Pro::get_comment_data_attributes( $settings ); ?>>
|
||||
<button class="sby-comments-trigger">
|
||||
<?php echo $message_icon; ?>
|
||||
<p><?php echo esc_html( 'Show Comments', 'feeds-for-youtube' ) ?></p>
|
||||
</button>
|
||||
<div class="sby-comments-wrap"></div>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
<?php
|
||||
/**
|
||||
* Class SBY_Cron_Updater_Pro
|
||||
*
|
||||
* Finds all regular feed transients saved in the database and updates
|
||||
* each cached feed in the background using WP Cron. This is set up with the
|
||||
* "sby_cron_updater" function in the if-functions.php file. The "display_instagram"
|
||||
* function will trigger a single feed update if no transient is found
|
||||
* for the feed
|
||||
*
|
||||
* @since 1.0/1.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Pro;
|
||||
use SmashBalloon\YouTubeFeed\SBY_Cron_Updater;
|
||||
use SmashBalloon\YouTubeFeed\Services\AdminAjaxService;
|
||||
|
||||
class SBY_Cron_Updater_Pro extends SBY_Cron_Updater
|
||||
{
|
||||
/**
|
||||
* Find and loop through all feed cache transients and update the post and
|
||||
* header caches
|
||||
*
|
||||
* Overwritten in the Pro version
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function do_feed_updates() {
|
||||
$feed_caches = self::get_feed_cache_option_names();
|
||||
shuffle( $feed_caches );
|
||||
$database_settings = sby_get_database_settings();
|
||||
|
||||
// this is outputted in system info
|
||||
$report = array(
|
||||
'notes' => array(
|
||||
'time_ran' => date( 'Y-m-d H:i:s' ),
|
||||
'num_found_transients' => count( $feed_caches )
|
||||
)
|
||||
);
|
||||
|
||||
foreach ( $feed_caches as $feed_cache ) {
|
||||
|
||||
$feed_id = str_replace( '_transient_', '', $feed_cache['option_name'] );
|
||||
$report[ $feed_id ] = array();
|
||||
|
||||
$transient = get_transient( $feed_id );
|
||||
|
||||
if ( $transient ) {
|
||||
$feed_data = json_decode( $transient, true );
|
||||
|
||||
// shortcode attributes are saved in order to recreate the feed is needed
|
||||
$atts = isset( $feed_data['atts'] ) ? $feed_data['atts'] : array();
|
||||
$last_retrieve = isset( $feed_data['last_retrieve'] ) ? (int)$feed_data['last_retrieve'] : 0;
|
||||
// the last approximate time the feed was requested to be displayed on a page is recorded
|
||||
// in order to stop updating feeds not in use.
|
||||
$last_requested = isset( $feed_data['last_requested'] ) ? (int)$feed_data['last_requested'] : false;
|
||||
$report[ $feed_id ]['last_retrieve'] = date( 'Y-m-d H:i:s', $last_retrieve );
|
||||
if ( $atts !== false ) {
|
||||
|
||||
if ( ! $last_requested || $last_requested > (time() - 60*60*24*30) ) {
|
||||
$sby_settings_obj = new SBY_Settings_Pro( $atts, $database_settings );
|
||||
|
||||
if ( empty( $database_settings['connected_accounts'] ) && empty( $database_settings['api_key'] ) ) {
|
||||
$report[ $feed_id ]['did_update'] = 'no - no connected account';
|
||||
} else {
|
||||
self::do_single_feed_cron_update( $sby_settings_obj, $feed_data, $atts );
|
||||
|
||||
$report[ $feed_id ]['did_update'] = 'yes';
|
||||
}
|
||||
} else {
|
||||
$report[ $feed_id ]['did_update'] = 'no - not recently requested';
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
$report[ $feed_id ]['did_update'] = 'no - missing atts';
|
||||
}
|
||||
|
||||
} else {
|
||||
$report[ $feed_id ]['did_update'] = 'no - no transient found';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
update_option( 'sby_cron_report', $report, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a single feed cache based on settings. Local image storing and
|
||||
* resizing is done in the background here as well unless this is the initial
|
||||
* time the feed is created and no cached data exists yet.
|
||||
*
|
||||
* Overwritten in the Pro version
|
||||
*
|
||||
* @param object $sby_settings_obj object created by the sby_settings class
|
||||
* @param array $feed_data post, header, shortcode settings, and other info
|
||||
* associated with the feed that is saved in the cache
|
||||
* @param array $atts shortcode settings
|
||||
* @param bool $include_resize whether or not to resize images during the update since
|
||||
* images can also be resized with an ajax call when the feed is viewed on the frontend
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function do_single_feed_cron_update( $sby_settings_obj, $feed_data, $atts, $include_resize = true ) {
|
||||
$sby_settings_obj->set_feed_type_and_terms();
|
||||
$sby_settings_obj->set_transient_name();
|
||||
$transient_name = $sby_settings_obj->get_transient_name();
|
||||
$settings = $sby_settings_obj->get_settings();
|
||||
$feed_type_and_terms = $sby_settings_obj->get_feed_type_and_terms();
|
||||
|
||||
$youtube_feed = new SBY_Feed_Pro( $transient_name );
|
||||
|
||||
while ( $youtube_feed->need_posts( $settings['num'] ) && $youtube_feed->can_get_more_posts() ) {
|
||||
$youtube_feed->add_remote_posts( $settings, $feed_type_and_terms, $sby_settings_obj->get_connected_accounts_in_feed() );
|
||||
}
|
||||
|
||||
$to_cache = array(
|
||||
'atts' => $atts,
|
||||
'last_requested' => $feed_data['last_requested'],
|
||||
'last_retrieve' => time()
|
||||
);
|
||||
|
||||
$youtube_feed->set_cron_cache( $to_cache, $sby_settings_obj->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
|
||||
|
||||
if ( $youtube_feed->need_header( $settings, $feed_type_and_terms ) ) {
|
||||
$youtube_feed->set_remote_header_data( $settings, $feed_type_and_terms, $sby_settings_obj->get_connected_accounts_in_feed() );
|
||||
|
||||
$youtube_feed->cache_header_data( $sby_settings_obj->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
|
||||
}
|
||||
|
||||
$post_data = $youtube_feed->get_post_data();
|
||||
$post_data = array_slice( $post_data, 0, $settings['num'] );
|
||||
|
||||
AdminAjaxService::sby_process_post_set_caching( $post_data, $transient_name );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve option name column values for all feed cache transients
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function get_feed_cache_option_names() {
|
||||
global $wpdb;
|
||||
$feed_caches = array();
|
||||
|
||||
$results = $wpdb->get_results( "
|
||||
SELECT option_name
|
||||
FROM $wpdb->options
|
||||
WHERE `option_name` LIKE ('%\_transient\_sby\_%')
|
||||
AND `option_name` NOT LIKE ('%\_transient\_sby\_-%')
|
||||
AND `option_name` NOT LIKE ('%\_transient\_sby\_header%');", ARRAY_A );
|
||||
|
||||
if ( isset( $results[0] ) ) {
|
||||
$feed_caches = $results;
|
||||
}
|
||||
|
||||
return $feed_caches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes comment transient on feed schedule.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 2.3.3
|
||||
*/
|
||||
public static function do_comment_delete() {
|
||||
global $wpdb;
|
||||
|
||||
$database_settings = sby_get_database_settings();
|
||||
|
||||
if ( empty( $database_settings['connected_accounts'] ) && empty( $database_settings['api_key'] ) ) {
|
||||
|
||||
// Define the prefix for the transients you want to delete
|
||||
$transient_prefix = 'sby_comment_';
|
||||
|
||||
// Prepare the SQL query to delete transients with the specified prefix
|
||||
$sql = $wpdb->prepare(
|
||||
"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s",
|
||||
$wpdb->esc_like($transient_prefix) . '%'
|
||||
);
|
||||
|
||||
// Execute the query
|
||||
$wpdb->query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start cron jobs based on user's settings for cron cache update frequency.
|
||||
* This is triggered when settings are saved on the "Configure" tab.
|
||||
*
|
||||
* @param string $sby_cache_cron_interval arbitrary name from one of the
|
||||
* settings on the "Configure" tab
|
||||
* @param string $sby_cache_cron_time hour of the day (1 = 1:00)
|
||||
* @param string $sby_cache_cron_am_pm am or pm (time of day)
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function start_cron_job( $sby_cache_cron_interval, $sby_cache_cron_time, $sby_cache_cron_am_pm ) {
|
||||
wp_clear_scheduled_hook( 'sby_feed_update' );
|
||||
|
||||
if ( $sby_cache_cron_interval === '12hours' || $sby_cache_cron_interval === '24hours' ) {
|
||||
$relative_time_now = time() + sby_get_utc_offset();
|
||||
$base_day = strtotime( date( 'Y-m-d', $relative_time_now ) );
|
||||
$add_time = $sby_cache_cron_am_pm === 'pm' ? (int)$sby_cache_cron_time + 12 : (int)$sby_cache_cron_time;
|
||||
$utc_start_time = $base_day + (($add_time * 60 * 60) - sby_get_utc_offset());
|
||||
|
||||
if ( $utc_start_time < time() ) {
|
||||
if ( $sby_cache_cron_interval === '12hours' ) {
|
||||
$utc_start_time += 60*60*12;
|
||||
} else {
|
||||
$utc_start_time += 60*60*24;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $sby_cache_cron_interval === '12hours' ) {
|
||||
wp_schedule_event( $utc_start_time, 'twicedaily', 'sby_feed_update' );
|
||||
} else {
|
||||
wp_schedule_event( $utc_start_time, 'daily', 'sby_feed_update' );
|
||||
}
|
||||
|
||||
} else {
|
||||
if ( $sby_cache_cron_interval === '30mins' ) {
|
||||
wp_schedule_event( time(), 'sby30mins', 'sby_feed_update' );
|
||||
} else {
|
||||
wp_schedule_event( time(), 'hourly', 'sby_feed_update' );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
/**
|
||||
* Class SBY_Display_Elements_Pro
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Pro;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\SBY_Display_Elements;
|
||||
|
||||
class SBY_Display_Elements_Pro extends SBY_Display_Elements
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $icon_type
|
||||
* @param $styles
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
private static function get_pro_icons( $type, $icon_type, $styles = '' ) {
|
||||
if ( $type === 'date' ) {
|
||||
if ( $icon_type === 'svg' ) {
|
||||
return '<svg ' . $styles . ' class="svg-inline--fa fa-clock fa-w-16" aria-hidden="true" data-fa-processed="" data-prefix="far" data-icon="clock" role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm61.8-104.4l-84.9-61.7c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v141.7l66.8 48.6c5.4 3.9 6.5 11.4 2.6 16.8L334.6 349c-3.9 5.3-11.4 6.5-16.8 2.6z"></path></svg>';
|
||||
} else {
|
||||
return '<i class="fa fa-clock" aria-hidden="true"></i>';
|
||||
}
|
||||
|
||||
} elseif ( $type === 'likes' ) {
|
||||
if ( $icon_type === 'svg' ) {
|
||||
return '<svg ' . $styles . ' class="svg-inline--fa fa-heart fa-w-18" aria-hidden="true" data-fa-processed="" data-prefix="fa" data-icon="heart" role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M414.9 24C361.8 24 312 65.7 288 89.3 264 65.7 214.2 24 161.1 24 70.3 24 16 76.9 16 165.5c0 72.6 66.8 133.3 69.2 135.4l187 180.8c8.8 8.5 22.8 8.5 31.6 0l186.7-180.2c2.7-2.7 69.5-63.5 69.5-136C560 76.9 505.7 24 414.9 24z"></path></svg>';
|
||||
} else {
|
||||
return '<i class="fa fa-heart" aria-hidden="true"></i>';
|
||||
}
|
||||
} elseif ( $type === 'comments' ) {
|
||||
if ( $icon_type === 'svg' ) {
|
||||
return '<svg ' . $styles . ' class="svg-inline--fa fa-comment fa-w-18" aria-hidden="true" data-fa-processed="" data-prefix="fa" data-icon="comment" role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M576 240c0 115-129 208-288 208-48.3 0-93.9-8.6-133.9-23.8-40.3 31.2-89.8 50.3-142.4 55.7-5.2.6-10.2-2.8-11.5-7.7-1.3-5 2.7-8.1 6.6-11.8 19.3-18.4 42.7-32.8 51.9-94.6C21.9 330.9 0 287.3 0 240 0 125.1 129 32 288 32s288 93.1 288 208z"></path></svg>';
|
||||
} else {
|
||||
return '<i class="fa fa-comment" aria-hidden="true"></i>';
|
||||
}
|
||||
|
||||
} elseif ( $type === 'newlogo' ) {
|
||||
return '<svg ' . $styles . ' class="sby_new_logo fa-instagram fa-w-14" aria-hidden="true" data-fa-processed="" data-prefix="fab" data-icon="instagram" role="img" viewBox="0 0 448 512">
|
||||
<path fill="currentColor" d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"></path>
|
||||
</svg>';
|
||||
|
||||
//return '<i class="sby_new_logo" aria-hidden="true"></i>';
|
||||
} elseif ( $type === 'map_marker' ) {
|
||||
if ( $icon_type === 'svg' ) {
|
||||
return '<svg ' . $styles . ' class="svg-inline--fa fa-map-marker fa-w-12" aria-hidden="true" data-fa-processed="" data-prefix="fa" data-icon="map-marker" role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path fill="currentColor" d="M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0z"></path></svg>';
|
||||
} else {
|
||||
return '<i class="fa fa-map-marker" aria-hidden="true"></i>';
|
||||
}
|
||||
|
||||
} elseif ( $type === 'photo' ) {
|
||||
if ( $icon_type === 'svg' ) {
|
||||
return '<svg class="svg-inline--fa fa-image fa-w-16" aria-hidden="true" data-fa-processed="" data-prefix="far" data-icon="image" role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM112 120c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56zM64 384h384V272l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L208 320l-55.515-55.515c-4.686-4.686-12.284-4.686-16.971 0L64 336v48z"></path></svg>';
|
||||
} else {
|
||||
return '<i class="fa fa-image" aria-hidden="true"></i>';
|
||||
}
|
||||
} elseif ( $type === 'user' ) {
|
||||
if ( $icon_type === 'svg' ) {
|
||||
return '<svg class="svg-inline--fa fa-user fa-w-16" style="margin-right: 3px;" aria-hidden="true" data-fa-processed="" data-prefix="fa" data-icon="user" role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M96 160C96 71.634 167.635 0 256 0s160 71.634 160 160-71.635 160-160 160S96 248.366 96 160zm304 192h-28.556c-71.006 42.713-159.912 42.695-230.888 0H112C50.144 352 0 402.144 0 464v24c0 13.255 10.745 24 24 24h464c13.255 0 24-10.745 24-24v-24c0-61.856-50.144-112-112-112z"></path></svg>';
|
||||
} else {
|
||||
return '<i class="fa fa-user" aria-hidden="true"></i>';
|
||||
}
|
||||
} elseif ( $type === 'views' ) {
|
||||
if ( $icon_type === 'svg' ) {
|
||||
return '<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="eye" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="svg-inline--fa fa-eye fa-w-18"><path fill="currentColor" d="M288 144a110.94 110.94 0 0 0-31.24 5 55.4 55.4 0 0 1 7.24 27 56 56 0 0 1-56 56 55.4 55.4 0 0 1-27-7.24A111.71 111.71 0 1 0 288 144zm284.52 97.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400c-98.65 0-189.09-55-237.93-144C98.91 167 189.34 112 288 112s189.09 55 237.93 144C477.1 345 386.66 400 288 400z" class=""></path></svg>';
|
||||
} else {
|
||||
return '<i class="fa fa-eye" aria-hidden="true"></i>';
|
||||
}
|
||||
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A not very elegant but useful method to abstract out how the settings
|
||||
* work for displaying certain elements in the feed.
|
||||
*
|
||||
* @param string $element specific key, view below for supported ones
|
||||
* @param $settings
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public static function should_show_element( $element, $context, $settings ) {
|
||||
if ( sby_doing_customizer( $settings ) ) {
|
||||
return true;
|
||||
}
|
||||
//user, views, date
|
||||
if ( $context === 'item-hover' ) {
|
||||
if ( $settings['layout'] === 'list' ) {
|
||||
$include_array = array();
|
||||
} else {
|
||||
$include_array = $settings['hoverinclude'];
|
||||
}
|
||||
} elseif ( $context === 'result' ) {
|
||||
$include_array = array();
|
||||
} elseif ( $context === 'single' ) {
|
||||
$cpt_settings = SBY_CPT::get_sby_cpt_settings();
|
||||
$include_array = $cpt_settings['include'];
|
||||
} else {
|
||||
$include_array = $settings['include'];
|
||||
}
|
||||
|
||||
$include_array = is_array( $include_array ) ? $include_array : explode( ',', str_replace( ' ', '', $include_array ) );
|
||||
|
||||
if ( $element === 'meta' ) {
|
||||
if ( in_array( 'user', $include_array, true )
|
||||
|| in_array( 'views', $include_array, true )
|
||||
|| in_array( 'date', $include_array, true ) ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} elseif ( in_array( $element, $include_array, true ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used with the core feed but can be used for customizations.
|
||||
*
|
||||
* @param $settings
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public static function get_feed_type_class( $settings ) {
|
||||
return 'sby_feed_type_' . esc_attr( $settings['type'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Boxed style headers have more color options - primary color
|
||||
*
|
||||
* @param $settings
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public static function get_boxed_header_styles( $settings ) {
|
||||
if ( ! empty( $settings['headerprimarycolor'] ) ) {
|
||||
return 'style="background: rgb(' . esc_attr( sby_hextorgb( $settings['headerprimarycolor'] ) ). ');"';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Boxed style headers have more color options - secondary color
|
||||
*
|
||||
* @param $settings
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public static function get_header_bar_styles( $settings ) {
|
||||
if ( ! empty( $settings['headersecondarycolor'] ) ) {
|
||||
return 'style="background: rgb(' . esc_attr( sby_hextorgb( $settings['headersecondarycolor'] ) ). ');"';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* For text, likes counts, post counts
|
||||
*
|
||||
* @param $settings
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public static function get_header_info_styles( $settings ) {
|
||||
if ( ! empty( $settings['headerprimarycolor'] ) ) {
|
||||
return 'style="color: rgb(' . esc_attr( sby_hextorgb( $settings['headerprimarycolor'] ) ). ');"';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Layout for mobile feeds altered with the class added here based on settings.
|
||||
*
|
||||
* @param $settings
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public static function get_mobilecols_class( $settings ) {
|
||||
$disable_mobile = $settings['disablemobile'];
|
||||
( $disable_mobile == 'on' || $disable_mobile == 'true' || $disable_mobile == true ) ? $disable_mobile = true : $disable_mobile = false;
|
||||
if( $settings[ 'disablemobile' ] === 'false' ) $disable_mobile = '';
|
||||
|
||||
if ( $disable_mobile !== ' sby_disable_mobile' && $settings['colsmobile'] !== 'same' ) {
|
||||
$colsmobile = (int)( $settings['colsmobile'] ) > 0 ? (int)$settings['colsmobile'] : 'auto';
|
||||
return ' sby_mob_col_' . $colsmobile;
|
||||
} else {
|
||||
$colsmobile = (int)( $settings['cols'] ) > 0 ? (int)$settings['cols'] : 4;
|
||||
return ' sby_disable_mobile sby_mob_col_' . (int)$settings['cols'];
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_list_type_subscribe_bar_attr( $settings ) {
|
||||
$customizer = sby_doing_customizer( $settings );
|
||||
|
||||
if ( ! $customizer ) {
|
||||
return;
|
||||
}
|
||||
|
||||
return self::create_condition_show_vue( $customizer, '$parent.valueIsEnabled($parent.customizerFeedData.settings.layout == \'list\' && $parent.customizerFeedData.settings.enablesubscriberlink)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Comment data attributes
|
||||
*
|
||||
* @param array $settings
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 2.3.3
|
||||
*/
|
||||
public static function get_comment_data_attributes( $settings ) {
|
||||
if ( ! sby_doing_customizer( $settings ) ) {
|
||||
return '';
|
||||
}
|
||||
return ' ' . self::display_vue_condition( 'enablecomments' );
|
||||
}
|
||||
}
|
||||
665
wp-content/plugins/youtube-feed-pro/inc/Pro/SBY_Feed_Pro.php
Normal file
665
wp-content/plugins/youtube-feed-pro/inc/Pro/SBY_Feed_Pro.php
Normal file
@@ -0,0 +1,665 @@
|
||||
<?php
|
||||
/**
|
||||
* Class SBY_Feed_Pro
|
||||
*
|
||||
* The Pro class mostly adds additional methods
|
||||
* used in the "display_instagram" function for supporting
|
||||
* additional features.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Pro;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\SBY_API_Connect;
|
||||
use SmashBalloon\YouTubeFeed\SBY_Feed;
|
||||
use SmashBalloon\YouTubeFeed\SBY_Parse;
|
||||
|
||||
class SBY_Feed_Pro extends SBY_Feed
|
||||
{
|
||||
private $stats_cache;
|
||||
|
||||
public function set_next_pages( $next_pages ) {
|
||||
$this->next_pages = $next_pages;
|
||||
}
|
||||
|
||||
public function need_header( $settings, $feed_types_and_terms ) {
|
||||
if ( ! empty( $settings['headerchannel'] ) || isset( $feed_types_and_terms['channels'] ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_first_user( $feed_types_and_terms, $settings = array() ) {
|
||||
if ( ! is_array( $settings ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( ! empty( $settings['headerchannel'] ) ) {
|
||||
return $settings['headerchannel'];
|
||||
} elseif ( isset( $feed_types_and_terms['channels'][0] ) ) {
|
||||
return $feed_types_and_terms['channels'][0]['term'];
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the settings to determine if avatars are going to be used.
|
||||
* Can make feed creation faster if not.
|
||||
*
|
||||
* @param $settings
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function need_avatars( $settings ) {
|
||||
if ( isset( $settings['type'] ) && $settings['type'] === 'hashtag' ) {
|
||||
return false;
|
||||
} elseif ( isset( $settings['disablelightbox'] ) && ($settings['disablelightbox'] === 'true' || $settings['disablelightbox'] === 'on') ) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Available avatars are added to the feed as an attribute so they can be used in the lightbox
|
||||
*
|
||||
* @param $connected_accounts_in_feed
|
||||
* @param $feed_types_and_terms
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function set_up_feed_avatars( $connected_accounts_in_feed, $feed_types_and_terms ) {
|
||||
foreach ( $feed_types_and_terms as $type => $terms ) {
|
||||
foreach ( $terms as $term_and_params ) {
|
||||
$existing_channel_cache = $this->get_channel_cache( $term_and_params['term'], true );
|
||||
$avatar = SBY_Parse::get_avatar( $existing_channel_cache );
|
||||
$channel_id = SBY_Parse::get_channel_id( $existing_channel_cache );
|
||||
$this->set_avatar( $channel_id, $avatar );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a key value pair of the username and the url of
|
||||
* the avatar image
|
||||
*
|
||||
* @param $name
|
||||
* @param $url
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function set_avatar( $channel_id, $url ) {
|
||||
$this->channel_id_avatars[ $channel_id ] = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_channel_id_avatars() {
|
||||
return $this->channel_id_avatars;
|
||||
}
|
||||
|
||||
/**
|
||||
* the API_Connect class can use either a premade url or
|
||||
* settings from a connected account, type, and parameters
|
||||
*
|
||||
* @param array|string $connected_account_or_page
|
||||
* @param null $type
|
||||
* @param null $params
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function make_api_connection( $connected_account_or_page, $type = NULL, $params = NULL ) {
|
||||
return new SBY_API_Connect_Pro( $connected_account_or_page, $type, $params );
|
||||
}
|
||||
|
||||
public function is_efficient_type( $type ) {
|
||||
return in_array( $type, array( 'playlist', 'channel' ), true );
|
||||
}
|
||||
|
||||
public function get_play_list_for_term( $type, $term, $connected_account_for_term, $params ) {
|
||||
if ( $type === 'playlist' ) {
|
||||
return $term;
|
||||
}
|
||||
if ( $type === 'search' || $type === 'single' || $type === 'live' ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$existing_channel_cache = $this->get_channel_cache( $term );
|
||||
|
||||
if ( $existing_channel_cache ) {
|
||||
$this->channels_data[ $term ] = $existing_channel_cache;
|
||||
}
|
||||
|
||||
if ( empty( $this->channels_data[ $term ] ) ) {
|
||||
if ( $connected_account_for_term['expires'] < time() + 5 ) {
|
||||
$error_message = '<p><b>' . __( 'Reconnect to YouTube to show this feed.', 'feeds-for-youtube' ) . '</b></p>';
|
||||
$error_message .= '<p>' . __( 'To create a new feed, first connect to YouTube using the "Connect to YouTube to Create a Feed" button on the settings page and connect any account.', 'feeds-for-youtube' ) . '</p>';
|
||||
|
||||
if ( current_user_can( 'manage_youtube_feed_options' ) ) {
|
||||
$error_message .= '<a href="' . admin_url( 'admin.php?page=youtube-feed-settings' ) . '" target="blank" rel="noopener nofollow">' . __( 'Reconnect in the YouTube Feeds Settings Area', 'feeds-for-youtube' ) . '</a>';
|
||||
}
|
||||
global $sby_posts_manager;
|
||||
|
||||
$sby_posts_manager->add_frontend_error( 'accesstoken', $error_message );
|
||||
$sby_posts_manager->add_error( 'accesstoken', array( 'Trying to connect a new account', $error_message ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
$channel_data = array();
|
||||
$api_connect_channels = $this->make_api_connection( $connected_account_for_term, 'channels', $params );
|
||||
|
||||
$this->add_report( 'channel api call made for ' . $term . ' - ' . $type );
|
||||
|
||||
$api_connect_channels->connect();
|
||||
if ( ! $api_connect_channels->is_wp_error() && ! $api_connect_channels->is_youtube_error() ) {
|
||||
$channel_data = $api_connect_channels->get_data();
|
||||
$channel_id = SBY_Parse::get_channel_id( $channel_data );
|
||||
$this->set_channel_cache( $channel_id, $channel_data );
|
||||
|
||||
if ( isset( $params['channel_name'] ) ) {
|
||||
sby_set_channel_id_from_channel_name( $params['channel_name'], $channel_id );
|
||||
$this->set_channel_cache( $params['channel_name'], $channel_data );
|
||||
}
|
||||
|
||||
$params = array( 'channel_id' => $channel_id );
|
||||
$this->channels_data[ $channel_id ] = $channel_data;
|
||||
$this->channels_data[ $term ] = $channel_data;
|
||||
} else {
|
||||
if ( ! $api_connect_channels->is_wp_error() ) {
|
||||
$return = SBY_API_Connect::handle_youtube_error( $api_connect_channels->get_data(), $connected_account_for_term );
|
||||
if ( $return && isset( $return['access_token'] ) ) {
|
||||
$connected_account_for_term['access_token'] = $return['access_token'];
|
||||
$connected_accounts_for_feed[ $term ]['access_token'] = $return['access_token'];
|
||||
$connected_account_for_term['expires'] = $return['expires_in'] + time();
|
||||
$connected_accounts_for_feed[ $term ]['expires'] = $return['expires_in'] + time();
|
||||
|
||||
sby_update_or_connect_account( $connected_account_for_term );
|
||||
$this->add_report( 'refreshing access token for ' . $connected_account_for_term['channel_id'] );
|
||||
|
||||
$sby_api_connect_channel = $this->make_api_connection( $connected_account_for_term, 'channels', $params );
|
||||
$sby_api_connect_channel->connect();
|
||||
if ( ! $sby_api_connect_channel->is_youtube_error() ) {
|
||||
$channel_data = $sby_api_connect_channel->get_data();
|
||||
$channel_id = SBY_Parse::get_channel_id( $channel_data );
|
||||
$this->set_channel_cache( $channel_id, $channel_data );
|
||||
|
||||
if ( isset( $params['channel_name'] ) ) {
|
||||
sby_set_channel_id_from_channel_name( $params['channel_name'], $channel_id );
|
||||
$this->set_channel_cache( $params['channel_name'], $channel_data );
|
||||
}
|
||||
|
||||
$this->channels_data[ $channel_id ] = $channel_data;
|
||||
$this->channels_data[ $term ] = $channel_data;
|
||||
|
||||
}
|
||||
} else {
|
||||
$this->add_report( 'error connecting to channel' );
|
||||
}
|
||||
} else {
|
||||
$api_connect_channels->handle_wp_remote_get_error( $api_connect_channels->get_data() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $type === 'favorites' ) {
|
||||
$playlist = isset( $this->channels_data[ $term ]['items'][0]['contentDetails']['relatedPlaylists']['favorites'] ) ? $this->channels_data[ $term ]['items'][0]['contentDetails']['relatedPlaylists']['favorites'] : false;
|
||||
if ( $playlist === false ) {
|
||||
$this->add_report( 'No favorites playlist found' );
|
||||
}
|
||||
|
||||
} else {
|
||||
$playlist = isset( $this->channels_data[ $term ]['items'][0]['contentDetails']['relatedPlaylists']['uploads'] ) ? $this->channels_data[ $term ]['items'][0]['contentDetails']['relatedPlaylists']['uploads'] : false;
|
||||
}
|
||||
|
||||
|
||||
return $playlist;
|
||||
}
|
||||
|
||||
protected function sort_posts( $post_set, $settings ) {
|
||||
if ( empty( $post_set ) ) {
|
||||
return $post_set;
|
||||
}
|
||||
|
||||
// sorting done with "merge_posts" to be more efficient
|
||||
if ( $settings['sortby'] === 'alternate' || $settings['sortby'] === 'relevance' || $settings['sortby'] === 'api' ) {
|
||||
$return_post_set = $post_set;
|
||||
} elseif ( $settings['sortby'] === 'random' ) {
|
||||
/*
|
||||
* randomly selects posts in a random order. Cache saves posts
|
||||
* in this random order so paginating does not cause some posts to show up
|
||||
* twice or not at all
|
||||
*/
|
||||
usort( $post_set, 'sby_rand_sort' );
|
||||
$return_post_set = $post_set;
|
||||
|
||||
} else {
|
||||
$scheduled_start = SBY_Parse_Pro::get_scheduled_start_timestamp( $post_set[0] );
|
||||
if ( ! empty( $scheduled_start ) ) {
|
||||
usort($post_set, 'sby_scheduled_start_sort' );
|
||||
} else {
|
||||
// compares posted on dates of posts
|
||||
usort( $post_set, 'sby_date_sort' );
|
||||
}
|
||||
|
||||
$return_post_set = $post_set;
|
||||
}
|
||||
|
||||
return $return_post_set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for filtering a single API request worth of posts
|
||||
*
|
||||
* @param $post_set
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 5.0
|
||||
* @since 5.1 support for filtering "includes any includeword
|
||||
* and also does not include any excludeword"
|
||||
*/
|
||||
protected function filter_posts( $post_set, $settings = array() ) {
|
||||
$hide_upcoming = $settings['type'] === 'live' && ! $settings['showpast'];
|
||||
|
||||
if ( empty( $settings['includewords'] )
|
||||
&& empty( $settings['excludewords'] )
|
||||
&& empty( $settings['whitelist'] )
|
||||
&& empty( $settings['hidevideos'] )
|
||||
&& empty( $hide_upcoming) ) {
|
||||
return $post_set;
|
||||
}
|
||||
|
||||
$includewords = ! empty( $settings['includewords'] ) ? explode( ',', $settings['includewords'] ) : array();
|
||||
$excludewords = ! empty( $settings['excludewords'] ) ? explode( ',', $settings['excludewords'] ) : array();
|
||||
$hide_videos = ! empty( $settings['hidevideos'] ) && empty( $settings['doingModerationMode'] ) ? explode( ',', str_replace( ' ', '', $settings['hidevideos'] ) ) : array();
|
||||
$white_list = ! empty( $settings['whitelist'] ) && empty( $settings['doingModerationMode'] ) ? get_option( 'sb_youtube_white_lists_'.$settings['whitelist'], array() ) : false;
|
||||
|
||||
$filtered_posts = array();
|
||||
foreach ( $post_set as $post ) {
|
||||
$keep_post = false;
|
||||
|
||||
$padded_caption = ' ' . str_replace( array( '+', '%0A' ), ' ', urlencode( str_replace( '#', ' HASHTAG', strtolower( SBY_Parse_Pro::get_caption( $post ) ) ) ) ) . ' ';
|
||||
$padded_title = ' ' . str_replace( array( '+', '%0A' ), ' ', urlencode( str_replace( '#', ' HASHTAG', strtolower( SBY_Parse_Pro::get_video_title( $post ) ) ) ) ) . ' ';
|
||||
|
||||
$id = SBY_Parse_Pro::get_video_id( $post );
|
||||
$post_id = SBY_Parse_Pro::get_post_id( $post );
|
||||
|
||||
|
||||
$is_hidden = false;
|
||||
if ( ! empty( $hide_videos )
|
||||
&& ((in_array( $id, $hide_videos, true ) || in_array( 'sby_' . $id, $hide_videos, true )) || (in_array( $post_id, $hide_videos, true ) || in_array( 'sby_' . $post_id, $hide_videos, true ))) ) {
|
||||
$is_hidden = true;
|
||||
}
|
||||
|
||||
// any blocked photos will not pass any additional filters so don't bother processing
|
||||
if ( ! $is_hidden ) {
|
||||
$is_on_white_list = false;
|
||||
$passes_word_filter = true;
|
||||
|
||||
if ( $white_list ) {
|
||||
if ( in_array( $id, $white_list, true ) || in_array( 'sby_' . $id, $white_list, true ) ) {
|
||||
$is_on_white_list = true;
|
||||
}
|
||||
} elseif ( ! empty( $includewords ) || ! empty( $excludewords ) ) {
|
||||
$has_includeword = $this->has_filter_keyword( $includewords, $padded_caption, $padded_title );
|
||||
$has_excludeword = $this->has_filter_keyword( $excludewords, $padded_caption, $padded_title );
|
||||
|
||||
if ( ! empty( $includewords ) ) {
|
||||
$passes_word_filter = $has_includeword;
|
||||
}
|
||||
|
||||
if ( ! empty( $has_excludeword ) ) {
|
||||
$passes_word_filter = ! $has_excludeword;
|
||||
}
|
||||
|
||||
} else {
|
||||
// no other filters so it belongs in the feed
|
||||
$keep_post = true;
|
||||
}
|
||||
|
||||
if ( $is_on_white_list || $passes_word_filter ) {
|
||||
$keep_post = true;
|
||||
}
|
||||
|
||||
if ( $hide_upcoming ) {
|
||||
$actual_end_timestamp_a = SBY_Parse_Pro::get_actual_end_timestamp( $post ); // get the time it ended
|
||||
|
||||
if ( $actual_end_timestamp_a > 0 ) { // started but hasn't ended! show it first, it's streaming now
|
||||
$keep_post = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$keep_post = apply_filters( 'sby_passes_filter', $keep_post, $post, $settings );
|
||||
if ( $keep_post ) {
|
||||
$filtered_posts[] = $post;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $filtered_posts;
|
||||
}
|
||||
|
||||
private function has_filter_keyword( $keywords, $padded_caption, $padded_title ) {
|
||||
$has_keyword = false;
|
||||
|
||||
if ( ! empty( $keywords ) ) {
|
||||
foreach ( $keywords as $keyword ) {
|
||||
if ( ! empty( $keyword ) ) {
|
||||
$converted_keyword = trim( str_replace( '+', ' ',
|
||||
urlencode( str_replace( '#', 'HASHTAG', strtolower( $keyword ) ) ) ) );
|
||||
if ( preg_match( '/\b' . $converted_keyword . '\b/i', $padded_caption, $matches ) ) {
|
||||
$has_keyword = true;
|
||||
} elseif ( preg_match( '/\b' . $converted_keyword . '\b/i', $padded_title, $matches ) ) {
|
||||
$has_keyword = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $has_keyword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Total number of IDs in the white list already exist in the feed. Used
|
||||
* to prevent further pagination when no more white listed posts will be
|
||||
* found
|
||||
*
|
||||
* @param array $settings
|
||||
* @param int $offset
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
protected function xfeed_is_complete( $settings, $offset = 0 ) {
|
||||
if ( ! empty( $settings['whitelist_ids'] ) ) {
|
||||
if ( isset( $settings['doingModerationMode'] ) && $settings['doingModerationMode'] ) {
|
||||
return false;
|
||||
}
|
||||
$total_posts_loaded = $settings['num'] + $offset;
|
||||
|
||||
if ( (int)$settings['whitelist_num'] <= $total_posts_loaded ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds various data attributes to the main feed divthat are used
|
||||
* by the JavaScript file to layout the feed, trigger certain features,
|
||||
* and launchvmoderation mode
|
||||
*
|
||||
* @param $other_atts
|
||||
* @param $settings
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
protected function add_other_atts( $other_atts, $settings ) {
|
||||
$options_att_arr = array();
|
||||
$customizer = sby_doing_customizer( $settings );
|
||||
|
||||
|
||||
$layout = $settings['layout'];
|
||||
if ( ! in_array( $layout, array( 'masonry', 'highlight', 'carousel' ) ) ) {
|
||||
$layout = 'grid';
|
||||
}
|
||||
|
||||
if ( $layout === 'carousel' ) {
|
||||
$arrows = $settings['carouselarrows'] == 'true' || $settings['carouselarrows'] == 'on' || $settings['carouselarrows'] == 1 || $settings['carouselarrows'] == '1';
|
||||
$pag = $settings['carouselpag'] == 'true' || $settings['carouselpag'] == 'on' || $settings['carouselpag'] == 1 || $settings['carouselpag'] == '1';
|
||||
$autoplay = $settings['carouselautoplay'] == 'true' || $settings['carouselautoplay'] == 'on' || $settings['carouselautoplay'] == 1 || $settings['carouselautoplay'] == '1';
|
||||
$time = $autoplay ? (int)$settings['carouseltime'] : false;
|
||||
$loop = ! empty( $settings['carouselloop'] ) && ($settings['carouselloop'] !== 'rewind') ? false : true;
|
||||
$rows = ! empty( $settings['carouselrows'] ) ? min( (int)$settings['carouselrows'], 2 ) : 1;
|
||||
$options_att_arr['carousel'] = array( $arrows, $pag, $autoplay, $time, $loop, $rows );
|
||||
}
|
||||
|
||||
$options_att_arr['cta'] = array(
|
||||
'type' => 'default'
|
||||
);
|
||||
if ( $settings['cta'] === 'link' ) {
|
||||
$options_att_arr['cta']['type'] = 'link';
|
||||
} else if ( $settings['cta'] === 'related' ) {
|
||||
$options_att_arr['cta']['type'] = 'related';
|
||||
$options_att_arr['cta']['defaultPosts'] = array();
|
||||
|
||||
if ( $settings['num'] < 5 ) {
|
||||
$options_att_arr['cta']['defaultPosts'] = $this->get_cta_posts();
|
||||
}
|
||||
}
|
||||
|
||||
$options_att_arr['cta']['defaultLink'] = $settings['linkurl'];
|
||||
$options_att_arr['cta']['defaultText'] = $settings['linktext'];
|
||||
$options_att_arr['cta']['openType'] = $settings['linkopentype'];
|
||||
$button_color = str_replace( '#', '', $settings['linkcolor'] );
|
||||
$button_text_color = str_replace( '#', '', $settings['linktextcolor'] );
|
||||
$options_att_arr['cta']['color'] = ! empty( $button_color ) ? sby_hextorgb( $button_color ) : '';
|
||||
$options_att_arr['cta']['textColor'] = ! empty( $button_text_color ) ? sby_hextorgb( $button_text_color ) : '';
|
||||
|
||||
if ( ! empty( $settings['descriptionlength'] ) ) {
|
||||
$options_att_arr['descriptionlength'] = (int)$settings['descriptionlength'];
|
||||
}
|
||||
|
||||
$other_atts .= ' data-options="'.esc_attr( wp_json_encode( $options_att_arr ) ).'"';
|
||||
|
||||
|
||||
return $other_atts;
|
||||
}
|
||||
|
||||
public function get_cta_posts() {
|
||||
$posts = $this->get_post_data();
|
||||
|
||||
|
||||
if ( count( $posts ) >= 4 ) {
|
||||
$cta_posts_indices = array_rand( $posts, min( count( $posts ), 5 ) );
|
||||
$cta_array = array();
|
||||
foreach ( $cta_posts_indices as $cta_post_index ) {
|
||||
$cta_array[] = array(
|
||||
'videoID' => SBY_Parse::get_video_id( $posts[ $cta_post_index ] ),
|
||||
'thumbnail' => SBY_Parse::get_media_url( $posts[ $cta_post_index ], 'medium' ),
|
||||
'title' => SBY_Parse::get_video_title( $posts[ $cta_post_index ] )
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$cta_array = array();
|
||||
foreach ( $posts as $post ) {
|
||||
$cta_array[] = array(
|
||||
'videoID' => SBY_Parse::get_video_id( $post ),
|
||||
'thumbnail' => SBY_Parse::get_media_url( $post, 'medium' ),
|
||||
'title' => SBY_Parse::get_video_title( $post )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return $cta_array;
|
||||
}
|
||||
|
||||
public function requires_workaround_connection( $type ) {
|
||||
return $type === 'live';
|
||||
}
|
||||
|
||||
public function make_workaround_connection( $connected_account_for_term, $type, $params, $feed_id = '' ) {
|
||||
|
||||
$live_streams = new SBY_Live_Streams( $params['channelId'], $feed_id );
|
||||
|
||||
$new_live_streams = $live_streams->add_remote_posts();
|
||||
$live_streams->sort();
|
||||
$live_streams->update_cached_video_details( $new_live_streams );
|
||||
$live_streams->update_cache();
|
||||
|
||||
$videos = $live_streams->get_video_cache();
|
||||
|
||||
$response = array(
|
||||
'items' => array_values( $videos )
|
||||
);
|
||||
|
||||
$connection = new SBY_API_Connect_Pro( $connected_account_for_term, $type, $params );
|
||||
$connection->set_response( $response );
|
||||
|
||||
return $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of standard classes to be added to the main feed div.
|
||||
*
|
||||
* @param $settings
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
protected function xadd_classes( $settings ) {
|
||||
$classes = array();
|
||||
|
||||
$moderation_mode = (isset ( $_GET['sbi_moderation_mode'] ) && $_GET['sbi_moderation_mode'] === 'true' && current_user_can( 'edit_posts' ));
|
||||
|
||||
if ( $moderation_mode ) {
|
||||
$classes[] = 'sbi_moderation_mode';
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
public function convert_feed_id_to_stats_transient( $feed_id ) {
|
||||
$attempt = str_replace( 'sby_', 'sby_-', $feed_id );
|
||||
if ( $attempt === $feed_id ) {
|
||||
$attempt = '-' . $attempt;
|
||||
}
|
||||
|
||||
return $attempt;
|
||||
}
|
||||
|
||||
public function get_misc_data( $feed_id, $posts ) {
|
||||
$misc = array(
|
||||
'stats' => array()
|
||||
);
|
||||
|
||||
if ( ! empty( $feed_id ) ) {
|
||||
$stats_cache = $this->get_regular_stats_cache( $feed_id );
|
||||
if ( $stats_cache ) {
|
||||
$this->add_report('Found stats cache');
|
||||
} else {
|
||||
$this->add_report('No stats cache found');
|
||||
}
|
||||
$misc['stats'] = $stats_cache ? $stats_cache : array();
|
||||
}
|
||||
|
||||
if ( ! empty( $posts ) ) {
|
||||
$vid_ids = array();
|
||||
foreach ( $posts as $post ) {
|
||||
$vid_ids[] = SBY_Parse::get_video_id( $post );
|
||||
}
|
||||
|
||||
if ( ! empty( $vid_ids ) ) {
|
||||
$details_query = new SBY_YT_Details_Query( array( 'video_ids' => $vid_ids ) );
|
||||
$stats_cached_results = $details_query->get_cached_details_for_posts();
|
||||
$this->add_report('Getting cached stats for posts');
|
||||
|
||||
|
||||
$organized_stats = array();
|
||||
$organized_live_streaming_details = array();
|
||||
foreach ( $stats_cached_results as $post ) {
|
||||
$organized_stats[ $post['sby_video_id'] ] = $post;
|
||||
$organized_live_streaming_details[ $post['sby_video_id'] ] = $post;
|
||||
}
|
||||
$misc['stats'] = $organized_stats;
|
||||
$misc['live_streaming_details'] = $organized_live_streaming_details;
|
||||
if ( ! empty( $feed_id ) ) {
|
||||
$this->add_report('Adding to stats cache');
|
||||
|
||||
$this->add_stats_to_cache( $feed_id, $misc['stats'] );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $misc;
|
||||
}
|
||||
|
||||
protected function add_stats_to_cache( $feed_id, $stats ) {
|
||||
$stats_array = is_array( $stats ) ? $stats : array();
|
||||
|
||||
$cache = $this->get_regular_stats_cache( $feed_id );
|
||||
if ( is_array( $cache ) ) {
|
||||
$stats_array = array_merge( $stats_array, $cache );
|
||||
}
|
||||
|
||||
$stats_json = wp_json_encode( $stats_array );
|
||||
|
||||
set_transient( $this->convert_feed_id_to_stats_transient( $feed_id ), $stats_json );
|
||||
|
||||
$this->set_stats_data( $stats_array );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function get_stats_data() {
|
||||
return $this->stats_cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function set_stats_data( $stats_array ) {
|
||||
$this->stats_cache = $stats_array;
|
||||
}
|
||||
|
||||
protected function posts_loop( $posts, $settings, $offset = 0 ) {
|
||||
$header_data = $this->get_header_data();
|
||||
$image_ids = array();
|
||||
$post_index = $offset;
|
||||
if ( ! isset( $settings['feed_id'] ) ) {
|
||||
$settings['feed_id'] = $this->regular_feed_transient_name;
|
||||
}
|
||||
$misc_data = $this->get_misc_data( $settings['feed_id'], $posts );
|
||||
$icon_type = $settings['font_method'];
|
||||
|
||||
foreach ( $posts as $post ) {
|
||||
$post_id = SBY_Parse::get_post_id( $post );
|
||||
$video_id = SBY_Parse::get_video_id( $post );
|
||||
$image_ids[] = $post_id;
|
||||
if ( empty( $misc_data['stats'][ $video_id ] ) ) {
|
||||
$this->post_ids_with_no_details[] = $video_id;
|
||||
}
|
||||
include sby_get_feed_template_part( 'item', $settings );
|
||||
$post_index++;
|
||||
}
|
||||
|
||||
$this->image_ids_post_set = $image_ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the database option related the transient expiration
|
||||
* to ensure it will be available when the page loads
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 2.0/4.0
|
||||
*/
|
||||
public function get_regular_stats_cache( $feed_id ) {
|
||||
//Check whether the cache transient exists in the database and is available for more than one more minute
|
||||
$transient = get_transient( $this->convert_feed_id_to_stats_transient( $feed_id ) );
|
||||
|
||||
if ( $transient ) {
|
||||
$transient = json_decode( $transient );
|
||||
}
|
||||
|
||||
return $transient;
|
||||
}
|
||||
}
|
||||
364
wp-content/plugins/youtube-feed-pro/inc/Pro/SBY_Live_Streams.php
Normal file
364
wp-content/plugins/youtube-feed-pro/inc/Pro/SBY_Live_Streams.php
Normal file
@@ -0,0 +1,364 @@
|
||||
<?php
|
||||
/**
|
||||
* SBY_Live_Streams.
|
||||
*
|
||||
* Live streamed videos are stored in a cache due to there being no
|
||||
* reliable way to retrieve then using an API key and a standard API endpoint.
|
||||
* The RSS feed for the channel is used to get the latest 15 published videos
|
||||
* and this class can be used tp store all of the ones that are scheduled
|
||||
* live streams.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Pro;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\SBY_Parse;
|
||||
use SmashBalloon\YouTubeFeed\SBY_RSS_Connect;
|
||||
|
||||
class SBY_Live_Streams {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $channel;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $feed_id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cache_name;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $video_cache;
|
||||
|
||||
/**
|
||||
* SBY_Live_Streams constructor.
|
||||
*
|
||||
* @param $channel string
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public function __construct( $channel, $feed_id ) {
|
||||
$this->channel = $channel;
|
||||
$this->feed_id = $feed_id;
|
||||
$this->cache_name = 'sby_livestreams_' . $channel;
|
||||
$this->video_cache = get_option( $this->cache_name, array() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Cached video api data
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public function get_video_cache() {
|
||||
return $this->video_cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get latest 15 videos from RSS and return only
|
||||
* live streams. Use the video IDs to retrieve details
|
||||
* using the "single" video API endpoint. Update or add
|
||||
* to the cache based on results.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public function add_remote_posts() {
|
||||
|
||||
$api_videos = $this->fetch_via_api();
|
||||
|
||||
if(empty($api_videos)) {
|
||||
$api_videos = $this->fetch_rss();
|
||||
}
|
||||
|
||||
$live_streams = $this->fetch_singles( $api_videos );
|
||||
$this->update_or_add( $live_streams );
|
||||
return $live_streams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the API data for the most recent 40
|
||||
* videos in the cache. Can exclude videos if they
|
||||
* were just updated from another process.
|
||||
*
|
||||
* @param $exclude array
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public function update_cached_video_details( $exclude ) {
|
||||
$to_check = array_slice( $this->video_cache, 0, 40 + count( $exclude ) );
|
||||
|
||||
$to_update = array();
|
||||
foreach ( $to_check as $vid_id => $post ) {
|
||||
// $exclude set as an associative array with the video ID
|
||||
// as the index.
|
||||
if ( ! isset( $exclude[ $vid_id ] )
|
||||
&& count( $to_update ) < 40 ) {
|
||||
$to_update[] = $vid_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( ! empty( $to_update ) ) {
|
||||
$live_streams = $this->fetch_singles( $to_update );
|
||||
$this->update_or_add( $live_streams, $to_update );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The RSS feed contains live stream videos.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public function fetch_rss() {
|
||||
$params = array(
|
||||
'channel_id' => $this->channel,
|
||||
'livestream' => '1'
|
||||
);
|
||||
|
||||
$connection = new SBY_RSS_Connect( 'playlistItems', $params );
|
||||
$connection->connect();
|
||||
$data = $connection->get_data();
|
||||
|
||||
$ids = array();
|
||||
if ( is_array( $data ) ) {
|
||||
foreach ( $data as $post ) {
|
||||
$vid_id = SBY_Parse::get_video_id( $post );
|
||||
$ids[] = $vid_id;
|
||||
}
|
||||
}
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the video IDs of live stream feeds for a specific event type.
|
||||
*
|
||||
* @param string $event_type The type of event for which to fetch live stream video IDs.
|
||||
* This parameter determines the category or type of live streams to query.
|
||||
* @param string $page_token (Optional) The token to retrieve the next page of results, if available.
|
||||
* Default is an empty string, which fetches the first page.
|
||||
*
|
||||
* @return array An associative array containing the video IDs of the live streams and any
|
||||
*
|
||||
* @since 1.3
|
||||
*
|
||||
*/
|
||||
public function get_live_stream_feed_video_ids($event_type, $page_token = '') {
|
||||
$ids = [];
|
||||
$page_token = '';
|
||||
|
||||
$params = array(
|
||||
'channel_id' => $this->channel,
|
||||
'event_type' => $event_type,
|
||||
);
|
||||
|
||||
if( !empty($page_token) ) {
|
||||
$params['page_token'] = $page_token;
|
||||
}
|
||||
|
||||
|
||||
$connection = new SBY_API_Connect_Pro(sby_get_first_connected_account(), 'livestream', $params);
|
||||
$connection->connect();
|
||||
if ( ! $connection->is_youtube_error() ) {
|
||||
$items = !empty( $connection->get_data()['items'] ) ? $connection->get_data()['items'] : '';
|
||||
$page_token = !empty( $connection->get_data()['nextPageToken'] ) ? $connection->get_data()['nextPageToken'] : '';
|
||||
|
||||
|
||||
if( !empty($items)) {
|
||||
foreach ( $items as $single ) {
|
||||
$videoId = isset($single['id']['videoId']) ? $single['id']['videoId'] : '';
|
||||
$ids[] = $videoId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'ids' => $ids,
|
||||
'page_token' => $page_token
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get livestream feed using api.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public function fetch_via_api() {
|
||||
$atts = ['feed' => (int)$this->feed_id];
|
||||
|
||||
$database_settings = sby_get_database_settings();
|
||||
$youtube_feed_settings = new SBY_Settings_Pro($atts, $database_settings);
|
||||
|
||||
if (empty($database_settings['connected_accounts']) && empty($database_settings['api_key'])) {
|
||||
wp_send_json_error('Error: No connected account');
|
||||
}
|
||||
|
||||
$settings = $youtube_feed_settings->get_settings();
|
||||
|
||||
$data = [];
|
||||
$event_types = ['upcoming','live'];
|
||||
$page_token = '';
|
||||
$archive_page_count = !empty($settings['showpast'] )? apply_filters( 'sby_past_live_stream_num_pages', 1 ) : 0;
|
||||
|
||||
// For adding more past live streams in the future.
|
||||
if ($archive_page_count > 0) {
|
||||
$event_types[] = 'completed';
|
||||
}
|
||||
|
||||
foreach ($event_types as $single) {
|
||||
$page_token = ''; // Initialize the page token for each event type.
|
||||
$current_page = 0; // Track the current page for "completed" events.
|
||||
do {
|
||||
// Fetch data with or without a page token.
|
||||
if ('completed' === $single && !empty($page_token)) {
|
||||
$response = self::get_live_stream_feed_video_ids($single, $page_token);
|
||||
} else {
|
||||
$response = self::get_live_stream_feed_video_ids($single);
|
||||
}
|
||||
|
||||
if (!empty($response)) {
|
||||
// Add video IDs to the data array.
|
||||
$ids = !empty($response['ids']) ? $response['ids'] : [];
|
||||
array_push($data, ...$ids);
|
||||
|
||||
// Update the page token for the next loop iteration.
|
||||
$page_token = !empty($response['page_token']) ? $response['page_token'] : '';
|
||||
|
||||
// Increment the page counter for "completed" events.
|
||||
if ('completed' === $single) {
|
||||
$current_page++;
|
||||
}
|
||||
} else {
|
||||
// Exit the loop if no response or no more pages.
|
||||
$page_token = '';
|
||||
}
|
||||
|
||||
} while (!empty($page_token) && $current_page < $archive_page_count); // Limit pages based on $archive_page_count.
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides an array of items into smaller batches of a specified size.
|
||||
*
|
||||
* @param array $items The array of items to be divided into batches.
|
||||
* @param int $batchSize The maximum number of items per batch.
|
||||
* @return array An array of batches, with each batch being a sub-array of items.
|
||||
*/
|
||||
public function slice_into_batches($items, $batchSize) {
|
||||
return array_chunk($items, $batchSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the "single" API endpoint to get video details and
|
||||
* returns only those that appear to be live streams.
|
||||
*
|
||||
* @param $vid_ids array
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public function fetch_singles( $vid_ids ) {
|
||||
|
||||
if( empty($vid_ids) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$batches = self::slice_into_batches($vid_ids, SBY_MAX_SINGLE_PAGE);
|
||||
$live_streamed_videos = array();
|
||||
|
||||
foreach ($batches as $batch) {
|
||||
|
||||
$params['video_ids'] = $batch;
|
||||
|
||||
$connected_account = sby_get_first_connected_account();
|
||||
$video_connection = new SBY_API_Connect_Pro( $connected_account, 'single', $params );
|
||||
|
||||
$video_connection->connect();
|
||||
$potential_live_streams = $video_connection->get_data();
|
||||
|
||||
if ( is_array( $potential_live_streams['items'] ) ) {
|
||||
foreach ( $potential_live_streams['items'] as $post ) {
|
||||
if ( ! empty( $post['liveStreamingDetails']['scheduledStartTime'] )
|
||||
|| ! empty( $post['liveStreamingDetails']['actualStartTime'] ) ) {
|
||||
$vid_id = SBY_Parse::get_video_id( $post );
|
||||
|
||||
$live_streamed_videos[ $vid_id ] = $post;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $live_streamed_videos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates or adds to video cache stored as an associative array with
|
||||
* the video ID as the index.
|
||||
*
|
||||
* @param $live_streams array
|
||||
* @param $update_attempted array
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public function update_or_add( $live_streams, $update_attempted = array() ) {
|
||||
|
||||
$actually_retrieved = array();
|
||||
foreach ( $live_streams as $vid_id => $live_stream ) {
|
||||
$actually_retrieved[] = $vid_id;
|
||||
$this->video_cache[ $vid_id ] = $live_stream;
|
||||
}
|
||||
|
||||
// If a video ID is attempted to be retrieve but nothing is returned for it
|
||||
// It's likely that it was removed so we should remove it from the cache
|
||||
$no_longer_exist = array_diff( $update_attempted, $actually_retrieved );
|
||||
|
||||
if ( ! empty( $no_longer_exist ) ) {
|
||||
foreach ( $no_longer_exist as $vid_id ) {
|
||||
if ( isset( $this->video_cache[ $vid_id ] ) ) {
|
||||
unset( $this->video_cache[ $vid_id ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Orders videos by schedules start date or actual start date
|
||||
* when available starting with the most recent.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public function sort() {
|
||||
$post_set = $this->video_cache;
|
||||
uasort($post_set, 'sby_scheduled_start_sort' );
|
||||
$this->video_cache = $post_set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save most recent 200 videos in cache.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public function update_cache() {
|
||||
$to_cache = array_slice( $this->video_cache, 0, 200 );
|
||||
|
||||
update_option( $this->cache_name, $to_cache, false );
|
||||
}
|
||||
}
|
||||
109
wp-content/plugins/youtube-feed-pro/inc/Pro/SBY_Parse_Pro.php
Normal file
109
wp-content/plugins/youtube-feed-pro/inc/Pro/SBY_Parse_Pro.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* Class SBY_Parse_Pro
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed\Pro;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\SBY_Parse;
|
||||
|
||||
class SBY_Parse_Pro extends SBY_Parse {
|
||||
|
||||
public static function get_item_avatar( $post, $avatars = array() ) {
|
||||
if ( empty ( $avatars ) ) {
|
||||
return '';
|
||||
} else {
|
||||
$username = SBY_Parse_Pro::get_channel_id( $post );
|
||||
if ( isset( $avatars[ $username ] ) ) {
|
||||
return $avatars[ $username ];
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of posts made by account
|
||||
*
|
||||
* @param $header_data
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public static function get_post_count( $header_data ) {
|
||||
if ( isset( $header_data['data']['counts'] ) ) {
|
||||
return $header_data['data']['counts']['media'];
|
||||
} elseif ( isset( $header_data['counts'] ) ) {
|
||||
return $header_data['counts']['media'];
|
||||
} elseif ( isset( $header_data['media_count'] ) ) {
|
||||
return $header_data['media_count'];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of followers for account
|
||||
*
|
||||
* @param $header_data
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public static function get_follower_count( $header_data ) {
|
||||
if ( isset( $header_data['data']['counts'] ) ) {
|
||||
return $header_data['data']['counts']['followed_by'];
|
||||
} elseif ( isset( $header_data['counts'] ) ) {
|
||||
return $header_data['counts']['followed_by'];
|
||||
} elseif ( isset( $header_data['followers_count'] ) ) {
|
||||
return $header_data['followers_count'];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function get_actual_end_timestamp( $post, $misc_data = array() ) {
|
||||
|
||||
if ( ! empty( $post['liveStreamingDetails']['actualEndTime'] ) ) {
|
||||
$remove_extra = str_replace( array( 'T', '+00:00', '.000Z', '+' ), ' ', $post['liveStreamingDetails']['actualEndTime'] );
|
||||
$timestamp = strtotime( $remove_extra );
|
||||
|
||||
return $timestamp;
|
||||
} elseif ( isset( $misc_data['live_streaming_details'][ SBY_Parse::get_video_id( $post ) ]['sby_actual_end_time'] ) ) {
|
||||
return strtotime( $misc_data['live_streaming_details'][ SBY_Parse::get_video_id( $post ) ]['sby_actual_end_time'] );
|
||||
} elseif ( isset( $misc_data['sby_actual_end_time'][0] ) ) {
|
||||
return strtotime( $misc_data['sby_actual_end_time'][0] );
|
||||
} elseif ( isset( $post['sby_actual_end_time'] ) ) {
|
||||
return strtotime( $post['sby_actual_end_time'] );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get video duration from post
|
||||
*
|
||||
* YouTube provide video duration in ISO 8601 format so we need to convert it to duration
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public static function get_video_duration( $post ) {
|
||||
if ( !isset( $post['contentDetails']['duration'] ) && !isset( $post['snippet']['videoDuration'] ) ) {
|
||||
return;
|
||||
}
|
||||
$duration = isset( $post['contentDetails']['duration'] ) ? $post['contentDetails']['duration'] : $post['snippet']['videoDuration'];
|
||||
$interval = new \DateInterval($duration);
|
||||
$totalSeconds = $interval->s + $interval->i * 60 + $interval->h * 3600;
|
||||
$hours = floor($totalSeconds / 3600);
|
||||
$minutes = floor(($totalSeconds - $hours * 3600) / 60);
|
||||
$seconds = str_pad($totalSeconds % 60, 2, '0', STR_PAD_LEFT);
|
||||
if ( $hours > 0 ) {
|
||||
return "$hours:$minutes:$seconds";
|
||||
} else {
|
||||
return "$minutes:$seconds";
|
||||
}
|
||||
}
|
||||
}
|
||||
81
wp-content/plugins/youtube-feed-pro/inc/Pro/SBY_Search.php
Normal file
81
wp-content/plugins/youtube-feed-pro/inc/Pro/SBY_Search.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
namespace SmashBalloon\YouTubeFeed\Pro;
|
||||
|
||||
class SBY_Search
|
||||
{
|
||||
public function __construct() {
|
||||
add_shortcode( SBY_SEARCH_SLUG, array( $this, 'youtube_video_search' ) );
|
||||
}
|
||||
|
||||
public static function youtube_video_search( $atts ) {
|
||||
global $sby_settings;
|
||||
$atts = is_array( $atts ) ? $atts : array();
|
||||
$input_name = SBY_SEARCH_NAME;
|
||||
$search_term = '';
|
||||
$results = array();
|
||||
$results_title = array();
|
||||
$results_description = array();
|
||||
|
||||
if ( isset( $_GET[ $input_name ] ) ) {
|
||||
$search_term = sanitize_text_field( $_GET[ $input_name ] );
|
||||
|
||||
$args = array(
|
||||
's' => $search_term,
|
||||
);
|
||||
$title_query = new SBY_YT_Query( $args );
|
||||
$results_title = $title_query->get_posts();
|
||||
|
||||
if ( empty( $results_title ) ) {
|
||||
$args = array(
|
||||
'sbys' => $search_term,
|
||||
'sbys_in' => array( 'description' )
|
||||
);
|
||||
$description_query = new SBY_YT_Query( $args );
|
||||
|
||||
$results_description = $description_query->get_posts();
|
||||
}
|
||||
|
||||
wp_reset_postdata();
|
||||
|
||||
$results_raw = array_merge( $results_title, $results_description );
|
||||
|
||||
$results = SBY_Search::remove_duplicates( $results_raw );
|
||||
}
|
||||
|
||||
ob_start();
|
||||
include sby_get_feed_template_part( 'form', $sby_settings );
|
||||
$html = ob_get_contents();
|
||||
ob_get_clean();
|
||||
|
||||
return $html;
|
||||
|
||||
}
|
||||
|
||||
public static function remove_duplicates( $posts ) {
|
||||
$return_posts = array();
|
||||
|
||||
$ids_included = array();
|
||||
foreach ( $posts as $post ) {
|
||||
if ( ! in_array( $post->ID, $ids_included, true ) ) {
|
||||
$ids_included[] = $post->ID;
|
||||
$return_posts[] = $post;
|
||||
}
|
||||
}
|
||||
|
||||
return $return_posts;
|
||||
}
|
||||
|
||||
public static function results_loop( $posts ) {
|
||||
global $sby_settings;
|
||||
foreach ( $posts as $youtube_post ) {
|
||||
$youtube_post_meta = get_post_meta( $youtube_post->ID );
|
||||
|
||||
$api_data = json_decode( $youtube_post_meta['sby_json'][0], true );
|
||||
$settings = $sby_settings;
|
||||
|
||||
include sby_get_feed_template_part( 'result', $sby_settings );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
508
wp-content/plugins/youtube-feed-pro/inc/Pro/SBY_Settings_Pro.php
Normal file
508
wp-content/plugins/youtube-feed-pro/inc/Pro/SBY_Settings_Pro.php
Normal file
@@ -0,0 +1,508 @@
|
||||
<?php
|
||||
namespace SmashBalloon\YouTubeFeed\Pro;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\SBY_Settings;
|
||||
|
||||
class SBY_Settings_Pro extends SBY_Settings {
|
||||
|
||||
protected function after_settings_set() {
|
||||
if ( $this->settings['type'] === 'search'
|
||||
&& $this->settings['sortby'] === 'none' ) {
|
||||
$this->settings['sortby'] = 'relevance';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on the settings related to retrieving post data from the API,
|
||||
* this setting is used to make sure all endpoints needed for the feed are
|
||||
* connected and stored for easily looping through when adding posts
|
||||
*
|
||||
* Overwritten in the Pro version.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function set_feed_type_and_terms() {
|
||||
//global $sby_posts_manager;
|
||||
|
||||
$connected_accounts_in_feed = array();
|
||||
$feed_type_and_terms = array();
|
||||
|
||||
$connected_account = sby_get_first_connected_account();
|
||||
$channel_only = isset( $connected_account['api_key'] ) ? false : true;
|
||||
|
||||
if ( $channel_only ) {
|
||||
|
||||
$updated_hoverinclude = array();
|
||||
if ( \is_array( $this->settings['hoverinclude'] ) ) {
|
||||
foreach ( $this->settings['hoverinclude'] as $hoverinclude ) {
|
||||
if ( ! in_array( $hoverinclude, array( 'views', 'stats', 'countdown' ), true ) ) {
|
||||
$updated_hoverinclude[] = $hoverinclude;
|
||||
}
|
||||
}
|
||||
$this->settings['hoverinclude'] = $updated_hoverinclude;
|
||||
}
|
||||
|
||||
if ( is_array( $this->settings['include'] ) ) {
|
||||
$updated_include = array();
|
||||
foreach ( $this->settings['include'] as $include ) {
|
||||
if ( ! in_array( $include, array( 'views', 'stats', 'countdown' ), true ) ) {
|
||||
$updated_include[] = $include;
|
||||
}
|
||||
}
|
||||
$this->settings['include'] = $updated_include;
|
||||
}
|
||||
|
||||
global $sby_posts_manager;
|
||||
|
||||
$message = '<p><b>' . __( 'Important: No API Key Entered.', 'feeds-for-youtube' ). '</b>';
|
||||
$message .= '<p>'. __( 'Many features are not available without adding an API Key. Please go to the YouTube Feeds settings page to add an API key after following <a href="https://smashballoon.com/youtube-api-key/" target="_blank" rel="noopener">these instructions.</a>', 'feeds-for-youtube' ). '</p>';
|
||||
|
||||
$sby_posts_manager->add_frontend_error( 'no_api_key', $message );
|
||||
}
|
||||
|
||||
if ( ! $channel_only && $this->settings['type'] === 'search' ) {
|
||||
$feed_type_and_terms = array( 'search' => array() );
|
||||
if ( $this->settings['usecustomsearch'] ) {
|
||||
$searches_array = is_array( $this->settings['customsearch'] ) ? $this->settings['customsearch'] : explode( ',', $this->settings['customsearch'] );
|
||||
foreach ( $searches_array as $search ) {
|
||||
$search_slug = trim( preg_replace( "/[^A-Za-z0-9]/", '', $search ) );
|
||||
$feed_type_and_terms['search'][] = array(
|
||||
'term' => $search_slug,
|
||||
'params' => array(
|
||||
'isCustom' => true,
|
||||
'customSearch' => $this->settings['customsearch'],
|
||||
'type' => 'video'
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $search_slug ] = $connected_account;
|
||||
}
|
||||
} elseif ( ! empty( $this->settings['search'] ) ) {
|
||||
$searches_array = is_array( $this->settings['search'] ) ? $this->settings['search'] : explode( ',', $this->settings['search'] );
|
||||
foreach ( $searches_array as $search ) {
|
||||
$search_slug = urlencode( trim( $search ) );
|
||||
$feed_type_and_terms['search'][] = array(
|
||||
'term' => $search_slug,
|
||||
'params' => array(
|
||||
'q' => trim( $search ),
|
||||
'type' => 'video'
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $search_slug ] = $connected_account;
|
||||
}
|
||||
}
|
||||
} elseif ( ! $channel_only && $this->settings['type'] === 'live' ) {
|
||||
$feed_type_and_terms = array( 'live' => array() );
|
||||
|
||||
$raw_term_att = '';
|
||||
if ( ! empty( $this->settings['live'] ) ) {
|
||||
$raw_term_att = $this->settings['live'];
|
||||
} elseif ( ! empty( $this->settings['id'] ) ) {
|
||||
$raw_term_att = $this->settings['id'];
|
||||
} elseif ( ! empty( $this->settings['channel'] ) ) {
|
||||
$raw_term_att = $this->settings['channel'];
|
||||
}
|
||||
|
||||
if ( ! empty( $raw_term_att ) ) {
|
||||
$channels_array = is_array( $raw_term_att ) ? $raw_term_att : explode( ',', $raw_term_att );
|
||||
if ( empty( $this->settings['headerchannel'] ) ) {
|
||||
$this->settings['headerchannel'] = $channels_array[0];
|
||||
}
|
||||
|
||||
foreach ( $channels_array as $channel ) {
|
||||
$feed_type_and_terms['live'][] = array(
|
||||
'term' => $channel.'_live',
|
||||
'params' => array(
|
||||
'channelId' => trim( $channel ),
|
||||
'eventType' => 'live',
|
||||
'type' => 'video'
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel.'_live' ] = $connected_account;
|
||||
}
|
||||
}
|
||||
} elseif ( ! $channel_only && $this->settings['type'] === 'playlist' ) {
|
||||
$this->settings['sortby'] = 'api';
|
||||
$feed_type_and_terms = array( 'playlist' => array() );
|
||||
|
||||
$raw_term_att = '';
|
||||
if ( ! empty( $this->settings['playlist'] ) ) {
|
||||
$raw_term_att = $this->settings['playlist'];
|
||||
} elseif ( ! empty( $this->settings['id'] ) ) {
|
||||
$raw_term_att = $this->settings['id'];
|
||||
}
|
||||
|
||||
if ( ! empty( $raw_term_att ) ) {
|
||||
$playlist_array = is_array( $raw_term_att ) ? $raw_term_att : explode( ',', $raw_term_att );
|
||||
foreach ( $playlist_array as $playlist ) {
|
||||
$feed_type_and_terms['playlist'][] = array(
|
||||
'term' => $playlist,
|
||||
'params' => array(
|
||||
'playlistId' => $playlist,
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $playlist ] = $connected_account;
|
||||
}
|
||||
}
|
||||
} elseif ( ! $channel_only && $this->settings['type'] === 'favorites' ) {
|
||||
$feed_type_and_terms = array( 'favorites' => array() );
|
||||
if ( ! empty( $this->settings['id'] ) ) {
|
||||
$channel_array = is_array( $this->settings['id'] ) ? $this->settings['id'] : explode( ',', str_replace( ' ', '', $this->settings['id'] ) );
|
||||
if ( empty( $this->settings['headerchannel'] ) ) {
|
||||
$this->settings['headerchannel'] = $channel_array[0];
|
||||
}
|
||||
foreach ( $channel_array as $channel ) {
|
||||
if ( isset( $this->connected_accounts[ $channel ] ) ) {
|
||||
$feed_type_and_terms['favorites'][] = array(
|
||||
'term' => $this->connected_accounts[ $channel ]['channel_id'],
|
||||
'params' => array(
|
||||
'channel_id' => $this->connected_accounts[ $channel ]['channel_id']
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $this->connected_accounts[ $channel ]['channel_id'] ] = $this->connected_accounts[ $channel ];
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $connected_accounts_in_feed ) ) {
|
||||
$an_account = array();
|
||||
foreach ( $this->connected_accounts as $account ) {
|
||||
if ( empty( $an_account ) ) {
|
||||
$an_account = $account;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $channel_array as $channel ) {
|
||||
$feed_type_and_terms['channels'][] = array(
|
||||
'term' => $channel,
|
||||
'params' => array(
|
||||
'channel_id' => $channel
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel ] = $an_account;
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ( ! $channel_only && ! empty( $this->settings['favorites'] ) ) {
|
||||
$channel_array = is_array( $this->settings['favorites'] ) ? $this->settings['favorites'] : explode( ',', str_replace( ' ', '', $this->settings['favorites'] ) );
|
||||
|
||||
$an_account = array();
|
||||
foreach ( $this->connected_accounts as $account ) {
|
||||
if ( empty( $an_account ) ) {
|
||||
$an_account = $account;
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $this->settings['headerchannel'] ) ) {
|
||||
$this->settings['headerchannel'] = $channel_array[0];
|
||||
}
|
||||
|
||||
foreach ( $channel_array as $channel ) {
|
||||
if ( strpos( $channel, 'UC' ) !== 0 ) {
|
||||
$channel_id = sby_get_channel_id_from_channel_name( $channel );
|
||||
if ( $channel_id ) {
|
||||
$feed_type_and_terms['favorites'][] = array(
|
||||
'term' => $channel_id,
|
||||
'params' => array(
|
||||
'channel_id' => $channel_id
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel_id ] = $an_account;
|
||||
} else {
|
||||
$feed_type_and_terms['favorites'][] = array(
|
||||
'term' => $channel,
|
||||
'params' => array(
|
||||
'channel_name' => $channel
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel ] = $an_account;
|
||||
}
|
||||
|
||||
} else {
|
||||
$feed_type_and_terms['favorites'][] = array(
|
||||
'term' => $channel,
|
||||
'params' => array(
|
||||
'channel_id' => $channel
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel ] = $an_account;
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ( ! empty( $this->settings['channel'] ) ) {
|
||||
$channel_array = is_array( $this->settings['channel'] ) ? $this->settings['channel'] : explode( ',', str_replace( ' ', '', $this->settings['channel'] ) );
|
||||
|
||||
$an_account = array();
|
||||
foreach ( $this->connected_accounts as $account ) {
|
||||
if ( empty( $an_account ) ) {
|
||||
$an_account = $account;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $channel_array as $channel ) {
|
||||
if ( strpos( $channel, 'UC' ) !== 0 ) {
|
||||
$channel_id = sby_get_channel_id_from_channel_name( $channel );
|
||||
if ( $channel_id ) {
|
||||
$feed_type_and_terms['favorites'][] = array(
|
||||
'term' => $channel_id,
|
||||
'params' => array(
|
||||
'channel_id' => $channel_id
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel_id ] = $an_account;
|
||||
} else {
|
||||
$feed_type_and_terms['favorites'][] = array(
|
||||
'term' => $channel,
|
||||
'params' => array(
|
||||
'channel_name' => $channel
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel ] = $an_account;
|
||||
}
|
||||
|
||||
} else {
|
||||
$feed_type_and_terms['favorites'][] = array(
|
||||
'term' => $channel,
|
||||
'params' => array(
|
||||
'channel_id' => $channel
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel ] = $an_account;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} elseif ( ! $channel_only && $this->settings['type'] === 'single' ) {
|
||||
|
||||
$feed_type_and_terms = array( 'single' => array() );
|
||||
$videos_array = array();
|
||||
if ( ! empty( $this->settings['id'] ) ) {
|
||||
$videos_array = is_array( $this->settings['id'] ) ? $this->settings['id'] : explode( ',', str_replace( ' ', '', $this->settings['id'] ) );
|
||||
} elseif ( ! empty( $this->settings['single'] ) ) {
|
||||
$videos_array = is_array( $this->settings['single'] ) ? $this->settings['single'] : explode( ',', str_replace( ' ', '', $this->settings['single'] ) );
|
||||
}
|
||||
|
||||
$filtered_vids = array();
|
||||
foreach ( $videos_array as $single_video ) {
|
||||
if ( strpos( $single_video, '=' ) === false ) {
|
||||
$filtered_vids[] = $single_video;
|
||||
} else {
|
||||
$exploded = explode( '&', $single_video );
|
||||
$filtered_vids[] = $exploded[0];
|
||||
}
|
||||
}
|
||||
$videos_array = $filtered_vids;
|
||||
|
||||
if ( ! empty( $videos_array ) ) {
|
||||
$feed_type_and_terms['single'][] = array(
|
||||
'term' => implode( '', $videos_array ),
|
||||
'params' => array(
|
||||
'video_ids' => $videos_array
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ implode( '', $videos_array ) ] = $connected_account;
|
||||
}
|
||||
|
||||
} else {
|
||||
$feed_type_and_terms = array( 'channels' => array() );
|
||||
if ( ! empty( $this->settings['id'] ) ) {
|
||||
$channel_array = is_array( $this->settings['id'] ) ? $this->settings['id'] : explode( ',', str_replace( ' ', '', $this->settings['id'] ) );
|
||||
foreach ( $channel_array as $channel ) {
|
||||
if ( isset( $this->connected_accounts[ $channel ] ) ) {
|
||||
$feed_type_and_terms['channels'][] = array(
|
||||
'term' => $this->connected_accounts[ $channel ]['channel_id'],
|
||||
'params' => array(
|
||||
'channel_id' => $this->connected_accounts[ $channel ]['channel_id']
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $this->connected_accounts[ $channel ]['channel_id'] ] = $this->connected_accounts[ $channel ];
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $connected_accounts_in_feed ) ) {
|
||||
$an_account = array();
|
||||
foreach ( $this->connected_accounts as $account ) {
|
||||
if ( empty( $an_account ) ) {
|
||||
$an_account = $account;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $channel_array as $channel ) {
|
||||
$feed_type_and_terms['channels'][] = array(
|
||||
'term' => $channel,
|
||||
'params' => array(
|
||||
'channel_id' => $channel
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel ] = $an_account;
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ( ! empty( $this->settings['channel'] ) ) {
|
||||
$channel_array = is_array( $this->settings['channel'] ) ? $this->settings['channel'] : explode( ',', str_replace( ' ', '', $this->settings['channel'] ) );
|
||||
|
||||
$an_account = array();
|
||||
foreach ( $this->connected_accounts as $account ) {
|
||||
if ( empty( $an_account ) ) {
|
||||
$an_account = $account;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $channel_array as $channel ) {
|
||||
if ( strpos( $channel, 'UC' ) !== 0 ) {
|
||||
$channel_id = sby_get_channel_id_from_channel_name( $channel );
|
||||
if ( $channel_id ) {
|
||||
$feed_type_and_terms['channels'][] = array(
|
||||
'term' => $channel_id,
|
||||
'params' => array(
|
||||
'channel_id' => $channel_id
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel_id ] = $an_account;
|
||||
} else {
|
||||
$feed_type_and_terms['channels'][] = array(
|
||||
'term' => $channel,
|
||||
'params' => array(
|
||||
'channel_name' => $channel
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel ] = $an_account;
|
||||
}
|
||||
|
||||
} else {
|
||||
$feed_type_and_terms['channels'][] = array(
|
||||
'term' => $channel,
|
||||
'params' => array(
|
||||
'channel_id' => $channel
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel ] = $an_account;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
foreach ( $this->connected_accounts as $connected_account ) {
|
||||
if ( empty( $feed_type_and_terms['channels'] ) && is_array($connected_account) ) {
|
||||
$feed_type_and_terms['channels'][] = array(
|
||||
'term' => $connected_account['channel_id'],
|
||||
'params' => array(
|
||||
'channel_id' => $connected_account['channel_id']
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $connected_account['channel_id'] ] = $connected_account;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->connected_accounts_in_feed = $connected_accounts_in_feed;
|
||||
$this->feed_type_and_terms = $feed_type_and_terms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the feed types and terms as well as as some
|
||||
* settings to create a semi-unique feed id used for
|
||||
* caching and other features.
|
||||
*
|
||||
* Overwritten in the Pro version.
|
||||
*
|
||||
* @param string $transient_name
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function set_transient_name( $transient_name = '' ) {
|
||||
|
||||
if ( ! empty( $transient_name ) ) {
|
||||
$this->transient_name = $transient_name;
|
||||
} elseif ( false && ! empty( $this->settings['feedid'] ) ) { //disabled due to new caching system not yet being used
|
||||
$this->transient_name = 'sby_' . $this->settings['feedid'];
|
||||
} else {
|
||||
$feed_type_and_terms = $this->feed_type_and_terms;
|
||||
|
||||
$sby_transient_name = 'sby_';
|
||||
|
||||
$sby_include_words = isset( $this->settings['includewords'] ) ? $this->settings['includewords'] : '';
|
||||
$sby_exclude_words = isset( $this->settings['excludewords'] ) ? $this->settings['excludewords'] : '';
|
||||
$cache_string_include = '';
|
||||
$cache_string_exclude = '';
|
||||
|
||||
//Convert include words array into a string consisting of 3 chars each
|
||||
if ( ! empty( $sby_include_words ) ) {
|
||||
$sby_include_words_arr = explode(',', $sby_include_words);
|
||||
|
||||
foreach( $sby_include_words_arr as $word ){
|
||||
$include_word = str_replace( str_split(' #'), '', $word );
|
||||
$cache_string_include .= substr( str_replace('%','', urlencode( $include_word ) ), 0, 3 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Convert exclude words array into a string consisting of 3 chars each
|
||||
if ( ! empty( $sby_exclude_words ) ) {
|
||||
$sby_exclude_words_arr = explode( ',', $sby_exclude_words );
|
||||
|
||||
foreach( $sby_exclude_words_arr as $word ){
|
||||
$exclude_word = str_replace( str_split( ' #' ) , '', $word );
|
||||
$cache_string_exclude .= substr( str_replace( '%','', urlencode( $exclude_word ) ), 0, 3 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Figure out how long the first part of the caching string should be
|
||||
$cache_string_include_length = strlen( $cache_string_include );
|
||||
$cache_string_exclude_length = strlen( $cache_string_exclude );
|
||||
$cache_string_length = $cache_string_include_length + $cache_string_exclude_length;
|
||||
|
||||
if ( isset( $feed_type_and_terms['channels'] ) ) {
|
||||
foreach ( $feed_type_and_terms['channels'] as $term_and_params ) {
|
||||
$channel = $term_and_params['term'];
|
||||
$sby_transient_name .= $channel;
|
||||
}
|
||||
} elseif ( isset( $feed_type_and_terms['playlist'] ) ) {
|
||||
foreach ( $feed_type_and_terms['playlist'] as $term_and_params ) {
|
||||
$playlist = substr( $term_and_params['term'], 0, 6 );
|
||||
$playlist_end = substr( $term_and_params['term'], -7 );
|
||||
$sby_transient_name .= $playlist . $playlist_end;
|
||||
}
|
||||
} elseif ( isset( $feed_type_and_terms['search'] ) ) {
|
||||
foreach ( $feed_type_and_terms['search'] as $term_and_params ) {
|
||||
$sby_transient_name .= 'Q?';
|
||||
$search = $term_and_params['term'];
|
||||
$length = strlen( $search );
|
||||
$sby_transient_name .= substr( $search, 0, 15 );
|
||||
if ( $length > 15 ) {
|
||||
$sby_transient_name .= substr( $search, -5, 5 );
|
||||
}
|
||||
}
|
||||
} elseif ( isset( $feed_type_and_terms['live'] ) ) {
|
||||
foreach ( $feed_type_and_terms['live'] as $term_and_params ) {
|
||||
$sby_transient_name .= $term_and_params['term'];
|
||||
}
|
||||
} elseif ( isset( $feed_type_and_terms['favorites'] ) ) {
|
||||
foreach ( $feed_type_and_terms['favorites'] as $term_and_params ) {
|
||||
$sby_transient_name .= 'F!';
|
||||
$channel = $term_and_params['term'];
|
||||
$sby_transient_name .= $channel;
|
||||
}
|
||||
} elseif ( isset( $feed_type_and_terms['single'] ) ) {
|
||||
foreach ( $feed_type_and_terms['single'] as $term_and_params ) {
|
||||
$sby_transient_name .= 'S!';
|
||||
$video = $term_and_params['term'];
|
||||
$sby_transient_name .= $video;
|
||||
}
|
||||
}
|
||||
|
||||
$num = $this->settings['num'];
|
||||
|
||||
$num_length = strlen( $num ) + 1;
|
||||
|
||||
//Add both parts of the caching string together and make sure it doesn't exceed 45
|
||||
$sby_transient_name = substr( $sby_transient_name, 0, 45 - $num_length - $cache_string_length ) . $cache_string_include . $cache_string_exclude;
|
||||
|
||||
$sby_transient_name .= '#' . $num;
|
||||
|
||||
$this->transient_name = $sby_transient_name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
namespace SmashBalloon\YouTubeFeed\Pro;
|
||||
|
||||
class SBY_YT_Details_Query
|
||||
{
|
||||
private $vid_details;
|
||||
|
||||
private $vid_ids;
|
||||
|
||||
private $cache_expiration_time;
|
||||
|
||||
public function __construct( $args, $settings = array() ) {
|
||||
|
||||
if ( isset( $args['video_ids'] ) ) {
|
||||
if ( is_array( $args['video_ids'] ) ) {
|
||||
$this->vid_ids = $args['video_ids'];
|
||||
} else {
|
||||
$this->vid_ids = explode( ',', $args['video_ids'] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $settings['details_cache_time'] ) ) {
|
||||
$this->cache_expiration_time = $settings['details_cache_time'];
|
||||
} else {
|
||||
$this->cache_expiration_time = 60 * 2;
|
||||
}
|
||||
|
||||
$this->vid_details = $this->get_cached_details_for_posts();
|
||||
}
|
||||
|
||||
public function get_video_details_to_update() {
|
||||
$vids_to_retrieve = array();
|
||||
$first_connected = sby_get_first_connected_account();
|
||||
|
||||
if ( ! isset( $first_connected['api_key'] ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$params = array();
|
||||
$parts = array( 'id', 'statistics' );
|
||||
foreach ( $this->vid_details as $video ) {
|
||||
if ( ! isset( $video['sby_last_details_check_time'] )
|
||||
|| strtotime( $video['sby_last_details_check_time'] ) < (time() - $this->cache_expiration_time) ) {
|
||||
if ( $video['sby_description'] === null
|
||||
|| substr( $video['sby_description'], -3 ) === '...' ) {
|
||||
if ( ! in_array( 'snippet', $parts, true ) ) {
|
||||
$parts[] = 'snippet';
|
||||
}
|
||||
}
|
||||
$live_broadcast_content = SBY_Parse_Pro::get_live_broadcast_content( $video );
|
||||
if ( ! empty( $live_broadcast_content )
|
||||
&& $live_broadcast_content === 'upcoming' || $live_broadcast_content === 'live' || $live_broadcast_content === 'completed' ) {
|
||||
if ( ! in_array( 'liveStreamingDetails', $parts, true ) ) {
|
||||
$parts[] = 'liveStreamingDetails';
|
||||
}
|
||||
}
|
||||
$vids_to_retrieve[] = $video['sby_video_id'];
|
||||
}
|
||||
}
|
||||
$params['part'] = $parts;
|
||||
|
||||
if ( ! empty( $vids_to_retrieve ) ) {
|
||||
$params['id'] = implode( ',', $vids_to_retrieve );
|
||||
$video_data_connection = new SBY_API_Connect_Pro( $first_connected, 'videos', $params );
|
||||
$video_data_connection->connect();
|
||||
|
||||
$data = $video_data_connection->get_data();
|
||||
|
||||
if ( isset( $data['items'] ) ) {
|
||||
return $data['items'];
|
||||
}
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function get_cached_details_for_posts() {
|
||||
global $wpdb;
|
||||
|
||||
$in_clause = "";
|
||||
foreach ( $this->vid_ids as $id ) {
|
||||
$in_clause .= "'" . esc_sql( $id ) . "',";
|
||||
}
|
||||
$in_clause = substr( $in_clause, 0, -1 );
|
||||
|
||||
$vid_details = $wpdb->get_results( "
|
||||
SELECT Max(CASE
|
||||
WHEN m.meta_key = 'sby_video_id' THEN m.meta_value
|
||||
ELSE NULL
|
||||
END) AS sby_video_id,
|
||||
Max(CASE
|
||||
WHEN m.meta_key = 'sby_last_details_check_time' THEN m.meta_value
|
||||
ELSE NULL
|
||||
END) AS sby_last_details_check_time,
|
||||
Max(CASE
|
||||
WHEN m.meta_key = 'sby_description' THEN m.meta_value
|
||||
ELSE NULL
|
||||
END) AS sby_description,
|
||||
Max(CASE
|
||||
WHEN m.meta_key = 'sby_comment_count' THEN m.meta_value
|
||||
ELSE NULL
|
||||
END) AS sby_comment_count,
|
||||
Max(CASE
|
||||
WHEN m.meta_key = 'sby_like_count' THEN m.meta_value
|
||||
ELSE NULL
|
||||
END) AS sby_like_count,
|
||||
Max(CASE
|
||||
WHEN m.meta_key = 'sby_view_count' THEN m.meta_value
|
||||
ELSE NULL
|
||||
END) AS sby_view_count,
|
||||
Max(CASE
|
||||
WHEN m.meta_key = 'sby_live_broadcast_content' THEN m.meta_value
|
||||
ELSE NULL
|
||||
END) AS sby_live_broadcast_content,
|
||||
Max(CASE
|
||||
WHEN m.meta_key = 'sby_actual_start_time' THEN m.meta_value
|
||||
ELSE NULL
|
||||
END) AS sby_actual_start_time,
|
||||
Max(CASE
|
||||
WHEN m.meta_key = 'sby_actual_end_time' THEN m.meta_value
|
||||
ELSE NULL
|
||||
END) AS sby_actual_end_time,
|
||||
Max(CASE
|
||||
WHEN m.meta_key = 'sby_scheduled_start_time' THEN m.meta_value
|
||||
ELSE NULL
|
||||
END) AS sby_scheduled_start_time,
|
||||
m.post_id
|
||||
FROM $wpdb->postmeta as m
|
||||
WHERE m.post_id IN (SELECT m2.post_id FROM $wpdb->postmeta as m2 WHERE m2.meta_key = 'sby_video_id' AND m2.meta_value IN ( $in_clause ))
|
||||
GROUP BY m.post_id", ARRAY_A );
|
||||
|
||||
return $vid_details;
|
||||
}
|
||||
}
|
||||
80
wp-content/plugins/youtube-feed-pro/inc/Pro/SBY_YT_Query.php
Normal file
80
wp-content/plugins/youtube-feed-pro/inc/Pro/SBY_YT_Query.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
namespace SmashBalloon\YouTubeFeed\Pro;
|
||||
|
||||
class SBY_YT_Query
|
||||
{
|
||||
private $posts;
|
||||
|
||||
private $sby_youtube_posts_obj;
|
||||
|
||||
public function __construct( $args ) {
|
||||
|
||||
$args['post_type'] = SBY_CPT;
|
||||
|
||||
if ( isset( $args['channel_title'] ) ) {
|
||||
$args['meta_query'][] = array(
|
||||
'value' => $args['channel_title'],
|
||||
'key' => 'sby_channel_title'
|
||||
);
|
||||
} elseif ( isset( $args['channel_id'] ) ) {
|
||||
$args['meta_query'][] = array(
|
||||
'value' => $args['channel_id'],
|
||||
'key' => 'sby_channel_id'
|
||||
);
|
||||
} elseif ( isset( $args['video_id'] ) ) {
|
||||
$args['meta_query'][] = array(
|
||||
'value' => $args['video_id'],
|
||||
'key' => 'sby_video_id'
|
||||
);
|
||||
} elseif ( isset( $args['sbys'] ) ) {
|
||||
$search_in = isset( $args['sbys_in'] ) ? $args['sbys_in'] : array( 'description' );
|
||||
foreach ( $search_in as $meta_key ) {
|
||||
if ( $meta_key !== 'title' ) {
|
||||
$args['meta_query'][] = array(
|
||||
'value' => $args['sbys'],
|
||||
'key' => 'sby_' . $meta_key,
|
||||
'compare' => 'LIKE'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sby_posts = new \WP_Query( $args );
|
||||
|
||||
$this->sby_youtube_posts_obj = $sby_posts;
|
||||
|
||||
if ( $sby_posts->have_posts() ) {
|
||||
$this->posts = $sby_posts->posts;
|
||||
} else {
|
||||
$this->posts = array();
|
||||
}
|
||||
}
|
||||
|
||||
public function get_posts() {
|
||||
return $this->posts;
|
||||
}
|
||||
|
||||
public static function get_unique_channel_titles() {
|
||||
global $wpdb;
|
||||
|
||||
$unique_channels = $wpdb->get_col( "
|
||||
SELECT m.meta_value
|
||||
FROM $wpdb->postmeta as m
|
||||
WHERE m.meta_key = 'sby_channel_title'
|
||||
GROUP BY m.meta_value" );
|
||||
|
||||
return $unique_channels;
|
||||
}
|
||||
|
||||
public static function get_unique_channel_ids() {
|
||||
global $wpdb;
|
||||
|
||||
$unique_channels = $wpdb->get_col( "
|
||||
SELECT m.meta_value
|
||||
FROM $wpdb->postmeta as m
|
||||
WHERE m.meta_key = 'sby_channel_id'
|
||||
GROUP BY m.meta_value" );
|
||||
|
||||
return $unique_channels;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* AdminAjaxServicePro
|
||||
*
|
||||
* @since 2.3.3
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Pro\Services;
|
||||
|
||||
use Smashballoon\Stubs\Services\ServiceProvider;
|
||||
use SmashBalloon\YouTubeFeed\Pro\SBY_API_Connect_Pro;
|
||||
use SmashBalloon\YouTubeFeed\Pro\SBY_Settings_Pro;
|
||||
|
||||
class AdminAjaxServicePro extends ServiceProvider {
|
||||
|
||||
public function register() {
|
||||
add_action('wp_ajax_sby_get_comments', [$this, 'sby_get_comments']);
|
||||
add_action('wp_ajax_nopriv_sby_get_comments', [$this, 'sby_get_comments']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves comments for a specific video.
|
||||
* @return void
|
||||
* @since 2.3.3
|
||||
*/
|
||||
public function sby_get_comments()
|
||||
{
|
||||
$video_id = !empty($_POST['video_id']) ? $_POST['video_id'] : '';
|
||||
|
||||
if (empty($video_id)) {
|
||||
wp_send_json_error('Error: Video ID is invalid');
|
||||
}
|
||||
|
||||
$atts = isset($_POST['atts']) ? json_decode(stripslashes($_POST['atts']), true) : null;
|
||||
if (is_array($atts)) {
|
||||
array_map('sanitize_text_field', $atts);
|
||||
} else {
|
||||
$atts = array();
|
||||
}
|
||||
|
||||
$database_settings = sby_get_database_settings();
|
||||
$youtube_feed_settings = new SBY_Settings_Pro($atts, $database_settings);
|
||||
|
||||
|
||||
if (empty($database_settings['connected_accounts']) && empty($database_settings['api_key'])) {
|
||||
wp_send_json_error('Error: No connected account');
|
||||
}
|
||||
|
||||
$video_id = sanitize_text_field($_POST['video_id']);
|
||||
|
||||
$settings = $youtube_feed_settings->get_settings();
|
||||
|
||||
$comment_count = isset($settings['numcomments']) ? $settings['numcomments'] : 5;
|
||||
$enable_comments = isset($settings['enablecomments']) ? (bool)$settings['enablecomments'] : false;
|
||||
|
||||
if (!empty($video_id) && true === $enable_comments) {
|
||||
|
||||
$get_cache = get_transient('sby_comment_cache');
|
||||
|
||||
$cache = json_decode($get_cache);
|
||||
|
||||
if (!isset($cache->$video_id->etag) ) {
|
||||
|
||||
$params = array(
|
||||
'num' => (int) $comment_count,
|
||||
'video_id' => $video_id
|
||||
);
|
||||
|
||||
$connection = new SBY_API_Connect_Pro(sby_get_first_connected_account(), 'comments', $params);
|
||||
$connection->connect();
|
||||
|
||||
$comment_data = array(
|
||||
$video_id => $connection->get_data()
|
||||
);
|
||||
|
||||
$current_set_cache = $comment_data;
|
||||
|
||||
if ($cache) {
|
||||
$cache->$video_id = $comment_data[$video_id];
|
||||
$current_set_cache = $cache;
|
||||
}
|
||||
|
||||
set_transient('sby_comment_cache', json_encode($current_set_cache));
|
||||
}
|
||||
|
||||
$updated_cache = get_transient('sby_comment_cache');
|
||||
|
||||
if (!empty($updated_cache)) {
|
||||
$cache = json_decode(get_transient('sby_comment_cache'));
|
||||
echo wp_json_encode($cache->$video_id);
|
||||
}
|
||||
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Pro\Services;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\Services\ServiceContainer;
|
||||
use SmashBalloon\YouTubeFeed\Pro\Services\AdminAjaxServicePro;
|
||||
|
||||
class ServiceContainerPro extends ServiceContainer
|
||||
{
|
||||
|
||||
protected $services = [
|
||||
AdminAjaxServicePro::class,
|
||||
];
|
||||
}
|
||||
44
wp-content/plugins/youtube-feed-pro/inc/Response.php
Normal file
44
wp-content/plugins/youtube-feed-pro/inc/Response.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Response
|
||||
*
|
||||
* Sends back ajax response to client end
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
|
||||
class Response {
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
private $is_success;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $data;
|
||||
/**
|
||||
* Response constructor.
|
||||
*
|
||||
* @param $is_success
|
||||
* @param $data
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct( $is_success, $data ) {
|
||||
$this->is_success = $is_success;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send JSON response
|
||||
*/
|
||||
public function send() {
|
||||
if ( $this->is_success ) {
|
||||
wp_send_json_success( $this->data );
|
||||
}
|
||||
wp_send_json_error( $this->data );
|
||||
}
|
||||
}
|
||||
287
wp-content/plugins/youtube-feed-pro/inc/SBY_API_Connect.php
Normal file
287
wp-content/plugins/youtube-feed-pro/inc/SBY_API_Connect.php
Normal file
@@ -0,0 +1,287 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
class SBY_API_Connect
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* @var object
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $args;
|
||||
|
||||
public function __construct( $connected_account_or_url = '', $endpoint = '', $params = array() ) {
|
||||
if ( is_array( $connected_account_or_url ) && isset( $connected_account_or_url['access_token'] ) ) {
|
||||
$this->set_url( $connected_account_or_url, $endpoint, $params );
|
||||
} elseif ( is_array( $connected_account_or_url ) ) {
|
||||
$this->set_url( $connected_account_or_url, $endpoint, $params );
|
||||
} elseif ( strpos( $connected_account_or_url, 'https' ) !== false ) {
|
||||
$this->url = $connected_account_or_url;
|
||||
} else {
|
||||
$this->url = '';
|
||||
}
|
||||
$this->set_args();
|
||||
}
|
||||
|
||||
public function get_data() {
|
||||
if (!is_wp_error($this->response) && !empty($this->response['data'])) {
|
||||
return $this->response['data'];
|
||||
} else {
|
||||
return $this->response;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_wp_error() {
|
||||
if ( $this->is_wp_error() ) {
|
||||
return array( 'response' => $this->response, 'url' => $this->url );
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_next_page( $params = false ) {
|
||||
if ( ! empty( $this->response['nextPageToken'] ) ) {
|
||||
return $this->response['nextPageToken'];
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function set_url_from_args( $url ) {
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
public function set_args( $args = array() ) {
|
||||
if ( empty( $args ) ) {
|
||||
$this->args = array(
|
||||
'timeout' => 60,
|
||||
'headers' => array(
|
||||
'referer' => home_url()
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->args = $args;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_url() {
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function get_args() {
|
||||
return $this->args;
|
||||
}
|
||||
|
||||
public function is_wp_error() {
|
||||
return is_wp_error( $this->response );
|
||||
}
|
||||
|
||||
|
||||
public function is_youtube_error() {
|
||||
return (is_wp_error( $this->response ) || isset( $this->response['error'] ));
|
||||
}
|
||||
|
||||
public function connect() {
|
||||
$response = wp_remote_get( esc_url_raw( $this->url ), $this->get_args() );
|
||||
|
||||
if ( ! is_wp_error( $response ) ) {
|
||||
// certain ways of representing the html for double quotes causes errors so replaced here.
|
||||
$response = json_decode( str_replace( '%22', '”', $response['body'] ), true );
|
||||
}
|
||||
|
||||
$this->response = $response;
|
||||
}
|
||||
|
||||
public static function handle_youtube_error( $response, $error_connected_account, $request_type = '' ) {
|
||||
//
|
||||
if ( isset( $response['error'] ) ) {
|
||||
if ( isset( $response['error']['errors'][0]['reason'] ) && $response['error']['errors'][0]['message'] === 'Invalid Credentials' ) {
|
||||
$error_message = '<p><b>' . __( 'Reconnect to YouTube to show this feed.', 'feeds-for-youtube' ) . '</b></p>';
|
||||
$error_message .= '<p>' . __( 'To create a new feed, first connect to YouTube using the "Connect to YouTube to Create a Feed" button on the settings page and connect any account.', 'feeds-for-youtube' ) . '</p>';
|
||||
|
||||
if ( current_user_can( 'manage_youtube_feed_options' ) ) {
|
||||
$error_message .= '<a href="' . admin_url( 'admin.php?page=youtube-feed-settings' ) . '" target="blank" rel="noopener nofollow">' . __( 'Reconnect in the YouTube Feeds Settings Area', 'feeds-for-youtube' ) . '</a>';
|
||||
}
|
||||
global $sby_posts_manager;
|
||||
|
||||
$sby_posts_manager->add_frontend_error( 'accesstoken', $error_message );
|
||||
$sby_posts_manager->add_error( 'accesstoken', array( 'Trying to connect a new account', $error_message ) );
|
||||
|
||||
return false;
|
||||
} elseif ( isset( $response['error']['errors'][0]['reason'] ) ) {
|
||||
$error = $response['error']['errors'][0]['message'];
|
||||
|
||||
$error_message = '<p><b>'. sprintf( __( 'Error %s: %s.', 'feeds-for-youtube' ), $response['error']['code'], $error ) .'</b></p>';
|
||||
$error_message .= '<p>Domain code: ' . $response['error']['errors'][0]['domain'];
|
||||
$error_message .= '<br>Reason code: ' . $response['error']['errors'][0]['reason'];
|
||||
if ( current_user_can( 'manage_youtube_feed_options' ) ) {
|
||||
if ( isset( $response['error']['errors'][0]['extendedHelp'] ) ) {
|
||||
$error_message .= '<br>Extended Help Link: ' . $response['error']['errors'][0]['extendedHelp'];
|
||||
}
|
||||
$error_message .= '</p>';
|
||||
|
||||
$error_message .= '<a href="https://smashballoon.com/youtube-feed/docs/errors/" target="blank" rel="noopener nofollow">' . __( 'Directions on how to resolve this issue', 'feeds-for-youtube' ) . '</a>';
|
||||
} else {
|
||||
$error_message .= '</p>';
|
||||
}
|
||||
|
||||
global $sby_posts_manager;
|
||||
|
||||
$sby_posts_manager->add_frontend_error( 'api', $error_message );
|
||||
$sby_posts_manager->add_error( 'api', array( 'Error connecting', $error_message ) );
|
||||
|
||||
$sby_posts_manager->add_api_request_delay( 300 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function handle_wp_remote_get_error( $response ) {
|
||||
$response_array = array();
|
||||
if ( is_wp_error( $response ) ) {
|
||||
$response_array = array(
|
||||
'url' => '',
|
||||
'response' => $response
|
||||
);
|
||||
} else {
|
||||
$response_array = $response;
|
||||
}
|
||||
|
||||
$message = sprintf( __( 'Error connecting to %s.', 'feeds-for-youtube' ), $response_array['url'] ). ' ';
|
||||
if ( isset( $response_array['response'] ) && isset( $response_array['response']->errors ) ) {
|
||||
foreach ( $response_array['response']->errors as $key => $item ) {
|
||||
$message .= ' '.$key . ' - ' . $item[0] . ' |';
|
||||
}
|
||||
}
|
||||
|
||||
global $sby_posts_manager;
|
||||
|
||||
$sby_posts_manager->add_api_request_delay( 300 );
|
||||
|
||||
$sby_posts_manager->add_error( 'connection', array( 'Error connecting', $message ) );
|
||||
}
|
||||
|
||||
protected function formatted_param_string( $params ) {
|
||||
$param_string= '';
|
||||
foreach ( $params as $param => $value ) {
|
||||
if ( $param !== 'part' && $param !== 'num' ) {
|
||||
$param_string .= '&' . $param . '=' . $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $param_string;
|
||||
}
|
||||
|
||||
protected function formatted_part_param_string( $part ) {
|
||||
if ( is_array( $part ) ) {
|
||||
return implode(',', str_replace( ' ', '', $part ) );
|
||||
}
|
||||
return str_replace( ' ', '', $part );
|
||||
}
|
||||
|
||||
public function set_url( $connected_account, $endpoint_slug, $params = [], $api_key = null ) {
|
||||
$num = ! empty( $params['num'] ) ? (int)$params['num'] : 50;
|
||||
|
||||
if ( empty( $connected_account ) && ! empty( $api_key ) ) {
|
||||
$connected_account = array(
|
||||
'api_key' => $api_key
|
||||
);
|
||||
}
|
||||
|
||||
$access_credentials = isset( $connected_account['api_key'] ) ? 'key=' . $connected_account['api_key'] : 'access_token=' . $connected_account['access_token'];
|
||||
$next_page = '';
|
||||
if ( isset( $params['nextPageToken'] ) && ! is_array( $params['nextPageToken'] ) ) {
|
||||
$next_page = '&pageToken=' . $params['nextPageToken'];
|
||||
}
|
||||
|
||||
if ( $endpoint_slug === 'tokeninfo' ) {
|
||||
$url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=' . $connected_account['access_token'];
|
||||
} elseif ( $endpoint_slug === 'channels' ) {
|
||||
$channel_param = 'mine=true';
|
||||
if ( isset( $params['channel_name'] ) ) {
|
||||
$channel_param = 'forUsername=' . $params['channel_name'];
|
||||
} elseif ( !empty( $params['channel_handle'] ) ){
|
||||
$channel_param = 'forHandle=' . $params['channel_handle'];
|
||||
} elseif ( isset( $params['channel_id'] ) ) {
|
||||
$channel_param = 'id=' . $params['channel_id'];
|
||||
}
|
||||
|
||||
$url = 'https://www.googleapis.com/youtube/v3/channels?part=id,snippet,statistics,contentDetails&'.$channel_param.'&' . $access_credentials . $next_page;
|
||||
} elseif ( $endpoint_slug === 'live' ) {
|
||||
$url = 'iframe_'.$params['channelId'];
|
||||
} elseif ( $endpoint_slug === 'search' ) {
|
||||
$part = 'snippet';
|
||||
if ( isset( $params['part'] ) ) {
|
||||
$part = $this->formatted_part_param_string( $params['part'] );
|
||||
}
|
||||
if ( ! isset( $params['isCustom'] ) ) {
|
||||
if ( isset( $params['eventType'] ) && $params['eventType'] === 'upcoming' ) {
|
||||
$num = 50; // get max videos so we can reverse sort them to show soonest playing live streams first, default order is by publish date
|
||||
}
|
||||
$params_string = $this->formatted_param_string( $params );
|
||||
|
||||
} else {
|
||||
$params_string = $params['customSearch'];
|
||||
|
||||
if ( isset( $params['nextPageToken'] ) ) {
|
||||
$params_string .= '&pageToken=' . $params['nextPageToken'];
|
||||
}
|
||||
}
|
||||
$num = max( 10, $num );
|
||||
|
||||
$query_var_string= 'type=video&part='.$part.'&maxResults=' . $num . $params_string;
|
||||
|
||||
$url = 'https://www.googleapis.com/youtube/v3/search?'.$query_var_string.'&'.$access_credentials.$next_page;
|
||||
} elseif ( $endpoint_slug === 'playlistItems' ) {
|
||||
$url = 'https://www.googleapis.com/youtube/v3/playlistItems?part=id,snippet,contentDetails,status&maxResults='.$num.'&playlistId='.$params['playlist_id'].'&' . $access_credentials.$next_page;
|
||||
} elseif ( $endpoint_slug === 'single' ) {
|
||||
$part = 'id,statistics,snippet,liveStreamingDetails';
|
||||
|
||||
$vid_ids = empty( $params['nextPageToken'] ) ? $params['video_ids'] : $params['nextPageToken'];
|
||||
$vid_ids = array_slice( $vid_ids, 0, SBY_MAX_SINGLE_PAGE );
|
||||
$vid_id_string = implode( ',', $vid_ids );
|
||||
|
||||
$url = 'https://www.googleapis.com/youtube/v3/videos?part='.$part.'&id='.$vid_id_string.'&maxResults=50&' . $access_credentials;
|
||||
|
||||
} elseif ( $endpoint_slug === 'videos' ) {
|
||||
$params_string = $this->formatted_param_string( $params );
|
||||
$part = 'id,statistics';
|
||||
if ( isset( $params['part'] ) ) {
|
||||
$part = $this->formatted_part_param_string( $params['part'] );
|
||||
}
|
||||
|
||||
$url = 'https://www.googleapis.com/youtube/v3/videos?part='.$part.$params_string.'&maxResults='.$num.'&' . $access_credentials;
|
||||
} else {
|
||||
$channel_param = 'mine=true';
|
||||
if ( isset( $params['username'] ) ) {
|
||||
$channel_param = 'forUsername=' . $params['username'];
|
||||
} elseif ( isset( $params['channel_id'] ) ) {
|
||||
$channel_param = 'id=' . $params['channel_id'];
|
||||
}
|
||||
|
||||
$url = 'https://www.googleapis.com/youtube/v3/channels?part=id,snippet&'.$channel_param.'&' . $access_credentials.$next_page;
|
||||
}
|
||||
|
||||
$this->set_url_from_args( $url );
|
||||
}
|
||||
|
||||
public static function refresh_token( $client_id, $refresh_token, $client_secret ) {
|
||||
$response = wp_remote_post( 'https://www.googleapis.com/oauth2/v4/token/?client_id=' . $client_id . '&client_secret=' . $client_secret . '&refresh_token='. $refresh_token . '&grant_type=refresh_token' );
|
||||
|
||||
if ( $response['response']['code'] === 200 ) {
|
||||
$return = json_decode( $response['body'], true );
|
||||
} else {
|
||||
$return = array();
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
}
|
||||
251
wp-content/plugins/youtube-feed-pro/inc/SBY_Cache.php
Normal file
251
wp-content/plugins/youtube-feed-pro/inc/SBY_Cache.php
Normal file
@@ -0,0 +1,251 @@
|
||||
<?php
|
||||
/**
|
||||
* YouTube Feeds Cache
|
||||
*
|
||||
* For the new feed builder
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
|
||||
class SBY_Cache {
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $feed_id;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $page;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $suffix;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $is_legacy;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $cache_time;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $posts;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $posts_page;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $is_expired;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $header;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $resized_images;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $meta;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $posts_backup;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $header_backup;
|
||||
|
||||
/**
|
||||
* @var object|SB_Instagram_Data_Encryption
|
||||
*/
|
||||
protected $encryption;
|
||||
|
||||
/**
|
||||
* SBY_Cache constructor. Set the feed id, cache key, legacy
|
||||
*
|
||||
* @param string $feed_id
|
||||
* @param int $page
|
||||
* @param int $cache_time
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __construct( $feed_id, $page = 1, $cache_time = 0 ) {
|
||||
$this->cache_time = (int) $cache_time;
|
||||
$this->is_legacy = strpos( $feed_id, '*' ) !== 0;
|
||||
$this->page = $page;
|
||||
|
||||
if ( $this->page === 1 ) {
|
||||
$this->suffix = '';
|
||||
} else {
|
||||
$this->suffix = '_' . $this->page;
|
||||
}
|
||||
|
||||
$this->feed_id = str_replace( '*', '', $feed_id );
|
||||
|
||||
if ( is_admin() ) {
|
||||
$this->feed_id .= $this->maybe_customizer_suffix();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add suffix to cache keys used in the customizer
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
private function maybe_customizer_suffix() {
|
||||
$additional_suffix = '';
|
||||
$in_customizer = ! empty( $_POST['previewSettings'] ) || ( isset( $_GET['page'] ) && $_GET['page'] === 'sby-feed-builder' );
|
||||
if ( $in_customizer ) {
|
||||
$additional_suffix .= '_CUSTOMIZER';
|
||||
|
||||
if ( ! empty( $_POST['moderationShoppableMode'] ) ) {
|
||||
$additional_suffix .= '_MODMODE';
|
||||
$offset = ! empty( $_POST['moderationShoppableModeOffset'] ) ? intval( $_POST['moderationShoppableModeOffset'] ) : '';
|
||||
$additional_suffix .= $offset;
|
||||
}
|
||||
}
|
||||
|
||||
return $additional_suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets caches after they expire
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return bool|false|int
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function clear( $type ) {
|
||||
$this->clear_wp_cache();
|
||||
|
||||
global $wpdb;
|
||||
$cache_table_name = $wpdb->prefix . 'sby_feed_caches';
|
||||
|
||||
$feed_id = str_replace( array( '_CUSTOMIZER', '_CUSTOMIZER_MODMODE' ), '', $this->feed_id );
|
||||
|
||||
if ( $type === 'all' ) {
|
||||
$affected = $wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"UPDATE $cache_table_name
|
||||
SET cache_value = ''
|
||||
WHERE feed_id = %s
|
||||
AND cache_key NOT IN ( 'posts', 'posts_backup', 'header_backup' );",
|
||||
$feed_id
|
||||
)
|
||||
);
|
||||
|
||||
$affected = $wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"UPDATE $cache_table_name
|
||||
SET cache_value = ''
|
||||
WHERE feed_id = %s",
|
||||
$feed_id . '_CUSTOMIZER'
|
||||
)
|
||||
);
|
||||
|
||||
$mod_mode_where = esc_sql( $feed_id ) . '_CUSTOMIZER_MODMODE%';
|
||||
$affected = $wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"UPDATE $cache_table_name
|
||||
SET cache_value = ''
|
||||
WHERE feed_id like %s",
|
||||
$mod_mode_where
|
||||
)
|
||||
);
|
||||
} else {
|
||||
|
||||
$data = array( 'cache_value' => '' );
|
||||
$format = array( '%s' );
|
||||
|
||||
$where['feed_id'] = $feed_id;
|
||||
$where_format[] = '%s';
|
||||
|
||||
$where['cache_key'] = $type . $this->suffix;
|
||||
$where_format[] = '%s';
|
||||
|
||||
$affected = $wpdb->update( $cache_table_name, $data, $where, $format, $where_format );
|
||||
|
||||
$where['feed_id'] = $feed_id . '_CUSTOMIZER';
|
||||
|
||||
$affected = $wpdb->update( $cache_table_name, $data, $where, $format, $where_format );
|
||||
|
||||
$where['feed_id'] = $feed_id . '_CUSTOMIZER_MODMODE';
|
||||
|
||||
$affected = $wpdb->update( $cache_table_name, $data, $where, $format, $where_format );
|
||||
}
|
||||
|
||||
return $affected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active/all cache count.
|
||||
*
|
||||
* @param bool $active when set to true only items updated in the last months are returned.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_cache_count($active = false) {
|
||||
global $wpdb;
|
||||
$cache_table_name = $wpdb->prefix . 'sby_feed_caches';
|
||||
$query = "SELECT COUNT(DISTINCT feed_id, cache_key) as cache_count FROM $cache_table_name WHERE feed_id Not Like '%_CUSTOMIZER%'";
|
||||
|
||||
if($active === true) {
|
||||
$query .= " AND feed_id Not Like '%_MODMODE%' AND last_updated >= DATE_SUB(NOW(), INTERVAL 1 MONTH)";
|
||||
}
|
||||
|
||||
$sql = $wpdb->prepare($query);
|
||||
$caches = $wpdb->get_results( $sql );
|
||||
|
||||
if(!empty($caches)) {
|
||||
return $caches[0]->cache_count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the wp_cache
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
private function clear_wp_cache() {
|
||||
wp_cache_delete( $this->get_wp_cache_key() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Key used to get the wp cache key
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
private function get_wp_cache_key() {
|
||||
return 'sby_feed_' . $this->feed_id . '_' . $this->page;
|
||||
}
|
||||
}
|
||||
204
wp-content/plugins/youtube-feed-pro/inc/SBY_Cron_Updater.php
Normal file
204
wp-content/plugins/youtube-feed-pro/inc/SBY_Cron_Updater.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
/**
|
||||
* Class SBY_Cron_Updater
|
||||
*
|
||||
* Finds all regular feed transients saved in the database and updates
|
||||
* each cached feed in the background using WP Cron. This is set up with the
|
||||
* "sby_cron_updater" function in the if-functions.php file. The "display_instagram"
|
||||
* function will trigger a single feed update if no transient is found
|
||||
* for the feed
|
||||
*
|
||||
* @since 1.0/1.0
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
use SmashBalloon\YouTubeFeed\Services\AdminAjaxService;
|
||||
|
||||
class SBY_Cron_Updater
|
||||
{
|
||||
/**
|
||||
* Find and loop through all feed cache transients and update the post and
|
||||
* header caches
|
||||
*
|
||||
* Overwritten in the Pro version
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function do_feed_updates() {
|
||||
$feed_caches = SBY_Cron_Updater::get_feed_cache_option_names();
|
||||
shuffle( $feed_caches );
|
||||
$database_settings = sby_get_database_settings();
|
||||
|
||||
// this is outputted in system info
|
||||
$report = array(
|
||||
'notes' => array(
|
||||
'time_ran' => date( 'Y-m-d H:i:s' ),
|
||||
'num_found_transients' => count( $feed_caches )
|
||||
)
|
||||
);
|
||||
|
||||
foreach ( $feed_caches as $feed_cache ) {
|
||||
|
||||
$feed_id = str_replace( '_transient_', '', $feed_cache['option_name'] );
|
||||
$report[ $feed_id ] = array();
|
||||
|
||||
$transient = get_transient( $feed_id );
|
||||
|
||||
if ( $transient ) {
|
||||
$feed_data = json_decode( $transient, true );
|
||||
|
||||
// shortcode attributes are saved in order to recreate the feed is needed
|
||||
$atts = isset( $feed_data['atts'] ) ? $feed_data['atts'] : array();
|
||||
$last_retrieve = isset( $feed_data['last_retrieve'] ) ? (int)$feed_data['last_retrieve'] : 0;
|
||||
// the last approximate time the feed was requested to be displayed on a page is recorded
|
||||
// in order to stop updating feeds not in use.
|
||||
$last_requested = isset( $feed_data['last_requested'] ) ? (int)$feed_data['last_requested'] : false;
|
||||
$report[ $feed_id ]['last_retrieve'] = date( 'Y-m-d H:i:s', $last_retrieve );
|
||||
if ( $atts !== false ) {
|
||||
|
||||
if ( ! $last_requested || $last_requested > (time() - 60*60*24*30) ) {
|
||||
$sby_settings_obj = new SBY_Settings( $atts, $database_settings );
|
||||
|
||||
if ( empty( $database_settings['connected_accounts'] ) && empty( $database_settings['api_key'] ) ) {
|
||||
$report[ $feed_id ]['did_update'] = 'no - no connected account';
|
||||
} else {
|
||||
SBY_Cron_Updater::do_single_feed_cron_update( $sby_settings_obj, $feed_data, $atts );
|
||||
|
||||
$report[ $feed_id ]['did_update'] = 'yes';
|
||||
}
|
||||
} else {
|
||||
$report[ $feed_id ]['did_update'] = 'no - not recently requested';
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
$report[ $feed_id ]['did_update'] = 'no - missing atts';
|
||||
}
|
||||
|
||||
} else {
|
||||
$report[ $feed_id ]['did_update'] = 'no - no transient found';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
update_option( 'sby_cron_report', $report, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a single feed cache based on settings. Local image storing and
|
||||
* resizing is done in the background here as well unless this is the initial
|
||||
* time the feed is created and no cached data exists yet.
|
||||
*
|
||||
* Overwritten in the Pro version
|
||||
*
|
||||
* @param object $sby_settings_obj object created by the sby_settings class
|
||||
* @param array $feed_data post, header, shortcode settings, and other info
|
||||
* associated with the feed that is saved in the cache
|
||||
* @param array $atts shortcode settings
|
||||
* @param bool $include_resize whether or not to resize images during the update since
|
||||
* images can also be resized with an ajax call when the feed is viewed on the frontend
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function do_single_feed_cron_update( $sby_settings_obj, $feed_data, $atts, $include_resize = true ) {
|
||||
$sby_settings_obj->set_feed_type_and_terms();
|
||||
$sby_settings_obj->set_transient_name();
|
||||
$transient_name = $sby_settings_obj->get_transient_name();
|
||||
$settings = $sby_settings_obj->get_settings();
|
||||
$feed_type_and_terms = $sby_settings_obj->get_feed_type_and_terms();
|
||||
|
||||
$youtube_feed = new SBY_Feed( $transient_name );
|
||||
|
||||
while ( $youtube_feed->need_posts( $settings['num'] ) && $youtube_feed->can_get_more_posts() ) {
|
||||
$youtube_feed->add_remote_posts( $settings, $feed_type_and_terms, $sby_settings_obj->get_connected_accounts_in_feed() );
|
||||
}
|
||||
|
||||
$to_cache = array(
|
||||
'atts' => $atts,
|
||||
'last_requested' => isset($feed_data['last_requested']) ? $feed_data['last_requested'] : '',
|
||||
'last_retrieve' => time()
|
||||
);
|
||||
|
||||
$youtube_feed->set_cron_cache( $to_cache, $sby_settings_obj->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
|
||||
|
||||
if ( $youtube_feed->need_header( $settings, $feed_type_and_terms ) ) {
|
||||
$youtube_feed->set_remote_header_data( $settings, $feed_type_and_terms, $sby_settings_obj->get_connected_accounts_in_feed() );
|
||||
|
||||
$youtube_feed->cache_header_data( $sby_settings_obj->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
|
||||
}
|
||||
|
||||
$post_data = $youtube_feed->get_post_data();
|
||||
$post_data = array_slice( $post_data, 0, $settings['num'] );
|
||||
|
||||
AdminAjaxService::sby_process_post_set_caching( $post_data, $transient_name );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve option name column values for all feed cache transients
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function get_feed_cache_option_names() {
|
||||
global $wpdb;
|
||||
$feed_caches = array();
|
||||
|
||||
$results = $wpdb->get_results( "
|
||||
SELECT option_name
|
||||
FROM $wpdb->options
|
||||
WHERE `option_name` LIKE ('%\_transient\_sby\_%')
|
||||
AND `option_name` NOT LIKE ('%\_transient\_sby\_header%');", ARRAY_A );
|
||||
|
||||
if ( isset( $results[0] ) ) {
|
||||
$feed_caches = $results;
|
||||
}
|
||||
|
||||
return $feed_caches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start cron jobs based on user's settings for cron cache update frequency.
|
||||
* This is triggered when settings are saved on the "Configure" tab.
|
||||
*
|
||||
* @param string $sby_cache_cron_interval arbitrary name from one of the
|
||||
* settings on the "Configure" tab
|
||||
* @param string $sby_cache_cron_time hour of the day (1 = 1:00)
|
||||
* @param string $sby_cache_cron_am_pm am or pm (time of day)
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function start_cron_job( $sby_cache_cron_interval, $sby_cache_cron_time, $sby_cache_cron_am_pm ) {
|
||||
wp_clear_scheduled_hook( 'sby_feed_update' );
|
||||
|
||||
if ( $sby_cache_cron_interval === '12hours' || $sby_cache_cron_interval === '24hours' ) {
|
||||
$relative_time_now = time() + sby_get_utc_offset();
|
||||
$base_day = strtotime( date( 'Y-m-d', $relative_time_now ) );
|
||||
$add_time = $sby_cache_cron_am_pm === 'pm' ? (int)$sby_cache_cron_time + 12 : (int)$sby_cache_cron_time;
|
||||
$utc_start_time = $base_day + (($add_time * 60 * 60) - sby_get_utc_offset());
|
||||
|
||||
if ( $utc_start_time < time() ) {
|
||||
if ( $sby_cache_cron_interval === '12hours' ) {
|
||||
$utc_start_time += 60*60*12;
|
||||
} else {
|
||||
$utc_start_time += 60*60*24;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $sby_cache_cron_interval === '12hours' ) {
|
||||
wp_schedule_event( $utc_start_time, 'twicedaily', 'sby_feed_update' );
|
||||
} else {
|
||||
wp_schedule_event( $utc_start_time, 'daily', 'sby_feed_update' );
|
||||
}
|
||||
|
||||
} else {
|
||||
if ( $sby_cache_cron_interval === '30mins' ) {
|
||||
wp_schedule_event( time(), 'sby30mins', 'sby_feed_update' );
|
||||
} else {
|
||||
wp_schedule_event( time(), 'hourly', 'sby_feed_update' );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
1150
wp-content/plugins/youtube-feed-pro/inc/SBY_Display_Elements.php
Normal file
1150
wp-content/plugins/youtube-feed-pro/inc/SBY_Display_Elements.php
Normal file
File diff suppressed because it is too large
Load Diff
1896
wp-content/plugins/youtube-feed-pro/inc/SBY_Feed.php
Normal file
1896
wp-content/plugins/youtube-feed-pro/inc/SBY_Feed.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/**
|
||||
* Class SBY_GDPR_Integrations
|
||||
*
|
||||
* Adds GDPR related workarounds for third-party plugins:
|
||||
* https://wordpress.org/plugins/cookie-law-info/
|
||||
*
|
||||
* @since 2.6/5.9
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
class SBY_GDPR_Integrations {
|
||||
|
||||
/**
|
||||
* Undoing of Cookie Notice's Twitter Feed related code
|
||||
* needs to be done late.
|
||||
*/
|
||||
public static function init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not consent plugins that Twitter Feed
|
||||
* is compatible with are active.
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function gdpr_plugins_active() {
|
||||
if ( function_exists( 'WPConsent' ) ) {
|
||||
return 'WPConsent by the WPConsent team';
|
||||
}
|
||||
if ( defined( 'RCB_ROOT_SLUG' ) ) {
|
||||
return 'Real Cookie Banner by devowl.io';
|
||||
}
|
||||
if ( function_exists( 'gdpr_cookie_is_accepted' ) ) {
|
||||
return 'GDPR Cookie Compliance by Moove Agency';
|
||||
}
|
||||
if ( class_exists( 'Cookie_Notice' ) ) {
|
||||
return 'Cookie Notice by dFactory';
|
||||
}
|
||||
if ( function_exists( 'run_cookie_law_info' ) || class_exists( 'Cookie_Law_Info' ) ) {
|
||||
return 'GDPR Cookie Consent by WebToffee';
|
||||
}
|
||||
if ( class_exists( 'Cookiebot_WP' ) ) {
|
||||
return 'Cookiebot by Cybot A/S';
|
||||
}
|
||||
if ( class_exists( 'COMPLIANZ' ) ) {
|
||||
return 'Complianz by Really Simple Plugins';
|
||||
}
|
||||
if ( function_exists( 'BorlabsCookieHelper' ) || ( defined( 'BORLABS_COOKIE_VERSION' ) && version_compare( BORLABS_COOKIE_VERSION, '3.0', '>=' ) ) ) {
|
||||
return 'Borlabs Cookie by Borlabs';
|
||||
}
|
||||
if ( is_admin() && ! empty( $_GET['page'] ) && $_GET['page'] === 'sby-feed-builder' ) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* GDPR features can be added automatically, forced enabled,
|
||||
* or forced disabled.
|
||||
*
|
||||
* @param $settings
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function doing_gdpr( $settings ) {
|
||||
$gdpr = isset( $settings['global_settings']['gdpr'] ) ? $settings['global_settings']['gdpr'] : 'auto';
|
||||
if ( $gdpr === 'no' ) {
|
||||
return false;
|
||||
}
|
||||
if ( $gdpr === 'yes' ) {
|
||||
return true;
|
||||
}
|
||||
return (SBY_GDPR_Integrations::gdpr_plugins_active() !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
* GDPR features are reliant on the image resizing features
|
||||
*
|
||||
* @param bool $retest
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function gdpr_tests_successful( $retest = false ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function gdpr_tests_error_message() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|mixed
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function statuses() {
|
||||
$statuses_option = get_option( 'sby_statuses', array() );
|
||||
|
||||
$return = isset( $statuses_option['gdpr'] ) ? $statuses_option['gdpr'] : array();
|
||||
return $return;
|
||||
}
|
||||
|
||||
}
|
||||
408
wp-content/plugins/youtube-feed-pro/inc/SBY_Parse.php
Normal file
408
wp-content/plugins/youtube-feed-pro/inc/SBY_Parse.php
Normal file
@@ -0,0 +1,408 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
class SBY_Parse
|
||||
{
|
||||
/**
|
||||
* @param $post array
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function get_post_id( $post ) {
|
||||
if ( isset( $post['id'] ) && ! is_array( $post['id'] ) ) {
|
||||
return $post['id'];
|
||||
} else {
|
||||
return SBY_Parse::get_channel_id( $post ) . '_' . SBY_Parse::get_video_id( $post );
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_subscriber_count( $channel_data ) {
|
||||
if ( isset( $channel_data['items'][0]['statistics']['subscriberCount'] ) ) {
|
||||
return $channel_data['items'][0]['statistics']['subscriberCount'];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function get_video_id( $post ) {
|
||||
if ( isset( $post['snippet']['resourceId']['videoId'] ) ) {
|
||||
return $post['snippet']['resourceId']['videoId'];
|
||||
} elseif ( isset( $post['id']['videoId'] ) ) {
|
||||
return $post['id']['videoId'];
|
||||
} elseif ( isset( $post['id']) ) {
|
||||
return $post['id'];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $post array
|
||||
*
|
||||
* @return false|int
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function get_timestamp( $post ) {
|
||||
$timestamp = 0;
|
||||
|
||||
if ( isset( $post['contentDetails']['videoPublishedAt'] ) ) {
|
||||
$data = $post['contentDetails']['videoPublishedAt'];
|
||||
} elseif ( isset( $post['snippet']['publishedAt'] ) ) {
|
||||
$data = $post['snippet']['publishedAt'];
|
||||
}
|
||||
if ( isset( $data ) ) {
|
||||
$remove_extra = str_replace( array( 'T', '+00:00', '.000Z', '+' ), ' ', $data );
|
||||
$timestamp = strtotime( $remove_extra );
|
||||
}
|
||||
|
||||
|
||||
return $timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $post array
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function get_permalink( $post ) {
|
||||
if ( isset( $post['snippet']['resourceId']['videoId'] ) ) {
|
||||
return 'https://www.youtube.com/watch?v=' . $post['snippet']['resourceId']['videoId'];
|
||||
} elseif ( isset( $post['snippet']['channelId'] ) ) {
|
||||
return 'https://www.youtube.com/channel/' . $post['snippet']['channelId'];
|
||||
}
|
||||
|
||||
return 'https://www.youtube.com/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $post
|
||||
* @param string $resolution
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function get_media_url( $post, $resolution = 'lightbox' ) {
|
||||
$thumbnail_key = 'standard';
|
||||
switch ( $resolution ) {
|
||||
case 'thumb' :
|
||||
$thumbnail_key = 'default';
|
||||
break;
|
||||
case 'medium' :
|
||||
$thumbnail_key = 'medium';
|
||||
break;
|
||||
case 'high' :
|
||||
$thumbnail_key = 'high';
|
||||
break;
|
||||
case 'lightbox' :
|
||||
$thumbnail_key = 'maxres';
|
||||
break;
|
||||
}
|
||||
|
||||
if ( isset( $post['snippet']['thumbnails'][ $thumbnail_key ]['url'] ) ) {
|
||||
return $post['snippet']['thumbnails'][ $thumbnail_key ]['url'];
|
||||
} elseif ( isset( $post['snippet']['thumbnails']['high']['url'] ) ) {
|
||||
return $post['snippet']['thumbnails']['high']['url'];
|
||||
} elseif ( isset( $post['snippet']['thumbnails']['medium']['url'] ) ) {
|
||||
return $post['snippet']['thumbnails']['medium']['url'];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the existing data for the individual YouTube post to
|
||||
* set the best image sources for each resolution size. Due to
|
||||
* random bugs or just how the API works, different post types
|
||||
* need special treatment.
|
||||
*
|
||||
* @param array $post
|
||||
* @param array $resized_images
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function get_media_src_set( $post, $resized_images = array() ) {
|
||||
$media_urls = array();
|
||||
$thumbnails = isset( $post['snippet']['thumbnails'] ) ? $post['snippet']['thumbnails'] : false;
|
||||
$largest_found = '';
|
||||
|
||||
if ( $thumbnails ) {
|
||||
if ( isset( $thumbnails['default']['url'] ) ) {
|
||||
$media_urls['120'] = $thumbnails['default']['url'];
|
||||
$largest_found = $thumbnails['default']['url'];
|
||||
} else {
|
||||
$media_urls['120'] = $largest_found;
|
||||
}
|
||||
if ( isset( $thumbnails['medium']['url'] ) ) {
|
||||
$media_urls['320'] = $thumbnails['medium']['url'];
|
||||
$largest_found = $thumbnails['medium']['url'];
|
||||
} else {
|
||||
$media_urls['320'] = $largest_found;
|
||||
}
|
||||
if ( isset( $thumbnails['high']['url'] ) ) {
|
||||
$media_urls['480'] = $thumbnails['high']['url'];
|
||||
$largest_found = $thumbnails['high']['url'];
|
||||
} else {
|
||||
$media_urls['480'] = $largest_found;
|
||||
}
|
||||
if ( isset( $thumbnails['standard']['url'] ) ) {
|
||||
$media_urls['640'] = $thumbnails['standard']['url'];
|
||||
} else {
|
||||
$media_urls['640'] = $largest_found;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $media_urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* A default can be set in the case that the user doesn't use captions
|
||||
* for posts as this is also used as the alt text for the image.
|
||||
*
|
||||
* @param $post
|
||||
* @param string $default
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function get_caption( $post, $default = '' ) {
|
||||
$caption = $default;
|
||||
if ( isset( $post['snippet']['description'] ) ) {
|
||||
$caption = $post['snippet']['description'];
|
||||
}
|
||||
|
||||
return $caption;
|
||||
}
|
||||
|
||||
public static function get_pro_caption( $post, $default = '', $misc_data = array() ) {
|
||||
$caption = $default;
|
||||
if ( isset( $misc_data['stats'][ SBY_Parse::get_video_id( $post ) ]['sby_description'] ) ) {
|
||||
$caption = $misc_data['stats'][ SBY_Parse::get_video_id( $post ) ]['sby_description'];
|
||||
} elseif ( isset( $post['snippet']['description'] ) ) {
|
||||
$caption = $post['snippet']['description'];
|
||||
}
|
||||
|
||||
return $caption;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $post array
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public static function get_like_count( $post, $misc_data = array() ) {
|
||||
if ( isset( $post['statistics']['likeCount'] ) ) {
|
||||
return $post['statistics']['likeCount'];
|
||||
} elseif ( isset( $misc_data['stats'][ SBY_Parse::get_video_id( $post ) ]['sby_like_count'] ) ) {
|
||||
return $misc_data['stats'][ SBY_Parse::get_video_id( $post ) ]['sby_like_count'];
|
||||
} elseif ( isset( $misc_data['sby_like_count'][0] ) ) {
|
||||
return (float)$misc_data['sby_like_count'][0];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $post array
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public static function get_comment_count( $post, $misc_data = array() ) {
|
||||
if ( isset( $post['statistics']['commentCount'] ) ) {
|
||||
return $post['statistics']['commentCount'];
|
||||
} elseif ( isset( $misc_data['stats'][ SBY_Parse::get_video_id( $post ) ]['sby_comment_count'] ) ) {
|
||||
return (float)$misc_data['stats'][ SBY_Parse::get_video_id( $post ) ]['sby_comment_count'];
|
||||
} elseif ( isset( $misc_data['sby_comment_count'][0] ) ) {
|
||||
return (float)$misc_data['sby_comment_count'][0];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function get_view_count( $post, $misc_data = array() ) {
|
||||
if ( isset( $post['statistics']['viewCount'] ) ) {
|
||||
return $post['statistics']['viewCount'];
|
||||
} elseif ( isset( $misc_data['stats'][ SBY_Parse::get_video_id( $post ) ]['sby_view_count'] ) ) {
|
||||
return $misc_data['stats'][ SBY_Parse::get_video_id( $post ) ]['sby_view_count'];
|
||||
} elseif ( isset( $misc_data['sby_view_count'][0] ) ) {
|
||||
return $misc_data['sby_view_count'][0];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function get_live_broadcast_content( $post, $misc_data = array() ) {
|
||||
if ( isset( $post['snippet']['liveBroadcastContent'] ) ) {
|
||||
return $post['snippet']['liveBroadcastContent'];
|
||||
} elseif ( isset( $misc_data['sby_live_broadcast_content'][0] ) ) {
|
||||
return $misc_data['sby_live_broadcast_content'][0];
|
||||
} elseif ( isset( $post['sby_live_broadcast_content'] ) ) {
|
||||
return $post['sby_live_broadcast_content'];
|
||||
}
|
||||
|
||||
return 'none';
|
||||
}
|
||||
|
||||
public static function get_live_streaming_timestamp( $post, $misc_data = array() ) {
|
||||
$actual_start_timestamp = self::get_actual_start_timestamp( $post, $misc_data );
|
||||
if ( $actual_start_timestamp > 0 ) {
|
||||
return $actual_start_timestamp;
|
||||
}
|
||||
|
||||
return self::get_scheduled_start_timestamp( $post, $misc_data );
|
||||
}
|
||||
|
||||
public static function get_scheduled_start_timestamp( $post, $misc_data = array() ) {
|
||||
|
||||
if ( ! empty( $post['liveStreamingDetails']['scheduledStartTime'] ) ) {
|
||||
$remove_extra = str_replace( array( 'T', '+00:00', '.000Z', '+' ), ' ', $post['liveStreamingDetails']['scheduledStartTime'] );
|
||||
$timestamp = strtotime( $remove_extra );
|
||||
|
||||
return $timestamp;
|
||||
} elseif ( isset( $misc_data['live_streaming_details'][ SBY_Parse::get_video_id( $post ) ]['sby_scheduled_start_time'] ) ) {
|
||||
return strtotime( $misc_data['live_streaming_details'][ SBY_Parse::get_video_id( $post ) ]['sby_scheduled_start_time'] );
|
||||
} elseif ( isset( $misc_data['sby_scheduled_start_time'][0] ) ) {
|
||||
return strtotime( $misc_data['sby_scheduled_start_time'][0] );
|
||||
} elseif ( isset( $post['sby_scheduled_start_time'] ) ) {
|
||||
return strtotime( $post['sby_scheduled_start_time'] );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function get_actual_start_timestamp( $post, $misc_data = array() ) {
|
||||
|
||||
if ( ! empty( $post['liveStreamingDetails']['actualStartTime'] ) ) {
|
||||
$remove_extra = str_replace( array( 'T', '+00:00', '.000Z', '+' ), ' ', $post['liveStreamingDetails']['actualStartTime'] );
|
||||
$timestamp = strtotime( $remove_extra );
|
||||
|
||||
return $timestamp;
|
||||
} elseif ( isset( $misc_data['live_streaming_details'][ SBY_Parse::get_video_id( $post ) ]['sby_actual_start_time'] ) ) {
|
||||
return strtotime( $misc_data['live_streaming_details'][ SBY_Parse::get_video_id( $post ) ]['sby_actual_start_time'] );
|
||||
} elseif ( isset( $misc_data['sby_actual_start_time'][0] ) ) {
|
||||
return strtotime( $misc_data['sby_actual_start_time'][0] );
|
||||
} elseif ( isset( $post['sby_actual_start_time'] ) ) {
|
||||
return strtotime( $post['sby_actual_start_time'] );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function get_video_title( $channel_or_playlist_item_data ) {
|
||||
if ( isset( $channel_or_playlist_item_data['items'][0]['snippet']['title'] ) ) {
|
||||
return $channel_or_playlist_item_data['items'][0]['snippet']['title'];
|
||||
} else if ( isset( $channel_or_playlist_item_data['snippet']['title'] ) ) {
|
||||
return $channel_or_playlist_item_data['snippet']['title'];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function get_channel_id( $channel_or_playlist_item_data ) {
|
||||
if ( isset( $channel_or_playlist_item_data['items'][0]['id'] ) ) {
|
||||
return $channel_or_playlist_item_data['items'][0]['id'];
|
||||
} elseif ( isset( $channel_or_playlist_item_data['snippet']['channelId'] ) ) {
|
||||
return $channel_or_playlist_item_data['snippet']['channelId'];
|
||||
} elseif ( isset( $channel_or_playlist_item_data['id'] ) ) {
|
||||
return $channel_or_playlist_item_data['id'];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function get_channel_title( $channel_or_playlist_item_data ) {
|
||||
if ( isset( $channel_or_playlist_item_data['items'][0]['snippet']['title'] ) ) {
|
||||
return $channel_or_playlist_item_data['items'][0]['snippet']['title'];
|
||||
} elseif ( isset( $channel_or_playlist_item_data['snippet']['channelTitle'] ) ) {
|
||||
return $channel_or_playlist_item_data['snippet']['channelTitle'];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function get_channel_permalink( $channel_data ) {
|
||||
return 'https://www.youtube.com/channel/' . SBY_Parse::get_channel_id( $channel_data ) . '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $header_data
|
||||
* @param array $settings
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function get_avatar( $header_data, $settings = array( 'favor_local' => false ) ) {
|
||||
if ( !empty($settings['favor_local'] ) && ! empty( $header_data['local_avatar'] ) ) {
|
||||
|
||||
return $header_data['local_avatar'];
|
||||
} else {
|
||||
if ( isset( $header_data['items'][0]['snippet']['thumbnails'] ) ) {
|
||||
$header_size = isset( $settings['headersize'] ) ? $settings['headersize'] : '';
|
||||
if ( $header_size === 'large' ) {
|
||||
return $header_data['items'][0]['snippet']['thumbnails']['high']['url'];
|
||||
} elseif ( $header_size === 'medium' ) {
|
||||
return $header_data['items'][0]['snippet']['thumbnails']['medium']['url'];
|
||||
} else {
|
||||
return $header_data['items'][0]['snippet']['thumbnails']['default']['url'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function get_item_avatar( $post, $avatars ) {
|
||||
if ( empty ( $avatars ) ) {
|
||||
return '';
|
||||
} else {
|
||||
$username = SBY_Parse::get_channel_id( $post );
|
||||
if ( isset( $avatars[ $username ] ) ) {
|
||||
return $avatars[ $username ];
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Account bio/description used in header
|
||||
*
|
||||
* @param $header_data
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function get_channel_description( $header_data ) {
|
||||
if ( isset( $header_data['items'][0]['snippet']['description'] ) ) {
|
||||
return $header_data['items'][0]['snippet']['description'];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse quoted strings as boolean such as 'true' and 'false'
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function parse_quoted_string_as_boolean( $settings ) {
|
||||
foreach($settings as $key => $value) {
|
||||
if ( $value == 'true' ) {
|
||||
$settings[$key] = true;
|
||||
}
|
||||
if ( $value == 'false' ) {
|
||||
$settings[$key] = false;
|
||||
}
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
327
wp-content/plugins/youtube-feed-pro/inc/SBY_Posts_Manager.php
Normal file
327
wp-content/plugins/youtube-feed-pro/inc/SBY_Posts_Manager.php
Normal file
@@ -0,0 +1,327 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
|
||||
class SBY_Posts_Manager
|
||||
{
|
||||
var $options_prefix;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
var $limit;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
var $errors;
|
||||
|
||||
var $ajax_status;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
var $frontend_errors;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
var $resizing_tables_exist;
|
||||
|
||||
/**
|
||||
* SBY_Posts_Manager constructor.
|
||||
*/
|
||||
public function __construct( $options_prefix, $errors, $ajax_status ) {
|
||||
$this->options_prefix = $options_prefix;
|
||||
$this->errors = $errors;
|
||||
$this->ajax_status = $ajax_status;
|
||||
$this->frontend_errors = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function get_ajax_status() {
|
||||
return $this->ajax_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $to_update
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function update_ajax_status( $to_update ) {
|
||||
foreach ( $to_update as $key => $value ) {
|
||||
$this->ajax_status[ $key ] = $value;
|
||||
}
|
||||
|
||||
update_option( $this->options_prefix . '_ajax_status', $this->ajax_status );
|
||||
}
|
||||
|
||||
/**
|
||||
* When the plugin is first installed and used, an AJAX call to admin-ajax.php
|
||||
* is made to verify that it's available
|
||||
*
|
||||
* @param bool $force_check
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function maybe_start_ajax_test( $force_check = false ) {
|
||||
if ( ! $this->ajax_status['tested'] || $force_check ) {
|
||||
set_transient( $this->options_prefix . '_doing_ajax_test', 'yes', 60*60 );
|
||||
$this->update_ajax_status( array( 'tested' => true ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called if a successful Admin ajax request is made
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function update_successful_ajax_test() {
|
||||
$this->update_ajax_status( array( 'successful' => true ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function should_add_ajax_test_notice() {
|
||||
return ($this->ajax_status['tested'] && ! $this->ajax_status['successful'] && get_transient( $this->options_prefix . '_doing_ajax_test' ) !== 'yes');
|
||||
}
|
||||
|
||||
/**
|
||||
* The plugin has a limit on how many post records can be stored and
|
||||
* images resized to avoid overloading servers. This function deletes the post that
|
||||
* has the longest time passed since it was retrieved.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function delete_least_used_image() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates how many records are in the database and whether or not it exceeds the limit
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function max_total_records_reached() {
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . SBY_ITEMS;
|
||||
|
||||
$num_records = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name" );
|
||||
|
||||
if ( !isset( $this->limit ) && (int)$num_records > SBY_MAX_RECORDS ) {
|
||||
$this->limit = (int)$num_records - SBY_MAX_RECORDS;
|
||||
}
|
||||
|
||||
return ((int)$num_records > SBY_MAX_RECORDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* The plugin caps how many new images are created in a 15 minute window to
|
||||
* avoid overloading servers
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function max_resizing_per_time_period_reached() {
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . SBY_ITEMS;
|
||||
|
||||
$fifteen_minutes_ago = date( 'Y-m-d H:i:s', time() - 15 * 60 );
|
||||
|
||||
$num_new_records = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name WHERE created_on > '$fifteen_minutes_ago'" );
|
||||
|
||||
return ((int)$num_new_records > 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function image_resizing_disabled() {
|
||||
global $sby_settings;
|
||||
|
||||
$disable_resizing = isset( $sby_settings['disable_resize'] ) ? $sby_settings['disable_resize'] === 'on' || $sby_settings['disable_resize'] === true : false;
|
||||
|
||||
if ( ! $disable_resizing ) {
|
||||
$disable_resizing = isset( $this->resizing_tables_exist ) ? ! $this->resizing_tables_exist : ! $this->does_resizing_tables_exist();
|
||||
}
|
||||
|
||||
return $disable_resizing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to skip image resizing if the tables were never successfully
|
||||
* created
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function does_resizing_tables_exist() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the custom tables and deletes all image files
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function delete_all_sby_posts() {
|
||||
$upload = wp_upload_dir();
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$image_files = glob( trailingslashit( $upload['basedir'] ) . trailingslashit( SBY_UPLOADS_NAME ) . '*' ); // get all file names
|
||||
foreach ( $image_files as $file ) { // iterate files
|
||||
if ( is_file( $file ) ) {
|
||||
unlink( $file );
|
||||
}
|
||||
}
|
||||
|
||||
$options = get_option( $this->options_prefix . '_settings', array() );
|
||||
$connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
|
||||
|
||||
foreach ( $connected_accounts as $account_id => $data ) {
|
||||
|
||||
if ( isset( $data['local_avatar'] ) ) {
|
||||
$connected_accounts[ $account_id ]['local_avatar'] = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$options['connected_accounts'] = $connected_accounts;
|
||||
|
||||
update_option( $this->options_prefix . '_settings', $options );
|
||||
|
||||
$table_name = $wpdb->prefix . "options";
|
||||
|
||||
$wpdb->query( "
|
||||
DELETE
|
||||
FROM $table_name
|
||||
WHERE `option_name` LIKE ('%\_transient\_\$sby\_%')
|
||||
" );
|
||||
$wpdb->query( "
|
||||
DELETE
|
||||
FROM $table_name
|
||||
WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sby\_%')
|
||||
" );
|
||||
|
||||
$upload = wp_upload_dir();
|
||||
$upload_dir = $upload['basedir'];
|
||||
$upload_dir = trailingslashit( $upload_dir ) . SBY_UPLOADS_NAME;
|
||||
if ( ! file_exists( $upload_dir ) ) {
|
||||
$created = wp_mkdir_p( $upload_dir );
|
||||
if ( $created ) {
|
||||
$this->remove_error( 'upload_dir' );
|
||||
} else {
|
||||
$this->add_error( 'upload_dir', array( __( 'There was an error creating the folder for storing resized images.', 'feeds-for-youtube' ), $upload_dir ) );
|
||||
}
|
||||
} else {
|
||||
$this->remove_error( 'upload_dir' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function get_errors() {
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $message_array
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function add_error( $type, $message_array ) {
|
||||
$message_array[] = "Error timestamp: " . strtotime( 'now' );
|
||||
$this->errors[ $type ] = $message_array;
|
||||
|
||||
update_option( 'sby_errors', $this->errors, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function remove_error( $type ) {
|
||||
if ( isset( $this->errors[ $type ] ) ) {
|
||||
unset( $this->errors[ $type ] );
|
||||
|
||||
update_option( $this->options_prefix . '_errors', $this->errors, false );
|
||||
}
|
||||
}
|
||||
|
||||
public function remove_all_errors() {
|
||||
delete_option( $this->options_prefix . '_errors' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $message
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function add_frontend_error( $type, $message ) {
|
||||
$this->frontend_errors[ $type ] = $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function get_frontend_errors() {
|
||||
return $this->frontend_errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function reset_frontend_errors() {
|
||||
return $this->frontend_errors = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.0
|
||||
*/
|
||||
public function add_api_request_delay( $time_in_seconds = 300, $account_id = false ) {
|
||||
if ( $account_id ) {
|
||||
set_transient( SBY_USE_BACKUP_PREFIX . $this->options_prefix . '_' . $account_id, '1', $time_in_seconds );
|
||||
} else {
|
||||
set_transient( SBY_USE_BACKUP_PREFIX . $this->options_prefix . '_delay_requests', '1', $time_in_seconds );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.0
|
||||
*/
|
||||
public function are_current_api_request_delays( $account_id = false ) {
|
||||
$is_delay = (get_transient( SBY_USE_BACKUP_PREFIX . $this->options_prefix . '_delay_requests' ) !== false);
|
||||
|
||||
return $is_delay;
|
||||
}
|
||||
}
|
||||
136
wp-content/plugins/youtube-feed-pro/inc/SBY_RSS_Connect.php
Normal file
136
wp-content/plugins/youtube-feed-pro/inc/SBY_RSS_Connect.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
|
||||
class SBY_RSS_Connect
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* @var object
|
||||
*/
|
||||
private $response;
|
||||
|
||||
private $is_live_stream;
|
||||
|
||||
public function __construct( $endpoint = '', $params = array() ) {
|
||||
$this->is_live_stream = false;
|
||||
if ( isset( $params['livestream'] ) ) {
|
||||
$this->is_live_stream = true;
|
||||
}
|
||||
$this->set_url( $endpoint, $params );
|
||||
}
|
||||
|
||||
public function get_data() {
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
public function set_url_from_args( $url ) {
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
public function get_url() {
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function connect() {
|
||||
|
||||
if ( ! ini_get( 'allow_url_fopen' ) ) {
|
||||
if ( ! $this->is_live_stream ) {
|
||||
$error_message = '<p><b>'. __( 'Unable to retrieve new videos without an API key.', 'feeds-for-youtube' ) .'</b></p>';
|
||||
if ( current_user_can( 'manage_youtube_feed_options' ) ) {
|
||||
$error_message .= '<p>' . sprintf( __( 'Due to your server configuration, an API key is required to update your feed. See %sthis FAQ%s to set up an API key.', 'feeds-for-youtube' ), '<a href="https://smashballoon.com/youtube-api-key/" target="_blank" rel="noopener nofollow">', '</a>' ) . '</p>';
|
||||
}
|
||||
} else {
|
||||
$error_message = '<p><b>'. __( 'Unable to retrieve new videos due to server configuration.', 'feeds-for-youtube' ) .'</b></p>';
|
||||
if ( current_user_can( 'manage_youtube_feed_options' ) ) {
|
||||
$error_message .= '<p>' . sprintf( __( 'You must have the allow_url_fopen directive enabled in your server\'s php.ini file to retrieve live streams.', 'feeds-for-youtube' ), '<a href="https://smashballoon.com/youtube-api-key/" target="_blank" rel="noopener nofollow">', '</a>' ) . '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
global $sby_posts_manager;
|
||||
|
||||
$sby_posts_manager->add_frontend_error( 'api', $error_message );
|
||||
$sby_posts_manager->add_error( 'api', array( 'Error connecting', $error_message ) );
|
||||
|
||||
$sby_posts_manager->add_api_request_delay( 300 );
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
if ( wp_remote_retrieve_response_code( wp_remote_get( $this->url ) ) === 404 ) {
|
||||
$error_message = '<p><b>'. __( 'Cannot collect videos from this channel. Please make sure this is a valid channel ID.', 'feeds-for-youtube' ) .'</b></p>';
|
||||
|
||||
global $sby_posts_manager;
|
||||
|
||||
$sby_posts_manager->add_frontend_error( 'api', $error_message );
|
||||
$sby_posts_manager->add_error( 'api', array( 'Error connecting', $error_message ) );
|
||||
|
||||
$sby_posts_manager->add_api_request_delay( 300 );
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
$parsed_obj = new \SimpleXMLElement( $this->url, null, true );
|
||||
|
||||
$items_array = array();
|
||||
if ( isset( $parsed_obj->entry ) ) {
|
||||
foreach ( $parsed_obj->entry as $video_xml ) {
|
||||
|
||||
$this_item_array = array();
|
||||
|
||||
$high_thumbnail_url = (string) $video_xml->children( 'http://search.yahoo.com/mrss/' )->group->thumbnail->attributes()->url;
|
||||
|
||||
$this_item_array['snippet'] = array(
|
||||
'publishedAt' => (string) $video_xml->published,
|
||||
'channelId' => (string) $video_xml->children( 'http://www.youtube.com/xml/schemas/2015' )->channelId,
|
||||
'title' => (string) $video_xml->title,
|
||||
'description' => (string) $video_xml->children( 'http://search.yahoo.com/mrss/' )->group->description,
|
||||
'thumbnails' => array(
|
||||
'default' => array(
|
||||
'url' => (string) str_replace( 'hqdefault.jpg', 'default.jpg', $high_thumbnail_url ),
|
||||
),
|
||||
'medium' => array(
|
||||
'url' => str_replace( 'hqdefault.jpg', 'mqdefault.jpg', $high_thumbnail_url ),
|
||||
),
|
||||
'high' => array(
|
||||
'url' => $high_thumbnail_url,
|
||||
'width' => (string) $video_xml->children( 'http://search.yahoo.com/mrss/' )->group->thumbnail->attributes()->width,
|
||||
'height' => (string) $video_xml->children( 'http://search.yahoo.com/mrss/' )->group->thumbnail->attributes()->height,
|
||||
),
|
||||
'standard' => array(
|
||||
'url' => str_replace( 'hqdefault.jpg', 'sddefault.jpg', $high_thumbnail_url ),
|
||||
),
|
||||
'maxres' => array(
|
||||
'url' => str_replace( 'hqdefault.jpg', 'maxresdefault.jpg', $high_thumbnail_url ),
|
||||
),
|
||||
),
|
||||
'channelTitle' => (string) $video_xml->author->name,
|
||||
'resourceId' => array(
|
||||
'videoId' => (string) $video_xml->children( 'http://www.youtube.com/xml/schemas/2015' )->videoId
|
||||
),
|
||||
);
|
||||
$this_item_array['statistics'] = array(
|
||||
'viewCount' => (int) $video_xml->children( 'http://search.yahoo.com/mrss/' )->group->community->statistics->attributes()->views,
|
||||
'starRating' => (float) $video_xml->children( 'http://search.yahoo.com/mrss/' )->group->community->starRating->attributes()->average,
|
||||
);
|
||||
$items_array[] = $this_item_array;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->response = $items_array;
|
||||
|
||||
}
|
||||
|
||||
protected function set_url( $endpoint_slug, $params ) {
|
||||
$url = 'https://www.youtube.com/feeds/videos.xml?channel_id=' . $params['channel_id'];
|
||||
|
||||
$this->set_url_from_args( $url );
|
||||
}
|
||||
|
||||
}
|
||||
641
wp-content/plugins/youtube-feed-pro/inc/SBY_Settings.php
Normal file
641
wp-content/plugins/youtube-feed-pro/inc/SBY_Settings.php
Normal file
@@ -0,0 +1,641 @@
|
||||
<?php
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
|
||||
use Smashballoon\Customizer\Feed_Saver;
|
||||
|
||||
class SBY_Settings {
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $atts;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $feed_type_and_terms;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $connected_accounts;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $connected_accounts_in_feed;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $transient_name;
|
||||
|
||||
/**
|
||||
* SBY_Settings constructor.
|
||||
*
|
||||
* Overwritten in the Pro version.
|
||||
*
|
||||
* @param array $atts shortcode settings
|
||||
* @param array $db settings from the wp_options table
|
||||
*/
|
||||
public function __construct( $atts, $db, $preview_settings = false ) {
|
||||
$atts = is_array( $atts ) ? $atts : array();
|
||||
|
||||
if ( ! empty( $atts['feed'] ) && $atts['feed'] !== 'legacy' ) {
|
||||
$this->settings = self::get_settings_by_feed_id( $atts['feed'], $preview_settings );
|
||||
|
||||
if ( ! empty( $this->settings ) ) {
|
||||
$this->settings['customizer'] = isset($atts['customizer']) && $atts['customizer'] == true ? true : false;
|
||||
$this->settings['feed'] = intval( $atts['feed'] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $atts['feed'] ) && $atts['feed'] === 'legacy' ) {
|
||||
$this->settings = $preview_settings;
|
||||
|
||||
if ( ! empty( $this->settings ) ) {
|
||||
$this->settings['customizer'] = isset($atts['customizer']) && $atts['customizer'] == true ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
// convert string 'false' and 'true' to booleans
|
||||
foreach ( $atts as $key => $value ) {
|
||||
if ( $value === 'false' ) {
|
||||
$atts[ $key ] = false;
|
||||
} elseif ( $value === 'true' ) {
|
||||
$atts[ $key ] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->atts = $atts;
|
||||
$this->db = $db;
|
||||
|
||||
$this->connected_accounts = isset( $db['connected_accounts'] ) ? $db['connected_accounts'] : array();
|
||||
|
||||
if ( ! empty( $this->db['api_key'] ) ) {
|
||||
$this->connected_accounts = array(
|
||||
'own' => array(
|
||||
'access_token' => '',
|
||||
'refresh_token' => '',
|
||||
'channel_id' => '',
|
||||
'username' => '',
|
||||
'is_valid' => true,
|
||||
'last_checked' => '',
|
||||
'profile_picture' => '',
|
||||
'privacy' => '',
|
||||
'expires' => '2574196927',
|
||||
'api_key' => $this->db['api_key']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( empty( $this->settings ) ) {
|
||||
$this->settings = wp_parse_args( $atts, $db );
|
||||
}
|
||||
|
||||
if ( empty( $this->connected_accounts ) ) {
|
||||
$this->settings['showheader'] = false;
|
||||
$this->connected_accounts = array( 'rss_only' => true );
|
||||
}
|
||||
|
||||
$this->settings['nummobile'] = $this->settings['num'];
|
||||
$this->settings['ajaxtheme'] = $this->db['ajaxtheme'];
|
||||
if ( empty( $atts['caching_type'] ) ) {
|
||||
$this->settings['caching_type'] = 'background';
|
||||
}
|
||||
if ( ! empty( $atts['cachetime'] ) ) {
|
||||
$this->settings['caching_type'] = 'page';
|
||||
}
|
||||
if ( ! empty( $atts['showpast'] ) ) {
|
||||
$this->settings['showpast'] = (bool)$atts['showpast'];
|
||||
}
|
||||
|
||||
$this->after_settings_set();
|
||||
}
|
||||
|
||||
protected function after_settings_set() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings or legacy settings depending on feed type
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $atts
|
||||
* @return array $settings
|
||||
*/
|
||||
public function maybe_get_settings_or_legacy_settings( $atts ) {
|
||||
if ( !empty( $atts['feed'] ) ) {
|
||||
$settings = $this->get_settings();
|
||||
} else {
|
||||
$settings = self::get_legacy_feed_settings( $atts );
|
||||
}
|
||||
|
||||
$settings['global_settings'] = sby_get_database_settings();
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get legacy feed settings
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $atts
|
||||
* @return array $legacy_settings
|
||||
*/
|
||||
public static function get_legacy_feed_settings( $atts = array() ) {
|
||||
$legacy_settings = get_option( 'sby_legacy_feed_settings', false );
|
||||
if(false === $legacy_settings) {
|
||||
$legacy_settings = sby_get_database_settings();
|
||||
} else {
|
||||
$legacy_settings = json_decode( $legacy_settings, true );
|
||||
}
|
||||
|
||||
if ( $atts && count( $atts ) > 0 ) {
|
||||
$legacy_settings = wp_parse_args( $atts, $legacy_settings );
|
||||
$legacy_settings = self::filter_legacy_shortcode_atts( $atts, $legacy_settings );
|
||||
}
|
||||
|
||||
return $legacy_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter legacy feed shortcode atts
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $atts
|
||||
* @param array $legacy_settings
|
||||
*
|
||||
* @return array $legacy_shortcode
|
||||
*/
|
||||
public static function filter_legacy_shortcode_atts( $atts, $legacy_settings ) {
|
||||
if ( isset($atts['gridcols']) && $atts['layout'] === 'grid' ) {
|
||||
$legacy_settings['cols'] = $legacy_settings['gridcols'];
|
||||
}
|
||||
if ( isset($atts['gridcolsmobile']) && $atts['layout'] === 'grid' ) {
|
||||
$legacy_settings['colsmobile'] = $legacy_settings['gridcolsmobile'];
|
||||
}
|
||||
if ( isset($atts['gallerycols']) && $atts['layout'] === 'gallery' ) {
|
||||
$legacy_settings['cols'] = $legacy_settings['gallerycols'];
|
||||
}
|
||||
if ( isset($atts['gallerycolsmobile']) && $atts['layout'] === 'gallery' ) {
|
||||
$legacy_settings['colsmobile'] = $legacy_settings['gallerycolsmobile'];
|
||||
}
|
||||
if ( isset($atts['carouselcols']) && $atts['layout'] === 'carousel' ) {
|
||||
$legacy_settings['cols'] = $legacy_settings['carouselcols'];
|
||||
}
|
||||
if ( isset($atts['carouselcolsmobile']) && $atts['layout'] === 'carousel' ) {
|
||||
$legacy_settings['colsmobile'] = $legacy_settings['carouselcolsmobile'];
|
||||
}
|
||||
$legacy_settings['nummobile'] = $legacy_settings['num'];
|
||||
|
||||
return $legacy_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Settings By Feed ID
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function get_settings_by_feed_id( $feed_id, $preview_settings = false ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( is_array( $preview_settings ) ) {
|
||||
return $preview_settings;
|
||||
}
|
||||
|
||||
if ( intval( $feed_id ) < 1 ) {
|
||||
return false;
|
||||
}
|
||||
$container = Container::get_instance();
|
||||
$feed_saver = $container->get(Feed_Saver::class);
|
||||
$feed_saver->set_feed_id( $feed_id );
|
||||
|
||||
return $feed_saver->get_feed_settings();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function get_settings() {
|
||||
return $this->settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* The plugin will output settings on the frontend for debugging purposes.
|
||||
* Safe settings to display are added here.
|
||||
*
|
||||
* Overwritten in the Pro version.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function get_public_db_settings_keys() {
|
||||
$public = array(
|
||||
'type' => 'channel',
|
||||
'channel' => '',
|
||||
'num' => 9,
|
||||
'nummobile' => 9,
|
||||
'minnum' => 9,
|
||||
'widthresp' => true,
|
||||
'class' => '',
|
||||
'height' => '',
|
||||
'heightunit' => '%',
|
||||
'disablemobile' => false,
|
||||
'itemspacing' => 5,
|
||||
'itemspacingunit' => 'px',
|
||||
'background' => '',
|
||||
'headercolor' => '',
|
||||
'subscribecolor' => '',
|
||||
'subscribehovercolor' => '',
|
||||
'subscribetextcolor' => '',
|
||||
'buttoncolor' => '',
|
||||
'buttonhovercolor' => '',
|
||||
'buttontextcolor' => '',
|
||||
'layout' => 'grid',
|
||||
'feedtemplate' => 'default',
|
||||
'playvideo' => 'automatically',
|
||||
'sortby' => 'none',
|
||||
'imageres' => 'auto',
|
||||
'showheader' => true,
|
||||
'headerstyle' => 'standard',
|
||||
'customheadertext' => __( 'We are on YouTube', 'feeds-for-youtube' ),
|
||||
'customheadersize' => 'small',
|
||||
'customheadertextcolor' => '',
|
||||
'showdescription' => true,
|
||||
'showbutton' => true,
|
||||
'headersize' => 'small',
|
||||
'headeroutside' => false,
|
||||
'showsubscribe' => true,
|
||||
'buttontext' => __( 'Load More...', 'feeds-for-youtube' ),
|
||||
'subscribetext' => __( 'Subscribe', 'feeds-for-youtube' ),
|
||||
'caching_type' => 'page',
|
||||
'cache_time' => 1,
|
||||
'cache_time_unit' => 'hours',
|
||||
'backup_cache_enabled' => true,
|
||||
'resizeprocess' => 'background',
|
||||
'disable_resize' => true,
|
||||
'storage_process' => 'background',
|
||||
'favor_local' => false,
|
||||
'disable_js_image_loading' => false,
|
||||
'ajax_post_load' => false,
|
||||
'ajaxtheme' => false,
|
||||
'enqueue_css_in_shortcode' => false,
|
||||
'font_method' => 'svg',
|
||||
'customtemplates' => false,
|
||||
'cols' => 3,
|
||||
'colsmobile' => 2,
|
||||
'playerratio' => '9:16',
|
||||
'eagerload' => false,
|
||||
'custom_css' => '',
|
||||
'custom_js' => '',
|
||||
'gdpr' => 'auto',
|
||||
'disablecdn' => false,
|
||||
'allowcookies' => false,
|
||||
|
||||
// pro only
|
||||
'usecustomsearch' => false,
|
||||
'headerchannel' => '',
|
||||
'customsearch' => '',
|
||||
'showpast' => true,
|
||||
'showlikes' => true,
|
||||
'carouselcols' => 3,
|
||||
'carouselcolsmobile' => 2,
|
||||
'carouselarrows' => true,
|
||||
'carouselpag' => true,
|
||||
'carouselautoplay' => false,
|
||||
'infoposition' => 'below',
|
||||
'include' => array( 'title', 'icon', 'user', 'date', 'countdown' ),
|
||||
'hoverinclude' => array( 'description', 'stats' ),
|
||||
'descriptionlength' => 150,
|
||||
'userelative' => true,
|
||||
'dateformat' => '0',
|
||||
'customdate' => '',
|
||||
'showsubscribers' => true,
|
||||
'enablelightbox' => true,
|
||||
'subscriberstext' => __( 'subscribers', 'feeds-for-youtube' ),
|
||||
'viewstext' => __( 'views', 'feeds-for-youtube' ),
|
||||
'agotext' => __( 'ago', 'feeds-for-youtube' ),
|
||||
'beforedatetext' => __( 'Streaming live', 'feeds-for-youtube' ),
|
||||
'beforestreamtimetext' => __( 'Streaming live in', 'feeds-for-youtube' ),
|
||||
'minutetext' => __( 'minute', 'feeds-for-youtube' ),
|
||||
'minutestext' => __( 'minutes', 'feeds-for-youtube' ),
|
||||
'hourstext' => __( 'hours', 'feeds-for-youtube' ),
|
||||
'thousandstext' => __( 'K', 'feeds-for-youtube' ),
|
||||
'millionstext' => __( 'M', 'feeds-for-youtube' ),
|
||||
'watchnowtext' => __( 'Watch Now', 'feeds-for-youtube' ),
|
||||
'cta' => 'related',
|
||||
'colorpalette' => 'inherit',
|
||||
'linktext' => __( 'Learn More', 'feeds-for-youtube' ),
|
||||
'linkurl' => '',
|
||||
'linkopentype' => 'same',
|
||||
'linkcolor' => '',
|
||||
'linktextcolor' => '',
|
||||
'videocardstyle' => 'regular',
|
||||
'videocardlayout' => 'vertical',
|
||||
'custombgcolor1' => '',
|
||||
'customtextcolor1' => '',
|
||||
'customtextcolor2' => '',
|
||||
'customlinkcolor1' => '',
|
||||
'custombuttoncolor1' => '',
|
||||
'custombuttoncolor2' => '',
|
||||
'boxedbgcolor' => '#ffffff',
|
||||
'boxborderradius' => '12',
|
||||
'enableboxshadow' => false,
|
||||
'descriptiontextsize' => '13px',
|
||||
|
||||
// Video elements color
|
||||
'playiconcolor' => '',
|
||||
'videotitlecolor' => '',
|
||||
'videouserecolor' => '',
|
||||
'videoviewsecolor' => '',
|
||||
'videocountdowncolor' => '',
|
||||
'videostatscolor' => '',
|
||||
'videodescriptioncolor' => '',
|
||||
|
||||
'enablesubscriberlink' => true,
|
||||
);
|
||||
|
||||
return array_keys( $public );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function get_connected_accounts() {
|
||||
return $this->connected_accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function get_connected_accounts_in_feed() {
|
||||
if ( isset( $this->connected_accounts_in_feed ) ) {
|
||||
return $this->connected_accounts_in_feed;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|string
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function get_transient_name() {
|
||||
if ( isset( $this->transient_name ) ) {
|
||||
return $this->transient_name;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the feed types and terms as well as as some
|
||||
* settings to create a semi-unique feed id used for
|
||||
* caching and other features.
|
||||
*
|
||||
* Overwritten in the Pro version.
|
||||
*
|
||||
* @param string $transient_name
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function set_transient_name( $transient_name = '' ) {
|
||||
|
||||
if ( ! empty( $transient_name ) ) {
|
||||
$this->transient_name = $transient_name;
|
||||
} elseif ( false && ! empty( $this->settings['feedid'] ) ) { // feed ID not yet applicable for transients
|
||||
$this->transient_name = 'sby_' . $this->settings['feedid'];
|
||||
} else {
|
||||
$feed_type_and_terms = $this->feed_type_and_terms;
|
||||
|
||||
$sby_transient_name = 'sby_';
|
||||
|
||||
if ( isset( $feed_type_and_terms['channels'] ) ) {
|
||||
foreach ( $feed_type_and_terms['channels'] as $term_and_params ) {
|
||||
$channel = $term_and_params['term'];
|
||||
$sby_transient_name .= $channel;
|
||||
}
|
||||
}
|
||||
|
||||
$num = $this->settings['num'];
|
||||
|
||||
$num_length = strlen( $num ) + 1;
|
||||
|
||||
//Add both parts of the caching string together and make sure it doesn't exceed 45
|
||||
$sby_transient_name = substr( $sby_transient_name, 0, 45 - $num_length );
|
||||
|
||||
$sby_transient_name .= '#' . $num;
|
||||
|
||||
$this->transient_name = $sby_transient_name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|bool
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function get_feed_type_and_terms() {
|
||||
if ( isset( $this->feed_type_and_terms ) ) {
|
||||
return $this->feed_type_and_terms;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function feed_type_and_terms_display() {
|
||||
|
||||
if ( ! isset( $this->feed_type_and_terms ) ) {
|
||||
return array();
|
||||
}
|
||||
$return = array();
|
||||
foreach ( $this->feed_type_and_terms as $feed_type => $type_terms ) {
|
||||
foreach ( $type_terms as $term ) {
|
||||
$return[] = $term['term'];
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on the settings related to retrieving post data from the API,
|
||||
* this setting is used to make sure all endpoints needed for the feed are
|
||||
* connected and stored for easily looping through when adding posts
|
||||
*
|
||||
* Overwritten in the Pro version.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function set_feed_type_and_terms() {
|
||||
//global $sby_posts_manager;
|
||||
|
||||
$connected_accounts_in_feed = array();
|
||||
$feed_type_and_terms = array(
|
||||
'channels' => array()
|
||||
);
|
||||
|
||||
if ( ! empty( $this->settings['id'] ) ) {
|
||||
$channel_array = is_array( $this->settings['id'] ) ? $this->settings['id'] : explode( ',', str_replace( ' ', '', $this->settings['id'] ) );
|
||||
foreach ( $channel_array as $channel ) {
|
||||
if ( isset( $this->connected_accounts[ $channel ] ) ) {
|
||||
$feed_type_and_terms['channels'][] = array(
|
||||
'term' => $this->connected_accounts[ $channel ]['channel_id'],
|
||||
'params' => array(
|
||||
'channel_id' => $this->connected_accounts[ $channel ]['channel_id']
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $this->connected_accounts[ $channel ]['channel_id'] ] = $this->connected_accounts[ $channel ];
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $connected_accounts_in_feed ) ) {
|
||||
$an_account = array();
|
||||
foreach ( $this->connected_accounts as $account ) {
|
||||
if ( empty( $an_account ) ) {
|
||||
$an_account = $account;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $channel_array as $channel ) {
|
||||
$feed_type_and_terms['channels'][] = array(
|
||||
'term' => $channel,
|
||||
'params' => array(
|
||||
'channel_id' => $channel
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel ] = $an_account;
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ( ! empty( $this->settings['channel'] ) ) {
|
||||
$channel_array = is_array( $this->settings['channel'] ) ? $this->settings['channel'] : explode( ',', str_replace( ' ', '', $this->settings['channel'] ) );
|
||||
|
||||
$an_account = array();
|
||||
foreach ( $this->connected_accounts as $account ) {
|
||||
if ( empty( $an_account ) ) {
|
||||
$an_account = $account;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $channel_array as $channel ) {
|
||||
if ( strpos( $channel, 'UC' ) !== 0 ) {
|
||||
$channel_id = sby_get_channel_id_from_channel_name( $channel );
|
||||
if ( $channel_id ) {
|
||||
$feed_type_and_terms['channels'][] = array(
|
||||
'term' => $channel_id,
|
||||
'params' => array(
|
||||
'channel_id' => $channel_id
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel_id ] = $an_account;
|
||||
} else {
|
||||
$feed_type_and_terms['channels'][] = array(
|
||||
'term' => $channel,
|
||||
'params' => array(
|
||||
'channel_name' => $channel
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel ] = $an_account;
|
||||
}
|
||||
|
||||
} else {
|
||||
$feed_type_and_terms['channels'][] = array(
|
||||
'term' => $channel,
|
||||
'params' => array(
|
||||
'channel_id' => $channel
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $channel ] = $an_account;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
foreach ( $this->connected_accounts as $connected_account ) {
|
||||
if ( empty( $feed_type_and_terms['channels'] ) ) {
|
||||
$feed_type_and_terms['channels'][] = array(
|
||||
'term' => $connected_account['channel_id'],
|
||||
'params' => array(
|
||||
'channel_id' => $connected_account['channel_id']
|
||||
)
|
||||
);
|
||||
$connected_accounts_in_feed[ $connected_account['channel_id'] ] = $connected_account;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$this->connected_accounts_in_feed = $connected_accounts_in_feed;
|
||||
$this->feed_type_and_terms = $feed_type_and_terms;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float|int
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function get_cache_time_in_seconds() {
|
||||
if ( $this->db['caching_type'] === 'background' ) {
|
||||
return SBY_CRON_UPDATE_CACHE_TIME;
|
||||
} else {
|
||||
//If the caching time doesn't exist in the database then set it to be 1 hour
|
||||
$cache_time = isset( $this->settings['cache_time'] ) ? (int)$this->settings['cache_time'] : 1;
|
||||
$cache_time_unit = isset( $this->settings['cache_time_unit'] ) ? $this->settings['cache_time_unit'] : 'hours';
|
||||
|
||||
//Calculate the cache time in seconds
|
||||
if ( $cache_time_unit == 'minutes' ) $cache_time_unit = 60;
|
||||
if ( $cache_time_unit == 'hours' ) $cache_time_unit = 60*60;
|
||||
if ( $cache_time_unit == 'days' ) $cache_time_unit = 60*60*24;
|
||||
|
||||
$cache_time = max( 900, $cache_time * $cache_time_unit );
|
||||
|
||||
return $cache_time;
|
||||
}
|
||||
}
|
||||
|
||||
public function update_settings($update_array = []) {
|
||||
if(!is_array($update_array)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$updated = array_merge($this->settings, array_map(function ($value) {
|
||||
return $this->convert_value($value);
|
||||
}, $update_array));
|
||||
|
||||
return update_option('sby_settings', $updated);
|
||||
}
|
||||
|
||||
private function convert_value($value) {
|
||||
switch($value) {
|
||||
case 'true':
|
||||
return true;
|
||||
case 'false':
|
||||
return false;
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
34
wp-content/plugins/youtube-feed-pro/inc/SBY_Vars.php
Normal file
34
wp-content/plugins/youtube-feed-pro/inc/SBY_Vars.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
|
||||
class SBY_Vars {
|
||||
public function version() { return SBYVER; }
|
||||
|
||||
public function plugin_dir() { return SBY_PLUGIN_DIR; }
|
||||
|
||||
public function plugin_url() { return SBY_PLUGIN_URL; }
|
||||
|
||||
public function plugin_basename() { return SBY_PLUGIN_BASENAME; }
|
||||
|
||||
public function cron_update_cache_time() { return SBY_CRON_UPDATE_CACHE_TIME; }
|
||||
|
||||
public function max_records() { return SBY_MAX_RECORDS; }
|
||||
|
||||
public function text_domain() { return SBY_TEXT_DOMAIN; }
|
||||
|
||||
public function slug() { return SBY_SLUG; }
|
||||
|
||||
public function plugin_name( $with_a_an = false ) { if ( $with_a_an ) { return SBY_INDEF_ART . ' ' . SBY_PLUGIN_NAME; } return SBY_PLUGIN_NAME; }
|
||||
|
||||
public function social_network() { return SBY_SOCIAL_NETWORK; }
|
||||
|
||||
public function setup_url() { return SBY_SETUP_URL; }
|
||||
|
||||
public function support_url() { return SBY_SUPPORT_URL; }
|
||||
|
||||
public function oauth_processor_url() { return SBY_OAUTH_PROCESSOR_URL; }
|
||||
|
||||
public function demo_url() { return SBY_DEMO_URL; }
|
||||
|
||||
public function pro_logo() { return SBY_PRO_LOGO; }
|
||||
}
|
||||
46
wp-content/plugins/youtube-feed-pro/inc/SBY_View.php
Normal file
46
wp-content/plugins/youtube-feed-pro/inc/SBY_View.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Class SBY_View
|
||||
*
|
||||
* This class loads view page template files on the admin dashboard area.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class SBY_View {
|
||||
|
||||
/**
|
||||
* Base file path of the templates
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
const BASE_PATH = SBY_PLUGIN_DIR . 'admin/templates/';
|
||||
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Render template
|
||||
*
|
||||
* @param string $file
|
||||
* @param array $data
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function render( $file, $data = array() ) {
|
||||
$file = str_replace( '.', '/', $file );
|
||||
$file = self::BASE_PATH . $file . '.php';
|
||||
|
||||
if ( file_exists( $file ) ) {
|
||||
if ( ! empty( $data ) ) {
|
||||
extract( $data );
|
||||
}
|
||||
include_once $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
195
wp-content/plugins/youtube-feed-pro/inc/SBY_WP_Post.php
Normal file
195
wp-content/plugins/youtube-feed-pro/inc/SBY_WP_Post.php
Normal file
@@ -0,0 +1,195 @@
|
||||
<?php
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
use SmashBalloon\YouTubeFeed\Pro\SBY_Parse_Pro;
|
||||
use Smashballoon\Customizer\YouTube_License_Tier;
|
||||
|
||||
class SBY_WP_Post
|
||||
{
|
||||
private $youtube_api_data;
|
||||
|
||||
private $feed_id;
|
||||
|
||||
private $wp_post_id;
|
||||
|
||||
public function __construct( $json_or_array, $feed_id ) {
|
||||
$this->youtube_api_data = $json_or_array;
|
||||
$this->feed_id = $feed_id;
|
||||
}
|
||||
|
||||
public function update_post( $status = 'draft' ) {
|
||||
// YouTube license tier
|
||||
$license_tier = new YouTube_License_Tier;
|
||||
$license_tier_features = $license_tier->tier_features();
|
||||
|
||||
// Get global settings
|
||||
$sby_settings = sby_get_database_settings();
|
||||
$wp_posts_disabled = !empty($sby_settings['disable_wp_posts']);
|
||||
|
||||
// Do not create posts if feature is not available in the tier or WP Posts creation disabled
|
||||
if ($wp_posts_disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add a filter to get the post type
|
||||
$post_type = apply_filters('sby_single_videos_post_type', SBY_CPT);
|
||||
$post_status = apply_filters('sby_single_videos_post_status', $status);
|
||||
|
||||
if ( ! $this->get_wp_post_id() ) {
|
||||
$postarr = array(
|
||||
'post_title' => SBY_Parse::get_video_title( $this->youtube_api_data ),
|
||||
'post_content' => $this->get_post_content(),
|
||||
'post_type' => $post_type,
|
||||
'post_date' => date( 'Y-m-d H:i:s', SBY_Parse::get_timestamp( $this->youtube_api_data ) + sby_get_utc_offset() ),
|
||||
'post_date_gmt' => date( 'Y-m-d H:i:s', SBY_Parse::get_timestamp( $this->youtube_api_data ) ),
|
||||
'post_status' => $post_status
|
||||
);
|
||||
$wp_post_id = wp_insert_post( $postarr );
|
||||
|
||||
if ( (int)$wp_post_id > 0 ) {
|
||||
$this->wp_post_id = $wp_post_id;
|
||||
|
||||
$success = $this->update_meta();
|
||||
|
||||
do_action( 'sby_after_insert_video_post', $wp_post_id, $this->youtube_api_data );
|
||||
}
|
||||
} else {
|
||||
do_action( 'sby_after_update_video_post', $this->wp_post_id, $this->youtube_api_data );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function update_meta() {
|
||||
if ( ! isset( $this->wp_post_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$prefix = 'sby_';
|
||||
|
||||
update_post_meta( $this->wp_post_id, $prefix . 'video_id', SBY_Parse::get_video_id( $this->youtube_api_data ) );
|
||||
update_post_meta( $this->wp_post_id, $prefix . 'feed_id', sby_strip_after_hash( $this->feed_id ) );
|
||||
update_post_meta( $this->wp_post_id, $prefix . 'channel_id', SBY_Parse::get_channel_id( $this->youtube_api_data ) );
|
||||
update_post_meta( $this->wp_post_id, $prefix . 'channel_title', SBY_Parse::get_channel_title( $this->youtube_api_data ) );
|
||||
update_post_meta( $this->wp_post_id, $prefix . 'description', SBY_Parse::get_caption( $this->youtube_api_data ) );
|
||||
update_post_meta( $this->wp_post_id, $prefix . 'last_updated', date( 'Y-m-d H:i:s' ) );
|
||||
update_post_meta( $this->wp_post_id, $prefix . 'thumbnails', SBY_Parse::get_media_src_set( $this->youtube_api_data ) );
|
||||
update_post_meta( $this->wp_post_id, $prefix . 'youtube_publish_date', date( 'Y-m-d H:i:s', SBY_Parse::get_timestamp( $this->youtube_api_data ) ) );
|
||||
|
||||
if ( sby_is_pro_version() ) {
|
||||
update_post_meta( $this->wp_post_id, $prefix . 'live_broadcast_content', SBY_Parse_Pro::get_live_broadcast_content( $this->youtube_api_data ) );
|
||||
}
|
||||
|
||||
$post_array = $this->youtube_api_data;
|
||||
|
||||
array_walk_recursive( $post_array, [$this, 'sby_replace_double_quotes'] );
|
||||
|
||||
update_post_meta( $this->wp_post_id, $prefix . 'json', esc_sql( wp_json_encode( $post_array ) ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function post_content_description_is_incomplete() {
|
||||
$content = get_the_content( '', false, $this->get_wp_post_id() );
|
||||
|
||||
return (strpos( $content, '<!-- sby:description-incomplete -->' ) !== false);
|
||||
}
|
||||
|
||||
public function update_video_details() {
|
||||
if ( empty( $this->youtube_api_data['statistics'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$post_id = $this->get_wp_post_id();
|
||||
|
||||
if ( $post_id ) {
|
||||
$prefix = 'sby_';
|
||||
|
||||
if ( sby_is_pro_version() ) {
|
||||
update_post_meta( $post_id, $prefix . 'comment_count', SBY_Parse_Pro::get_comment_count( $this->youtube_api_data ) );
|
||||
update_post_meta( $post_id, $prefix . 'view_count', SBY_Parse_Pro::get_view_count( $this->youtube_api_data ) );
|
||||
update_post_meta( $post_id, $prefix . 'like_count', SBY_Parse_Pro::get_like_count( $this->youtube_api_data ) );
|
||||
update_post_meta( $post_id, $prefix . 'scheduled_start_time', date( 'Y-m-d H:i:s', SBY_Parse_Pro::get_scheduled_start_timestamp( $this->youtube_api_data ) ) );
|
||||
update_post_meta( $post_id, $prefix . 'actual_start_time', date( 'Y-m-d H:i:s', SBY_Parse_Pro::get_actual_start_timestamp( $this->youtube_api_data ) ) );
|
||||
update_post_meta( $post_id, $prefix . 'actual_end_time', date( 'Y-m-d H:i:s', SBY_Parse_Pro::get_actual_end_timestamp( $this->youtube_api_data ) ) );
|
||||
}
|
||||
|
||||
update_post_meta( $post_id, $prefix . 'last_details_check_time', date( 'Y-m-d H:i:s' ) );
|
||||
$description = SBY_Parse::get_caption( $this->youtube_api_data );
|
||||
if ( ! empty( $description ) ) {
|
||||
update_post_meta( $post_id, $prefix . 'description', $description );
|
||||
if ( $this->post_content_description_is_incomplete() ) {
|
||||
$this->update_content();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public function update_content() {
|
||||
$my_post = array();
|
||||
$my_post['ID'] = $this->get_wp_post_id();
|
||||
$my_post['post_content'] = $this->get_post_content( true );
|
||||
|
||||
wp_update_post( $my_post );
|
||||
}
|
||||
|
||||
public static function maybe_get_channel_id_for_name( $name ) {
|
||||
|
||||
}
|
||||
|
||||
public static function maybe_get_channel_id_for_channel_title( $title ) {
|
||||
global $wpdb;
|
||||
|
||||
$channel_id = $wpdb->get_col( $wpdb->prepare( "
|
||||
SELECT Max(CASE
|
||||
WHEN m.meta_key = 'sby_channel_id' THEN m.meta_value
|
||||
ELSE NULL
|
||||
END) AS sby_channel_id
|
||||
FROM $wpdb->postmeta as m
|
||||
WHERE m.post_id IN (SELECT m2.post_id FROM $wpdb->postmeta as m2 WHERE m2.meta_key = 'sby_channel_title' AND m2.meta_value = %s )
|
||||
GROUP BY m.post_id
|
||||
LIMIT 1", $title ) );
|
||||
|
||||
if ( isset( $channel_id[0] ) ) {
|
||||
return $channel_id[0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_wp_post_id() {
|
||||
if ( isset( $this->wp_post_id ) ) {
|
||||
return $this->wp_post_id;
|
||||
}
|
||||
|
||||
$video_id = SBY_Parse::get_video_id( $this->youtube_api_data );
|
||||
|
||||
global $wpdb;
|
||||
$results = $wpdb->get_results( $wpdb->prepare( "SELECT post_id, meta_key FROM $wpdb->postmeta WHERE meta_value = %s AND meta_key = %s", $video_id, 'sby_video_id' ), ARRAY_A );
|
||||
|
||||
if ( isset( $results[0] ) ) {
|
||||
$this->wp_post_id = $results[0]['post_id'];
|
||||
|
||||
return $results[0]['post_id'];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function get_post_content( $override = false ) {
|
||||
$description = SBY_Parse::get_caption( $this->youtube_api_data );
|
||||
$flag = '';
|
||||
if ( ! $override && substr( $description, -3 ) === '...' ) {
|
||||
$flag = '<!-- sby:description-incomplete -->';
|
||||
}
|
||||
|
||||
$content = '['.SBY_SLUG.'-single]<!-- sby:description-start -->' . wp_kses_post( make_clickable( wp_encode_emoji( $description ) ) ) . '<!-- sby:description-end -->' . $flag;
|
||||
|
||||
$content = apply_filters( 'sby_wp_post_content', $content, $this->youtube_api_data, $this->wp_post_id );
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function sby_replace_double_quotes( &$element, $index ) {
|
||||
$element = str_replace( array( '"', "\nn", "\n" ), array( """, '<br />', '<br />' ), $element );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
/**
|
||||
* Class SB_YouTube_Data_Encryption
|
||||
*
|
||||
* @copyright 2021 Google LLC
|
||||
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
|
||||
* @link https://sitekit.withgoogle.com
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class responsible for encrypting and decrypting data.
|
||||
*
|
||||
* @since 2.9.4/5.12.4
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
|
||||
class SB_YouTube_Data_Encryption {
|
||||
|
||||
/**
|
||||
* Key to use for encryption.
|
||||
*
|
||||
* @since 2.9.4/5.12.4
|
||||
* @var string
|
||||
*/
|
||||
private $key;
|
||||
|
||||
/**
|
||||
* Salt to use for encryption.
|
||||
*
|
||||
* @since 2.9.4/5.12.4
|
||||
* @var string
|
||||
*/
|
||||
private $salt;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 2.9.4/5.12.4
|
||||
*/
|
||||
public function __construct( $remote = array() ) {
|
||||
if ( ! empty( $remote ) ) {
|
||||
$this->key = $remote['key'];
|
||||
$this->salt = $remote['salt'];
|
||||
} else {
|
||||
$this->key = $this->get_default_key();
|
||||
$this->salt = $this->get_default_salt();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a value.
|
||||
*
|
||||
* If a user-based key is set, that key is used. Otherwise the default key is used.
|
||||
*
|
||||
* @since 2.9.4/5.12.4
|
||||
*
|
||||
* @param string $value Value to encrypt.
|
||||
* @return string|bool Encrypted value, or false on failure.
|
||||
*/
|
||||
public function encrypt( $value ) {
|
||||
if ( ! sby_doing_openssl() ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$method = 'aes-256-ctr';
|
||||
$ivlen = openssl_cipher_iv_length( $method );
|
||||
$iv = openssl_random_pseudo_bytes( $ivlen );
|
||||
|
||||
$raw_value = openssl_encrypt( $value . $this->salt, $method, $this->key, 0, $iv );
|
||||
if ( ! $raw_value ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return base64_encode( $iv . $raw_value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a value.
|
||||
*
|
||||
* If a user-based key is set, that key is used. Otherwise the default key is used.
|
||||
*
|
||||
* @since 2.9.4/5.12.4
|
||||
*
|
||||
* @param string $raw_value Value to decrypt.
|
||||
* @return string|bool Decrypted value, or false on failure.
|
||||
*/
|
||||
public function decrypt( $raw_value ) {
|
||||
if ( ! sby_doing_openssl() ) {
|
||||
return $raw_value;
|
||||
}
|
||||
|
||||
$raw_value = base64_decode( $raw_value, true );
|
||||
|
||||
$method = 'aes-256-ctr';
|
||||
$ivlen = openssl_cipher_iv_length( $method );
|
||||
$iv = substr( $raw_value, 0, $ivlen );
|
||||
|
||||
$raw_value = substr( $raw_value, $ivlen );
|
||||
|
||||
$value = openssl_decrypt( $raw_value, $method, $this->key, 0, $iv );
|
||||
if ( ! $value || substr( $value, - strlen( $this->salt ) ) !== $this->salt ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return substr( $value, 0, - strlen( $this->salt ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a value that may already be encrypted.
|
||||
*
|
||||
* If a user-based key is set, that key is used. Otherwise the default key is used.
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param string $raw_value Value to encrypt.
|
||||
* @return string|bool encrypted value, or false on failure.
|
||||
*/
|
||||
public function maybe_encrypt( $raw_value ) {
|
||||
$maybe_decrypted = $this->decrypt( $raw_value );
|
||||
|
||||
if ( $maybe_decrypted ) {
|
||||
return $this->encrypt( $maybe_decrypted );
|
||||
}
|
||||
|
||||
return $this->encrypt( $raw_value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default encryption key to use.
|
||||
*
|
||||
* @since 2.9.4/5.12.4
|
||||
*
|
||||
* @return string Default (not user-based) encryption key.
|
||||
*/
|
||||
private function get_default_key() {
|
||||
if ( defined( 'SBI_ENCRYPTION_KEY' ) && '' !== SBI_ENCRYPTION_KEY ) {
|
||||
return SBI_ENCRYPTION_KEY;
|
||||
}
|
||||
|
||||
if ( defined( 'LOGGED_IN_KEY' ) && '' !== LOGGED_IN_KEY ) {
|
||||
return LOGGED_IN_KEY;
|
||||
}
|
||||
|
||||
// If this is reached, you're either not on a live site or have a serious security issue.
|
||||
return 'das-ist-kein-geheimer-schluessel';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default encryption salt to use.
|
||||
*
|
||||
* @since 2.9.4/5.12.4
|
||||
*
|
||||
* @return string Encryption salt.
|
||||
*/
|
||||
private function get_default_salt() {
|
||||
if ( defined( 'SBI_ENCRYPTION_SALT' ) && '' !== SBI_ENCRYPTION_SALT ) {
|
||||
return SBI_ENCRYPTION_SALT;
|
||||
}
|
||||
|
||||
if ( defined( 'LOGGED_IN_SALT' ) && '' !== LOGGED_IN_SALT ) {
|
||||
return LOGGED_IN_SALT;
|
||||
}
|
||||
|
||||
// If this is reached, you're either not on a live site or have a serious security issue.
|
||||
return 'das-ist-kein-geheimes-salz';
|
||||
}
|
||||
}
|
||||
66
wp-content/plugins/youtube-feed-pro/inc/SbyWidget.php
Normal file
66
wp-content/plugins/youtube-feed-pro/inc/SbyWidget.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* Class SbyWidget
|
||||
*
|
||||
* Adds support for a text widget with the [youtube-feed] shortcode inside
|
||||
*/
|
||||
namespace SmashBalloon\YouTubeFeed;
|
||||
|
||||
use WP_Widget;
|
||||
|
||||
class SbyWidget extends WP_Widget
|
||||
{
|
||||
public function __construct() {
|
||||
parent::__construct(
|
||||
'youtube-feeds-widget',
|
||||
__( 'YouTube Feeds', 'feeds-for-youtube' ),
|
||||
array( 'description' => __( 'Display your YouTube feeds', 'feeds-for-youtube' ), )
|
||||
);
|
||||
}
|
||||
|
||||
public function widget( $args, $instance ) {
|
||||
|
||||
$title = isset( $instance['title'] ) ? apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ) : '';
|
||||
$content = isset( $instance['content'] ) ? strip_tags( $instance['content'] ) : '['.SBY_SLUG.']';
|
||||
|
||||
echo $args['before_widget'];
|
||||
|
||||
if ( ! empty( $title ) ) {
|
||||
echo $args['before_title'] . esc_html( $title ) . $args['after_title'];
|
||||
}
|
||||
|
||||
echo do_shortcode( $content );
|
||||
|
||||
echo $args['after_widget'];
|
||||
}
|
||||
|
||||
public function form( $instance ) {
|
||||
|
||||
$title = isset( $instance['title'] ) ? $instance['title'] : '';
|
||||
$content = isset ( $instance['content'] ) ? strip_tags( $instance['content'] ) : '['.SBY_SLUG.']';
|
||||
?>
|
||||
<p>
|
||||
<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php _e( 'Title:' ); ?></label>
|
||||
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
|
||||
</p>
|
||||
<textarea class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'content' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'content' ) ); ?>" rows="16"><?php echo strip_tags( $content ); ?></textarea>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function update( $new_instance, $old_instance ) {
|
||||
$instance = array();
|
||||
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
|
||||
$instance['content'] = ( ! empty( $new_instance['content'] ) ) ? strip_tags( $new_instance['content'] ) : '';
|
||||
|
||||
return $instance;
|
||||
}
|
||||
}
|
||||
|
||||
// register and load the widget
|
||||
function sby_load_widget() {
|
||||
register_widget( 'SbyWidget' );
|
||||
}
|
||||
add_action( 'widgets_init', 'sby_load_widget' );
|
||||
|
||||
// allow shortcode in widgets
|
||||
add_filter( 'widget_text', 'do_shortcode' );
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Services;
|
||||
|
||||
use Smashballoon\Stubs\Services\ServiceProvider;
|
||||
|
||||
class ActivationService extends ServiceProvider {
|
||||
|
||||
public function register() {
|
||||
add_action( 'activated_plugin', [ $this, 'on_plugin_activation' ] );
|
||||
}
|
||||
|
||||
public function on_plugin_activation( $plugin ) {
|
||||
if ( ! in_array( basename( $plugin ), array( 'youtube-feed.php', 'youtube-feed-pro.php' ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$plugin_to_deactivate = 'youtube-feed.php';
|
||||
if ( basename( $plugin ) === $plugin_to_deactivate ) {
|
||||
$plugin_to_deactivate = 'youtube-feed-pro.php';
|
||||
}
|
||||
|
||||
foreach ( $this->get_active_plugins() as $basename ) {
|
||||
if ( false !== strpos( $basename, $plugin_to_deactivate ) ) {
|
||||
deactivate_plugins( $basename );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function get_active_plugins() {
|
||||
if ( is_multisite() ) {
|
||||
$active_plugins = array_keys( (array) get_site_option( 'active_sitewide_plugins', array() ) );
|
||||
} else {
|
||||
$active_plugins = (array) get_option( 'active_plugins', array() );
|
||||
}
|
||||
|
||||
return $active_plugins;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Services\Admin;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\Vendor\DI\Container;
|
||||
use Smashballoon\Stubs\Services\ServiceProvider;
|
||||
use SmashBalloon\YouTubeFeed\Customizer\Customizer_Compatibility;
|
||||
use SmashBalloon\YouTubeFeed\Pro\SBY_API_Connect_Pro;
|
||||
use SmashBalloon\YouTubeFeed\SBY_API_Connect;
|
||||
use SmashBalloon\YouTubeFeed\SBY_Settings;
|
||||
use SmashBalloon\YouTubeFeed\Admin\SBY_Admin_Notice;
|
||||
use SmashBalloon\YouTubeFeed\Services\Admin\Settings\PagesServiceContainer;
|
||||
|
||||
class AdminServiceContainer extends ServiceProvider {
|
||||
private $services = [
|
||||
MenuService::class,
|
||||
Customizer_Compatibility::class,
|
||||
AssetsService::class,
|
||||
GUIService::class,
|
||||
LicenseService::class,
|
||||
MiscService::class,
|
||||
PagesServiceContainer::class,
|
||||
SourcesService::class,
|
||||
SBY_Admin_Notice::class,
|
||||
ImporterService::class,
|
||||
CacheService::class
|
||||
];
|
||||
|
||||
public function register() {
|
||||
$container = \SmashBalloon\YouTubeFeed\Container::get_instance();
|
||||
$container->set(SBY_Settings::class, new SBY_Settings([], sby_get_database_settings()));
|
||||
foreach ( $this->services as $service ) {
|
||||
$container->get($service)->register();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Services\Admin;
|
||||
|
||||
|
||||
use Smashballoon\Stubs\Services\ServiceProvider;
|
||||
|
||||
class AssetsService extends ServiceProvider {
|
||||
|
||||
public function register() {
|
||||
add_action( 'admin_enqueue_scripts', [$this, 'sby_admin_style'] );
|
||||
add_action( 'admin_enqueue_scripts', [$this, 'sby_admin_scripts'] );
|
||||
add_action( 'admin_enqueue_scripts', [$this, 'enqueue_vue_assets'] );
|
||||
}
|
||||
|
||||
public function enqueue_vue_assets() {
|
||||
if ( ! sby_is_admin_page() ) {
|
||||
return;
|
||||
}
|
||||
wp_enqueue_script(
|
||||
'feed-builder-vue',
|
||||
'https://cdn.jsdelivr.net/npm/vue@2.6.12',
|
||||
null,
|
||||
'2.6.12',
|
||||
true
|
||||
);
|
||||
}
|
||||
public function sby_admin_style() {
|
||||
wp_enqueue_style( SBY_SLUG . '_admin_notices_css', SBY_PLUGIN_URL . 'css/sby-notices.css', array(), SBYVER );
|
||||
wp_enqueue_style( SBY_SLUG . '_admin_css', SBY_PLUGIN_URL . 'css/admin.css', array(), SBYVER );
|
||||
if ( ! sby_is_admin_page() ) {
|
||||
return;
|
||||
}
|
||||
wp_enqueue_style( 'sb_font_awesome',
|
||||
'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css' );
|
||||
wp_enqueue_style( 'wp-color-picker' );
|
||||
}
|
||||
|
||||
public function sby_admin_scripts() {
|
||||
// We need to enqueue this globally
|
||||
wp_enqueue_script( SBY_SLUG . '_sby_admin_js', SBY_PLUGIN_URL . 'js/sby-admin.js', array(), SBYVER );
|
||||
|
||||
// wp_enqueue_script( SBY_SLUG . '_admin_js', SBY_PLUGIN_URL . 'js/admin.js', array(), SBYVER );
|
||||
wp_localize_script( SBY_SLUG . '_sby_admin_js', 'sby_admin', array(
|
||||
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
|
||||
'nonce' => wp_create_nonce( 'sby-admin' )
|
||||
)
|
||||
);
|
||||
if ( ! sby_is_admin_page() ) {
|
||||
return;
|
||||
}
|
||||
wp_enqueue_script( 'wp-color-picker' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Services\Admin;
|
||||
|
||||
use Smashballoon\Stubs\Services\ServiceProvider;
|
||||
use SmashBalloon\YouTubeFeed\Helpers\Util;
|
||||
|
||||
class CacheService extends ServiceProvider {
|
||||
|
||||
public function register() {
|
||||
add_action( 'wp_ajax_sby_clear_cache', [ $this, 'ajax_clear_cache' ] );
|
||||
}
|
||||
|
||||
public function ajax_clear_cache() {
|
||||
Util::ajaxPreflightChecks();
|
||||
// clear object cache
|
||||
sby_clear_object_cache();
|
||||
// clear transients
|
||||
sby_clear_cache();
|
||||
wp_clear_scheduled_hook( 'sby_feed_update' );
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Services\Admin;
|
||||
|
||||
|
||||
use Smashballoon\Stubs\Services\ServiceProvider;
|
||||
|
||||
class GUIService extends ServiceProvider {
|
||||
public function register() {
|
||||
add_action( 'wp_ajax_sby_dismiss_api_key_notice', [$this, 'sby_dismiss_api_key_notice'] );
|
||||
add_action( 'wp_ajax_sby_dismiss_at_warning_notice', [$this, 'sby_dismiss_at_warning_notice'] );
|
||||
add_action( 'wp_ajax_sby_dismiss_connect_warning_button', [$this, 'sby_dismiss_connect_warning_notice'] );
|
||||
add_action( 'admin_footer', [$this, 'sby_access_token_warning_modal'], 1 );
|
||||
add_action('admin_init', [$this, 'sby_nag_ignore']);
|
||||
add_action( 'admin_print_scripts', [$this, 'sby_admin_hide_unrelated_notices'] );
|
||||
}
|
||||
|
||||
public function sby_dismiss_api_key_notice() {
|
||||
|
||||
update_user_meta( get_current_user_id(), 'sby_api_key_notice', 'dismissed' );
|
||||
|
||||
die();
|
||||
}
|
||||
public function sby_dismiss_at_warning_notice() {
|
||||
|
||||
update_user_meta( get_current_user_id(), 'sby_at_warning_notice', time() );
|
||||
|
||||
die();
|
||||
}
|
||||
public function sby_dismiss_connect_warning_notice() {
|
||||
|
||||
update_user_meta( get_current_user_id(), 'sby_connect_warning_notice', time() );
|
||||
|
||||
die();
|
||||
}
|
||||
public function sby_access_token_warning_modal() {
|
||||
if ( isset( $_GET['page'] ) && $_GET['page'] === SBY_SLUG && isset( $_GET['sby_access_token'] ) && sby_notice_not_dismissed() ) {
|
||||
$text_domain = SBY_TEXT_DOMAIN;
|
||||
include_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/Admin/templates/modal.php';
|
||||
echo '<span class="sby_account_just_added"></span>';
|
||||
}
|
||||
|
||||
}
|
||||
public function sby_nag_ignore() {
|
||||
global $current_user;
|
||||
$user_id = $current_user->ID;
|
||||
if ( isset($_GET['sby_nag_ignore']) && '0' == $_GET['sby_nag_ignore'] ) {
|
||||
add_user_meta($user_id, 'sby_ignore_notice', 'true', true);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Remove non-WPForms notices from WPForms pages.
|
||||
*
|
||||
* @since 1.3.9
|
||||
*/
|
||||
public function sby_admin_hide_unrelated_notices() {
|
||||
|
||||
// Bail if we're not on a Sby screen or page.
|
||||
if ( ! sby_is_admin_page() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Extra banned classes and callbacks from third-party plugins.
|
||||
$blacklist = array(
|
||||
'classes' => array(),
|
||||
'callbacks' => array(
|
||||
'sbydb_admin_notice', // 'Database for Sby' plugin.
|
||||
),
|
||||
);
|
||||
|
||||
global $wp_filter;
|
||||
|
||||
foreach ( array( 'user_admin_notices', 'admin_notices', 'all_admin_notices' ) as $notices_type ) {
|
||||
if ( empty( $wp_filter[ $notices_type ]->callbacks ) || ! is_array( $wp_filter[ $notices_type ]->callbacks ) ) {
|
||||
continue;
|
||||
}
|
||||
foreach ( $wp_filter[ $notices_type ]->callbacks as $priority => $hooks ) {
|
||||
foreach ( $hooks as $name => $arr ) {
|
||||
if ( $arr['function'] instanceof \Closure ) {
|
||||
unset( $wp_filter[ $notices_type ]->callbacks[ $priority ][ $name ] );
|
||||
continue;
|
||||
}
|
||||
$class = ! empty( $arr['function'][0] ) && is_object( $arr['function'][0] ) ? strtolower( get_class( $arr['function'][0] ) ) : '';
|
||||
if (
|
||||
! empty( $class ) &&
|
||||
strpos( $class, 'sby' ) !== false &&
|
||||
! in_array( $class, $blacklist['classes'], true )
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
! empty( $name ) && (
|
||||
strpos( $name, 'sby' ) === false ||
|
||||
in_array( $class, $blacklist['classes'], true ) ||
|
||||
in_array( $name, $blacklist['callbacks'], true )
|
||||
)
|
||||
) {
|
||||
unset( $wp_filter[ $notices_type ]->callbacks[ $priority ][ $name ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Services\Admin;
|
||||
|
||||
use Smashballoon\Customizer\Feed_Saver_Manager;
|
||||
use Smashballoon\Stubs\Services\ServiceProvider;
|
||||
use SmashBalloon\YouTubeFeed\Helpers\Util;
|
||||
|
||||
class ImporterService extends ServiceProvider {
|
||||
/**
|
||||
* @var Feed_Saver_Manager
|
||||
*/
|
||||
private $saver_manager;
|
||||
|
||||
public function __construct(Feed_Saver_Manager $saver_manager) {
|
||||
$this->saver_manager = $saver_manager;
|
||||
}
|
||||
|
||||
public function register() {
|
||||
add_action('wp_ajax_sby_do_feed_import', [$this, 'ajax_handle_file_import']);
|
||||
}
|
||||
|
||||
public function ajax_handle_file_import() {
|
||||
Util::ajaxPreflightChecks();
|
||||
|
||||
$filename = $_FILES['feedFile']['name'];
|
||||
$ext = pathinfo( $filename, PATHINFO_EXTENSION );
|
||||
|
||||
if ( 'json' !== $ext ) {
|
||||
wp_send_json_error(['message' => __('Unsupported file type.', 'feeds-for-youtube'), 'success' => false]);
|
||||
}
|
||||
|
||||
$imported_settings = file_get_contents( $_FILES['feedFile']['tmp_name'] );
|
||||
|
||||
if ( empty($imported_settings) ) {
|
||||
wp_send_json_error(['message' => __('Could not parse file contents.', 'feeds-for-youtube'), 'success' => false]);
|
||||
}
|
||||
|
||||
$decoded_settings = json_decode($imported_settings, true);
|
||||
|
||||
$result = $this->saver_manager->import_feed($imported_settings, $decoded_settings['feedName']);
|
||||
|
||||
wp_send_json_success($result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,761 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Services\Admin;
|
||||
|
||||
use Smashballoon\Stubs\Services\ServiceProvider;
|
||||
use SmashBalloon\YouTubeFeed\Helpers\Util;
|
||||
use SmashBalloon\YouTubeFeed\HTTP_Request;
|
||||
use SmashBalloon\YouTubeFeed\Response;
|
||||
use SmashBalloon\YouTubeFeed\Services\LicenseNotification;
|
||||
|
||||
class LicenseService extends ServiceProvider {
|
||||
|
||||
private $license_service;
|
||||
|
||||
public function __construct() {
|
||||
$this->license_service = new LicenseNotification();
|
||||
}
|
||||
|
||||
public function register() {
|
||||
/* Display a license expired notice */
|
||||
add_action('sby_admin_notices', [$this, 'sby_renew_license_notice']);
|
||||
add_action('sby_admin_header_notices', [$this, 'sby_admin_header_license_notice']);
|
||||
|
||||
// Add extra localize script items
|
||||
add_filter('sby_localized_settings', [$this, 'localized_license_settings']);
|
||||
add_action('wp_ajax_sby_check_connection', [$this, 'test_connection']);
|
||||
add_action('wp_ajax_sby_license_activation', [$this, 'ajax_activate_license']);
|
||||
add_action('wp_ajax_sby_license_deactivation', [$this, 'ajax_deactivate_license']);
|
||||
add_action( 'wp_ajax_sby_check_license', [ $this, 'check_license' ] );
|
||||
add_action( 'wp_ajax_sby_dismiss_license_notice', [ $this, 'dismiss_license_notice' ] );
|
||||
}
|
||||
|
||||
public function localized_license_settings($settings) {
|
||||
$license_key = $this->get_license_key();
|
||||
|
||||
$settings['licenseStatus'] = $this->get_license_status();
|
||||
$settings['licenseData'] = $this->get_license_data();
|
||||
$settings['licenseKey'] = $license_key;
|
||||
$settings['upgradeUrl'] = sprintf( 'https://smashballoon.com/youtube-feed/pricing/?edd_license_key=%s&upgrade=true&utm_campaign=youtube-pro&utm_source=settings&utm_medium=upgrade-license', $this->get_license_key() );
|
||||
return $settings;
|
||||
}
|
||||
|
||||
public function test_connection() {
|
||||
check_ajax_referer( 'sby-admin', 'nonce' );
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_send_json_error(); // This auto-dies.
|
||||
}
|
||||
|
||||
$api_params = array(
|
||||
'edd_action' => 'check_license',
|
||||
'license' => $this->get_license_key(),
|
||||
'item_name' => urlencode( SBY_PLUGIN_EDD_NAME ), // the name of our product in EDD
|
||||
);
|
||||
$url = add_query_arg( $api_params, SBY_STORE_URL );
|
||||
$args = array(
|
||||
'timeout' => 60,
|
||||
);
|
||||
// Make the remote API request
|
||||
$request = HTTP_Request::request( 'GET', $url, $args );
|
||||
|
||||
if ( HTTP_Request::is_error( $request ) ) {
|
||||
$response = new Response(
|
||||
false,
|
||||
array(
|
||||
'hasError' => true,
|
||||
)
|
||||
);
|
||||
$response->send();
|
||||
}
|
||||
|
||||
$response = new Response(
|
||||
true,
|
||||
array(
|
||||
'hasError' => false,
|
||||
)
|
||||
);
|
||||
|
||||
$response->send();
|
||||
}
|
||||
|
||||
public function ajax_deactivate_license() {
|
||||
check_ajax_referer( 'sby-admin', 'nonce' );
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_send_json_error(); // This auto-dies.
|
||||
}
|
||||
|
||||
$response = $this->sby_deactivate_license();
|
||||
|
||||
if ( $response === true ) {
|
||||
wp_send_json_success( [
|
||||
'licenseStatus' => $this->get_license_status(),
|
||||
'licenseData' => $this->get_license_data()
|
||||
] );
|
||||
}
|
||||
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
public function ajax_activate_license() {
|
||||
check_ajax_referer( 'sby-admin', 'nonce' );
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_send_json_error(); // This auto-dies.
|
||||
}
|
||||
|
||||
$license_key = sanitize_text_field($_POST['license_key']);
|
||||
|
||||
$response = $this->sby_activate_license($license_key);
|
||||
|
||||
if ( $response === true ) {
|
||||
wp_send_json_success( [
|
||||
'licenseStatus' => $this->get_license_status(),
|
||||
'licenseData' => $this->get_license_data()
|
||||
] );
|
||||
}
|
||||
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
public function sby_activate_license($license_key) {
|
||||
// retrieve the license from the database
|
||||
$sby_license = trim( $license_key );
|
||||
|
||||
|
||||
// data to send in our API request
|
||||
$api_params = array(
|
||||
'edd_action' => 'activate_license',
|
||||
'license' => $sby_license,
|
||||
'item_name' => urlencode( SBY_PLUGIN_EDD_NAME ), // the name of our product in EDD
|
||||
'url' => home_url()
|
||||
);
|
||||
|
||||
// Call the custom API.
|
||||
$response = wp_remote_get( add_query_arg( $api_params, SBY_STORE_URL ),
|
||||
array( 'timeout' => 15, 'sslverify' => false ) );
|
||||
|
||||
// make sure the response came back okay
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// decode the license data
|
||||
$sby_license_data = json_decode( wp_remote_retrieve_body( $response ) );
|
||||
|
||||
if (
|
||||
isset( $sby_license_data->success ) && ( $sby_license_data->success == false ) ||
|
||||
isset( $sby_license_data->error ) && ( $sby_license_data->error == 'missing' ) ||
|
||||
isset( $sby_license_data->license ) && (
|
||||
$sby_license_data->license == 'invalid_item_id' ||
|
||||
$sby_license_data->license == 'invalid' ||
|
||||
$sby_license_data->license == 'expired'
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// only store the license key
|
||||
update_option( 'sby_license_key', $license_key );
|
||||
//store the license data in an option
|
||||
update_option( 'sby_license_data', $sby_license_data );
|
||||
// $license_data->license will be either "valid" or "invalid"
|
||||
update_option( 'sby_license_status', $sby_license_data->license );
|
||||
// make license check_api true so next time it expires it checks again
|
||||
update_option( 'sby_check_license_api_when_expires', 'true' );
|
||||
update_option( 'sby_check_license_api_post_grace_period', 'true' );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function sby_deactivate_license() {
|
||||
|
||||
// retrieve the license from the database
|
||||
$sby_license= trim( get_option( 'sby_license_key' ) );
|
||||
|
||||
|
||||
// data to send in our API request
|
||||
$api_params = array(
|
||||
'edd_action'=> 'deactivate_license',
|
||||
'license' => $sby_license,
|
||||
'item_name' => urlencode( SBY_PLUGIN_EDD_NAME ), // the name of our product in EDD
|
||||
'url' => home_url()
|
||||
);
|
||||
|
||||
// Call the custom API.
|
||||
$response = wp_remote_get( add_query_arg( $api_params, SBY_STORE_URL ), array( 'timeout' => 15, 'sslverify' => false ) );
|
||||
|
||||
// make sure the response came back okay
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// decode the license data
|
||||
$sby_license_data = json_decode( wp_remote_retrieve_body( $response ) );
|
||||
|
||||
// $license_data->license will be either "deactivated" or "failed"
|
||||
if( $sby_license_data->license == 'deactivated' || $sby_license_data->license == 'failed' ) {
|
||||
delete_option( 'sby_license_data' );
|
||||
delete_option( 'sby_license_status' );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check license key
|
||||
*
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public function sby_check_license( $sby_license, $check_license_status = false ) {
|
||||
// data to send in our API request
|
||||
$sby_api_params = array(
|
||||
'edd_action'=> 'check_license',
|
||||
'license' => $sby_license,
|
||||
'item_name' => urlencode( SBY_PLUGIN_NAME ) // the name of our product in EDD
|
||||
);
|
||||
$api_url = add_query_arg( $sby_api_params, SBY_STORE_URL );
|
||||
$args = array(
|
||||
'timeout' => 60,
|
||||
'sslverify' => false
|
||||
);
|
||||
// Call the custom API.
|
||||
$request = wp_remote_get( $api_url, $args );
|
||||
if ( is_wp_error( $request ) ) {
|
||||
return;
|
||||
}
|
||||
// decode the license data
|
||||
$sby_license_data = json_decode( wp_remote_retrieve_body( $request ) );
|
||||
|
||||
if ( $check_license_status ) {
|
||||
//Check whether it's active
|
||||
if( $sby_license_data['license'] !== 'expired' && ( strtotime( $sby_license_data['expires'] ) > strtotime( $sby_todays_date ) ) ){
|
||||
$sby_license_status = false;
|
||||
} else {
|
||||
$sby_license_status = true;
|
||||
//Set a flag so it doesn't check the API again until the next time it expires
|
||||
update_option( 'sby_check_license_api_when_expires', 'false' );
|
||||
}
|
||||
|
||||
return $sby_license_status;
|
||||
}
|
||||
|
||||
//Store license data in db
|
||||
update_option( 'sby_license_data', $sby_license_data );
|
||||
|
||||
return $sby_license_data;
|
||||
}
|
||||
|
||||
public function sby_renew_license_notice() {
|
||||
if ( !current_user_can( Util::sby_capability_check() ) ) {
|
||||
return;
|
||||
}
|
||||
// We will display the license notice only on specified allowed screens
|
||||
if ( ! Util::isCurrentScreenAllowed() ) {
|
||||
return;
|
||||
}
|
||||
// Check that the license exists and the user hasn't already clicked to ignore the message
|
||||
if ( empty( Util::get_license_key() ) ) {
|
||||
return;
|
||||
}
|
||||
// If license not expired then return;
|
||||
if ( !Util::is_license_expired() ) {
|
||||
return;
|
||||
}
|
||||
// Grace period ended?
|
||||
if ( Util::is_license_grace_period_ended() ) {
|
||||
return;
|
||||
}
|
||||
// So, license has expired and grace period active
|
||||
// Lets display the error notice
|
||||
echo $this->get_expired_license_notice_content();
|
||||
}
|
||||
|
||||
public function old_sby_renew_license_notice() {
|
||||
|
||||
//Show this notice on every page apart from the YouTube Feed settings pages
|
||||
isset($_GET['page'])? $sby_check_page = $_GET['page'] : $sby_check_page = '';
|
||||
( $sby_check_page == 'youtube-feed' || $sby_check_page == 'sby_single_settings' || $sby_check_page == 'youtube-feed_license' ) ? $sby_notice_dismissible = false : $sby_notice_dismissible = true;
|
||||
|
||||
//If the user is re-checking the license key then use the API below to recheck it
|
||||
( isset( $_GET['sbychecklicense'] ) ) ? $sby_check_license = true : $sby_check_license = false;
|
||||
|
||||
$sby_license = trim( get_option( 'sby_license_key' ) );
|
||||
|
||||
global $current_user;
|
||||
$user_id = $current_user->ID;
|
||||
|
||||
// Use this to show notice again
|
||||
// delete_user_meta($user_id, 'sby_ignore_notice');
|
||||
|
||||
/* Check that the license exists and the user hasn't already clicked to ignore the message */
|
||||
if( empty($sby_license) || !isset($sby_license) || ( ( get_user_meta( $user_id,
|
||||
'sby_ignore_notice' ) && $sby_notice_dismissible ) && ! $sby_check_license ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Is there already license data in the db?
|
||||
if( get_option( 'sby_license_data' ) && !$sby_check_license ){
|
||||
//Yes
|
||||
//Get license data from the db and convert the object to an array
|
||||
$sby_license_data = (array) get_option( 'sby_license_data' );
|
||||
} else {
|
||||
//No
|
||||
// data to send in our API request
|
||||
$sby_api_params = array(
|
||||
'edd_action'=> 'check_license',
|
||||
'license' => $sby_license,
|
||||
'item_name' => urlencode( SBY_PLUGIN_EDD_NAME ) // the name of our product in EDD
|
||||
);
|
||||
|
||||
// Call the custom API.
|
||||
$sby_response = wp_remote_get( add_query_arg( $sby_api_params, SBY_STORE_URL ), array( 'timeout' => 60, 'sslverify' => false ) );
|
||||
|
||||
// decode the license data
|
||||
$sby_license_data = (array) json_decode( wp_remote_retrieve_body( $sby_response ) );
|
||||
|
||||
//Store license data in db
|
||||
update_option( 'sby_license_data', $sby_license_data );
|
||||
}
|
||||
|
||||
//Number of days until license expires
|
||||
$sby_license_expires_date = isset( $sby_license_data['expires'] ) ? $sby_license_data['expires'] : $sby_license_expires_date = '2036-12-31 23:59:59'; //If expires param isn't set yet then set it to be a date to avoid PHP notice
|
||||
if( $sby_license_expires_date == 'lifetime' ) $sby_license_expires_date = '2036-12-31 23:59:59';
|
||||
$sby_todays_date = date('Y-m-d');
|
||||
$sby_interval = round(abs(strtotime($sby_todays_date . ' -1 day')-strtotime($sby_license_expires_date))/86400); //-1 day to make sure auto-renewal has run before showing expired
|
||||
|
||||
//Is license expired?
|
||||
if( $sby_interval == 0 || strtotime($sby_license_expires_date) < strtotime($sby_todays_date) ){
|
||||
|
||||
//If we haven't checked the API again one last time before displaying the expired notice then check it to make sure the license hasn't been renewed
|
||||
if( get_option( 'sby_check_license_api_when_expires' ) == FALSE || get_option( 'sby_check_license_api_when_expires' ) == 'true' ){
|
||||
|
||||
// Check the API
|
||||
$sby_api_params = array(
|
||||
'edd_action'=> 'check_license',
|
||||
'license' => $sby_license,
|
||||
'item_name' => urlencode( SBY_PLUGIN_EDD_NAME ) // the name of our product in EDD
|
||||
);
|
||||
$sby_response = wp_remote_get( add_query_arg( $sby_api_params, SBY_STORE_URL ), array( 'timeout' => 60, 'sslverify' => false ) );
|
||||
$sby_license_data = (array) json_decode( wp_remote_retrieve_body( $sby_response ) );
|
||||
|
||||
//Check whether it's active
|
||||
if( $sby_license_data['license'] !== 'expired' && ( strtotime( $sby_license_data['expires'] ) > strtotime($sby_todays_date) ) ){
|
||||
$sby_license_expired = false;
|
||||
} else {
|
||||
$sby_license_expired = true;
|
||||
//Set a flag so it doesn't check the API again until the next time it expires
|
||||
update_option( 'sby_check_license_api_when_expires', 'false' );
|
||||
}
|
||||
|
||||
//Store license data in db
|
||||
update_option( 'sby_license_data', $sby_license_data );
|
||||
|
||||
} else {
|
||||
//Display the expired notice
|
||||
$sby_license_expired = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
$sby_license_expired = false;
|
||||
|
||||
//License is not expired so change the check_api setting to be true so the next time it expires it checks again
|
||||
update_option( 'sby_check_license_api_when_expires', 'true' );
|
||||
}
|
||||
|
||||
//If expired date is returned as 1970 (or any other 20th century year) then it means that the correct expired date was not returned and so don't show the renewal notice
|
||||
if( $sby_license_expires_date[0] == '1' ) $sby_license_expired = false;
|
||||
|
||||
//If there's no expired date then don't show the expired notification
|
||||
if( empty($sby_license_expires_date) || !isset($sby_license_expires_date) ) $sby_license_expired = false;
|
||||
|
||||
//Is license missing - ie. on very first check
|
||||
if( isset($sby_license_data['error']) ){
|
||||
if( $sby_license_data['error'] == 'missing' ) $sby_license_expired = false;
|
||||
}
|
||||
|
||||
|
||||
//Is the license expired?
|
||||
if( $sby_license_expired || $sby_check_license ) {
|
||||
|
||||
global $sby_download_id;
|
||||
|
||||
$sby_expired_box_classes = "sby-license-expired";
|
||||
|
||||
$sby_expired_box_msg = '<svg style="width:16px;height:16px;" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="exclamation-triangle" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="svg-inline--fa fa-exclamation-triangle fa-w-18 fa-2x"><path fill="currentColor" d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z" class=""></path></svg>';
|
||||
$sby_expired_box_msg .= "<b>Important: Your YouTube Feeds Pro license key has expired.</b><br /><span>You are no longer receiving updates that protect you against upcoming YouTube platform changes.</span>";
|
||||
|
||||
//Create the re-check link using the existing query string in the URL
|
||||
$sby_url = '?' . $_SERVER["QUERY_STRING"];
|
||||
//Determine the separator
|
||||
( !empty($sby_url) && $sby_url != '' ) ? $separator = '&' : $separator = '';
|
||||
//Add the param to check license if it doesn't already exist in URL
|
||||
if( strpos($sby_url, 'sbychecklicense') === false ) $sby_url .= $separator . "sbychecklicense=true";
|
||||
|
||||
//Create the notice message
|
||||
$sby_expired_box_msg .= " <a href='https://smashballoon.com/checkout/?edd_license_key=".$sby_license."&download_id=".$sby_download_id."&utm_source=plugin-pro&utm_campaign=youtube-pro&utm_medium=expired-notice-dashboard' target='_blank' class='button button-primary'>Renew License</a><a href='javascript:void(0);' id='sby-why-renew-show' onclick='sbyShowReasons()' class='button button-secondary'>Why renew?</a><a href='javascript:void(0);' id='sby-why-renew-hide' onclick='sbyHideReasons()' class='button button-secondary' style='display: none;'>Hide text</a> <a href='".$sby_url."' class='button button-secondary'>Re-check License</a></p>
|
||||
<div id='sby-why-renew' style='display: none;'>
|
||||
<h4><svg style='width:16px;height:16px;' aria-hidden='true' focusable='false' data-prefix='fas' data-icon='shield-check' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' class='svg-inline--fa fa-shield-check fa-w-16 fa-2x' data-ce-key='470'><path fill='currentColor' d='M466.5 83.7l-192-80a48.15 48.15 0 0 0-36.9 0l-192 80C27.7 91.1 16 108.6 16 128c0 198.5 114.5 335.7 221.5 380.3 11.8 4.9 25.1 4.9 36.9 0C360.1 472.6 496 349.3 496 128c0-19.4-11.7-36.9-29.5-44.3zm-47.2 114.2l-184 184c-6.2 6.2-16.4 6.2-22.6 0l-104-104c-6.2-6.2-6.2-16.4 0-22.6l22.6-22.6c6.2-6.2 16.4-6.2 22.6 0l70.1 70.1 150.1-150.1c6.2-6.2 16.4-6.2 22.6 0l22.6 22.6c6.3 6.3 6.3 16.4 0 22.6z' class='' data-ce-key='471'></path></svg>Protected Against All Upcoming YouTube Platform Updates and API Changes</h4>
|
||||
<p>You currently don't need to worry about your YouTube feeds breaking due to constant changes in the YouTube platform. You are currently protected by access to continual plugin updates, giving you peace of mind that the software will always be up to date.</p>
|
||||
|
||||
<h4><svg style='width:16px;height:16px;' aria-hidden='true' focusable='false' data-prefix='fab' data-icon='wordpress' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' class='svg-inline--fa fa-wordpress fa-w-16 fa-2x'><path fill='currentColor' d='M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z' class=''></path></svg>WordPress Compatability Updates</h4>
|
||||
<p>With WordPress updates being released continually, we make sure the plugin is always compatible with the latest version so you can update WordPress without needing to worry.</p>
|
||||
|
||||
<h4><svg style='width:16px;height:16px;' aria-hidden='true' focusable='false' data-prefix='far' data-icon='life-ring' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' class='svg-inline--fa fa-life-ring fa-w-16 fa-2x' data-ce-key='500'><path fill='currentColor' d='M256 504c136.967 0 248-111.033 248-248S392.967 8 256 8 8 119.033 8 256s111.033 248 248 248zm-103.398-76.72l53.411-53.411c31.806 13.506 68.128 13.522 99.974 0l53.411 53.411c-63.217 38.319-143.579 38.319-206.796 0zM336 256c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zm91.28 103.398l-53.411-53.411c13.505-31.806 13.522-68.128 0-99.974l53.411-53.411c38.319 63.217 38.319 143.579 0 206.796zM359.397 84.72l-53.411 53.411c-31.806-13.505-68.128-13.522-99.973 0L152.602 84.72c63.217-38.319 143.579-38.319 206.795 0zM84.72 152.602l53.411 53.411c-13.506 31.806-13.522 68.128 0 99.974L84.72 359.398c-38.319-63.217-38.319-143.579 0-206.796z' class='' data-ce-key='501'></path></svg>Expert Technical Support</h4>
|
||||
<p>Without a valid license key you will no longer be able to receive updates or support for the YouTube Feeds plugin. A renewed license key grants you access to our top-notch, quick and effective support for another full year.</p>
|
||||
|
||||
<h4><svg style='width:16px;height:16px;' aria-hidden='true' focusable='false' data-prefix='fas' data-icon='unlock' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512' class='svg-inline--fa fa-unlock fa-w-14 fa-2x' data-ce-key='477'><path fill='currentColor' d='M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z' class='' data-ce-key='478'></path></svg>All Pro YouTube Feeds Features</h4>
|
||||
<p>Live Streaming API, Custom End-of-Video Actions, YouTube Search API, Carousel Sliders, Combine Feeds, Convert Videos to WP Posts, Favorites, Video Filtering, Smart Video Player Loading, and more!</p>
|
||||
</div>";
|
||||
|
||||
if( $sby_check_license && !$sby_license_expired ){
|
||||
$sby_expired_box_classes = "sby-license-expired sby-license-valid";
|
||||
$sby_expired_box_msg = "Thanks ".$sby_license_data["customer_name"].", your YouTube Feeds Pro license key is valid.";
|
||||
}
|
||||
|
||||
_e("<div class='".$sby_expired_box_classes."'>");
|
||||
if( $sby_notice_dismissible ){
|
||||
_e("<a style='float:right; color: #dd3d36; text-decoration: none;' href='" .esc_url( add_query_arg( 'sby_nag_ignore', '0' ) ). "'>Dismiss</a>");
|
||||
}
|
||||
_e("<p>".$sby_expired_box_msg."
|
||||
</div>
|
||||
<script type='text/javascript'>
|
||||
function sbyShowReasons() {
|
||||
document.getElementById('sby-why-renew').style.display = 'block';
|
||||
document.getElementById('sby-why-renew-show').style.display = 'none';
|
||||
document.getElementById('sby-why-renew-hide').style.display = 'inline-block';
|
||||
}
|
||||
function sbyHideReasons() {
|
||||
document.getElementById('sby-why-renew').style.display = 'none';
|
||||
document.getElementById('sby-why-renew-show').style.display = 'inline-block';
|
||||
document.getElementById('sby-why-renew-hide').style.display = 'none';
|
||||
}
|
||||
</script>
|
||||
<style>.sby-license-expired{clear:both;width:96%;margin:10px 0 20px 0;background:#f7e6e6;padding:15px 1.5%;border:1px solid #ba7b7b;color:#592626;border-left:4px solid #dc3232;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.sby-license-valid{border:1px solid #5baf2a;background:#e2f2d5}.sby-license-expired p{padding:0;margin:0 5px 0 0}.sby-license-expired b{display:inline-block;padding:0;font-size:15px}#sby-why-renew{clear:both;width:100%}#sby-why-renew h4{clear:both;margin:15px 0 0 0;font-size:15px}#sby-why-renew p{margin:0;clear:both}.sby-license-expired .button-primary{margin:0 4px 0 5px}.sby-license-expired .button-secondary{margin:0 0 0 3px;background:rgba(255,255,255,.3);border:1px solid rgba(0,0,0,.15);display:inline-block}.sby-license-expired svg{width:16px;height:16px;position:relative;top:2px;margin:0 8px 0 0}.sby-license-expired svg path{fill:#cc2727}@media all and (max-width:600px){.sby-license-expired b{display:inline}.sby-license-expired span{display:block}.sby-license-expired .button{margin:10px 5px 0 0}}</style>
|
||||
");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin header notices
|
||||
*
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public function sby_admin_header_license_notice () {
|
||||
if ( !sby_is_pro() ) {
|
||||
return;
|
||||
}
|
||||
if ( !current_user_can( Util::sby_capability_check() ) ) {
|
||||
return;
|
||||
}
|
||||
// We will display the license notice only on specified allowed screens
|
||||
if ( ! Util::isCurrentScreenAllowed() ) {
|
||||
return;
|
||||
}
|
||||
// Check that the license exists and the user hasn't already clicked to ignore the message
|
||||
if ( empty( Util::get_license_key() ) ) {
|
||||
echo $this->get_post_grace_period_header_notice( $inactive = 'sby-license-inactive-state' );
|
||||
return;
|
||||
}
|
||||
// If license not expired then return;
|
||||
$license_expired = Util::is_license_expired();
|
||||
if ( !$license_expired ) {
|
||||
return;
|
||||
}
|
||||
// Grace period ended?
|
||||
if ( Util::is_license_grace_period_ended( true ) ) {
|
||||
if ( get_option( 'sby_check_license_api_post_grace_period' ) !== 'false' ) {
|
||||
$license_expired = Util::sby_check_license( Util::get_license_key(), true, true );
|
||||
}
|
||||
if ( $license_expired ) {
|
||||
echo $this->get_post_grace_period_header_notice();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post grace period header notice content
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function get_post_grace_period_header_notice( $license_status = 'expired' ) {
|
||||
$notice_text = 'Your YouTube Feeds Pro License has expired. Renew to keep using PRO features.';
|
||||
if ( $license_status == 'sby-license-inactive-state' ) {
|
||||
$notice_text = 'Your license key is inactive. Please add license key to enable PRO features.';
|
||||
}
|
||||
return '<div id="sby-license-expired-agp" class="sby-license-expired-agp sby-le-flow-1 '. $license_status .'">
|
||||
<span class="sby-license-expired-agp-message">'. $notice_text .' <span @click.prevent.default="activateView(\'licenseLearnMore\')">Learn More</span></span>
|
||||
<button type="button" id="sby-dismiss-header-notice" title="Dismiss this message" data-page="overview" class="sby-dismiss">
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.8327 5.34175L14.6577 4.16675L9.99935 8.82508L5.34102 4.16675L4.16602 5.34175L8.82435 10.0001L4.16602 14.6584L5.34102 15.8334L9.99935 11.1751L14.6577 15.8334L15.8327 14.6584L11.1744 10.0001L15.8327 5.34175Z" fill="white"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>';
|
||||
}
|
||||
|
||||
private function get_license_key() {
|
||||
return Util::get_license_key();
|
||||
}
|
||||
|
||||
private function recheck_license_status() {
|
||||
if ( empty( $this->get_license_key() ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$license_last_check = get_option( 'sby_license_last_check_timestamp' );
|
||||
$date = time() - ( DAY_IN_SECONDS * 90 );
|
||||
|
||||
if ( $date < $license_last_check ) {
|
||||
return $this->get_license_data();
|
||||
}
|
||||
|
||||
$sby_license = $this->get_license_key();
|
||||
|
||||
$this->sby_activate_license($sby_license);
|
||||
|
||||
update_option( 'sby_license_last_check_timestamp', time() );
|
||||
|
||||
return $this->get_license_data();
|
||||
}
|
||||
|
||||
public function get_license_status() {
|
||||
return get_option('sby_license_status', 'inactive');
|
||||
}
|
||||
|
||||
public function get_license_data() {
|
||||
return $this->get_license_error_message( get_option( 'sby_license_data' ) );
|
||||
}
|
||||
|
||||
public function get_license_error_message( $license_data ) {
|
||||
global $sby_download_id;
|
||||
|
||||
$license_key = $this->get_license_key();
|
||||
|
||||
$upgrade_url = sprintf( 'https://smashballoon.com/youtube-feed/pricing/?edd_license_key=%s&upgrade=true&utm_campaign=youtube-pro&utm_source=settings&utm_medium=upgrade-license', $license_key );
|
||||
$renew_url = sprintf( 'https://smashballoon.com/checkout/?edd_license_key=%s&download_id=%s&utm_campaign=youtube-pro&utm_source=settings&utm_medium=upgrade-license&utm_content=renew-license', $license_key, $sby_download_id );
|
||||
$learn_more_url = 'https://smashballoon.com/doc/my-license-key-wont-activate/?utm_campaign=youtube-pro&utm_source=settings&utm_medium=license&utm_content=learn-more';
|
||||
|
||||
// Check if the license key reached max site installations
|
||||
if ( !empty($license_data->error) && 'no_activations_left' === $license_data->error ) {
|
||||
$license_data->errorMsg = sprintf(
|
||||
'%s (%s/%s). %s <a href="%s" target="_blank">%s</a> %s <a href="%s" target="_blank">%s</a>',
|
||||
__( 'You have reached the maximum number of sites available in your plan', 'feeds-for-youtube' ),
|
||||
$license_data->site_count,
|
||||
$license_data->max_sites,
|
||||
__( 'Learn more about it', 'feeds-for-youtube' ),
|
||||
$learn_more_url,
|
||||
'here',
|
||||
__( 'or upgrade your plan.', 'feeds-for-youtube' ),
|
||||
$upgrade_url,
|
||||
__( 'Upgrade', 'feeds-for-youtube' )
|
||||
);
|
||||
}
|
||||
// Check if the license key has expired
|
||||
if (
|
||||
( !empty( $license_data->license ) && 'expired' === $license_data->license ) ||
|
||||
( !empty( $license_data->error ) && 'expired' === $license_data->error )
|
||||
) {
|
||||
$license_data->error = true;
|
||||
$expired_date = new \DateTime( $license_data->expires );
|
||||
$expired_date = $expired_date->format( 'F d, Y' );
|
||||
$license_data->errorMsg = sprintf(
|
||||
'%s %s. %s <a href="%s" target="_blank">%s</a>',
|
||||
__( 'The license expired on ', 'feeds-for-youtube' ),
|
||||
$expired_date,
|
||||
__( 'Please renew it and try again.', 'feeds-for-youtube' ),
|
||||
$renew_url,
|
||||
__( 'Renew', 'feeds-for-youtube' )
|
||||
);
|
||||
}
|
||||
return $license_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content for expired license notice
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string $output
|
||||
*/
|
||||
public function get_expired_license_notice_content() {
|
||||
global $current_user;
|
||||
$current_screen = get_current_screen();
|
||||
|
||||
$output = '<div class="sb-license-notice">
|
||||
<h4>Your license key has expired</h4>
|
||||
<p>You are no longer receiving updates that protect you against upcoming YouTube changes. There’s a <strong>14 day</strong> grace period before access to some Pro features in the plugin will be limited.</p>
|
||||
<div class="sb-notice-buttons">
|
||||
<a href="'. $this->license_service->get_renew_url() .'" class="sb-btn sb-btn-blue" target="_blank">Renew License</a>
|
||||
<a href="#" class="sb-btn" @click.prevent.default="activateView(\'whyRenewLicense\')">Why Renew?</a>
|
||||
<a href="" class="sb-btn" @click.prevent.default="reCheckLicenseKey()" v-html="recheckBtnText()" :class="recheckLicenseStatus">Re-check License Key</a>
|
||||
</div>
|
||||
<svg class="sb-notice-icon" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M10 0C4.48 0 0 4.48 0 10C0 15.52 4.48 20 10 20C15.52 20 20 15.52 20 10C20 4.48 15.52 0 10 0ZM11 15H9V13H11V15ZM11 11H9V5H11V11Z" fill="#D72C2C"/></svg>
|
||||
</div>';
|
||||
|
||||
if ( ! empty( $current_screen->base ) && $current_screen->base == 'dashboard' ) {
|
||||
$output .= '<button id="sb-dismiss-notice">
|
||||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.66683 1.27325L8.72683 0.333252L5.00016 4.05992L1.2735 0.333252L0.333496 1.27325L4.06016 4.99992L0.333496 8.72659L1.2735 9.66659L5.00016 5.93992L8.72683 9.66659L9.66683 8.72659L5.94016 4.99992L9.66683 1.27325Z" fill="white"/>
|
||||
</svg>
|
||||
</button>';
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content for successfully renewed license notice
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string $output
|
||||
*/
|
||||
public function get_renewed_license_notice_content() {
|
||||
$output = '<span class="sb-notice-icon sb-error-icon">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 2C6.5 2 2 6.5 2 12C2 17.5 6.5 22 12 22C17.5 22 22 17.5 22 12C22 6.5 17.5 2 12 2ZM10 17L5 12L6.41 10.59L10 14.17L17.59 6.58L19 8L10 17Z" fill="#59AB46"/>
|
||||
</svg>
|
||||
</span>
|
||||
<div class="sb-notice-body">
|
||||
<h3 class="sb-notice-title">Thanks! Your license key is valid.</h3>
|
||||
<p>You can safely dismiss this modal.</p>
|
||||
<div class="license-action-btns">
|
||||
<a target="_blank" class="sby-license-btn sby-btn-blue sby-notice-btn" id="sby-hide-notice">
|
||||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.66683 1.27325L8.72683 0.333252L5.00016 4.05992L1.2735 0.333252L0.333496 1.27325L4.06016 4.99992L0.333496 8.72659L1.2735 9.66659L5.00016 5.93992L8.72683 9.66659L9.66683 8.72659L5.94016 4.99992L9.66683 1.27325Z" fill="white"/>
|
||||
</svg>
|
||||
Dismiss
|
||||
</a>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get modal content that will trigger by "Why Renew" button
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string $output
|
||||
*/
|
||||
public function get_modal_content() {
|
||||
$output = '<div class="sby-sb-modal license-details-modal">
|
||||
<div class="sby-modal-content">
|
||||
<button type="button" class="cancel-btn sby-btn" id="sby-sb-close-modal">
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14.2084 2.14275L12.8572 0.791504L7.50008 6.14859L2.143 0.791504L0.791748 2.14275L6.14883 7.49984L0.791748 12.8569L2.143 14.2082L7.50008 8.85109L12.8572 14.2082L14.2084 12.8569L8.85133 7.49984L14.2084 2.14275Z" fill="#141B38">
|
||||
</path>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="sby-sb-modal-body">
|
||||
<h2 class="sb-modal-title">Why Renew?</h2>
|
||||
<p class="sb-modal-description">See below for why it\'s so important to keep an active plugin license.</p>
|
||||
<div class="sb-why-renew-list-parent">
|
||||
<div class="sb-why-renew-list">
|
||||
<div class="sb-icon">
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M16 1.33325L4 6.66659V14.6666C4 22.0666 9.12 28.9866 16 30.6666C22.88 28.9866 28 22.0666 28 14.6666V6.66659L16 1.33325Z" fill="#59AB46"/>
|
||||
<path d="M10.3433 16.5525L14.1145 20.3237L21.657 12.7813" stroke="white" stroke-width="2.66667"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="sb-list-item">
|
||||
<h4>Protected Against All Upcoming YouTube Platform Updates and API Changes</h4>
|
||||
<p>Don\'t worry about your YouTubes feeds breaking due to constant changes in the YouTube platform. Stay protected with access to continual plugin updates, giving you peace of mind that the software will always be up to date.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sb-why-renew-list">
|
||||
<div class="sb-icon">
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.9998 2.66675C8.63984 2.66675 2.6665 8.64008 2.6665 16.0001C2.6665 23.3601 8.63984 29.3334 15.9998 29.3334C23.3598 29.3334 29.3332 23.3601 29.3332 16.0001C29.3332 8.64008 23.3598 2.66675 15.9998 2.66675ZM25.9465 12.1601L22.2398 13.6934C21.9059 12.7949 21.3814 11.9793 20.7025 11.3027C20.0235 10.626 19.2061 10.1043 18.3065 9.77341L19.8398 6.06675C22.6398 7.13341 24.8665 9.36008 25.9465 12.1601ZM15.9998 20.0001C13.7865 20.0001 11.9998 18.2134 11.9998 16.0001C11.9998 13.7867 13.7865 12.0001 15.9998 12.0001C18.2132 12.0001 19.9998 13.7867 19.9998 16.0001C19.9998 18.2134 18.2132 20.0001 15.9998 20.0001ZM12.1732 6.05341L13.7332 9.76008C12.8229 10.0918 11.9959 10.6179 11.3097 11.3018C10.6235 11.9857 10.0946 12.811 9.75984 13.7201L6.05317 12.1734C6.58782 10.7816 7.40887 9.51764 8.46313 8.46338C9.5174 7.40911 10.7814 6.58806 12.1732 6.05341ZM6.05317 19.8267L9.75984 18.2934C10.0923 19.2002 10.619 20.0233 11.303 20.705C11.9871 21.3868 12.812 21.9107 13.7198 22.2401L12.1598 25.9467C10.771 25.4097 9.51009 24.5876 8.45831 23.5335C7.40653 22.4795 6.58722 21.2167 6.05317 19.8267ZM19.8398 25.9467L18.3065 22.2401C19.2103 21.9052 20.0304 21.3775 20.7097 20.6936C21.3889 20.0098 21.9111 19.1862 22.2398 18.2801L25.9465 19.8401C25.4101 21.2272 24.5898 22.4869 23.5382 23.5385C22.4866 24.59 21.2269 25.4103 19.8398 25.9467Z" fill="#59AB46"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="sb-list-item">
|
||||
<h4>Expert Technical Support</h4>
|
||||
<p>Without a valid license key you will no longer be able to receive updates or support for the YouTube Feeds plugin. A renewed license key grants you access to our top-notch, quick and effective support for another full year.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sb-why-renew-list">
|
||||
<div class="sb-icon">
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 0C7.16343 0 0 7.16342 0 16C0 24.8365 7.16343 32 16 32C24.8366 32 32 24.8365 32 16C32 7.16342 24.8366 0 16 0ZM16 0.96C18.0308 0.96 20.0004 1.35753 21.8539 2.14152C22.7449 2.51837 23.6044 2.98488 24.4084 3.528C25.205 4.06617 25.9541 4.68427 26.6349 5.3651C27.3157 6.04593 27.9338 6.79507 28.472 7.59163C29.0152 8.39563 29.4816 9.25507 29.8585 10.146C30.6425 11.9996 31.04 13.9692 31.04 16C31.04 18.0308 30.6425 20.0003 29.8585 21.8539C29.4816 22.7449 29.0152 23.6043 28.472 24.4083C27.9338 25.2049 27.3157 25.954 26.6349 26.6349C25.9541 27.3157 25.205 27.9338 24.4084 28.472C23.6044 29.0151 22.7449 29.4816 21.8539 29.8584C20.0004 30.6425 18.0308 31.04 16 31.04C13.9692 31.04 11.9996 30.6425 10.1461 29.8584C9.25508 29.4816 8.39564 29.0151 7.59164 28.472C6.79508 27.9338 6.04594 27.3157 5.36511 26.6349C4.68428 25.954 4.06618 25.2049 3.528 24.4083C2.98488 23.6043 2.51837 22.7449 2.14152 21.8539C1.35754 20.0003 0.960001 18.0308 0.960001 16C0.960001 13.9692 1.35754 11.9996 2.14152 10.146C2.51837 9.25507 2.98488 8.39563 3.528 7.59163C4.06618 6.79507 4.68428 6.04593 5.36511 5.3651C6.04594 4.68427 6.79508 4.06617 7.59164 3.528C8.39564 2.98488 9.25508 2.51837 10.1461 2.14152C11.9996 1.35753 13.9692 0.96 16 0.96Z" fill="#0068A0"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.7008 9.60322C27.7581 10.0278 27.7904 10.4834 27.7904 10.9742C27.7904 12.3266 27.537 13.8476 26.7762 15.7497L22.7039 27.5239C26.6679 25.2129 29.3337 20.9184 29.3337 15.9996C29.3337 13.6814 28.7413 11.5022 27.7008 9.60322ZM16.2346 17.1658L12.2335 28.7901C13.4284 29.1417 14.6917 29.3334 16.0004 29.3334C17.553 29.3334 19.0425 29.0654 20.4283 28.5774C20.3926 28.5204 20.3598 28.4598 20.3326 28.3937L16.2346 17.1658ZM25.0015 15.3271C25.0015 13.6788 24.4094 12.5379 23.9023 11.6501C23.2264 10.5513 22.5925 9.62166 22.5925 8.52289C22.5925 7.29745 23.5219 6.15659 24.8316 6.15659C24.8908 6.15659 24.9468 6.16369 25.0042 6.16734C22.632 3.9938 19.4715 2.66675 16.0004 2.66675C11.342 2.66675 7.24413 5.05691 4.85997 8.6762C5.17303 8.68614 5.46799 8.69238 5.71807 8.69238C7.11237 8.69238 9.27175 8.52289 9.27175 8.52289C9.99012 8.48079 10.075 9.53674 9.357 9.62166C9.357 9.62166 8.63445 9.70628 7.83113 9.74833L12.6863 24.1908L15.6046 15.4399L13.5274 9.74833C12.809 9.70628 12.129 9.62166 12.129 9.62166C11.4102 9.57922 11.4944 8.48079 12.2135 8.52289C12.2135 8.52289 14.415 8.69238 15.725 8.69238C17.1193 8.69238 19.279 8.52289 19.279 8.52289C19.9978 8.48079 20.0824 9.53674 19.364 9.62166C19.364 9.62166 18.6407 9.70628 17.8381 9.74833L22.6566 24.0807L24.0321 19.7223C24.6432 17.8175 25.0015 16.468 25.0015 15.3271ZM2.66699 15.9996C2.66699 21.2769 5.73372 25.838 10.1819 27.999L3.82154 10.5734C3.08171 12.2315 2.66699 14.0665 2.66699 15.9996Z" fill="#0068A0"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="sb-list-item">
|
||||
<h4>WordPress Compatibility Updates</h4>
|
||||
<p>With WordPress updates being released continually, we make sure the plugin is always compatible with the latest version so you can update WordPress without needing to worry.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sb-why-renew-list">
|
||||
<div class="sb-icon">
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.1583 8.40195C12.8183 7.39434 10.3809 5.88954 8.10558 5.18909C8.91398 7.03648 9.59628 9.00467 10.3023 10.9501C8.89406 11.9642 7.2491 12.7514 5.67754 13.6091C7.0149 14.8758 8.9089 15.609 10.418 16.7112C9.20919 18.1404 6.83433 19.6258 6.25565 20.9211C8.758 20.6207 11.6739 20.1336 14.0021 20.0348C14.5137 22.4989 14.7776 25.2005 15.5052 27.4577C16.5887 24.4706 17.5684 21.384 18.8581 18.5945C20.8485 19.3834 23.2742 20.3453 25.2172 20.8103C23.8539 18.9776 22.6098 17.0307 21.4018 15.0493C23.1895 13.8079 24.9976 12.5862 26.7202 11.2824C24.2854 11.0675 21.7627 10.9367 19.205 10.8394C18.7985 8.31133 18.9053 5.29159 18.28 2.97334C17.3339 4.87343 16.2174 6.61017 15.1583 8.40195ZM16.3145 29.3411C15.993 30.6598 17.0524 31.2007 16.8926 32C15.8465 31.6546 15.0596 31.4771 13.6553 31.6676C13.6992 30.6387 14.6649 30.4932 14.4646 29.2303C-0.500692 27.5999 -0.530751 1.68764 14.349 0.0928438C32.9539 -1.90125 33.5377 28.8829 16.3145 29.3411Z" fill="#FE544F"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.2802 2.97314C18.9055 5.2914 18.7987 8.31114 19.2052 10.8391C21.7629 10.9365 24.2856 11.0672 26.7204 11.2823C24.9978 12.586 23.1896 13.8077 21.4019 15.0491C22.61 17.0305 23.8541 18.9774 25.2174 20.8101C23.2744 20.3451 20.8487 19.3832 18.8583 18.5943C17.5686 21.3838 16.5889 24.4704 15.5054 27.4575C14.7778 25.2003 14.5139 22.4987 14.0023 20.0346C11.6741 20.1334 8.7582 20.6205 6.25584 20.9209C6.83452 19.6256 9.20937 18.1402 10.4181 16.7109C8.90907 15.6088 7.01509 14.8756 5.67773 13.6089C7.24929 12.7512 8.89422 11.964 10.3025 10.9499C9.59646 9.00448 8.91419 7.03628 8.10578 5.18889C10.381 5.88935 12.8185 7.39414 15.1585 8.40176C16.2176 6.60997 17.3341 4.87324 18.2802 2.97314Z" fill="white"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="sb-list-item">
|
||||
<h4>All Pro YouTube Feeds Features</h4>
|
||||
<p>Video Statistics, Live Streams, Search Feeds, PlayLists, Call to Action Settings, Carousel Layouts, Video filtering and more!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* SBY Check License
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function check_license() {
|
||||
$sby_license = trim( get_option( 'sby_license_key' ) );
|
||||
|
||||
// Check the API
|
||||
$sby_api_params = array(
|
||||
'edd_action'=> 'check_license',
|
||||
'license' => $sby_license,
|
||||
'item_name' => urlencode( SBY_PLUGIN_NAME ) // the name of our product in EDD
|
||||
);
|
||||
$sby_response = wp_remote_get( add_query_arg( $sby_api_params, SBY_STORE_URL ), array( 'timeout' => 60, 'sslverify' => false ) );
|
||||
$sby_license_data = (array) json_decode( wp_remote_retrieve_body( $sby_response ) );
|
||||
// Update the updated license data
|
||||
update_option( 'sby_license_data', $sby_license_data );
|
||||
|
||||
$sby_todays_date = date('Y-m-d');
|
||||
// Check whether it's active
|
||||
if( $sby_license_data['license'] !== 'expired' && ( strtotime( $sby_license_data['expires'] ) > strtotime($sby_todays_date) ) ) {
|
||||
// if the license is active then lets remove the ignore check for dashboard so next time it will show the expired notice in dashboard screen
|
||||
update_user_meta( get_current_user_id(), 'sby_ignore_dashboard_license_notice', false );
|
||||
wp_send_json_success( array(
|
||||
'msg' => 'License Active',
|
||||
'content' => $this->get_renewed_license_notice_content()
|
||||
) );
|
||||
|
||||
} else {
|
||||
$content = $this->get_expired_license_notice_content();
|
||||
$content = str_replace( 'Your YouTube Feeds Pro license key has expired', 'We rechecked but your license key is still expired', $content );
|
||||
wp_send_json_success( array(
|
||||
'msg' => 'License Not Renewed',
|
||||
'content' => $content
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SBY Dismiss Notice
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function dismiss_license_notice() {
|
||||
global $current_user;
|
||||
$user_id = $current_user->ID;
|
||||
update_user_meta( $user_id, 'sby_ignore_dashboard_license_notice', true );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Services\Admin;
|
||||
|
||||
use Smashballoon\Customizer\Container;
|
||||
use Smashballoon\Customizer\Feed_Builder;
|
||||
use SmashBalloon\YouTubeFeed\Helpers\Util;
|
||||
use Smashballoon\Stubs\Services\ServiceProvider;
|
||||
use SmashBalloon\YouTubeFeed\Admin\SBY_Notifications;
|
||||
|
||||
class MenuService extends ServiceProvider {
|
||||
|
||||
/**
|
||||
* @var mixed|Feed_Builder
|
||||
*/
|
||||
private $builder;
|
||||
|
||||
/**
|
||||
* @var SBY_Notifications
|
||||
*/
|
||||
private $notifications;
|
||||
|
||||
public function __construct(SBY_Notifications $notifications) {
|
||||
$this->builder = Container::getInstance()->get(Feed_Builder::class);
|
||||
$this->notifications = $notifications;
|
||||
}
|
||||
|
||||
public function register() {
|
||||
add_action('admin_menu', [$this, 'register_menus']);
|
||||
}
|
||||
|
||||
public function register_menus() {
|
||||
$cap = current_user_can( 'manage_options' ) ? 'manage_options' : 'manage_youtube_feed_options';
|
||||
|
||||
add_menu_page(
|
||||
__('YouTube Feed', 'feeds-for-youtube'),
|
||||
__('YouTube Feed', 'feeds-for-youtube') . $this->alert_html(),
|
||||
$cap,
|
||||
SBY_MENU_SLUG,
|
||||
null,
|
||||
'dashicons-video-alt3',
|
||||
99
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
SBY_MENU_SLUG,
|
||||
__( 'All Feeds', 'feeds-for-youtube' ),
|
||||
__( 'All Feeds', 'feeds-for-youtube' ),
|
||||
$cap,
|
||||
SBY_MENU_SLUG,
|
||||
array( $this->builder, 'feed_builder' ),
|
||||
0
|
||||
);
|
||||
|
||||
if ( (sby_is_pro() && empty( Util::get_license_key() )) || Util::is_license_expired() || !sby_is_pro() ) {
|
||||
add_submenu_page(
|
||||
SBY_MENU_SLUG,
|
||||
__( 'Upgrade to Pro', 'feeds-for-youtube' ),
|
||||
__( '<span class="sby_get_pro">Try the Pro Demo</span>', 'feeds-for-youtube' ),
|
||||
$cap,
|
||||
'https://smashballoon.com/youtube-feed/demo/?utm_campaign=youtube-free&utm_source=menu-link&utm_medium=upgrade-link',
|
||||
''
|
||||
);
|
||||
}
|
||||
|
||||
if ( sby_should_add_free_plugin_submenu( 'facebook' ) ) {
|
||||
add_submenu_page(
|
||||
SBY_MENU_SLUG,
|
||||
__( 'Facebook Feed', 'feeds-for-youtube' ),
|
||||
'<span class="sby_get_cff">' . __( 'Facebook Feed', 'feeds-for-youtube' ) . '</span>',
|
||||
'manage_options',
|
||||
'admin.php?page=sby-feed-builder&tab=more',
|
||||
5
|
||||
);
|
||||
}
|
||||
|
||||
if ( sby_should_add_free_plugin_submenu( 'instagram' ) ) {
|
||||
add_submenu_page(
|
||||
SBY_MENU_SLUG,
|
||||
__( 'Instagram Feed', 'feeds-for-youtube' ),
|
||||
'<span class="sby_get_sbi">' . __( 'Instagram Feed', 'feeds-for-youtube' ) . '</span>',
|
||||
'manage_options',
|
||||
'admin.php?page=sby-feed-builder&tab=more',
|
||||
6
|
||||
);
|
||||
}
|
||||
|
||||
if ( sby_should_add_free_plugin_submenu( 'twitter' ) ) {
|
||||
add_submenu_page(
|
||||
SBY_MENU_SLUG,
|
||||
__( 'Twitter Feed', 'feeds-for-youtube' ),
|
||||
'<span class="sby_get_ctf">' . __( 'Twitter Feed', 'feeds-for-youtube' ) . '</span>',
|
||||
'manage_options',
|
||||
'admin.php?page=sby-feed-builder&tab=more',
|
||||
7
|
||||
);
|
||||
}
|
||||
|
||||
if ( sby_should_add_free_plugin_submenu( 'tiktok' ) ) {
|
||||
add_submenu_page(
|
||||
SBY_MENU_SLUG,
|
||||
__( 'Tiktok Feed', 'feeds-for-youtube' ),
|
||||
'<span class="sby_get_sbtt">' . __( 'Tiktok Feed', 'feeds-for-youtube' ) . '</span>',
|
||||
'manage_options',
|
||||
'admin.php?page=sby-feed-builder&tab=more',
|
||||
8
|
||||
);
|
||||
}
|
||||
|
||||
if ( sby_should_add_free_plugin_submenu( 'reviews' ) ) {
|
||||
add_submenu_page(
|
||||
SBY_MENU_SLUG,
|
||||
__( 'Reviews Feed', 'feeds-for-youtube' ),
|
||||
'<span class="sby_get_sbr">' . __( 'Reviews Feed', 'feeds-for-youtube' ) . '</span>',
|
||||
'manage_options',
|
||||
'admin.php?page=sby-feed-builder&tab=more',
|
||||
9
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function alert_html() {
|
||||
$notice = '';
|
||||
$notice_bubble = '';
|
||||
|
||||
$notifications = $this->notifications->get();
|
||||
|
||||
if ( empty( $notice ) && ! empty( $notifications ) && is_array( $notifications ) ) {
|
||||
$notice_bubble = ' <span class="sby-notice-alert"><span>' . count( $notifications ) . '</span></span>';
|
||||
}
|
||||
|
||||
if ( sby_is_pro() && empty( Util::get_license_key() ) || Util::is_license_expired() ) {
|
||||
$notice_bubble = ' <span class="sby-notice-alert"><span>1</span></span>';
|
||||
}
|
||||
|
||||
return $notice_bubble . $notice;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Services\Admin;
|
||||
|
||||
use Smashballoon\Stubs\Services\ServiceProvider;
|
||||
use SmashBalloon\YouTubeFeed\Helpers\Util;
|
||||
use SmashBalloon\YouTubeFeed\Pro\SBY_API_Connect_Pro;
|
||||
use SmashBalloon\YouTubeFeed\Services\AdminAjaxService;
|
||||
|
||||
class MiscService extends ServiceProvider {
|
||||
public function register() {
|
||||
add_action( 'wp_ajax_sby_ca_after_remove_clicked', [$this, 'sby_delete_connected_account'] );
|
||||
add_action( 'wp_ajax_sby_process_access_token', [$this, 'sby_process_access_token'] );
|
||||
add_action( 'wp_ajax_sby_delete_wp_posts', [$this, 'sby_delete_wp_posts'] );
|
||||
add_action( 'wp_ajax_sbspf_account_search', [$this, 'sbspf_account_search'] );
|
||||
add_action('admin_init', [$this, 'sby_register_option']);
|
||||
add_action( 'wp_ajax_sby_do_import_batch', [$this, 'sby_do_import_batch'] );
|
||||
add_action( 'sby_settings_after_configure_save', [$this, 'sby_reset_cron'], 10, 1 );
|
||||
|
||||
}
|
||||
|
||||
public function sby_delete_connected_account() {
|
||||
if ( ! isset( $_POST['sbspf_nonce'] ) || ! isset( $_POST['account_id']) ) return;
|
||||
$nonce = $_POST['sbspf_nonce'];
|
||||
if ( ! wp_verify_nonce( $nonce, 'sbspf_nonce' ) ) {
|
||||
die ( 'You did not do this the right way!' );
|
||||
}
|
||||
|
||||
global $sby_settings;
|
||||
|
||||
$account_id = sanitize_text_field( $_POST['account_id'] );
|
||||
$to_save = array();
|
||||
|
||||
foreach ( $sby_settings['connected_accounts'] as $connected_account ) {
|
||||
if ( (string)$connected_account['channel_id'] !== (string)$account_id ) {
|
||||
$to_save[ $connected_account['channel_id'] ] = $connected_account;
|
||||
}
|
||||
}
|
||||
|
||||
$sby_settings['connected_accounts'] = $to_save;
|
||||
update_option( 'sby_settings', $sby_settings );
|
||||
|
||||
echo wp_json_encode( array( 'success' => true ) );
|
||||
|
||||
die();
|
||||
}
|
||||
public function sby_process_access_token() {
|
||||
if ( ! isset( $_POST['sbspf_nonce'] ) || ! isset( $_POST['sby_access_token'] ) ) return;
|
||||
$nonce = $_POST['sbspf_nonce'];
|
||||
if ( ! wp_verify_nonce( $nonce, 'sbspf_nonce' ) ) {
|
||||
die ( 'You did not do this the right way!' );
|
||||
}
|
||||
|
||||
$account = sby_attempt_connection();
|
||||
|
||||
if ( $account ) {
|
||||
global $sby_settings;
|
||||
|
||||
$options = $sby_settings;
|
||||
$username = $account['username'] ? $account['username'] : $account['channel_id'];
|
||||
if ( isset( $account['local_avatar'] ) && $account['local_avatar'] && isset( $options['favorlocal'] ) && $options['favorlocal' ] === 'on' ) {
|
||||
$upload = wp_upload_dir();
|
||||
$resized_url = trailingslashit( $upload['baseurl'] ) . trailingslashit( SBY_UPLOADS_NAME );
|
||||
$profile_picture = '<img class="sbspf_ca_avatar" src="'.$resized_url . $account['username'].'.jpg" />'; //Could add placeholder avatar image
|
||||
} else {
|
||||
$profile_picture = $account['profile_picture'] ? '<img class="sbspf_ca_avatar" src="'.$account['profile_picture'].'" />' : ''; //Could add placeholder avatar image
|
||||
}
|
||||
|
||||
$text_domain = SBY_TEXT_DOMAIN;
|
||||
$slug = SBY_SLUG;
|
||||
ob_start();
|
||||
include_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/Admin/templates/single-connected-account.php';
|
||||
if ( sby_notice_not_dismissed() ) {
|
||||
include_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/Admin/templates/modal.php';
|
||||
echo '<span class="sby_account_just_added"></span>';
|
||||
}
|
||||
|
||||
$html = ob_get_contents();
|
||||
ob_get_clean();
|
||||
|
||||
$return = array(
|
||||
'account_id' => $account['channel_id'],
|
||||
'html' => $html
|
||||
);
|
||||
} else {
|
||||
$return = array(
|
||||
'error' => __( 'Could not connect your account. Please check to make sure this is a valid access token for the Smash Balloon YouTube App.'),
|
||||
'html' => ''
|
||||
);
|
||||
}
|
||||
|
||||
echo wp_json_encode( $return );
|
||||
|
||||
die();
|
||||
}
|
||||
public function sby_delete_wp_posts() {
|
||||
if ( ! isset( $_POST['sbspf_nonce'] ) ) return;
|
||||
$nonce = $_POST['sbspf_nonce'];
|
||||
if ( ! wp_verify_nonce( $nonce, 'sbspf_nonce' ) ) {
|
||||
die ( 'You did not do this the right way!' );
|
||||
}
|
||||
|
||||
sby_clear_wp_posts();
|
||||
|
||||
sby_clear_cache();
|
||||
|
||||
echo '{}';
|
||||
|
||||
die();
|
||||
}
|
||||
public function sbspf_account_search() {
|
||||
if ( ! isset( $_POST['sbspf_nonce'] ) || ! isset( $_POST['term']) ) return;
|
||||
$nonce = $_POST['sbspf_nonce'];
|
||||
if ( ! wp_verify_nonce( $nonce, 'sbspf_nonce' ) ) {
|
||||
die ( 'You did not do this the right way!' );
|
||||
}
|
||||
|
||||
global $sby_settings;
|
||||
|
||||
$term = sanitize_text_field( $_POST['term'] );
|
||||
$params = array(
|
||||
'q' => $term,
|
||||
'type' => 'channel'
|
||||
);
|
||||
|
||||
$connected_account_for_term = array();
|
||||
foreach ( $sby_settings['connected_accounts'] as $connected_account ) {
|
||||
$connected_account_for_term = $connected_account;
|
||||
}
|
||||
if ( $connected_account_for_term['expires'] < time() + 5 ) {
|
||||
$new_token_data = SBY_API_Connect::refresh_token( '', $connected_account_for_term['refresh_token'], '' );
|
||||
|
||||
if ( isset( $new_token_data['access_token'] ) ) {
|
||||
$connected_account_for_term['access_token'] = $new_token_data['access_token'];
|
||||
$connected_accounts_for_feed[ $term ]['access_token'] = $new_token_data['access_token'];
|
||||
$connected_account_for_term['expires'] = $new_token_data['expires_in'] + time();
|
||||
$connected_accounts_for_feed[ $term ]['expires'] = $new_token_data['expires_in'] + time();
|
||||
|
||||
sby_update_or_connect_account( $connected_account_for_term );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$search = new SBY_API_Connect( $connected_account_for_term, 'search', $params );
|
||||
|
||||
$search->connect();
|
||||
|
||||
|
||||
echo wp_json_encode( $search->get_data() );
|
||||
|
||||
die();
|
||||
}
|
||||
public function sby_register_option() {
|
||||
// creates our settings in the options table
|
||||
register_setting('sby_license', 'sby_license_key', 'sby_sanitize_license' );
|
||||
}
|
||||
|
||||
public function sby_do_import_batch() {
|
||||
|
||||
Util::ajaxPreflightChecks();
|
||||
|
||||
$next_page = isset( $_POST['page'] ) ? sanitize_text_field( $_POST['page'] ) : '';
|
||||
$channel = isset( $_POST['channel'] ) ? sanitize_text_field( $_POST['channel'] ) : '';
|
||||
$needed = isset( $_POST['needed'] ) ? sanitize_text_field( $_POST['needed'] ) : 1;
|
||||
$playlist = isset( $_POST['playlist'] ) ? sanitize_text_field( $_POST['playlist'] ) : '';
|
||||
|
||||
if ( empty( $channel ) && empty( $playlist ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'num' => (int) $needed
|
||||
);
|
||||
|
||||
if ( ! empty( $next_page ) ) {
|
||||
$params['nextPageToken'] = $next_page;
|
||||
}
|
||||
|
||||
if ( strpos( $channel, 'UC' ) === 0 ) {
|
||||
$params['channel_id'] = $channel;
|
||||
} else {
|
||||
$params['channel_name'] = $channel;
|
||||
}
|
||||
|
||||
if ( empty( $playlist ) ) {
|
||||
$connection = new SBY_API_Connect_Pro( sby_get_first_connected_account(), 'channels', $params );
|
||||
$connection->connect();
|
||||
$channel_data = $connection->get_data();
|
||||
|
||||
$playlist = isset( $channel_data['items'][0]['contentDetails']['relatedPlaylists']['uploads'] ) ? $channel_data['items'][0]['contentDetails']['relatedPlaylists']['uploads'] : false;
|
||||
}
|
||||
|
||||
$return = array();
|
||||
if ( $playlist ) {
|
||||
$return['playlist'] = $playlist;
|
||||
$params['playlist_id'] = $playlist;
|
||||
$playlist_connection = new SBY_API_Connect_Pro( sby_get_first_connected_account(), 'playlistItems', $params );
|
||||
$playlist_connection->connect();
|
||||
$data = $playlist_connection->get_data();
|
||||
|
||||
$posts = isset( $data['items'] ) ? $data['items'] : array();
|
||||
|
||||
AdminAjaxService::sby_process_post_set_caching( $posts, 'sby_importer' );
|
||||
|
||||
$return['num_retrieved'] = count( $posts );
|
||||
|
||||
$return['next'] = $playlist_connection->get_next_page();
|
||||
|
||||
echo wp_json_encode( $return );
|
||||
}
|
||||
|
||||
die();
|
||||
}
|
||||
public function sby_reset_cron( $settings ) {
|
||||
$sby_caching_type = isset( $settings['caching_type'] ) ? $settings['caching_type'] : '';
|
||||
$sby_cache_cron_interval = isset( $settings['cache_cron_interval'] ) ? $settings['cache_cron_interval'] : '';
|
||||
$sby_cache_cron_time = isset( $settings['cache_cron_time'] ) ? $settings['cache_cron_time'] : '';
|
||||
$sby_cache_cron_am_pm = isset( $settings['cache_cron_am_pm'] ) ? $settings['cache_cron_am_pm'] : '';
|
||||
|
||||
if ( $sby_caching_type === 'background' ) {
|
||||
delete_option( 'sby_cron_report' );
|
||||
SBY_Cron_Updater::start_cron_job( $sby_cache_cron_interval, $sby_cache_cron_time, $sby_cache_cron_am_pm );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Services\Admin\Settings;
|
||||
|
||||
use SmashBalloon\YouTubeFeed\Helpers\Util;
|
||||
|
||||
class AboutPage extends BaseSettingPage {
|
||||
protected $menu_slug = 'about';
|
||||
protected $menu_title = 'About Us';
|
||||
protected $page_title = 'About Us';
|
||||
protected $has_menu = true;
|
||||
protected $template_file = 'settings.index';
|
||||
protected $has_assets = true;
|
||||
protected $menu_position = 4;
|
||||
protected $menu_position_free_version = 4;
|
||||
|
||||
public function register() {
|
||||
parent::register();
|
||||
|
||||
add_filter( 'sby_localized_settings', [ $this, 'filter_settings_object' ] );
|
||||
add_action( 'wp_ajax_sby_install_addon', [ $this, 'ajax_install_addon' ] );
|
||||
add_action( 'wp_ajax_sby_activate_addon', [ $this, 'ajax_activate_addon' ] );
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function ajax_activate_addon() {
|
||||
|
||||
Util::ajaxPreflightChecks();
|
||||
|
||||
// Check for permissions.
|
||||
if ( ! current_user_can( 'activate_plugins' ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
if ( isset( $_POST['plugin'] ) ) {
|
||||
|
||||
$type = 'addon';
|
||||
if ( ! empty( $_POST['type'] ) ) {
|
||||
$type = sanitize_key( $_POST['type'] );
|
||||
}
|
||||
|
||||
$activate = activate_plugins( preg_replace( '/[^a-z-_\/]/', '', wp_unslash( str_replace( '.php', '', $_POST['plugin'] ) ) ) . '.php' );
|
||||
|
||||
if ( ! is_wp_error( $activate ) ) {
|
||||
if ( 'plugin' === $type ) {
|
||||
wp_send_json_success( esc_html__( 'Plugin activated.', 'feeds-for-youtube' ) );
|
||||
} else {
|
||||
wp_send_json_success( esc_html__( 'Addon activated.', 'feeds-for-youtube' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_error( esc_html__( 'Could not activate addon. Please activate from the Plugins page.', 'feeds-for-youtube' ) );
|
||||
}
|
||||
|
||||
public function ajax_install_addon() {
|
||||
|
||||
// Run a security check.
|
||||
Util::ajaxPreflightChecks();
|
||||
|
||||
// Check for permissions.
|
||||
if ( ! current_user_can( 'install_plugins' ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$error = esc_html__( 'Could not install addon. Please download from wpforms.com and install manually.', 'feeds-for-youtube' );
|
||||
|
||||
if ( empty( $_POST['plugin'] ) ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
// Only install plugins from the .org repo
|
||||
if ( strpos( $_POST['plugin'], 'https://downloads.wordpress.org/plugin/' ) !== 0 ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
// Set the current screen to avoid undefined notices.
|
||||
set_current_screen( 'youtube-feed-about' );
|
||||
|
||||
// Prepare variables.
|
||||
$url = esc_url_raw(
|
||||
add_query_arg(
|
||||
array(
|
||||
'page' => 'youtube-feed-about',
|
||||
),
|
||||
admin_url( 'admin.php' )
|
||||
)
|
||||
);
|
||||
|
||||
$creds = request_filesystem_credentials( $url, '', false, false, null );
|
||||
|
||||
// Check for file system permissions.
|
||||
if ( false === $creds ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
if ( ! WP_Filesystem( $creds ) ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not need any extra credentials if we have gotten this far, so let's install the plugin.
|
||||
*/
|
||||
|
||||
// Do not allow WordPress to search/download translations, as this will break JS output.
|
||||
remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
|
||||
|
||||
if(!class_exists("Plugin_Upgrader")) {
|
||||
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
|
||||
include_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php';
|
||||
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-skin.php';
|
||||
}
|
||||
|
||||
// Create the plugin upgrader with our custom skin.
|
||||
$installer = new \Plugin_Upgrader( new \WP_Upgrader_Skin() );
|
||||
|
||||
// Error check.
|
||||
if ( empty( $_POST['plugin'] ) ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
$installer->install( esc_url_raw( wp_unslash( $_POST['plugin'] ) ) );
|
||||
|
||||
// Flush the cache and return the newly installed plugin basename.
|
||||
wp_cache_flush();
|
||||
|
||||
$plugin_basename = $installer->plugin_info();
|
||||
|
||||
if ( $plugin_basename ) {
|
||||
|
||||
$type = 'addon';
|
||||
if ( ! empty( $_POST['type'] ) ) {
|
||||
$type = sanitize_key( $_POST['type'] );
|
||||
}
|
||||
|
||||
// Activate the plugin silently.
|
||||
$activated = activate_plugin( $plugin_basename );
|
||||
|
||||
if ( ! is_wp_error( $activated ) ) {
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'msg' => 'plugin' === $type ? esc_html__( 'Plugin installed & activated.', 'feeds-for-youtube' ) : esc_html__( 'Addon installed & activated.', 'feeds-for-youtube' ),
|
||||
'is_activated' => true,
|
||||
'basename' => $plugin_basename,
|
||||
)
|
||||
);
|
||||
} else {
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'msg' => 'plugin' === $type ? esc_html__( 'Plugin installed.', 'feeds-for-youtube' ) : esc_html__( 'Addon installed.', 'feeds-for-youtube' ),
|
||||
'is_activated' => false,
|
||||
'basename' => $plugin_basename,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
public function filter_settings_object( $settings ) {
|
||||
$sb_other_plugins = sby_get_active_plugins_info();
|
||||
$installed_plugins = $sb_other_plugins['installed_plugins'];
|
||||
$license_key = get_option( 'sby_license_key', null );
|
||||
|
||||
$settings['pluginInfo'] = [
|
||||
"plugins" => [
|
||||
'facebook' => array(
|
||||
'plugin' => $sb_other_plugins['facebook_plugin'],
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/custom-facebook-feed.zip',
|
||||
'title' => __( 'Facebook Feeds', 'feeds-for-youtube' ),
|
||||
'description' => __( 'Get in depth analytics on all your social feeds in a single place', 'feeds-for-youtube' ),
|
||||
'icon' => 'fb-icon.svg',
|
||||
'installed' => isset( $sb_other_plugins['is_facebook_installed'] ) && $sb_other_plugins['is_facebook_installed'] == true,
|
||||
'activated' => is_plugin_active( $sb_other_plugins['facebook_plugin'] ),
|
||||
),
|
||||
'instagram' => array(
|
||||
'plugin' => $sb_other_plugins['instagram_plugin'],
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/instagram-feed.zip',
|
||||
'title' => __( 'Instagram Feeds', 'feeds-for-youtube' ),
|
||||
'description' => __( 'Display customizable Instagram feeds in WordPress', 'feeds-for-youtube' ),
|
||||
'icon' => 'insta-icon.svg',
|
||||
'installed' => isset( $sb_other_plugins['is_instagram_installed'] ) && $sb_other_plugins['is_instagram_installed'] == true,
|
||||
'activated' => is_plugin_active( $sb_other_plugins['instagram_plugin'] ),
|
||||
),
|
||||
'twitter' => array(
|
||||
'plugin' => $sb_other_plugins['twitter_plugin'],
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/custom-twitter-feeds.zip',
|
||||
'title' => __( 'Twitter Feeds', 'feeds-for-youtube' ),
|
||||
'description' => __( 'Display customizable Twitter feeds in WordPress', 'feeds-for-youtube' ),
|
||||
'icon' => 'twitter-icon.svg',
|
||||
'installed' => isset( $sb_other_plugins['is_twitter_installed'] ) && $sb_other_plugins['is_twitter_installed'] == true,
|
||||
'activated' => is_plugin_active( $sb_other_plugins['twitter_plugin'] ),
|
||||
),
|
||||
'youtube' => array(
|
||||
'plugin' => $sb_other_plugins['youtube_plugin'],
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/feeds-for-youtube.zip',
|
||||
'title' => __( 'YouTube Feeds', 'feeds-for-youtube' ),
|
||||
'description' => __( 'Display customizable YouTube feeds in WordPress', 'feeds-for-youtube' ),
|
||||
'icon' => 'youtube-icon.svg',
|
||||
'installed' => isset( $sb_other_plugins['is_youtube_installed'] ) && $sb_other_plugins['is_youtube_installed'] == true,
|
||||
'activated' => is_plugin_active( $sb_other_plugins['youtube_plugin'] ),
|
||||
),
|
||||
'tiktok' => array(
|
||||
'plugin' => $sb_other_plugins['tiktok_plugin'],
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/feeds-for-tiktok.zip',
|
||||
'title' => __( 'Tiktok Feeds', 'feeds-for-youtube' ),
|
||||
'description' => __( 'Display customizable TikTok feeds in WordPress', 'feeds-for-youtube' ),
|
||||
'icon' => 'tiktok-icon.svg',
|
||||
'installed' => isset( $sb_other_plugins['is_tiktok_installed'] ) && $sb_other_plugins['is_tiktok_installed'] == true,
|
||||
'activated' => is_plugin_active( $sb_other_plugins['tiktok_plugin'] ),
|
||||
),
|
||||
],
|
||||
'social_wall' => array(
|
||||
'plugin' => 'social-wall/social-wall.php',
|
||||
'title' => __( 'Social Wall', 'feeds-for-youtube' ),
|
||||
'description' => __( 'Connect all social feeds in a single feed with Social Wall', 'feeds-for-youtube' ),
|
||||
'graphic' => 'social-wall-graphic.png',
|
||||
'icon' => 'reviews-icon.svg',
|
||||
'permalink' => sprintf( 'https://smashballoon.com/social-wall/demo?edd_license_key=%s&upgrade=true&utm_campaign='. sby_utm_campaign() .'&utm_source=about&utm_medium=social-wall', $license_key ),
|
||||
'permalink_text' => __( 'See Demo', 'feeds-for-youtube' ),
|
||||
'installed' => isset( $sb_other_plugins['is_social_wall_installed'] ) && $sb_other_plugins['is_social_wall_installed'] == true,
|
||||
'activated' => is_plugin_active( $sb_other_plugins['social_wall_plugin'] ),
|
||||
),
|
||||
'reviews' => array(
|
||||
'plugin' => $sb_other_plugins['reviews_plugin'],
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/reviews-feed.zip',
|
||||
'title' => __( 'Reviews Feeds', 'feeds-for-youtube' ),
|
||||
'description' => __( 'Display customizable Reviews feeds in WordPress', 'feeds-for-youtube' ),
|
||||
'icon' => 'reviews-icon.svg',
|
||||
'installed' => isset( $sb_other_plugins['is_reviews_installed'] ) && $sb_other_plugins['is_reviews_installed'] == true,
|
||||
'activated' => is_plugin_active( $sb_other_plugins['reviews_plugin'] ),
|
||||
),
|
||||
'click_social' => array(
|
||||
'plugin' => $sb_other_plugins['click_social_plugin'],
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/click-social.zip',
|
||||
'title' => __( 'ClickSocial', 'feeds-for-youtube' ),
|
||||
'description' => __( 'Effortlessly manage your social media presence directly within WordPress. ', 'feeds-for-youtube' ),
|
||||
'icon' => 'click-social-icon.svg',
|
||||
'installed' => isset( $sb_other_plugins['is_click_social_installed'] ) && $sb_other_plugins['is_click_social_installed'] == true,
|
||||
'activated' => is_plugin_active( $sb_other_plugins['click_social_plugin'] ),
|
||||
),
|
||||
'feed_analytics' => array(
|
||||
'plugin' => $sb_other_plugins['click_social_plugin'],
|
||||
'download_plugin' => '',
|
||||
'title' => __( 'Feed Analytics', 'feeds-for-youtube' ),
|
||||
'description' => __( 'Get in depth analytics on all your social feeds in a single place', 'feeds-for-youtube' ),
|
||||
'icon' => 'feed-analytics-icon.svg',
|
||||
'permalink' => sprintf( 'https://smashballoon.com/social-wall/demo?edd_license_key=%s&upgrade=true&utm_campaign='. sby_utm_campaign() .'&utm_source=about&utm_medium=social-wall', $license_key ),
|
||||
'permalink_text' => __( 'See Demo', 'feeds-for-youtube' ),
|
||||
'installed' => isset( $sb_other_plugins['is_click_social_installed'] ) && $sb_other_plugins['is_click_social_installed'] == true,
|
||||
'activated' => is_plugin_active( $sb_other_plugins['click_social_plugin'] ),
|
||||
),
|
||||
'recommendedPlugins' => array(
|
||||
'aioseo' => array(
|
||||
'plugin' => 'all-in-one-seo-pack/all_in_one_seo_pack.php',
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/all-in-one-seo-pack.zip',
|
||||
'title' => __('All in One SEO Pack', 'feeds-for-youtube'),
|
||||
'description' => __('The original WordPress SEO plugin and toolkit that improves your website\'s search rankings. Comes with all the SEO features like Local SEO, WooCommerce SEO, sitemaps, SEO optimizer, schema, and more.', 'feeds-for-youtube'),
|
||||
'icon' => 'plugin-seo.png',
|
||||
'installed' => isset( $installed_plugins['all-in-one-seo-pack/all_in_one_seo_pack.php'] ) ? true : false,
|
||||
'activated' => is_plugin_active('all-in-one-seo-pack/all_in_one_seo_pack.php'),
|
||||
'installs_number' => __('3 Million+ Installs', 'feeds-for-youtube')
|
||||
),
|
||||
'wpforms' => array(
|
||||
'plugin' => 'wpforms-lite/wpforms.php',
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/wpforms-lite.zip',
|
||||
'title' => __('WPForms', 'feeds-for-youtube'),
|
||||
'description' => __('The best drag & drop WordPress form builder. Easily create beautiful contact forms, surveys, payment forms, and more with our 900+ form templates. Trusted by over 6 million websites as the best forms plugin.', 'feeds-for-youtube'),
|
||||
'icon' => 'plugin-wpforms.png',
|
||||
'installed' => isset( $installed_plugins['wpforms-lite/wpforms.php'] ) ? true : false,
|
||||
'activated' => is_plugin_active('wpforms-lite/wpforms.php'),
|
||||
'installs_number' => __('6 Million+ Installs', 'feeds-for-youtube')
|
||||
),
|
||||
'monsterinsights' => array(
|
||||
'plugin' => 'google-analytics-for-wordpress/googleanalytics.php',
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/google-analytics-for-wordpress.zip',
|
||||
'title' => __('MonsterInsights', 'feeds-for-youtube'),
|
||||
'description' => __('The leading WordPress analytics plugin that shows you how people find and use your website, so you can make data driven decisions to grow your business. Properly set up Google Analytics without writing code.', 'feeds-for-youtube'),
|
||||
'icon' => 'plugin-mi.png',
|
||||
'installed' => isset( $installed_plugins['google-analytics-for-wordpress/googleanalytics.php'] ) ? true : false,
|
||||
'activated' => is_plugin_active('google-analytics-for-wordpress/googleanalytics.php'),
|
||||
'installs_number' => __('3 Million+ Installs', 'feeds-for-youtube')
|
||||
),
|
||||
'optinmonster' => array(
|
||||
'plugin' => 'optinmonster/optin-monster-wp-api.php',
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/optinmonster.zip',
|
||||
'title' => __('OptinMonster', 'feeds-for-youtube'),
|
||||
'description' => __('Instantly get more subscribers, leads, and sales with the #1 conversion optimization toolkit. Create high converting popups, announcement bars, spin a wheel, and more with smart targeting and personalization.', 'feeds-for-youtube'),
|
||||
'icon' => 'plugin-om.png',
|
||||
'installed' => isset( $installed_plugins['optinmonster/optin-monster-wp-api.php'] ) ? true : false,
|
||||
'activated' => is_plugin_active('optinmonster/optin-monster-wp-api.php'),
|
||||
'installs_number' => __('1 Million+ Installs', 'feeds-for-youtube')
|
||||
),
|
||||
'wp_mail_smtp' => array(
|
||||
'plugin' => 'wp-mail-smtp/wp_mail_smtp.php',
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/wp-mail-smtp.zip',
|
||||
'title' => __('WP Mail SMTP', 'feeds-for-youtube'),
|
||||
'description' => __('Improve your WordPress email deliverability and make sure that your website emails reach user\'s inbox with the #1 SMTP plugin for WordPress. Over 3 million websites use it to fix WordPress email issues.', 'feeds-for-youtube'),
|
||||
'icon' => 'plugin-smtp.png',
|
||||
'installed' => isset( $installed_plugins['wp-mail-smtp/wp_mail_smtp.php'] ) ? true : false,
|
||||
'activated' => is_plugin_active('wp-mail-smtp/wp_mail_smtp.php'),
|
||||
'installs_number' => __('3 Million+ Installs', 'feeds-for-youtube')
|
||||
),
|
||||
'rafflepress' => array(
|
||||
'plugin' => 'rafflepress/rafflepress.php',
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/rafflepress.zip',
|
||||
'title' => __('RafflePress', 'feeds-for-youtube'),
|
||||
'description' => __('Turn your website visitors into brand ambassadors! Easily grow your email list, website traffic, and social media followers with the most powerful giveaways & contests plugin for WordPress.', 'feeds-for-youtube'),
|
||||
'icon' => 'plugin-rp.png',
|
||||
'installed' => isset( $installed_plugins['rafflepress/rafflepress.php'] ) ? true : false,
|
||||
'activated' => is_plugin_active('rafflepress/rafflepress.php'),
|
||||
'installs_number' => __('20 Thousand+ Installs', 'feeds-for-youtube')
|
||||
),
|
||||
'seedprod' => array(
|
||||
'plugin' => 'coming-soon/coming-soon.php',
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/coming-soon.zip',
|
||||
'title' => __('SeedProd Website Builder', 'feeds-for-youtube'),
|
||||
'description' => __('The fastest drag & drop landing page builder for WordPress. Create custom landing pages without writing code, connect a CRM, collect subscribers, and grow an audience. Trusted by 1 million sites.', 'feeds-for-youtube'),
|
||||
'icon' => 'plugin-seedprod.png',
|
||||
'installed' => isset( $installed_plugins['coming-soon/coming-soon.php'] ) ? true : false,
|
||||
'activated' => is_plugin_active('coming-soon/coming-soon.php'),
|
||||
'installs_number' => __('800 Thousand+ Installs', 'feeds-for-youtube')
|
||||
),
|
||||
'pushengage' => array(
|
||||
'plugin' => 'pushengage/main.php',
|
||||
'download_plugin' => 'https://downloads.wordpress.org/plugin/pushengage.zip',
|
||||
'title' => __('PushEngage Web Push Notifications', 'feeds-for-youtube'),
|
||||
'description' => __('Connect with your visitors after they leave your website with the leading web push notification software. Over 10,000+ businesses worldwide use PushEngage to send 15 billion notifications each month.', 'feeds-for-youtube'),
|
||||
'icon' => 'plugin-push.png',
|
||||
'installed' => isset( $installed_plugins['pushengage/main.php'] ) ? true : false,
|
||||
'activated' => is_plugin_active('pushengage/main.php'),
|
||||
'installs_number' => __('10 Thousand+ Installs', 'feeds-for-youtube')
|
||||
)
|
||||
),
|
||||
];
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Services\Admin\Settings;
|
||||
|
||||
use Smashballoon\Customizer\Feed_Builder;
|
||||
use Smashballoon\Stubs\Services\ServiceProvider;
|
||||
use SmashBalloon\YouTubeFeed\Admin\SBY_Notifications;
|
||||
use SmashBalloon\YouTubeFeed\Container;
|
||||
use SmashBalloon\YouTubeFeed\Helpers\Util;
|
||||
use SmashBalloon\YouTubeFeed\Pro\SBY_CPT;
|
||||
use SmashBalloon\YouTubeFeed\SBY_View;
|
||||
use Smashballoon\Customizer\YouTube_License_Tier;
|
||||
|
||||
abstract class BaseSettingPage extends ServiceProvider {
|
||||
|
||||
protected $has_menu = false;
|
||||
protected $has_assets = false;
|
||||
protected $page_title = "";
|
||||
protected $menu_title = "";
|
||||
protected $menu_slug = "";
|
||||
protected $template_file = "";
|
||||
protected $menu_position = 0;
|
||||
protected $has_page_restriction = false;
|
||||
protected $menu_position_free_version = 0;
|
||||
|
||||
public function register() {
|
||||
if ( true === $this->has_menu ) {
|
||||
add_action('admin_menu', [$this, 'register_menu_page']);
|
||||
}
|
||||
|
||||
if ( ( true === $this->has_assets ) && isset( $_GET['page'] ) && false !== strpos( $_GET['page'],
|
||||
SBY_SLUG . '-' . $this->menu_slug ) ) {
|
||||
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function render() {
|
||||
SBY_View::render($this->template_file);
|
||||
}
|
||||
|
||||
public function enqueue_assets() {
|
||||
wp_enqueue_style(
|
||||
'sby-global-style',
|
||||
CUSTOMIZER_PLUGIN_URL . 'assets/css/global.css',
|
||||
false,
|
||||
SBYVER
|
||||
);
|
||||
//settings page script
|
||||
$script_file = SBY_PLUGIN_URL . 'frontend/build/static/js/main.js';
|
||||
|
||||
if ( ! Util::isProduction() ) {
|
||||
$script_file = "http://localhost:3000/static/js/main.js";
|
||||
} else {
|
||||
wp_enqueue_style(
|
||||
'sby-settings-style',
|
||||
SBY_PLUGIN_URL . 'frontend/build/static/css/main.css',
|
||||
false,
|
||||
SBYVER
|
||||
);
|
||||
}
|
||||
|
||||
wp_enqueue_script(
|
||||
'sby-settings',
|
||||
$script_file,
|
||||
array( 'wp-i18n' ),
|
||||
SBYVER,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script(
|
||||
'sby-settings',
|
||||
'sby_settings',
|
||||
$this->get_settings_object()
|
||||
);
|
||||
|
||||
wp_set_script_translations('sby-settings', 'feeds-for-youtube', SBY_PLUGIN_DIR . 'languages/');
|
||||
}
|
||||
|
||||
public function register_menu_page() {
|
||||
$menu_slug = SBY_SLUG . '-' . $this->menu_slug;
|
||||
if ($this->has_page_restriction) {
|
||||
$menu_slug = 'admin.php?page=sby-feed-builder&tab=more';
|
||||
}
|
||||
|
||||
add_submenu_page(
|
||||
SBY_MENU_SLUG,
|
||||
$this->page_title,
|
||||
$this->menu_title,
|
||||
'manage_options',
|
||||
$menu_slug,
|
||||
[$this, 'render'],
|
||||
$this->menu_position
|
||||
);
|
||||
}
|
||||
|
||||
private function get_notifications() {
|
||||
return Container::get_instance()->get(SBY_Notifications::class)->output_return();
|
||||
}
|
||||
|
||||
protected function get_settings_object() {
|
||||
return apply_filters( 'sby_localized_settings', [
|
||||
'admin_url' => admin_url(),
|
||||
'ajax_handler' => admin_url( 'admin-ajax.php' ),
|
||||
'nonce' => wp_create_nonce( 'sby-admin' ),
|
||||
'setupPageUrl' => admin_url( 'admin.php?page=youtube-feed-setup' ),
|
||||
'supportPageUrl' => admin_url( 'admin.php?page=youtube-feed-support' ),
|
||||
'settingsPageUrl' => admin_url( 'admin.php?page=youtube-feed-settings' ),
|
||||
'builderUrl' => admin_url( 'admin.php?page=sby-feed-builder' ),
|
||||
'connectionURL' => Feed_Builder::oauth_connet_url(),
|
||||
'manageLicense' => 'https://smashballoon.com/account/downloads/?utm_campaign='. sby_utm_campaign() .'&utm_source=settings&utm_medium=manage-license',
|
||||
'single_video_settings' => sby_is_pro() ? SBY_CPT::get_sby_cpt_settings() : [],
|
||||
'single_video_admin_url' => admin_url("admin.php?page=youtube-feed-settings#/single-videos"),
|
||||
'pluginItemName' => SBY_PLUGIN_EDD_NAME,
|
||||
'licenseType' => 'pro',
|
||||
'socialWallLinks' => Feed_Builder::get_social_wall_links(),
|
||||
'socialWallActivated' => is_plugin_active( 'social-wall/social-wall.php' ),
|
||||
'genericText' => Feed_Builder::get_generic_text(),
|
||||
'licenseTierFeatures' => (new YouTube_License_Tier)->tier_features(),
|
||||
'tooltipHelpSvg' => '<svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.1665 8H10.8332V6.33333H9.1665V8ZM9.99984 17.1667C6.32484 17.1667 3.33317 14.175 3.33317 10.5C3.33317 6.825 6.32484 3.83333 9.99984 3.83333C13.6748 3.83333 16.6665 6.825 16.6665 10.5C16.6665 14.175 13.6748 17.1667 9.99984 17.1667ZM9.99984 2.16666C8.90549 2.16666 7.82186 2.38221 6.81081 2.801C5.79976 3.21979 4.8811 3.83362 4.10728 4.60744C2.54448 6.17024 1.6665 8.28986 1.6665 10.5C1.6665 12.7101 2.54448 14.8298 4.10728 16.3926C4.8811 17.1664 5.79976 17.7802 6.81081 18.199C7.82186 18.6178 8.90549 18.8333 9.99984 18.8333C12.21 18.8333 14.3296 17.9554 15.8924 16.3926C17.4552 14.8298 18.3332 12.7101 18.3332 10.5C18.3332 9.40565 18.1176 8.32202 17.6988 7.31097C17.28 6.29992 16.6662 5.38126 15.8924 4.60744C15.1186 3.83362 14.1999 3.21979 13.1889 2.801C12.1778 2.38221 11.0942 2.16666 9.99984 2.16666ZM9.1665 14.6667H10.8332V9.66666H9.1665V14.6667Z" fill="#434960"/></svg>',
|
||||
'svgIcons' => Feed_Builder::builder_svg_icons(),
|
||||
'smashBalloonInfo' => Feed_Builder::get_smashballoon_info(),
|
||||
'assetsURL' => SBY_PLUGIN_URL . 'frontend/build',
|
||||
'notifications' => $this->get_notifications(),
|
||||
'shouldShowPostGracePeriodNotice' => Util::expiredLicenseWithGracePeriodEnded(),
|
||||
'isLicenseInactive' => empty( Util::get_license_key() ),
|
||||
] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
<?php
|
||||
|
||||
namespace SmashBalloon\YouTubeFeed\Services\Admin\Settings;
|
||||
|
||||
use Smashballoon\Customizer\Container;
|
||||
use Smashballoon\Customizer\Feed_Builder;
|
||||
use SmashBalloon\YouTubeFeed\Builder\SBY_Feed_Builder;
|
||||
use SmashBalloon\YouTubeFeed\SBY_Settings;
|
||||
|
||||
class HelpPage extends BaseSettingPage {
|
||||
|
||||
protected $menu_slug = 'support';
|
||||
protected $menu_title = 'Support';
|
||||
protected $page_title = 'Support';
|
||||
protected $has_menu = true;
|
||||
protected $template_file = 'settings.index';
|
||||
protected $has_assets = true;
|
||||
protected $menu_position = 3;
|
||||
protected $menu_position_free_version = 3;
|
||||
|
||||
/**
|
||||
* @var Feed_Builder
|
||||
*/
|
||||
private $feed_builder;
|
||||
|
||||
public function __construct() {
|
||||
$this->feed_builder = Container::getInstance()->get(Feed_Builder::class);
|
||||
}
|
||||
|
||||
public function register() {
|
||||
parent::register();
|
||||
|
||||
add_filter( 'sby_localized_settings', [ $this, 'filter_settings_object' ] );
|
||||
}
|
||||
|
||||
public static function get_whitespace( $times ) {
|
||||
return str_repeat( ' ', $times );
|
||||
}
|
||||
|
||||
public function filter_settings_object( $settings ) {
|
||||
$settings['system_info'] = $this->get_system_info();
|
||||
$settings['system_info_n'] = str_replace( '<br />', "\n", $this->get_system_info() );
|
||||
$settings['feeds'] = Container::getInstance()->get(Feed_Builder::class)->get_feed_list();
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
public function get_system_info() {
|
||||
$output = '';
|
||||
|
||||
// Build the output strings
|
||||
$output .= $this->get_site_n_server_info();
|
||||
$output .= $this->get_active_plugins_info();
|
||||
$output .= $this->get_global_settings_info();
|
||||
$output .= $this->get_feeds_settings_info();
|
||||
$output .= $this->get_sources_info();
|
||||
$output .= $this->get_cron_report();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Site and Server Info
|
||||
*
|
||||
* @since 6.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_site_n_server_info() {
|
||||
$allow_url_fopen = ini_get( 'allow_url_fopen' ) ? 'Yes' : 'No';
|
||||
$php_curl = is_callable( 'curl_init' ) ? 'Yes' : 'No';
|
||||
$php_json_decode = function_exists( 'json_decode' ) ? 'Yes' : 'No';
|
||||
$php_ssl = in_array( 'https', stream_get_wrappers(), true ) ? 'Yes' : 'No';
|
||||
$settings = sby_get_database_settings();
|
||||
$api_verification_status = get_option('sby_api_key_verification', null);
|
||||
$output = '## SITE/SERVER INFO: ##<br />';
|
||||
$output .= 'Plugin Version:' . self::get_whitespace( 11 ) . esc_html( SBY_PLUGIN_NAME ) . '<br />';
|
||||
$output .= 'Site URL:' . self::get_whitespace( 17 ) . esc_html( site_url() ) . '<br />';
|
||||
$output .= 'Home URL:' . self::get_whitespace( 17 ) . esc_html( home_url() ) . '<br />';
|
||||
$output .= 'WordPress Version:' . self::get_whitespace( 8 ) . esc_html( get_bloginfo( 'version' ) ) . '<br />';
|
||||
$output .= 'PHP Version:' . self::get_whitespace( 14 ) . esc_html( PHP_VERSION ) . '<br />';
|
||||
$output .= 'Web Server Info:' . self::get_whitespace( 10 ) . esc_html( $_SERVER['SERVER_SOFTWARE'] ) . '<br />';
|
||||
$output .= 'PHP allow_url_fopen:' . self::get_whitespace( 6 ) . esc_html( $allow_url_fopen ) . '<br />';
|
||||
$output .= 'PHP cURL:' . self::get_whitespace( 17 ) . esc_html( $php_curl ) . '<br />';
|
||||
$output .= 'JSON:' . self::get_whitespace( 21 ) . esc_html( $php_json_decode ) . '<br />';
|
||||
$output .= 'SSL Stream:' . self::get_whitespace( 15 ) . esc_html( $php_ssl ) . '<br />';
|
||||
$output .= 'API Key:' . self::get_whitespace( 18 ) . esc_html( isset($settings['api_key']) ? $settings['api_key'] : 'Empty' ) . '<br />';
|
||||
$output .= 'API Status:' . self::get_whitespace( 15 ) . esc_html( !empty($api_verification_status) ? ($api_verification_status->status == true ? "Successful" : "Failed") : 'Unknown' ) . '<br />';
|
||||
$output .= '<br />';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Active Plugins
|
||||
*
|
||||
* @since 6.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_active_plugins_info() {
|
||||
$plugins = get_plugins();
|
||||
$active_plugins = get_option( 'active_plugins' );
|
||||
$output = '## ACTIVE PLUGINS: ## <br />';
|
||||
|
||||
foreach ( $plugins as $plugin_path => $plugin ) {
|
||||
if ( in_array( $plugin_path, $active_plugins, true ) ) {
|
||||
$output .= esc_html( $plugin['Name'] ) . ': ' . esc_html( $plugin['Version'] ) . '<br />';
|
||||
}
|
||||
}
|
||||
|
||||
$output .= '<br />';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Global Settings
|
||||
*
|
||||
* @since 6.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_global_settings_info() {
|
||||
$output = '## GLOBAL SETTINGS: ## <br />';
|
||||
$sby_license_key = get_option( 'sby_license_key' );
|
||||
$sby_license_data = get_option( 'sby_license_data' );
|
||||
$sby_license_status = get_option( 'sby_license_status' );
|
||||
$sby_settings = get_option( 'settings', array() );
|
||||
|
||||
$usage_tracking = get_option(
|
||||
'sby_usage_tracking',
|
||||
array(
|
||||
'last_send' => 0,
|
||||
'enabled' => \sby_is_pro_version(),
|
||||
)
|
||||
);
|
||||
|
||||
$output .= 'License key: ';
|
||||
if ( $sby_license_key ) {
|
||||
$output .= esc_html( $sby_license_key );
|
||||
} else {
|
||||
$output .= ' Not added';
|
||||
|
||||
}
|
||||
$output .= '<br />';
|
||||
$output .= 'License status: ';
|
||||
if ( $sby_license_status ) {
|
||||
$output .= $sby_license_status;
|
||||
} else {
|
||||
$output .= ' Inactive';
|
||||
}
|
||||
$output .= '<br />';
|
||||
$output .= 'Preserve settings if plugin is removed: ';
|
||||
$output .= isset( $sby_settings['preserve_settings'] ) && ( $sby_settings['preserve_settings'] ) ? 'Yes' : 'No';
|
||||
$output .= '<br />';
|
||||
$output .= 'Connected Accounts: ';
|
||||
$output .= 'Placeholder!';
|
||||
|
||||
$output .= '<br />';
|
||||
$output .= 'Caching: ';
|
||||
if ( wp_next_scheduled( 'sby_feed_update' ) ) {
|
||||
$time_format = get_option( 'time_format' );
|
||||
if ( ! $time_format ) {
|
||||
$time_format = 'g:i a';
|
||||
}
|
||||
//
|
||||
$schedule = wp_get_schedule( 'sby_feed_update' );
|
||||
if ( $schedule === '30mins' ) {
|
||||
$schedule = __( 'every 30 minutes', 'feeds-for-youtube' );
|
||||
}
|
||||
if ( $schedule === 'twicedaily' ) {
|
||||
$schedule = __( 'every 12 hours', 'feeds-for-youtube' );
|
||||
}
|
||||
$sby_next_cron_event = wp_next_scheduled( 'sby_feed_update' );
|
||||
$output = __( 'Next check', 'feeds-for-youtube' ) . ': ' . gmdate( $time_format, $sby_next_cron_event + sby_get_utc_offset() ) . ' (' . $schedule . ')';
|
||||
|
||||
} else {
|
||||
$output .= 'Nothing currently scheduled';
|
||||
}
|
||||
$output .= '<br />';
|
||||
$output .= 'GDPR: ';
|
||||
$output .= isset( $sby_settings['gdpr'] ) ? $sby_settings['gdpr'] : ' Not setup';
|
||||
$output .= '<br />';
|
||||
$output .= 'Custom CSS: ';
|
||||
$output .= isset( $sby_settings['custom_css'] ) && ! empty( $sby_settings['custom_css'] ) ? $sby_settings['custom_css'] : 'Empty';
|
||||
$output .= '<br />';
|
||||
$output .= 'Custom JS: ';
|
||||
$output .= isset( $sby_settings['custom_js'] ) && ! empty( $sby_settings['custom_js'] ) ? $sby_settings['custom_js'] : 'Empty';
|
||||
$output .= '<br />';
|
||||
$output .= 'Usage Tracking: ';
|
||||
$output .= isset( $usage_tracking['enabled'] ) && $usage_tracking['enabled'] === true ? 'Enabled' : 'Disabled';
|
||||
$output .= '<br />';
|
||||
$output .= 'AJAX theme loading fix: ';
|
||||
$output .= isset( $sby_settings['ajax_theme'] ) && $sby_settings['ajax_theme'] ? 'Enabled' : 'Disabled';
|
||||
$output .= '<br />';
|
||||
$output .= 'AJAX Initial: ';
|
||||
$output .= isset( $sby_settings['sb_ajax_initial'] ) && $sby_settings['sb_ajax_initial'] === true ? 'Enabled' : 'Disabled';
|
||||
$output .= '<br />';
|
||||
$output .= 'Enqueue in Head: ';
|
||||
$output .= isset( $sby_settings['enqueue_js_in_head'] ) && $sby_settings['enqueue_js_in_head'] === true ? 'Enabled' : 'Disabled';
|
||||
$output .= '<br />';
|
||||
$output .= 'Disable WP Posts: ';
|
||||
$output .= !empty($sby_settings['disable_wp_posts']) ? 'True' : 'False';;
|
||||
$output .= '<br />';
|
||||
$output .= 'Enqueue in Shortcode: ';
|
||||
$output .= isset( $sby_settings['enqueue_css_in_shortcode'] ) && $sby_settings['enqueue_css_in_shortcode'] === true ? 'Enabled' : 'Disabled';
|
||||
$output .= '<br />';
|
||||
$output .= 'Enable JS Image: ';
|
||||
$output .= isset( $sby_settings['disable_js_image_loading'] ) && $sby_settings['disable_js_image_loading'] === false ? 'Enabled' : 'Disabled';
|
||||
$output .= '<br />';
|
||||
$output .= 'Admin Error Notice: ';
|
||||
$output .= isset( $sby_settings['disable_admin_notice'] ) && $sby_settings['disable_admin_notice'] === false ? 'Enabled' : 'Disabled';
|
||||
$output .= '<br />';
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Feeds Settings
|
||||
*
|
||||
* @since 6.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_feeds_settings_info() {
|
||||
$output = '## FEEDS: ## <br />';
|
||||
|
||||
$feeds_list = $this->feed_builder->get_feed_list();
|
||||
|
||||
$i = 0;
|
||||
foreach ( $feeds_list as $feed ) {
|
||||
$settings = json_decode($feed['settings'], true);
|
||||
$type = ! empty( $settings['type'] ) ? $settings['type'] : 'channel';
|
||||
if ( $i >= 25 ) {
|
||||
break;
|
||||
}
|
||||
$output .= $feed['feed_name'];
|
||||
$output .= '<br />';
|
||||
if ( isset( $feed['location_summary'] ) && count( $feed['location_summary'] ) > 0 ) {
|
||||
$first_feed = $feed['location_summary'][0];
|
||||
if ( ! empty( $first_feed['link'] ) ) {
|
||||
$output .= esc_html( $first_feed['link'] ) . '?sb_debug';
|
||||
$output .= '<br />';
|
||||
}
|
||||
}
|
||||
|
||||
if ( $i < ( count( $feeds_list ) - 1 ) ) {
|
||||
$output .= '<br />';
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
$output .= '<br />';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Feeds Settings
|
||||
*
|
||||
* @since 6.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_sources_info() {
|
||||
$output = '## Sources: ## <br />';
|
||||
|
||||
foreach ( [] as $source ) {
|
||||
|
||||
$output .= $source['account_id'];
|
||||
$output .= '<br />';
|
||||
$output .= 'Type: ' . esc_html( $source['account_type'] );
|
||||
$output .= '<br />';
|
||||
$output .= 'Username: ' . esc_html( $source['username'] );
|
||||
$output .= '<br />';
|
||||
$output .= 'Error: ' . esc_html( $source['error'] );
|
||||
$output .= '<br />';
|
||||
$output .= '<br />';
|
||||
$output .= '<br />';
|
||||
|
||||
}
|
||||
$output .= '<br />';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Reports
|
||||
*
|
||||
* @since 6.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_cron_report() {
|
||||
$output = '## Cron Cache Report: ## <br />';
|
||||
$cron_report = get_option( 'sby_cron_report', array() );
|
||||
if ( ! empty( $cron_report ) ) {
|
||||
$output .= 'Time Ran: ' . esc_html( $cron_report['notes']['time_ran'] );
|
||||
$output .= '<br />';
|
||||
$output .= 'Found Feeds: ' . esc_html( $cron_report['notes']['num_found_transients'] );
|
||||
$output .= '<br />';
|
||||
$output .= '<br />';
|
||||
|
||||
foreach ( $cron_report as $key => $value ) {
|
||||
if ( $key !== 'notes' ) {
|
||||
$output .= esc_html( $key ) . ':';
|
||||
$output .= '<br />';
|
||||
if ( ! empty( $value['last_retrieve'] ) ) {
|
||||
$output .= 'Last Retrieve: ' . esc_html( $value['last_retrieve'] );
|
||||
$output .= '<br />';
|
||||
}
|
||||
$output .= 'Did Update: ' . esc_html( $value['did_update'] );
|
||||
$output .= '<br />';
|
||||
$output .= '<br />';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$output .= '<br />';
|
||||
}
|
||||
|
||||
$cron = _get_cron_array();
|
||||
foreach ( $cron as $key => $data ) {
|
||||
$is_target = false;
|
||||
foreach ( $data as $key2 => $val ) {
|
||||
if ( strpos( $key2, 'sby' ) !== false || strpos( $key2, 'sb_youtube' ) !== false ) {
|
||||
$is_target = true;
|
||||
$output .= esc_html( $key2 );
|
||||
$output .= '<br />';
|
||||
}
|
||||
}
|
||||
if ( $is_target ) {
|
||||
$output .= esc_html( date( 'Y-m-d H:i:s', $key ) );
|
||||
$output .= '<br />';
|
||||
$output .= esc_html( 'Next Scheduled: ' . round( ( (int) $key - time() ) / 60 ) . ' minutes' );
|
||||
$output .= '<br />';
|
||||
$output .= '<br />';
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user