Commit inicial - WordPress Análisis de Precios Unitarios

- WordPress core y plugins
- Tema Twenty Twenty-Four configurado
- Plugin allow-unfiltered-html.php simplificado
- .gitignore configurado para excluir wp-config.php y uploads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-11-03 21:04:30 -06:00
commit a22573bf0b
24068 changed files with 4993111 additions and 0 deletions

View File

@@ -0,0 +1,237 @@
<?php
/**
* Created by PhpStorm.
* User: radu
* Date: 05.08.2014
* Time: 14:37
*/
/**
* base abstract class that will be extended by all available actions
*
* Class TCB_Event_Action_Abstract
*/
abstract class TCB_Event_Action_Abstract {
/**
* @var array|mixed $data holds data that will be available in the view settings file
*/
protected $data;
protected $key = '';
/**
* holds the configuration values for this action
*
* @var array
*/
protected $config = [];
protected $flag_available = null;
/**
* instantiate a new Event Action class based on $class_name
*
* if a class does not exist, it tries to automatically include it from within the /actions folder
*
* if it's a third-party API - added action, the class MUST previously exist
*
* @param string $class_name
* @param mixed $constructor_param optional argument to call the class constructor with
*
* @return TCB_Event_Action_Abstract
*
* @throws Exception
*/
public static final function actionFactory( $class_name, $constructor_param = null ) {
if ( ! class_exists( $class_name ) && file_exists( __DIR__ . "/actions/$class_name.php" ) ) {
require_once __DIR__ . "/actions/$class_name.php";
}
if ( ! class_exists( $class_name ) ) {
throw new Exception( 'TCB Event Action factory: Could not find ' . $class_name );
}
return new $class_name( $constructor_param );
}
/**
* used only by TCB, it will render a view from /settings folder
*
* @param string $view view file to be rendered
* @param mixed $data data to make available in the view
*
* @return string
*/
protected final function renderTCBSettings( $view, $data ) {
if ( substr( $view, - 4 ) !== '.php' ) {
$view .= '.php';
}
$file = dirname( dirname( __FILE__ ) ) . '/views/settings/' . $view;
if ( ! file_exists( $file ) ) {
exit( 'No settings found' );
}
if ( ! empty( $this->config ) ) {
$data['config'] = $this->config;
}
$this->data = $data;
ob_start();
include $file;
$content = ob_get_contents();
ob_end_clean();
return $content;
}
/**
* sets the saved configuration values for this Action
*
* @param $config
*
* @return TCB_Event_Action_Abstract
*/
public final function setConfig( $config ) {
$this->config = $config;
return $this;
}
/**
* magic getter for the view variables
*
* @param $key
*
* @return mixed
*/
public function __get( $key ) {
return isset( $this->data[ $key ] ) ? $this->data[ $key ] : null;
}
/**
* makes all necessary changes to the content depending on the $data param
*
* this gets called each time this action is encountered in the DOM event configuration
*
* @param $data
*
* @return mixed
*/
public function applyContentFilter( $data ) {
return '';
}
/**
* this will get displayed after the Action Name in the Actions list on the editor page
*/
public function getSummary() {
return '';
}
/**
* abstract methods that must be implemented in each of the derived classes
*/
/**
* Should return the user-friendly name for this Action
*
* @return string
*/
public abstract function getName();
/**
* Should return an actual string containing the JS function that's handling this action.
* The function will be called with 3 parameters:
* -> event_trigger (e.g. click, dblclick etc)
* -> action_code (the action that's being executed)
* -> config (specific configuration for each specific action - the same configuration that has been setup in the settings section)
*
* Example (php): return 'function (trigger, action, config) { console.log(trigger, action, config); }';
*
* The function will be called in the context of the element
*
* The output MUST be a valid JS function definition.
*
* @return string the JS function definition (declaration + body)
*/
public abstract function getJsActionCallback();
/**
* this will only be called ONCE if this action is encountered in the element's settings, and it should output all the necessary
* preparation javascript, such as helpers etc for this action
* It should use namespaces and WP naming conventions, we don't want to mess up the global namespace with these
*
* @return mixed
*/
public function outputGlobalJavascript() {
}
/**
* validate the current configuration for an action
*/
public function validateConfig() {
return true;
}
/**
* called in the main loop when getting the main page / post content - used to append stuff such as fonts / icons that are (possibly) required in the action handler
*
* @param array $data
*
* @return void
*/
public function mainPostCallback( $data ) {
}
/**
* should check if the current action is available to be displayed in the lists inside the event manager
*
* @return bool
*/
public function is_available() {
return isset( $this->flag_available ) ? $this->flag_available : true;
}
/**
* Return the javascript constructor name for a view which will be instantiated for the editor settings of this action
*
* @return string
*/
public function get_editor_js_view() {
return 'ActionDefault';
}
/**
* Getter action key
*/
public function get_key() {
return $this->key;
}
public function set_key( $key ) {
$this->key = $key;
return $this;
}
/**
* Render the settings for this action
*/
public function render_editor_settings() {
echo '';
}
public function get_options() {
return [];
}
public function set_is_available( $flag ) {
$this->flag_available = $flag;
return $this;
}
}

View File

@@ -0,0 +1,133 @@
<?php
/**
* Created by PhpStorm.
* User: radu
* Date: 11.08.2014
* Time: 15:24
*/
/**
* represents logic for an event Trigger
* Class TCB_Event_Trigger_Abstract
*
* Each Event Trigger must override this class
*/
abstract class TCB_Event_Trigger_Abstract {
/**
* holds the configuration for the selected trigger
*
* @var array
*/
protected $config;
/**
* should return the Event name
* @return string
*/
public abstract function getName();
/**
* convenience method to display the name of this Event Trigger. It allows statements like echo $trigger;
* @return mixed
*/
public function __toString() {
return $this->getName();
}
/**
* instantiate a new Event Trigger class based on $class_name
*
* if a class does not exist, it tries to automatically include it from within the /actions folder
*
* if it's a third-party API - added trigger, the class MUST previously exist
*
* @param string $class_name
* @param mixed $constructor_param optional argument to call the class constructor with
*
* @return TCB_Event_Trigger_Abstract
*/
public static final function triggerFactory( $class_name, $constructor_param = null ) {
if ( ! class_exists( $class_name ) && file_exists( dirname( __FILE__ ) . '/triggers/' . $class_name . '.php' ) ) {
require_once dirname( __FILE__ ) . '/triggers/' . $class_name . '.php';
}
if ( ! class_exists( $class_name ) ) {
throw new Exception( 'TCB Event Trigger factory: Could not find ' . $class_name );
}
return new $class_name( $constructor_param );
}
/**
* this will only be called ONCE if this trigger is encountered in the element's settings, and it should output all the necessary
* preparation javascript, such as helpers etc for this action
* It should use namespaces and WP naming conventions, we don't want to mess up the global namespace with these
*
* @return mixed
*/
public function outputGlobalJavascript() {
}
/**
* called for each instance of the trigger that's registered in the Event Manager
* it just needs to return a piece of javascript code that will trigger the event, if this is the case
*
* and example: Timer triggers -> need to trigger the event after a delay
*/
public function getInstanceJavascript( $config ) {
return '';
}
/**
* set the current configuration, if any
*
* @param $data
*
* @return $this
*/
public function setConfig( $config ) {
$this->config = $config;
return $this;
}
/**
* render individual settings for a trigger (if it applies)
*
* @param $data
*/
public function renderSettings( $data ) {
return '';
}
/**
* used only by TCB, it will render a view from /settings folder
*
* @param string $view view file to be rendered
* @param mixed $data data to make available in the view
*/
protected final function renderTCBSettings( $view, $data ) {
if ( substr( $view, - 4 ) !== '.php' ) {
$view .= '.php';
}
$file = dirname( dirname( __FILE__ ) ) . '/views/settings/triggers/' . $view;
if ( ! file_exists( $file ) ) {
exit( 'No settings found' );
}
$this->data = $data;
ob_start();
include $file;
$content = ob_get_contents();
ob_end_clean();
return $content;
}
public function get_options() {
return [];
}
}

View File

@@ -0,0 +1,327 @@
<?php
/**
* Created by PhpStorm.
* User: radu
* Date: 11.08.2014
* Time: 16:03
*/
class TCB_Thrive_CSS_Animation extends TCB_Event_Action_Abstract {
protected $key = 'thrive_animation';
/**
* available CSS animations
*
* @var array
*/
protected $_animations
= array(
'slide_top' => 'Top to bottom',
'slide_bottom' => 'Bottom to top',
'slide_left' => 'Left to right',
'slide_right' => 'Right to left',
'appear' => 'Appear from Centre (Zoom In)',
'zoom_out' => 'Zoom Out',
'fade' => 'Fade in',
'rotate' => 'Rotational',
'roll_in' => 'Roll In',
'roll_out' => 'Roll Out',
'grow' => 'Grow',
'shrink' => 'Shrink',
'pulse' => 'Pulse',
'pulse_grow' => 'Pulse Grow',
'pulse_shrink' => 'Pulse Shrink',
'push' => 'Push',
'pop' => 'Pop',
'bounce_in' => 'Bounce In',
'bounce_out' => 'Bounce Out',
'bob' => 'Bob',
'hang' => 'Hang',
'wobble_horizontal' => 'Wobble Horizontal',
'wobble_vertical' => 'Wobble Vertical',
'buzz' => 'Buzz',
'buzz_out' => 'Buzz Out',
'forward' => 'Forward',
'backward' => 'Backward',
'sweep_to_right' => 'Sweep to right',
'sweep_to_left' => 'Sweep to left',
'sweep_to_bottom' => 'Sweep to bottom',
'sweep_to_top' => 'Sweep to top',
'bounce_to_right' => 'Bounce to right',
'bounce_to_left' => 'Bounce to left',
'bounce_to_bottom' => 'Bounce to bottom',
'bounce_to_top' => 'Bounce to top',
'radial_out' => 'Radial out',
'radial_in' => 'Radial in',
'rectangle_in' => 'Rectangle in',
'rectangle_out' => 'Rectangle out',
'shutter_out_horizontal' => 'Shutter out horizontal',
'shutter_out_vertical' => 'Shutter out vertical',
);
/**
*
* @return array
*/
public static function get_config() {
$config = array(
'slide' => array(
'title' => __( 'Sliding', 'thrive-cb' ),
'items' => array(
'slide_top' => array(
'title' => __( 'Slide, top', 'thrive-cb' ),
'trigger' => [ 'tve-viewport' ],
),
'slide_bottom' => array(
'title' => __( 'Slide, bottom', 'thrive-cb' ),
'trigger' => [ 'tve-viewport' ],
),
'slide_right' => array(
'title' => __( 'Slide, right', 'thrive-cb' ),
'trigger' => [ 'tve-viewport' ],
),
'slide_left' => array(
'title' => __( 'Slide, left', 'thrive-cb' ),
'trigger' => [ 'tve-viewport' ],
),
),
),
'zoom' => array(
'title' => __( 'Zoom (Appear)', 'thrive-cb' ),
'items' => array(
'appear' => array(
'title' => __( 'Zoom in', 'thrive-cb' ),
'trigger' => [ 'tve-viewport' ],
),
'zoom_out' => array(
'title' => __( 'Zoom out', 'thrive-cb' ),
'trigger' => [ 'tve-viewport' ],
),
),
),
'modify' => array(
'title' => __( 'Modify', 'thrive-cb' ),
'items' => array(
'grow' => array(
'title' => __( 'Grow', 'thrive-cb' ),
'trigger' => [ 'tve-viewport', 'mouseover' ],
),
'shrink' => array(
'title' => __( 'Shrink', 'thrive-cb' ),
'trigger' => [ 'tve-viewport', 'mouseover' ],
),
'pulse' => array(
'title' => __( 'Pulse', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'pulse_grow' => array(
'title' => __( 'Pulse Grow', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'pulse_shrink' => array(
'title' => __( 'Pulse Shrink', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'push' => array(
'title' => __( 'Push', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'pop' => array(
'title' => __( 'Pop', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'bounce_in' => array(
'title' => __( 'Bounce In', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'bounce_out' => array(
'title' => __( 'Bounce Out', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'bob' => array(
'title' => __( 'Bob', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'hang' => array(
'title' => __( 'Hang', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'wobble_horizontal' => array(
'title' => __( 'Wobble Horizontal', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'wobble_vertical' => array(
'title' => __( 'Wobble Vertical', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'buzz' => array(
'title' => __( 'Buzz', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'buzz_out' => array(
'title' => __( 'Buzz Out', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'forward' => array(
'title' => __( 'Forward', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'backward' => array(
'title' => __( 'Backward', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
),
),
'background' => array(
'title' => __( 'Background', 'thrive-cb' ),
'items' => array(
'sweep_to_right' => array(
'title' => __( 'Sweep to right', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'sweep_to_left' => array(
'title' => __( 'Sweep to left', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'sweep_to_bottom' => array(
'title' => __( 'Sweep to bottom', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'sweep_to_top' => array(
'title' => __( 'Sweep to top', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'bounce_to_right' => array(
'title' => __( 'Bounce to right', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'bounce_to_left' => array(
'title' => __( 'Bounce to left', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'bounce_to_bottom' => array(
'title' => __( 'Bounce to bottom', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'bounce_to_top' => array(
'title' => __( 'Bounce to top', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'radial_out' => array(
'title' => __( 'Radial out', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'radial_in' => array(
'title' => __( 'Radial in', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'rectangle_in' => array(
'title' => __( 'Rectangle in', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'rectangle_out' => array(
'title' => __( 'Rectangle out', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'shutter_out_horizontal' => array(
'title' => __( 'Shutter out horizontal', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
'shutter_out_vertical' => array(
'title' => __( 'Shutter out vertical', 'thrive-cb' ),
'trigger' => [ 'mouseover' ],
),
),
),
'other' => array(
'title' => __( 'Other (Appear)', 'thrive-cb' ),
'items' => array(
'fade_in' => array(
'title' => __( 'Fade in', 'thrive-cb' ),
'trigger' => [ 'tve-viewport' ],
),
'rotate' => array(
'title' => __( 'Rotate', 'thrive-cb' ),
'trigger' => [ 'tve-viewport' ],
),
'roll_in' => array(
'title' => __( 'Roll in', 'thrive-cb' ),
'trigger' => [ 'tve-viewport' ],
),
),
),
);
return apply_filters( 'tcb_animations', $config );
}
/**
* Should return the user-friendly name for this Action
*
* @return string
*/
public function getName() {
return 'Animation';
}
/**
* Should output the settings needed for this Action when a user selects it from the list
*
* @param mixed $data existing configuration data, etc
*/
public function renderSettings( $data ) {
return $this->renderTCBSettings( 'animation', $data );
}
/**
* Should return an actual string containing the JS function that's handling this action.
* The function will be called with 3 parameters:
* -> event_trigger (e.g. click, dblclick etc)
* -> action_code (the action that's being executed)
* -> config (specific configuration for each specific action - the same configuration that has been setup in the settings section)
*
* Example (php): return 'function (trigger, action, config) { console.log(trigger, action, config); }';
*
* The function will be called in the context of the element
*
* The output MUST be a valid JS function definition.
*
* @return string the JS function definition (declaration + body)
*/
public function getJsActionCallback() {
return tcb_template( 'actions/animation.js', null, true );
}
public function getSummary() {
if ( ! empty( $this->config ) ) {
return ': ' . $this->_animations[ $this->config['anim'] ];
}
}
public function get_editor_js_view() {
return 'Animation';
}
public function render_editor_settings() {
tcb_template( 'actions/animation', self::get_config() );
}
public function get_options() {
$labels = [
'__config_key' => 'anim',
];
$triggers = [];
foreach ( self::get_config() as $item ) {
foreach ( $item['items'] as $key => $data ) {
$labels[ $key ] = $data['title'];
$triggers[ $key ] = $data['trigger'];
}
}
return [
'labels' => $labels,
'triggers' => $triggers,
];
}
}

View File

@@ -0,0 +1,87 @@
<?php
/**
* Thrive Themes - https://thrivethemes.com
*
* @package thrive-visual-editor
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Silence is golden!
}
class TCB_Thrive_Image_Zoom extends TCB_Event_Action_Abstract {
protected $key = 'thrive_zoom';
/**
* Should return the user-friendly name for this Action
*
* @return string
*/
public function getName() {
return __( 'Open image', 'thrive-cb' );
}
/**
* Should output the settings needed for this Action when a user selects it from the list
*
* @param mixed $data existing configuration data, etc
*
* @return string html
*/
public function renderSettings( $data ) {
return $this->renderTCBSettings( 'zoom', $data );
}
/**
* Should return an actual string containing the JS function that's handling this action.
* The function will be called with 3 parameters:
* -> event_trigger (e.g. click, dblclick etc)
* -> action_code (the action that's being executed)
* -> config (specific configuration for each specific action - the same configuration that has been setup in the settings section)
*
* Example (php): return 'function (trigger, action, config) { console.log(trigger, action, config); }';
*
* The function will be called in the context of the element
*
* The output MUST be a valid JS function definition.
*
* @return string the JS function definition (declaration + body)
*/
public function getJsActionCallback() {
return tcb_template( 'actions/image-zoom.js', null, true );
}
public function applyContentFilter( $data ) {
/**
* IF an ID exists in the config array, it means that the attachment with the corresponding id must be opened
* Append it to the body
*/
$config = ! empty( $data['config'] ) ? $data['config'] : [];
if ( empty( $config ) && array_key_exists( 'c', $data ) ) {
$config = $data['c'];
}
if ( $config ) {
if ( empty( $config['url'] ) ) {
$image = wp_get_attachment_image( $config['id'], empty( $config['size'] ) ? 'full' : $config['size'] );
return sprintf( '<div class="tcb-image-zoom" style="display: none" id="tcb-image-zoom-%s">%s</div>', $config['id'], $image );
} elseif ( ! empty( $config['url'] ) && filter_var( $config['url'], FILTER_VALIDATE_URL ) !== false ) { //This is a custom image URL. Not saved in WordPress
return sprintf( '<div class="tcb-image-zoom" style="display: none" id="tcb-image-zoom-%s">%s</div>', $config['id'], '<img src="' . $config['url'] . '" />' );
}
}
}
public function get_editor_js_view() {
return 'ImageZoom';
}
public function get_options() {
return array( 'labels' => __( 'Open image', 'thrive-cb' ) );
}
public function render_editor_settings() {
}
}

View File

@@ -0,0 +1,270 @@
<?php
/**
* Created by PhpStorm.
* User: radu
* Date: 05.08.2014
* Time: 14:35
*/
if ( ! class_exists( 'TCB_Thrive_Lightbox' ) ) {
/**
*
* handles the server-side logic for the Thrive Lightbox action = opens a lightbox on an Event Trigger
*
* Class TCB_Thrive_Lightbox
*/
class TCB_Thrive_Lightbox extends TCB_Event_Action_Abstract {
protected $key = 'thrive_lightbox';
/**
* holds all lightbox ids that have been rendered in the footer - this is to not render a lightbox twice
*
* @var array
*/
private static $loaded_lightboxes = [];
/**
* holds all lightbox ids that have been parsed for events configuration - this is to not create an infinite loop in case of
* lightboxes used within lightboxes
*
* @var array
*/
private static $lightboxes_events_parsed = [];
/**
* Should return the user-friendly name for this Action
*
* @return string
*/
public function getName() {
return 'Open Thrive lightbox';
}
/**
* Should return an actual string containing the JS function that's handling this action.
* The function will be called with 3 parameters:
* -> event_trigger (e.g. click, dblclick etc)
* -> action_code (the action that's being executed)
* -> config (specific configuration for each specific action - the same configuration that has been setup in the settings section)
*
* Example (php): return 'function (trigger, action, config) { console.log(trigger, action, config); }';
*
* The output MUST be a valid JS function definition.
*
* @return string the JS function definition (declaration + body)
*/
public function getJsActionCallback() {
return 'function(t,a,c){var $t=jQuery("#tve_thrive_lightbox_"+c.l_id);if(t==="exit"&&$t.data("shown-on-exit")){return;}$t.css("display", "");$t.data("shown-on-"+t, true);var a=c.l_anim||"instant";TCB_Front.openLightbox($t,a);return false;};';
}
/**
* makes all necessary changes to the content depending on the $data param
*
* this gets called each time this action is encountered in the DOM event configuration
*
* @param $data
*/
public function applyContentFilter( $data ) {
$lightbox_id = isset( $data['config']['l_id'] ) ? (int) $data['config']['l_id'] : 0;
if ( ! $lightbox_id ) {
return false;
}
if ( isset( self::$loaded_lightboxes[ $lightbox_id ] ) ) {
return '';
}
/**
* Leave the possibility for others to change the lightbox showed to the users
*/
$lightbox = tve_filter_intrusive_forms( 'tcb', get_post( $lightbox_id ) );
if ( empty( $lightbox ) ) {
return '';
}
global $post;
$old_post = $post;
$GLOBALS['tcb_main_post_lightbox'] = $old_post;
$post = $lightbox;
/**
* this if was added for TU Main Ajax request, the the html must be returned
*/
if ( ! has_filter( 'the_content', 'tve_editor_content' ) ) {
add_filter( 'the_content', 'tve_editor_content' );
/*
* This fixes the duplicated content that appears in TU when a lightbox is triggered to open inside a ribbon
*/
add_filter( 'the_content', 'tve_clean_wp_editor_content', - 100 );
}
$lightbox_html = tcb_lightbox( $lightbox_id )->get_html();
$post = $old_post;
self::$loaded_lightboxes[ $lightbox_id ] = $lightbox_html;
ob_start();
TCB\Lightspeed\Css::get_instance( $lightbox_id )->load_optimized_style( 'base' );
TCB\Lightspeed\JS::get_instance( $lightbox_id )->load_modules();
tve_load_custom_css( $lightbox_id );
$lightbox_html = ob_get_clean() . $lightbox_html;
return $lightbox_html;
}
/**
* check if the associated lightbox exists and it's not trashed
*
* @return bool
*/
public function validateConfig() {
$lightbox_id = $this->config['l_id'];
if ( empty( $lightbox_id ) ) {
return false;
}
$lightbox = get_post( $lightbox_id );
if ( empty( $lightbox ) || $lightbox->post_status === 'trash' || $lightbox->post_type != 'tcb_lightbox' ) {
return false;
}
return true;
}
/**
* make sure that if custom icons are used, the CSS for that is included in the main page
* the same with Custom Fonts
*
* @param array $data
*/
public function mainPostCallback( $data ) {
$lightbox_id = empty( $data['config']['l_id'] ) ? 0 : $data['config']['l_id'];
if ( isset( self::$lightboxes_events_parsed[ $lightbox_id ] ) ) {
return;
}
self::$lightboxes_events_parsed[ $lightbox_id ] = true;
if ( tve_get_post_meta( $lightbox_id, 'thrive_icon_pack' ) && ! wp_style_is( 'thrive_icon_pack', 'enqueued' ) ) {
TCB_Icon_Manager::enqueue_icon_pack();
}
tve_enqueue_extra_resources( $lightbox_id );
tve_enqueue_custom_fonts( $lightbox_id, true );
/* output any css needed for the extra (imported) fonts */
if ( function_exists( 'tve_output_extra_custom_fonts_css' ) ) {
tve_output_extra_custom_fonts_css( $lightbox_id );
}
if ( tve_get_post_meta( $lightbox_id, 'tve_has_masonry' ) ) {
wp_script_is( 'jquery-masonry' ) || wp_enqueue_script( 'jquery-masonry', [ 'jquery' ] );
}
$lightbox_content = get_post_meta( $lightbox_id, 'tve_updated_post', true );
tve_parse_events( $lightbox_content );
$lightspeed_css = \TCB\Lightspeed\Css::get_instance( $lightbox_id );
if ( $lightspeed_css->should_load_optimized_styles() ) {
$optimized_styles = $lightspeed_css->get_optimized_styles();
}
TCB\Lightspeed\JS::get_instance( $lightbox_id )->load_modules();
if ( ! empty( $optimized_styles ) ) {
if ( wp_doing_ajax() ) {
$lightbox_content = $optimized_styles . $lightbox_content;
} else {
echo $optimized_styles;
}
}
$globals = tve_get_post_meta( $lightbox_id, 'tve_globals' );
if ( ! empty( $globals['js_sdk'] ) ) {
foreach ( $globals['js_sdk'] as $handle ) {
wp_script_is( 'tve_js_sdk_' . $handle ) || wp_enqueue_script( 'tve_js_sdk_' . $handle, tve_social_get_sdk_link( $handle ), [], false );
}
}
}
public function get_editor_js_view() {
return 'ThriveLightbox';
}
public function get_options() {
return array(
'labels' => __( 'Open lightbox', 'thrive-cb' ),
'data' => self::lightbox_data(),
);
}
public function render_editor_settings() {
tcb_template( 'actions/lightbox', self::animations() );
}
/**
* Get all TCB lightboxes - if the current post is a landing page, only lightboxes specific to that landing page are returned
*
* @return array
*/
public static function lightbox_data() {
$post_id = get_the_ID();
$landing_page_template = tve_post_is_landing_page( $post_id );
$all_lightboxes = get_posts( [
'posts_per_page' => - 1,
'post_type' => 'tcb_lightbox',
] );
$data['lightboxes'] = [];
foreach ( $all_lightboxes as $lightbox ) {
if ( (int) $lightbox->ID === (int) $post_id ) { // makes no sense to open the same lightbox from within itself
continue;
}
/**
* @deprecated in TCB2 - display all lightboxes on all pages..
*
* $lightbox_lp = get_post_meta( $lightbox->ID, 'tve_lp_lightbox', true );
* if ( ! empty( $landing_page_template ) ) {
* if ( $lightbox_lp !== $landing_page_template ) {
* continue;
* }
* } elseif ( ! empty( $lightbox_lp ) ) {
* continue;
* }
*/
$data['lightboxes'] [] = array(
'id' => $lightbox->ID,
'title' => $lightbox->post_title,
'edit_url' => tcb_get_editor_url( $lightbox->ID ),
);
}
/* we use this to display the user the possibility of creating a new lightbox */
$data['for_landing_page'] = $landing_page_template;
$data['animations'] = self::animations();
return $data;
}
/**
* available lightbox animations
*
* @return array
*/
public static function animations() {
return array(
'instant' => __( 'Instant (no animation)', 'thrive-cb' ),
'zoom_in' => __( 'Zoom', 'thrive-cb' ),
'zoom_out' => __( 'Zoom out', 'thrive-cb' ),
'rotate' => __( 'Rotational', 'thrive-cb' ),
'slide_top' => __( 'Slide in from top', 'thrive-cb' ),
'slide_bottom' => __( 'Slide in from bottom', 'thrive-cb' ),
'lateral' => __( 'Lateral', 'thrive-cb' ),
);
}
}
}

View File

@@ -0,0 +1,33 @@
<?php
if ( ! class_exists( 'TCB_Thrive_LightboxClose' ) ) {
/**
* Class TCB_Thrive_LightboxClose
*/
class TCB_Thrive_LightboxClose extends TCB_Event_Action_Abstract {
protected $key = 'close_lightbox';
public function getName() {
return 'Close Thrive Lightbox';
}
public function getJsActionCallback() {
return tcb_template( 'actions/close-lightbox.js', null, true );
}
public function get_editor_js_view() {
return 'ThriveLightboxClose';
}
public function render_editor_settings() {
tcb_template( 'actions/lightbox-close', null );
}
public function get_options() {
return array( 'labels' => __( 'Close Lightbox', 'thrive-cb' ) );
}
}
}

View File

@@ -0,0 +1,90 @@
<?php
class TCB_Thrive_Tooltip extends TCB_Event_Action_Abstract {
protected $key = 'thrive_tooltip';
/**
* available tooltip positions
*
* @var array
*/
protected $_positions = [
'top' => 'Top',
'top_right' => 'Top right',
'right' => 'Right',
'bottom_right' => 'Bottom right',
'bottom' => 'Bottom',
'bottom_left' => 'Bottom left',
'left' => 'Left',
'top_left' => 'Top left',
];
/**
* available tooltip styles
*
* @var array
*/
protected $_styles = [
'light' => 'Light',
'dark' => 'Dark',
];
/**
* available tooltip text decorations
*
* @var array
*/
protected $_decorations = [
'solid' => 'Solid',
'dotted' => 'Dotted',
'dashed' => 'Dashed',
];
/**
* Should return the user-friendly name for this Action
*
* @return string
*/
public function getName() {
return __( 'Tooltip', 'thrive-cb' );
}
/**
* Should return an actual string containing the JS function that's handling this action.
* The function will be called with 3 parameters:
* -> event_trigger (e.g. click, dblclick etc)
* -> action_code (the action that's being executed)
* -> config (specific configuration for each specific action - the same configuration that has been setup in the settings section)
*
* Example (php): return 'function (trigger, action, config) { console.log(trigger, action, config); }';
*
* The function will be called in the context of the element
*
* The output MUST be a valid JS function definition.
*
* @return string the JS function definition (declaration + body)
*/
public function getJsActionCallback() {
return tcb_template( 'actions/tooltip.js.php', null, true );
}
public function render_editor_settings() {
tcb_template( 'actions/tooltip', [
'positions' => $this->_positions,
'styles' => $this->_styles,
] );
}
/**
* Backbone View implementing the tooltip functionality.
*
* @return string
*/
public function get_editor_js_view() {
return 'Tooltip';
}
public function get_options() {
return array( 'labels' => __( 'Tooltip', 'thrive-cb' ) );
}
}

View File

@@ -0,0 +1,412 @@
<?php
/**
* Handles opening of video popups
*
* Class TCB_Thrive_Video_Popup
*/
class TCB_Thrive_Video_Popup extends TCB_Event_Action_Abstract {
/**
* Action key.
*
* @var string
*/
protected $key = 'thrive_video';
/**
* Render settings.
*
* @param mixed $data template data.
*
* @deprecated
*
*/
public function renderSettings( $data ) {
}
/**
* Should return the user-friendly name for this Action
*
* @return string
*/
public function getName() {
return __( 'Open video', 'thrive-cb' );
}
/**
* Should return an actual string containing the JS function that's handling this action.
* The function will be called with 3 parameters:
* -> event_trigger (e.g. click, dblclick etc)
* -> action_code (the action that's being executed)
* -> config (specific configuration for each specific action - the same configuration that has been setup in the settings section)
*
* Example (php): return 'function (trigger, action, config) { console.log(trigger, action, config); }';
*
* The function will be called in the context of the element
*
* The output MUST be a valid JS function definition.
*
* @return string the JS function definition (declaration + body)
*/
public function getJsActionCallback() {
return tcb_template( 'actions/video-popup.js', null, true );
}
/**
* Checks for cases of Wistia popups and ensures backward compatibility
*
* @param array $data
*/
protected function _check_wistia_bc( &$data ) {
if ( $data['a'] === 'thrive_wistia' && ! isset( $data['config']['s'] ) ) {
/**
* Backwards compatibility support for Wistia popups
*/
$data['config'] = $this->provider_factory( 'wistia', $data['config'] )->migrate_config();
}
}
/**
*
* @param mixed $data action configuration data.
*/
public function applyContentFilter( $data ) {
$this->_check_wistia_bc( $data );
if ( empty( $data['config'] ) || empty( $data['config']['s'] ) || ! isset( $data['config']['p'] ) ) {
return;
}
$config = $data['config'];
$provider = $this->provider_factory( $config['s'], $config['p'] );
if ( empty( $provider ) ) {
return;
}
return $provider->get_html();
}
public function mainPostCallback( $data ) {
$this->_check_wistia_bc( $data );
$provider = $this->provider_factory( $data['config']['s'], $data['config']['p'] );
if ( ! $provider ) {
return;
}
return $provider->main_post_callback();
}
/**
* @return string
*/
public function get_editor_js_view() {
return 'VideoPopup';
}
public function get_options() {
return array( 'labels' => __( 'Open video', 'thrive-cb' ) );
}
public function render_editor_settings() {
echo '<div class="video-settings"></div>';
}
/**
* @param $provider
* @param $config
*
* @return null|TCB_Video_Base
*/
public function provider_factory( $provider, $config ) {
switch ( $provider ) {
case 'youtube':
return new TCB_Video_Youtube( $config );
case 'vimeo':
return new TCB_Video_Vimeo( $config );
case 'wistia':
return new TCB_Video_Wistia( $config );
case 'external':
return new TCB_Video_Custom( $config );
case 'custom':
return new TCB_Video_Custom( $config );
case 'vooplayer':
return new TCB_Video_VooPlayer( $config );
case 'bunnynet':
return new TCB_Video_BunnyNet( $config );
default:
return null;
}
}
}
class TCB_Video_Base {
protected $params;
public function __construct( $params = [] ) {
$this->params = $params;
}
public function get_embed() {
return sprintf(
'<iframe data-src="%s" frameborder="0" allowtransparency="true" style="display: block" allowfullscreen></iframe>',
$this->get_url()
);
}
public function main_post_callback() {
return '';
}
/**
* Check if a video provider has autoplay
*
* 1 - for Youtube and Vimeo
* true - for Wistia
*
* @return bool
*/
public function has_autoplay() {
$autoplay = $this->_get( 'a' );
return ! empty( $autoplay ) && in_array( $autoplay, [ 1, 'true' ] );
}
public function get_id() {
return isset( $this->params['id'] ) ? $this->params['id'] : '';
}
public function get_url() {
return '';
}
protected function _get( $key, $default = null ) {
return array_key_exists( $key, $this->params ) ? $this->params[ $key ] : $default;
}
public function get_html() {
return sprintf(
'<div class="tcb-video-popup" style="visibility: hidden; position:fixed; left: -5000px;max-width: 100%%;width: 70%%" id="tcb-video-popup-%s">%s</div>',
$this->get_id(),
'<div class="tve_responsive_video_container">' . $this->get_embed() . '</div>'
);
}
}
class TCB_Video_Youtube extends TCB_Video_Base {
public function get_url() {
$no_cookie = $this->_get( 'no-cookie', false );
$domain = $no_cookie ? 'youtube-nocookie' : 'youtube';
$url = 'https://www.' . $domain . '.com/embed/' . $this->get_id();
$url = add_query_arg( array(
'rel' => (int) ( ! $this->_get( 'hrv', false ) ),
'modestbranding' => (int) $this->_get( 'hyl' ),
'controls' => (int) ( ! $this->_get( 'ahi', false ) ),
'showinfo' => (int) ( ! $this->_get( 'htb', false ) ),
'autoplay' => (int) $this->_get( 'a' ),
'fs' => (int) ( ! $this->_get( 'hfs', false ) ),
'wmode' => 'transparent',
), $url );
if ( $this->has_autoplay() ) {
$url = add_query_arg( [ 'mute' => 1 ], $url );
}
return $url;
}
}
class TCB_Video_Vimeo extends TCB_Video_Base {
public function get_url() {
$url = 'https://player.vimeo.com/video/' . $this->get_id();
if ( ! empty( $this->params['hash'] ) ) {
$url = add_query_arg( [
'h' => $this->params['hash'],
], $url );
}
$url = add_query_arg( array(
'color' => $this->_get( 'c', 'ffffff' ),
'portrait' => (int) $this->_get( 'p', 0 ),
'title' => (int) $this->_get( 't', 0 ),
'byline' => (int) $this->_get( 'b', 0 ),
'badge' => 0,
'autoplay' => (int) $this->_get( 'a', 0 ),
'loop' => (int) $this->_get( 'l', 0 ),
), $url );
if ( $this->has_autoplay() ) {
$url = add_query_arg( [ 'muted' => 1 ], $url );
}
return $url;
}
}
class TCB_Video_Wistia extends TCB_Video_Base {
public function get_params() {
return sprintf(
'videoFoam=true autoPlay=%s playbar=%s fullscreenButton=%s playerColor=%s',
$this->_get( 'a' ) ? 'true' : 'false',
$this->_get( 'p' ) ? 'true' : 'false',
$this->_get( 'hfs' ) ? 'false' : 'true',
$this->_get( 'c', '00aeef' )
);
}
/**
* migrate old-style wistia popups to TCB2.0
*/
public function migrate_config() {
$old = $this->params;
$this->params = array(
's' => 'wistia',
'p' => array(
'a' => true,
'url' => ! empty( $old['event_video_url'] ) ? $old['event_video_url'] : '',
'c' => ! empty( $old['event_video_color'] ) ? str_replace( '#', '', $old['event_video_color'] ) : '',
'p' => ! empty( $old['event_option_play_bar'] ),
'hfs' => ! empty( $old['event_option_fs'] ),
),
);
$id_pattern = '#https?:\/\/(.+)?(wistia\.com|wi\.st)\/(medias|embed)\/(.+)#';
if ( preg_match( $id_pattern, $this->params['p']['url'], $m ) ) {
$this->params['p']['id'] = $m[4];
}
return $this->params;
}
public function main_post_callback() {
wp_script_is( 'tl-wistia-popover' ) || wp_enqueue_script( 'tl-wistia-popover', '//fast.wistia.com/assets/external/E-v1.js', [], '', true );
ob_start(); ?>
<script type="text/javascript">window._wq = window._wq || [];
window.tcb_w_videos = window.tcb_w_videos || {};
_wq.push( {
id: <?php echo json_encode( $this->_get( 'id' ) ) ?>, onReady: function ( video ) {
tcb_w_videos[<?php echo json_encode( $this->_get( 'id' ) ) ?>] = video;
}
} );
</script><?php
$content = ob_get_contents();
ob_end_clean();
return $content;
}
public function get_html() {
return sprintf(
'<div class="wistia_embed wistia_async_%s popover=true %s"></div>',
$this->get_id(),
$this->get_params()
);
}
}
class TCB_Video_Custom extends TCB_Video_Base {
/**
* Attributes for the current video
*
* @var array
*/
protected $video_attr = [];
public function wp_video_shortcode( $output, $atts ) {
if ( empty( $this->video_attr['width'] ) || empty( $this->video_attr['height'] ) || empty( $atts['width'] ) || empty( $atts['height'] ) ) {
return $output;
}
$replace = [];
if ( $atts['width'] != $this->video_attr['width'] ) {
$replace[ 'width:' . $atts['width'] ] = 'width:' . $this->video_attr['width'];
$replace[ 'width: ' . $atts['width'] ] = 'width: ' . $this->video_attr['width'];
$replace[ 'width="' . $atts['width'] ] = 'width="' . $this->video_attr['width'];
$replace[ 'height:' . $atts['height'] ] = 'height:' . $this->video_attr['height'];
$replace[ 'height: ' . $atts['height'] ] = 'height: ' . $this->video_attr['height'];
$replace[ 'height="' . $atts['height'] ] = 'height="' . $this->video_attr['height'];
$output = str_replace( array_keys( $replace ), array_values( $replace ), $output );
}
remove_filter( 'wp_video_shortcode', [ $this, 'wp_video_shortcode' ] );
return $output;
}
public function get_html() {
$html = '';
if ( ! $this->get_id() || ! function_exists( 'wp_video_shortcode' ) ) {
return $html;
}
$attr = [];
if ( empty( $this->params['url'] ) ) { //This is a WordPress saved video
$metadata = wp_get_attachment_metadata( $this->get_id() );
if ( ! empty( $metadata['width'] ) ) {
$attr['width'] = $metadata['width'];
}
if ( ! empty( $metadata['height'] ) ) {
$attr['height'] = $metadata['height'];
}
$attr['src'] = wp_get_attachment_url( $this->get_id() );
} elseif ( ! empty( $this->params['url'] ) && filter_var( $this->params['url'], FILTER_VALIDATE_URL ) !== false ) { //This is a custom URL video. Not saved in WordPress
$attr['src'] = $this->params['url'];
}
$attr['class'] = 'tcb-video-shortcode';
$attr['autoplay'] = false;
$this->video_attr = $attr;
add_filter( 'wp_video_shortcode', [ $this, 'wp_video_shortcode' ], 10, 2 );
return sprintf(
'<div class="tcb-video-popup tcb-custom-video" style="position:fixed;visibility:hidden;left: -5000px;max-width: 100%%" id="tcb-video-popup-%s">%s</div>',
$this->get_id(),
wp_video_shortcode( $attr )
);
}
public function main_post_callback() {
tve_dash_ajax_enqueue_style( 'mediaelement' );
tve_dash_ajax_enqueue_style( 'mediaelement' );
wp_style_is( 'wp-mediaelement' ) || wp_enqueue_style( 'mediaelement' );
wp_script_is( 'wp-mediaelement' ) || wp_enqueue_script( 'mediaelement' );
}
}
class TCB_Video_VooPlayer extends TCB_Video_Base {
public function get_url() {
return $this->params['url'];
}
}
class TCB_Video_BunnyNet extends TCB_Video_Base {
public function get_url() {
$changed_url = '';
if ( ! empty( $this->params['url'] ) ) {
$pattern = '/\/([^\/]+\/[^\/]+)$/';
preg_match( $pattern, $this->params['url'], $matches );
if ( ! empty( $matches[1] ) ) {
$library_video_id = $matches[1];
$changed_url = 'https://iframe.mediadelivery.net/embed/' . $library_video_id;
}
}
return $changed_url;
}
}

View File

@@ -0,0 +1,119 @@
<?php
if ( ! class_exists( 'TCB_Thrive_Wistia' ) ) {
/**
*?
* handles the server-side logic for the Thrive Lightbox action = opens a lightbox on an Event Trigger
*
* Class TCB_Thrive_Wistia
*/
class TCB_Thrive_Wistia extends TCB_Event_Action_Abstract {
private static $_loaded_videos = [];
/**
* Should return the user-friendly name for this Action
*
* @return string
*/
public function getName() {
return 'Wistia Popover';
}
/**
* Should output the settings needed for this Action when a user selects it from the list
*
* @param mixed $data
*/
public function renderSettings( $data ) {
return $this->renderTCBSettings( 'wistia_popover', $data );
}
/**
* Should return an actual string containing the JS function that's handling this action.
* The function will be called with 3 parameters:
* -> event_trigger (e.g. click, dblclick etc)
* -> action_code (the action that's being executed)
* -> config (specific configuration for each specific action - the same configuration that has been setup in the settings section)
*
* Example (php): return 'function (trigger, action, config) { console.log(trigger, action, config); }';
*
* The output MUST be a valid JS function definition.
*
* @return string the JS function definition (declaration + body)
*/
public function getJsActionCallback() {
return "function(t,a,c){
if (typeof Wistia === 'undefined') {
return false;
}
var videoId = c.event_video_url.split('/').pop(),
startTime = null,
uniqIdentifier = 'tve_wistia_' + videoId + '_' + c.event_option_uniq,
_video = Wistia.api(uniqIdentifier);
if (!_video) {
return false;
}
if (c.event_start_min_time && c.event_start_sec_time) {
_video.time(c.event_start_min_time * 60 + parseInt(c.event_start_sec_time));
}
_video.play();
return false;
};";
}
/**
* makes all necessary changes to the content depending on the $data param
*
* this gets called each time this action is encountered in the DOM event configuration
*
* @param $data
*/
public function applyContentFilter( $data ) {
$config = $data['config'];
$videoUrl = $config['event_video_url'];
$url = explode( "/", $videoUrl );
$videoId = end( $url );
$attr = array(
"videoFoam=true",
"playbar=" . ( isset( $config['event_option_play_bar'] ) ? "true" : "false" ),
"chromeless=" . ( isset( $config['event_option_hide_controls'] ) ? "true" : "false" ),
"controlsVisibleOnLoad=" . ( isset( $config['event_option_onload'] ) ? "true" : "false" ),
"fullscreenButton=" . ( isset( $config['event_option_fs'] ) ? "true" : "false" ),
"popover=true",
"popoverAnimateThumbnail=true"
);
if ( isset( $config['event_video_color'] ) && $config['event_video_color'] != '' ) {
array_push( $attr, "playerColor=" . $config['event_video_color'] );
}
$wistia_url_class = "tve_wistia_popover wistia_embed wistia_async_" . $videoId . " ";
$queryString = implode( " ", $attr );
$uniqIdentifier = "tve_wistia_" . $videoId . "_" . $config['event_option_uniq'];
$wistia_popover = "<div id='" . $uniqIdentifier . "' class='" . $wistia_url_class . $queryString . "' style='display: none;'>Wistia Popover Video</div>";
return '<div class="tve-wistia-wrap">' . $wistia_popover . '</div>';
}
/**
* make sure to include wistia popover js only once (E-v1.js)
*
* @param array $data
*/
public function mainPostCallback( $data ) {
$videoUrl = $data['config']['event_video_url'];
if ( ! is_editor_page() && isset( $videoUrl ) && $videoUrl != '' ) {
wp_script_is( 'tl-wistia-popover' ) || wp_enqueue_script( 'tl-wistia-popover', '//fast.wistia.com/assets/external/E-v1.js', [], '', true );
}
}
public function get_editor_js_view() {
return 'Wistia';
}
}
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* Created by PhpStorm.
* User: radu
* Date: 11.08.2014
* Time: 15:25
*/
class TCB_Event_Trigger_Click extends TCB_Event_Trigger_Abstract {
/**
* should return the Event name
*
* @return mixed
*/
public function getName() {
return __( 'Click on element', 'thrive-cb' );
}
public function get_options() {
return array(
'label' => __( 'Click', 'thrive-cb' ),
'name' => $this->getName(),
);
}
}

View File

@@ -0,0 +1,65 @@
<?php
/**
* Created by PhpStorm.
* User: radu
* Date: 30.10.2014
* Time: 09:47
*/
class TCB_Event_Trigger_Exit_Intent extends TCB_Event_Trigger_Abstract {
/**
* should return the Event name
*
* @return mixed
*/
public function getName() {
return __( 'Exit intent (user about to leave the page)', 'thrive-cb' );
}
/**
* render the exit_intent settings
*
* @param $data
*
* @return string
*/
public function renderSettings( $data ) {
return $this->renderTCBSettings( 'exit_intent.php', $data );
}
/**
* setup the main code for triggering exit intent events
*
* @return mixed|void
*/
public function outputGlobalJavascript() {
if ( wp_is_mobile() ) {
return;
}
include dirname( dirname( dirname( __FILE__ ) ) ) . '/views/js/trigger_exit_intent.php';
}
/**
* only on mobile devices, if the user explicitely set this, it will trigger the action after a delay
*
* @param $config
*
* @return string
*/
public function getInstanceJavascript( $event_data ) {
$config = $event_data['config'];
if ( ! wp_is_mobile() || empty( $config['e_mobile'] ) ) {
return '';
}
return 'jQuery(function () {setTimeout(function () {jQuery(document).trigger("tve-page-event-exit")}, ' . (int) $config['e_delay'] * 1000 . ')})';
}
public function get_options() {
return array(
'label' => __( 'Exit intent', 'thrive-cb' ),
'name' => $this->getName(),
);
}
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* Created by PhpStorm.
* User: radu
* Date: 11.08.2014
* Time: 15:31
*/
class TCB_Event_Trigger_Mouseover extends TCB_Event_Trigger_Abstract {
/**
* should return the Event name
*
* @return mixed
*/
public function getName() {
return __( 'Mouse over element', 'thrive-cb' );
}
public function get_options() {
return array(
'label' => __( 'Hover', 'thrive-cb' ),
'name' => $this->getName(),
);
}
}

View File

@@ -0,0 +1,52 @@
<?php
/**
* Created by PhpStorm.
* User: radu
* Date: 30.10.2014
* Time: 09:48
*/
class TCB_Event_Trigger_Timer extends TCB_Event_Trigger_Abstract {
/**
* should return the Event name
*
* @return mixed
*/
public function getName() {
return __( 'Timer (duration after page load)', 'thrive-cb' );
}
/**
* render the timer settings
*
* @param $data
*
* @return string
*/
public function renderSettings( $data ) {
return $this->renderTCBSettings( 'timer.php', $data );
}
/**
* trigger the event after a duration specified by the user
*
* @param $config
*
* @return string
*/
public function getInstanceJavascript( $event_data ) {
$config = $event_data['config'];
if ( empty( $config['t_delay'] ) ) {
return '';
}
return 'jQuery(function () {setTimeout(function () {jQuery(document).trigger("tve-page-event-timer", ["' . $config['t_delay'] . '"])}, ' . (int) $config['t_delay'] * 1000 . ')})';
}
public function get_options() {
return array(
'label' => __( 'Timer', 'thrive-cb' ),
'name' => $this->getName(),
);
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* Created by PhpStorm.
* User: radu
* Date: 11.08.2014
* Time: 15:33
*/
class TCB_Event_Trigger_Viewport extends TCB_Event_Trigger_Abstract {
/**
* should return the Event name
*
* @return mixed
*/
public function getName() {
return __( 'Comes into viewport', 'thrive-cb' );
}
/**
* this needs to listen to window scroll and trigger events if an element enters the viewport
*
* @return mixed|void
*/
public function outputGlobalJavascript() {
include dirname( dirname( dirname( __FILE__ ) ) ) . '/views/js/trigger_viewport.php';
}
public function get_options() {
return array(
'label' => __( 'Into view', 'thrive-cb' ),
'name' => $this->getName(),
);
}
}

View File

@@ -0,0 +1,294 @@
<?php
/** setup the event and event callbacks( = actions) manager */
require_once dirname( __FILE__ ) . '/classes/TCB_Event_Action_Abstract.php';
require_once dirname( __FILE__ ) . '/classes/TCB_Event_Trigger_Abstract.php';
/**
* get all available Event triggers
*
* Each event trigger a a way for the user to interact with a DOM element on a page
* each trigger must have a javascript name for the event, e.g. 'click', 'dblclick' as a key and an existing class as value
*
* each Event Trigger class must override TCB_Event_Trigger_Abstract
*
* @param $scope can be empty or 'page' for now
*
* @return TCB_Event_Trigger_Abstract[]
*
* @see TCB_Event_Trigger_Abstract
*/
function tve_get_event_triggers( $scope = '' ) {
/* make sure these will not get overwritten */
$tcb_triggers = [
'' => [
'click' => 'TCB_Event_Trigger_Click',
'mouseover' => 'TCB_Event_Trigger_Mouseover',
'mouseenter' => 'TCB_Event_Trigger_Mouseover',
'tve-viewport' => 'TCB_Event_Trigger_Viewport',
],
'page' => [
'exit' => 'TCB_Event_Trigger_Exit_Intent',
'timer' => 'TCB_Event_Trigger_Timer',
],
];
$tcb_triggers = $tcb_triggers[ $scope ];
$api_triggers = apply_filters( 'tcb_event_triggers', [], [ 'scope' => $scope ] );
if ( is_array( $api_triggers ) ) {
foreach ( $api_triggers as $key => $class_name ) {
$key = strtolower( $key );
if ( isset( $tcb_triggers[ $key ] ) || ! is_string( $class_name ) || ! preg_match( '#^([a-z0-9-_]+)$#', $key ) || ! class_exists( $class_name ) ) {
continue;
}
$tcb_triggers[ $key ] = $class_name;
}
}
$triggers = [];
foreach ( $tcb_triggers as $key => $class ) {
$triggers[ $key ] = TCB_Event_Trigger_Abstract::triggerFactory( $class );
}
return $triggers;
}
/**
* Get a list with all available actions as pairs key => action class
*
* @return array
*/
function tcb_get_all_action_classes() {
$classes = [
'thrive_lightbox' => 'TCB_Thrive_Lightbox',
'close_lightbox' => 'TCB_Thrive_LightboxClose',
'thrive_animation' => 'TCB_Thrive_CSS_Animation',
'thrive_zoom' => 'TCB_Thrive_Image_Zoom',
'thrive_video' => 'TCB_Thrive_Video_Popup',
'thrive_tooltip' => 'TCB_Thrive_Tooltip',
];
/**
* Allow adding php classes to the available Actions
*/
return apply_filters( 'tcb_event_action_classes', $classes );
}
/**
* get all available event actions
*
* Event Actions are behaviours that happen after a user interaction via an event, such as 'click'
*
* each event action must extend the TCB_Event_Action_Abstract class and implement its required methods
*
* All the classes that are specified here MUST be previously loaded
* Each array key has to be a lowercase, unique identifier for the Action
*
* @return TCB_Event_Action_Abstract[] with action_key => Action Name (Action name will be taken from the class representing the Action)
*/
function tve_get_event_actions( $scope = '' ) {
$actions = tcb_get_all_action_classes();
foreach ( $actions as $key => $class ) {
$actions[ $key ] = TCB_Event_Action_Abstract::actionFactory( $class );
}
/* deprecated - Wistia popups - added here for backwards compatibility */
$actions['thrive_wistia'] = TCB_Event_Action_Abstract::actionFactory( 'TCB_Thrive_Video_Popup' );
return $actions;
}
/**
* get all available event actions
*
* Event Actions are behaviours that happen after a user interaction via an event, such as 'click'
*
* each event action must extend the TCB_Event_Action_Abstract class and implement its required methods
*
* All the classes that are specified here MUST be previously loaded
* Each array key has to be a lowercase, unique identifier for the Action
*
* @return TCB_Event_Action_Abstract[] with action_key => Action Name (Action name will be taken from the class representing the Action)
*/
function tve_get_event_actions_old( $scope = '' ) {
$post_id = empty( $_POST['post_id'] ) ? get_the_ID() : absint( $_POST['post_id'] );
$tcb_event_actions = [
'' => [
'thrive_lightbox' => [
'class' => 'TCB_Thrive_Lightbox',
'order' => 10,
],
'thrive_animation' => [
'class' => 'TCB_Thrive_CSS_Animation',
'order' => 30,
],
'thrive_zoom' => [
'class' => 'TCB_Thrive_Image_Zoom',
'order' => 40,
],
'thrive_wistia' => [
'class' => 'TCB_Thrive_Wistia',
'order' => 50,
],
'thrive_tooltip' => [
'class' => 'TCB_Thrive_Tooltip',
'order' => 60,
],
],
'page' => [
'thrive_lightbox' => [
'class' => 'TCB_Thrive_Lightbox',
'order' => 10,
],
],
];
$tcb_event_actions = $tcb_event_actions[ $scope ];
$tcb_event_actions = apply_filters( 'tcb_event_actions', $tcb_event_actions, $scope, $post_id );
uasort( $tcb_event_actions, 'tcb_event_manager_sort_actions' );
$actions = [];
foreach ( $tcb_event_actions as $key => $data ) {
$class = $data['class'];
$actions[ $key ] = TCB_Event_Action_Abstract::actionFactory( $class );
}
return $actions;
}
/**
* @param $a
* @param $b
*
* @return int
*/
function tcb_event_manager_sort_actions( $a, $b ) {
return $a['order'] < $b['order'] ? - 1 : 1;
}
/**
* Returns a list of TCB actions for the editor page - structured in tabs and sub-sections
*
* @return array
*/
function tcb_get_editor_actions() {
$actions = tcb_get_all_action_classes();
$action_tabs = array(
'animation' => array(
'title' => __( 'CSS Animation', 'thrive-cb' ),
'icon' => 'animation2',
'class' => $actions['thrive_animation'],
'on_states' => [ 'default', 'hover' ],
),
'popup' => array(
'title' => __( 'Popups', 'thrive-cb' ),
'trigger' => 'click',
'icon' => 'open-lightbox2',
'on_states' => [ 'default' ],
'actions' => [
'thrive_lightbox' => [
'class' => $actions['thrive_lightbox'],
'order' => 10,
],
'thrive_zoom' => [
'class' => $actions['thrive_zoom'],
'order' => 30,
],
'thrive_video' => [
'class' => $actions['thrive_video'],
'order' => 40,
],
'close_lightbox' => [
'class' => $actions['close_lightbox'],
'order' => 50,
],
],
),
'tooltip' => array(
'title' => __( 'Display tooltip', 'thrive-cb' ),
'trigger' => 'mouseover',
'icon' => 'tooltip-text',
'class' => $actions['thrive_tooltip'],
'on_states' => [ 'hover' ],
),
'link' => array(
'title' => __( 'Create hyperlink', 'thrive-cb' ),
'icon' => 'link-variant2',
'on_states' => [ 'default' ],
),
'custom' => array(
'title' => __( 'Custom integrations', 'thrive-cb' ),
'icon' => 't-lightbox',
'actions' => [],
'on_states' => [ 'default' ],
),
);
$action_tabs = apply_filters( 'tcb_event_manager_action_tabs', $action_tabs );
if ( get_post_type() !== 'tcb_lightbox' ) {
unset( $action_tabs['popup']['actions']['close_lightbox'] );
}
foreach ( $action_tabs as $key => $data ) {
if ( isset( $data['class'] ) ) {
$instance = TCB_Event_Action_Abstract::actionFactory( $data['class'] );
if ( isset( $data['available'] ) ) {
$instance->set_is_available( $data['available'] );
}
$action_tabs[ $key ]['instance'] = $instance;
} elseif ( isset( $data['actions'] ) ) {
uasort( $data['actions'], 'tcb_event_manager_sort_actions' );
$action_tabs[ $key ]['actions'] = $data['actions'];
foreach ( $data['actions'] as $action_key => $action ) {
$instance = TCB_Event_Action_Abstract::actionFactory( $action['class'] );
if ( isset( $action['available'] ) ) {
$instance->set_is_available( $action['available'] );
}
$action_tabs[ $key ]['actions'][ $action_key ]['instance'] = $instance;
}
}
if ( $key !== 'link' && empty( $data['class'] ) && empty( $data['actions'] ) ) {
unset( $action_tabs[ $key ] );
}
}
return $action_tabs;
}
/**
* Build the javascript config object for the animation and actions component
*
* @return array
*/
function tcb_event_manager_config() {
$tabs = tcb_get_editor_actions();
/** @var TCB_Event_Action_Abstract[] $actions */
$config = $actions = [];
foreach ( $tabs as $k => $tab ) {
/** @var TCB_Event_Action_Abstract[] $tab */
if ( isset( $tab['class'] ) ) {
$actions[ $tab['instance']->get_key() ] = $tab['instance'];
} elseif ( isset( $tab['actions'] ) ) {
foreach ( $tab['actions'] as $action_key => $action ) {
/** @var TCB_Event_Action_Abstract[] $action */
$actions[ $action_key ] = $action['instance'];
}
}
$config['tabs'][ $k ]['visible'] = isset( $tab['visible'] ) ? $tab['visible'] : true;
//tabs will be toggled based on state
$config['tabs'][ $k ]['on_states'] = isset( $tab['on_states'] ) ? $tab['on_states'] : [];
}
$triggers = tve_get_event_triggers();
foreach ( $actions as $key => $action ) {
$config['actions'][ $key ] = $action->get_options();
$config['actions'][ $key ]['visible'] = $action->is_available();
}
foreach ( $triggers as $key => $trigger ) {
$config['triggers'][ $key ] = $trigger->get_options();
}
return $config;
}

View File

@@ -0,0 +1,137 @@
<?php
$animationClasses = [];
foreach ( array_keys( $this->_animations ) as $animation ) {
$animationClasses [] = 'tve_lb_anim_' . $animation;
}
$animationClasses = implode( ' ', $animationClasses );
/* adding <script type="text/javascript"> just for editor autocompletion */
?>
<script type="text/javascript">
function (trigger, action, config) {
function getBrowserScrollSize() {
var $ = jQuery;
var css = {
"border": "none",
"height": "200px",
"margin": "0",
"padding": "0",
"width": "200px"
};
var inner = $("<div>").css($.extend({}, css));
var outer = $("<div>").css($.extend({
"left": "-1000px",
"overflow": "scroll",
"position": "absolute",
"top": "-1000px"
}, css)).append(inner).appendTo("body")
.scrollLeft(1000)
.scrollTop(1000);
var scrollSize = {
"height": (outer.offset().top - inner.offset().top) || 0,
"width": (outer.offset().left - inner.offset().left) || 0
};
outer.remove();
return scrollSize;
}
var $target = jQuery("#tve_thrive_lightbox_" + config.l_id).css('display', ''),
animation = config.l_anim ? config.l_anim : "instant",
$body = jQuery('body'),
$html = jQuery('html'),
overflow_hidden = 'tve-o-hidden tve-l-open tve-hide-overflow',
scroll_width = getBrowserScrollSize().width,
oPadding = parseInt($body.css('padding-right'));
function close_it($lightbox, skip_body_scroll) {
$lightbox.find('.thrv_responsive_video iframe, .thrv_responsive_video video').each(function () {
var $this = jQuery(this);
$this.attr('data-src', $this.attr('src'));
$this.attr('src', '');
});
$lightbox.removeClass('tve_lb_open tve_lb_opening').addClass('tve_lb_closing');
if (typeof skip_body_scroll === 'undefined') {
$body.removeClass(overflow_hidden).css('padding-right', '');
$html.removeClass(overflow_hidden)
}
setTimeout(function () {
$lightbox.attr('class', '').css('display', 'none').find('tve_p_lb_content').trigger('tve.lightbox-close');
}, 300);
}
$target.off().on("click", ".tve_p_lb_close", function () {
close_it($target);
});
$body.off('keyup.tve_lb_close').on('keyup.tve_lb_close', function (e) {
if (e.which == 27) {
close_it($target);
}
});
$target.children('.tve_p_lb_overlay').off('click.tve_lb_close').on('click.tve_lb_close', function () {
close_it($target);
});
/* close any other opened lightboxes */
close_it(jQuery('.tve_p_lb_background.tve_lb_open'), true);
$target.addClass('tve_p_lb_background tve_lb_anim_' + animation);
$body.addClass(overflow_hidden);
$html.addClass(overflow_hidden);
var wHeight = jQuery(window).height(),
page_has_scroll = wHeight < jQuery(document).height();
if (page_has_scroll) {
$body.css('padding-right', (oPadding + scroll_width) + 'px');
}
$target.find('.thrv_responsive_video iframe, .thrv_responsive_video video').each(function () {
var $this = jQuery(this);
if ($this.attr('data-src')) {
$this.attr('src', $this.attr('data-src'));
}
});
setTimeout(function () {
$target.addClass('tve_lb_opening');
/* reload any iframe that might be in there, this was causing issues with google maps embeds in hidden tabs */
$target.find('iframe').each(function () {
var $this = jQuery(this);
if ($this.data('tve_ifr_loaded')) {
return;
}
$this.data('tve_ifr_loaded', 1).attr('src', $this.attr('src'));
});
setTimeout(function () {
var $lContent = $target.find('.tve_p_lb_content'),
cHeight = $lContent.outerHeight(true),
top = (wHeight - cHeight) / 2;
$target.find('.tve_p_lb_overlay').css({
height: (cHeight + 80) + 'px',
'min-height': wHeight + 'px'
});
$lContent.css('top', (top < 40 ? 40 : top) + 'px');
if (cHeight + 40 > wHeight) {
$target.addClass('tve-scroll');
}
}, 0);
}, 20);
setTimeout(function () {
$target.removeClass('tve_lb_opening').addClass('tve_lb_open').find('.tve_p_lb_content').trigger('tve.lightbox-open');
}, 300);
return false;
}
;
</script>

View File

@@ -0,0 +1,29 @@
<script type="text/javascript">
(function ($) {
/* Chrome has a stupid bug in which it triggers almost simultaneously "mouseenter" "mouseleave" "mouseenter" if the following applies:
- at page load, the cursor is outside the html element
- the user moves the cursor over the html element
*/
var chrome_fix_id = 0,
me = function (e) { /* mouse enter */
clearTimeout(chrome_fix_id);
},
ml = function (e) {
if (e.clientY <= config.s) {
chrome_fix_id = setTimeout(function () {
$(document).trigger('tve-page-event-exit');
}, 50);
}
},
config = { // we can adjust this and the code below to allow users to tweak settings
s: 20 // sensitivity
};
$(function () {
$(document).on('mouseleave.exit_intent', ml)
.on('mouseenter.exit_intent', me);
});
})(jQuery);
</script>

View File

@@ -0,0 +1,88 @@
<script type="text/javascript">
( function ( $ ) {
var $window = $( window ),
trigger_elements = function ( elements ) {
elements.each( function () {
var $elem = $( this ),
lb_content = $elem.parents( '.tve_p_lb_content' ),
ajax_content = $elem.parents( '.ajax-content' ),
inViewport = TCB_Front.isInViewport( $elem ) || isOutsideBody( $elem ) || isAtTheBottomOfThePage( $elem );
if ( lb_content.length ) {
lb_content.on( 'tve.lightbox-open', function () {
if ( ! $elem.hasClass( 'tve-viewport-triggered' ) ) {
$elem.trigger( 'tve-viewport' ).addClass( 'tve-viewport-triggered' );
}
} );
return;
}
if ( ajax_content.length ) {
ajax_content.on( 'content-inserted.tcb', function () {
if ( inViewport && ! $elem.hasClass( 'tve-viewport-triggered' ) ) {
$elem.trigger( 'tve-viewport' ).addClass( 'tve-viewport-triggered' );
}
} );
return;
}
if ( inViewport ) {
$elem.trigger( 'tve-viewport' ).addClass( 'tve-viewport-triggered' );
}
} );
},
trigger_exit = function ( elements ) {
elements.each( function () {
var $elem = $( this );
if ( ! ( TCB_Front.isInViewport( $elem ) || isOutsideBody( $elem ) ) ) {
$elem.trigger( 'tve-viewport-leave' ).removeClass( 'tve-viewport-triggered' );
}
} );
},
/**
* Returns true if the element is located at the bottom of the page and the element is in viewport
*/
isAtTheBottomOfThePage = function ( $elem ) {
return TCB_Front.isInViewport( $elem, 0 ) && $window.scrollTop() >= parseInt( $elem.offset().top + $elem.outerHeight() - window.innerHeight );
},
/**
* Check if element is always outside of the viewport, is above the top scroll
* @param element
* @returns {boolean}
*/
isOutsideBody = function ( element ) {
if ( element.jquery ) {
element = element[ 0 ];
}
var rect = element.getBoundingClientRect();
/* we've scrolled maximum to the top, but the element is above */
return window.scrollY + rect.bottom < 0;
/* leaving this commented, can be added if more bugs appear. it checks for bottom elements
var $window = ThriveGlobal.$j( window ),
scrolledToBottom = $window.scrollTop() + $window.height() === ThriveGlobal.$j( document ).height();
return ( scrolledToBottom && rect.top > ( window.innerHeight - delta ) );
*/
};
$( document ).ready( function () {
window.tar_trigger_viewport = trigger_elements;
window.tar_trigger_exit_viewport = trigger_exit;
let $to_test = $( '.tve_et_tve-viewport' ).removeClass('tve-viewport-triggered');
$window.scroll( function () {
$to_test = $( '.tve_et_tve-viewport' );
trigger_elements( $to_test.filter( ':not(.tve-viewport-triggered)' ) );
trigger_exit( $to_test.filter( '.tve-viewport-triggered' ) );
} );
setTimeout( function () {
trigger_elements( $to_test.filter( ':not(.tve-viewport-triggered)' ) );
}, 200 );
} );
} )
( jQuery );
</script>