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,2 @@
@import url(https://fonts.bunny.net/css?family=Roboto:500);
.tvd-notifications{color:red}#tvd-notifications-btn{width:24px;height:24px;vertical-align:middle;display:inline-block;border-radius:50%;margin:0 0 0 20px;background:#57a21d url("../images/bell.png") center no-repeat}#wpbody #tvd-notifications-btn{padding:0}.ni-inbox-counter{position:relative}.ni-inbox-counter span{position:absolute;top:17px;left:32px;display:inline-block;cursor:pointer;background-color:#d0021b;color:#fff;font-size:11px;font-weight:bold;min-width:16px;height:16px;line-height:16px;border-radius:8px;text-align:center;padding:0 5px}.tvd-inbox-holder{position:absolute;top:60px;right:0;background:#fff;width:360px;height:335px;box-shadow:0 3px 6px 0 rgba(99,99,99,.5);border-radius:3px;z-index:10;font-family:"Roboto",sans-serif}.tvd-inbox-holder li{float:left;width:100%}.tvd-ni-detail-data{line-height:1.33}#wpbody .tvd-ni-detail-data a{color:#0a5cc1;text-decoration:underline}#wpbody .tvd-ni-detail-data a:hover{color:#0877ff}.tvd-ni-inbox-detail{padding:25px}#wpbody .tvd-ni-inbox-detail{line-height:14px;font-size:12px;color:#4d4d4d}.tvd-ni-inbox-detail .tvd-ni-detail-title{font-weight:500;font-size:14px;margin:0 0 15px;line-height:19px}.tvd-ni-inbox-detail .ni-go-back{cursor:pointer;color:#57a21d;font-size:12px;margin:20px 0 0;display:inline-block;font-weight:500}.tvd-ni-inbox-detail .ni-go-back:hover{color:#388100}.tvd-notification-header{height:30px;background-color:#57a21d;display:flex;padding:0 10px 0 25px;border-radius:3px 3px 0 0;position:relative}.tvd-notification-header:after{content:"";position:absolute;top:-8px;right:49px;width:0;height:0;border-left:8px solid rgba(0,0,0,0);border-right:8px solid rgba(0,0,0,0);border-bottom:9px solid #57a21d}#wpbody .tvd-notification-header span{line-height:30px}#wpbody .tvd-notification-header span.tvd-ni-box-title{width:65%;font-size:14px;color:#fff;font-weight:500}#wpbody .tvd-notification-header span.tvd-ni-mark-read{width:28%;color:#fff;text-decoration:underline;font-size:12px;cursor:pointer}#wpbody .tvd-notification-header span.tvd-ni-mark-read.tvd-ni-disabled{pointer-events:none}#wpbody .tvd-notification-header span.tvd-ni-close{width:7%;color:#fff;text-align:right;font-size:12px;cursor:pointer;background:url("../images/times.png") center right no-repeat}.tvd-ni-single-header{position:absolute;top:0;width:100%;height:30px;left:0;padding:0 10px 0 0;display:flex}.tvd-ni-single-header span{line-height:30px}.tvd-ni-single-header span.ni-go-back{width:110px;font-size:14px;color:#fff;margin:0;padding:0 0 0 25px;border-radius:3px 0 0 0;background:url("../images/arrow-left.png") left 10px center no-repeat}.tvd-ni-single-header span.ni-go-back:hover{background-color:#388101;color:#fff}.tvd-ni-single-header span.tvd-ni-close{width:calc(100% - 110px);color:#fff;text-align:right;font-size:12px;cursor:pointer;background:url("../images/times.png") center right no-repeat}.tvd-notification-wrapper{height:calc(100% - 30px);overflow:auto}.tvd-notification-wrapper::-webkit-scrollbar{width:4px}.tvd-notification-wrapper::-webkit-scrollbar-track{background-color:rgba(0,0,0,.05)}.tvd-notification-wrapper::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.2);border-radius:2.5px}.td-inbox-item{padding:10px 25px;cursor:pointer;position:relative;background-color:#fff;transition:all .15s;border-bottom:1px solid rgba(0,0,0,.05)}.td-inbox-item.td-inbox-item-unread{background-color:rgba(219,234,208,.42)}.td-inbox-item.td-inbox-item-unread .td-inbox-date{color:#8ab36c}.td-inbox-item:hover{background-color:#f2f2f2}.td-inbox-item:hover .td-inbox-date{color:#a9a9a9}.td-inbox-item:last-of-type{border:none}#wpbody .td-inbox-item{line-height:normal}.td-inbox-item .td-inbox-title{line-height:16px;font-size:12px;color:#4d4d4d;display:inline-block;font-weight:500}.td-inbox-item .td-inbox-status-unread{position:absolute;left:9px;top:17px;width:6px;height:6px;border-radius:50%;background-color:#d0021b}.td-inbox-item .td-inbox-date{font-size:10px;color:#a9a9a9;display:block;margin:3px 0 0;font-weight:500}.tvd-ni-load{display:block;background-color:#fff;text-align:center;padding:8px 15px 15px;border-top:1px solid #f6f6f6}#wpbody .tvd-ni-load{line-height:22px}.tvd-ni-load .tvd-ni-load-inner{line-height:22px;background-color:#f1f1f1;color:#4d4d4d;font-size:12px;display:inline-block;width:100%;cursor:pointer;transition:all .15s}.tvd-ni-load .tvd-ni-load-inner:hover{color:#57a21d}.tvd-ni-no-more-data,.tvd-ni-no-data{font-size:12px;color:#4d4d4d;padding:0 25px}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

View File

@@ -0,0 +1,643 @@
<?php
/**
* Thrive Themes - https://thrivethemes.com
*
* @package thrive-dashboard
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Silence is golden!
}
/**
* Class TD_Inbox
*
* Main class for: enqueue scripts, autoloader, initialization
*/
final class TD_Inbox {
const WEBINARJAM_V4 = 4;
/**
* @var TD_Inbox
*/
public static $_instance;
/**
* @var array
*/
protected $_list = array();
/**
* @var string
*/
private $_init_path;
/**
* @var string
*/
private $_admin_path;
/**
* @var string
*/
private $_namespace;
/**
* @var string
*/
private $_version;
/**
* @var array
*/
private $_allowed_screens;
/**
* @var array
*/
private $_allowed_routes;
/**
* GTW slug
*
* @var string
*/
private $_gtw_slug = 'gotowebinar';
/**
* Ontraport slug
*
* @var string
*/
private $_ontraport_slug = 'ontraport';
/**
* Ontraport slug
*
* @var string
*/
private $_webinarjam_slug = 'webinarjamstudio';
/**
* TD_Inbox constructor.
*/
private function __construct() {
// Setters
$this->_set_data();
// Needs global inclusion for push notifications from TTW trough endpoint
$this->_load();
// Load data where needed
$this->load_by_request_type();
// Add default notifications
$this->default_notifications();
}
/**
* @return TD_Inbox
*/
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Loaders and hooks for admin and ajax
*/
public function load_by_request_type() {
// Includes for admin ajax on allowed actions
if ( $this->is_request( 'admin_ajax' ) && $this->allowed_action() ) {
$this->_loadAdmin();
$this->hooks();
}
// Includes for admin with screen restrictions
if ( $this->is_request( 'admin' ) ) {
add_action( 'current_screen', array( $this, 'load_on_screen' ) );
}
}
/**
* Add default notifications
*/
public function default_notifications() {
$gotowebinar_version = $this->get_api_version( $this->_gtw_slug );
$webinarjam_version = $this->get_api_version( $this->_webinarjam_slug );
$gtw_on_without_version = $this->connected_api_without_version( $this->_gtw_slug, $gotowebinar_version );
$gtw_version = $this->api_version_number( $gotowebinar_version );
// GoToWebinar v1 default messages:
if ( $gtw_on_without_version || 1 === $gtw_version ) {
$this->add_notification( 'gtw_warn_default' );
}
// Message for active v1 connections one month before GoToWebinar turn off support
if ( ( $gtw_on_without_version || 1 === $gtw_version ) && date( 'Y-m-d' ) >= date( '2019-09-01' ) ) {
$this->add_notification( 'gtw_warn_before' );
}
// Message for active v1 connections one week before GoToWebinar turn off support
if ( ( $gtw_on_without_version || 1 === $gtw_version ) && date( 'Y-m-d' ) >= date( '2019-09-21' ) ) {
$this->add_notification( 'gtw_warn_last' );
}
// Message for active old GTW API connections or v1 connections to show on the API connection list
if ( $gtw_on_without_version || 1 === $gtw_version ) {
$this->add_notification( 'gtw_warn_connection' );
}
if ( $this->api_is_connected( $this->_ontraport_slug ) ) {
$this->add_notification( 'ontraport_updated' );
}
//Message for V4 for WebinarJam api
if ( $this->api_is_connected( $this->_webinarjam_slug ) && self::WEBINARJAM_V4 !== (int) $webinarjam_version ) {
$this->add_notification( 'webinarjamstudio_updated' );
}
if ( $this->api_is_connected( 'sendinblue' ) ) {
$this->add_notification( 'sendinblue_outdated' );
}
$this->add_notification( 'zoom_temporary_disabled' );
}
/**
* Return numeric API version
*
* @param $api_version
*
* @return int
*/
public function api_version_number( $api_version ) {
$api_nr = 0;
if ( ! empty( $api_version['version'] ) ) {
$api_nr = (int) $api_version['version'];
}
return $api_nr;
}
/**
* Verify for connected API without version set [by slug]
*
* @param $api_name
*
* @return bool
*/
public function connected_api_without_version( $api_name, $api_version ) {
if ( empty( $api_name ) || ! is_string( $api_name ) ) {
return false;
}
if ( $this->api_is_connected( $api_name ) && empty( $api_version['version'] ) ) {
return true;
}
return false;
}
/**
* Add inbox notification using inbox manager
*
* @param string $type
*
* @return bool
* @throws Exception
*/
public function add_notification( $type = '' ) {
if ( empty( $type ) ) {
return false;
}
$message = array();
$inbox_manager = TVE_Dash_InboxManager::instance();
switch ( $type ) {
case 'gtw_warn_default':
$message = array(
'title' => __( 'Your GoToWebinar Connection will Expire', 'thrive-dash' ),
'info' => __(
'Your GoToWebinar API connection will no longer work after 1st of October, 2019 because GoToWebinar are deactivating their service for this type of connection.<br /><br />
You solve this by going to your <a href="' . esc_url( add_query_arg( 'page', 'tve_dash_api_connect', admin_url( 'admin.php' ) ) ) . '" target="_self">API dashboard</a> and re-connecting your existing GoToWebinar account. After you\'ve connected, your existing forms will carry on working as they are now.<br /><br />
<a href="https://thrivethemes.com/tkb_item/how-to-upgrade-gotowebinar-and-what-does-this-upgrade-involve/" target="_blank">Click here</a> to learn more about this upgrade and if you have any further questions, get in touch with our <a href="https://thrivethemes.com/forums/forum/general-discussion/" target="_blank">support team</a> and we\'ll help you out.<br /><br />
From your team at Thrive Themes',
'thrive-dash'
),
'type' => TD_Inbox_Message::TYPE_INBOX, // to be shown on API list
);
break;
case 'gtw_warn_before':
$message = array(
'title' => __( 'You have one Month to Update your GoToWebinar Connection', 'thrive-dash' ),
'info' => __(
'This is just a quick reminder of the message we sent a few months ago. You only have one month left to connect through their new API.<br /><br />
Your existing GoToWebinar API connection will no longer work after 1st of October, 2019 because GoToWebinar are deactivating their service for this type of connection.<br /><br />
You solve this by going to your <a href="' . esc_url( add_query_arg( 'page', 'tve_dash_api_connect', admin_url( 'admin.php' ) ) ) . '" target="_self">API dashboard</a> and re-connecting your existing GoToWebinar account. After you\'ve connected, your existing forms will carry on working as they are now.<br /><br />
<a href="https://thrivethemes.com/tkb_item/how-to-upgrade-gotowebinar-and-what-does-this-upgrade-involve/" target="_blank">Click here</a> to learn more about this upgrade and if you have any further questions, get in touch with our <a href="https://thrivethemes.com/forums/forum/general-discussion/" target="_blank">support team</a> and we\'ll help you out.<br /><br />
From your team at Thrive Themes',
'thrive-dash'
),
'type' => TD_Inbox_Message::TYPE_INBOX, // to be shown on API list
);
break;
case 'gtw_warn_last':
$message = array(
'title' => __( 'Urgent: Your GoToWebinar forms will stop working', 'thrive-dash' ),
'info' => __(
'Just to remind you that your GoToWebinar forms will no longer work if you dont upgrade to their new API connection.<br /><br />
You solve this by going to your <a href="' . esc_url( add_query_arg( 'page', 'tve_dash_api_connect', admin_url( 'admin.php' ) ) ) . '" target="_self">API dashboard</a> and re-connecting your existing GoToWebinar account.
After you\'ve connected, your existing forms will carry on working as they are now.',
'thrive-dash'
),
'type' => TD_Inbox_Message::TYPE_INBOX, // to be shown on API list
);
break;
case 'gtw_warn_connection':
$message = array(
'title' => __( 'Your GoToWebinar Connection will Expire!', 'thrive-dash' ),
'info' => '<span>' . __( 'Important Note:', 'thrive-dash' ) . ' </span>' .
__( 'GoToWebinar are no longer supporting this type of connection. You have until October 1st 2019 to connect trough the new api. <a href="https://thrivethemes.com/tkb_item/how-to-upgrade-gotowebinar-and-what-does-this-upgrade-involve/" target="_blank">Learn more about this</a><br /><br />
<a class="tvd-api-edit tvd-inbox-btn">Connect to new API</a>',
'thrive-dash'
),
'type' => TD_Inbox_Message::TYPE_API, // to be shown on API connection list
'slug' => 'gotowebinar',
);
break;
case'ontraport_updated':
$message = array(
'title' => __( 'Your Ontraport connection has been updated in order for it to work with the latest Ontraport release.', 'thrive-dash' ),
'info' => __(
'We have updated the API connection you have previously made between Ontraport and your Thrive product(s), in order to make sure it works with the latest Ontraport release.<br /><br />
Due to these changes, now, whenever you connect a "Lead Generation" element to Ontraport, you can choose between sequences and campaigns you have previously added in Ontraport. <br />
This way, your users will be able to subscribe to these when using the "Lead Generation" element.<br />
For more information about the Ontraport release, please visit their website <a href="https://ontraport.com/service-status" target="_blank">here</a> .<br/><br/>
We highly recommend that you sign up through one of your opt-in forms to make sure that everything is working as expected.',
'thrive-dash'
),
'type' => TD_Inbox_Message::TYPE_INBOX, // to be shown on API list
);
break;
case'webinarjamstudio_updated':
$message = array(
'title' => __( 'Urgent: Your WebinarJam forms will stop working', 'thrive-dash' ),
'info' => __(
'The 3.0 Version of the WebinarJam platform is closing on March 31st. On this date, the systems will be wiped and any replays or information you have will be permanently deleted.<br /><br />
This is why it is crucial for you to migrate all your content to the 4.0 Version before then. It is critical that you go to your WebinarJam account today and upgrade to the new version. This way, you will give yourself ample time to move your content over. <br /><br />
After upgrading your WebinarJam account, please make sure to delete and re-add the WebinarJam connection, within your Thrive Dashboard, using the v4 option. Then, you will have to update the connection for all forms on your website that you have previously connected to WebinarJam. <br/>',
'thrive-dash'
),
'type' => TD_Inbox_Message::TYPE_INBOX, // to be shown on API list
);
break;
case'zoom_temporary_disabled':
$message = array(
'title' => __( 'The Zoom integration was temporarily removed, we are sorry for any inconvenience!', 'thrive-dash' ),
'info' => '',
'type' => TD_Inbox_Message::TYPE_INBOX, // to be shown on API list
);
break;
case'sendinblue_outdated':
$message = array(
'title' => __( 'Starting with 25th June SendinBlue API v2 will be deprecated. In order to switch to v3, please navigate to Thrive Dashboard, API connections and under SendInBlue, click on "I want to use API v3".', 'thrive-dash' ),
'info' => '',
'type' => TD_Inbox_Message::TYPE_INBOX, // to be shown on API list
);
break;
}
if ( empty( $message ) ) {
return false;
}
try {
$message_obj = new TD_Inbox_Message( $message );
$inbox_manager->prepend( $message_obj );
$inbox_manager->push_notifications();
} catch ( Exception $e ) {
}
}
/**
* Retreive versioning saved data
*
* @param string $api_name
*
* @return array
*/
public function get_api_version( $api_name = '' ) {
if ( empty( $api_name ) ) {
return array();
}
$saved = get_option( 'thrive_mail_list_api', array() );
$data = array(
'version' => ! empty( $saved[ $api_name ]['version'] ) ? $saved[ $api_name ]['version'] : '',
'versioning' => ! empty( $saved[ $api_name ]['versioning'] ) ? $saved[ $api_name ]['versioning'] : '',
);
return $data;
}
/**
* Verify if API connection exists
*
* @param string $api_name
*
* @return bool
*/
public function api_is_connected( $api_name = '' ) {
if ( empty( $api_name ) ) {
return false;
}
$saved = get_option( 'thrive_mail_list_api', array() );
if ( empty( $saved[ $api_name ] ) ) {
return false;
}
return true;
}
/**
* @return bool
*/
public function allowed_action() {
$action = $this->param( 'action', null );
return in_array( $action, $this->_allowed_routes, true );
}
/**
* Load dash inbox on the allowed screens
*/
public function load_on_screen() {
// Load on allowed screens
if ( $this->allowed_on_screen() ) {
$this->_loadAdmin();
$this->hooks();
}
}
/**
* @param string $file
*
* @return string
*/
public function url( $file = '' ) {
return untrailingslashit( TVE_DASH_URL ) . '/inc/notification-inbox' . ( ! empty( $file ) ? '/' : '' ) . ltrim( $file, '\\/' );
}
/**
* @param string $file
*
* @return string
*/
public function path( $file = '' ) {
return untrailingslashit( plugin_dir_path( __FILE__ ) ) . ( ! empty( $file ) ? '/' : '' ) . ltrim( $file, '\\/' );
}
/**
* Initialize hooks
*/
public function hooks() {
$this->_register_routes();
add_action( 'admin_enqueue_scripts', array( $this, 'enqueueScripts' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'enqueueStyles' ) );
add_action( 'tvd_notification_inbox', array( $this, 'notification_button' ) );
add_action( 'admin_print_footer_scripts', array( $this, 'admin_backbone_templates' ) );
}
/**
* Screen restriction
*
* @return bool
*/
public function allowed_on_screen() {
return in_array( tve_get_current_screen_key(), $this->_allowed_screens, true );
}
/**
* Backbone templates
*/
public function admin_backbone_templates() {
$templates = tve_dash_get_backbone_templates( $this->path( 'views/templates/backbone' ) );
tve_dash_output_backbone_templates( $templates );
}
/**
* Admin ajax
*/
public function admin_create_rest_routes() {
if ( ! current_user_can( TVE_DASH_CAPABILITY ) ) {
wp_die( '' );
}
TD_NI_Ajax_Controller::instance()->handle();
}
/**
* Inbox template
*
* @param bool $return
*
* @return string
*/
public function notification_button( $return = false ) {
return false;
$template = dirname( __FILE__ ) . '/views/templates/notification-inbox-button.php';
ob_start();
if ( file_exists( $template ) ) {
include $template;
}
$html = ob_get_clean();
if ( $return ) {
return $html;
}
echo $html; // phpcs:ignore
}
/**
* Enqueue styles
*/
public function enqueueStyles() {
tve_dash_enqueue_style( 'td-ni-admin', $this->url( 'assets/css/notification-inbox.css' ) );
}
/**
* Enqueue scripts
*/
public function enqueueScripts() {
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'backbone' );
$js_prefix = tve_dash_is_debug_on() ? '.js' : '.min.js';
tve_dash_enqueue_script( 'td-ni-admin', $this->url( 'assets/dist/admin' . $js_prefix ), array(
'tve-dash-main-js',
'jquery',
'backbone',
), false, true );
$limit = 10;
$offset = 0;
$notifications = array_values( TVE_Dash_InboxManager::instance()->get_data( TD_Inbox_Message::TYPE_INBOX ) );
$total_unread = TVE_Dash_InboxManager::instance()->count_unread( $notifications );
$total = count( $notifications );
if ( $total > $limit ) {
$notifications = array_slice( $notifications, $offset, $limit );
}
$params = array(
't' => include $this->path( 'i18n.php' ),
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'dash_url' => admin_url( 'admin.php?page=tve_dash_section' ),
'url' => $this->url(),
'admin_nonce' => wp_create_nonce( 'td_ni_admin_ajax_request' ),
'data' => $notifications,
'total' => $total,
'total_unread' => $total_unread,
'limit' => $limit,
'offset' => $offset + $limit,
);
wp_localize_script( 'td-ni-admin', 'TD_Inbox', $params );
}
/**
* @param $key
* @param null $default
*
* @return null
*/
protected function param( $key, $default = null ) {
return isset( $_POST[ $key ] ) ? map_deep( $_POST[ $key ], 'sanitize_text_field' ) : ( isset( $_REQUEST[ $key ] ) ? map_deep( $_REQUEST[ $key ], 'sanitize_text_field' ) : $default );
}
/**
* @param $type
*
* @return bool
*/
protected function is_request( $type ) {
switch ( $type ) {
case 'admin':
return is_admin();
case 'admin_ajax':
return is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX;
case 'ajax':
return defined( 'DOING_AJAX' );
case 'cron':
return defined( 'DOING_CRON' );
case 'frontend':
return ( ! is_admin() || defined( 'DOING_AJAX' ) ) && ! defined( 'DOING_CRON' );
}
}
/**
* Register admin ajax actions
*/
private function _register_routes() {
if ( is_array( $this->_allowed_routes ) ) {
foreach ( $this->_allowed_routes as $action ) {
add_action( 'wp_ajax_' . $action, array( $this, 'admin_create_rest_routes' ) );
}
}
}
/**
* Setters
*/
private function _set_data() {
$this->_init_path = TVE_DASH_PATH . '/inc/notification-inbox/includes/init/';
$this->_admin_path = TVE_DASH_PATH . '/inc/notification-inbox/includes/admin/';
$this->_namespace = 'notification-inbox/';
$this->_version = 1;
$this->_allowed_screens = array(
'admin_page_tve_dash_api_connect',
'toplevel_page_tve_dash_section',
'thrive-dashboard_page_tve_dash_general_settings_section',
);
$this->_allowed_routes = array(
'thrv_notifications',
'thrv_bulkread',
'thrv_load_more',
);
}
/**
* Includes
*
* @param string $path
*/
private function _load( $path = '' ) {
$path = $path ? $path : $this->_init_path;
$dir = new DirectoryIterator( $path );
foreach ( $dir as $file ) {
if ( $file->isDot() ) {
continue;
}
if ( file_exists( $file->getPathname() ) && $file->isFile() ) {
require_once( $file->getPathname() );
}
}
}
/**
* Load ajax controller
*/
private function _loadAdmin() {
$this->_load( $this->_admin_path );
}
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* Thrive Themes - https://thrivethemes.com
*
* @package thrive-dashboard
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Silence is golden
}
return array(
'Notifications' => __( 'Notifications', 'thrive-dash' ),
'more_10' => __( 'Load more 10', 'thrive-dash' ),
'no_data' => __( 'There are no notifications', 'thrive-dash' ),
'no_more_data' => __( 'No more notifications', 'thrive-dash' ),
);

View File

@@ -0,0 +1,154 @@
<?php
/**
* Thrive Themes - https://thrivethemes.com
*
* @package thrive-dashboard
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Silence is golden
}
class TD_NI_Ajax_Controller {
/**
* @var TD_NI_Ajax_Controller
*/
protected static $_instance;
/**
* @var int
*/
public $version = 1;
/**
* @var string
*/
public $namespace = 'notification-inbox/v';
/**
* TD_NI_Ajax_Controller constructor.
*/
private function __construct() {
}
/**
* @return TD_NI_Ajax_Controller
*/
public static function instance() {
if ( empty( static::$_instance ) ) {
static::$_instance = new static();
}
return static::$_instance;
}
/**
* @return mixed
*/
public function handle() {
if ( ! check_ajax_referer( 'td_ni_admin_ajax_request', '_nonce', false ) ) {
$this->error( sprintf( __( 'Invalid request', 'thrive-dash' ) ) );
}
$route = $this->param( 'action' );
$route = preg_replace( '#([^a-zA-Z0-9-])#', '', $route );
$method_name = $route . '_action';
if ( ! method_exists( $this, $method_name ) ) {
$this->error( sprintf( __( 'Method %s not implemented', 'thrive-dash' ), $method_name ) );
}
$model = json_decode( file_get_contents( 'php://input' ), true );
wp_send_json( $this->{$method_name}( $model ) );
}
/**
* Handle ajax route for read inbox message read
*
* @return false|mixed|string|void
*/
public function thrvnotifications_action() {
$this->_verify_nonce();
if ( empty( $_REQUEST['notification_id'] ) ) {
$this->error( __( 'Missing parameter [notification_id] in ajax request', 'thrive-dash' ) );
}
try {
TVE_Dash_InboxManager::instance()->set_read( $this->param( 'notification_id' ) );
$return = array( 'total_unread' => TVE_Dash_InboxManager::instance()->count_unread() );
return json_encode( $return );
} catch ( Exception $e ) {
$this->error( $e->getMessage() );
}
return $this->error( __( 'An error ocurred on updating notification', 'thrive-dash' ) );
}
/**
* Buld read action
*
* @return bool
*/
public function thrvbulkread_action() {
$this->_verify_nonce();
TVE_Dash_InboxManager::instance()->bulk_read();
$response = array( 'total_unread' => TVE_Dash_InboxManager::instance()->count_unread() );
return json_encode( $response );
}
/**
* @return bool
*/
public function thrvloadmore_action() {
$this->_verify_nonce();
$offset = $this->param( 'offset' );
$limit = $this->param( 'limit' );
return array_values( TVE_Dash_InboxManager::instance()->load_more( $offset, $limit ) );
}
/**
* @param $key
* @param null $default
*
* @return null
*/
protected function param( $key, $default = null ) {
return isset( $_POST[ $key ] ) ? map_deep( $_POST[ $key ], 'sanitize_text_field' ) : ( isset( $_REQUEST[ $key ] ) ? map_deep( $_REQUEST[ $key ], 'sanitize_text_field' ) : $default );
}
/**
* @param $message
* @param string $status
*/
protected function error( $message, $status = '404 Not Found' ) {
status_header( 400 );
wp_send_json( array(
'error' => $message,
) );
return $message;
}
/**
* Verify nonce
*/
private function _verify_nonce() {
if ( ! check_ajax_referer( 'td_ni_admin_ajax_request', '_nonce', false ) ) {
$this->error( sprintf( __( 'Invalid request', 'thrive-dash' ) ) );
}
}
}

View File

@@ -0,0 +1,355 @@
<?php
/**
* Thrive Themes - https://thrivethemes.com
*
* @package thrive-dashboard
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Silence is golden!
}
/**
* Class TVE_Dash_InboxManager
*/
class TVE_Dash_InboxManager {
/**
* Option name, for storing NI messages
*/
const INBOX_OPTION_NAME = 'tvd_dash_inbox';
/**
* For saving inbox errors into this option
*/
const INBOX_OPTION_ERRORS = 'tvd_dash_inbox_err';
/**
* @var null
*/
protected static $_instance = null;
/**
* @var array
*/
public $list = array();
/**
* Retrieved data from DB
*
* @var array
*/
private $_existing_list = array();
/**
* TVE_Dash_InboxManager constructor.
*/
private function __construct() {
}
/**
* @return TVE_Dash_InboxManager|null
*/
public static function instance() {
if ( empty( static::$_instance ) ) {
static::$_instance = new self();
}
return static::$_instance;
}
/**
* @param $msg_id
*
* @throws Exception
*/
public function set_read( $msg_id ) {
if ( empty( $msg_id ) ) {
throw new Exception( __( __METHOD__ . ' required message_id on updating notification status. ', 'thrive-dash' ) );
}
$this->_refresh_messages();
if ( isset( $this->_existing_list[ $msg_id ] ) ) {
$this->_existing_list[ $msg_id ]['read'] = 1;
}
$this->_update();
}
/**
* Remove message from API connection lsit
*
* @param $slug
*
* @return bool
*/
public function remove_api_connection( $slug ) {
if ( empty( $slug ) ) {
return false;
}
$this->_refresh_messages();
$found = 0;
foreach ( $this->_existing_list as $msg_id => $message ) {
if ( ! empty( $message['slug'] ) && ! empty( $message['type'] ) && $slug === $message['slug'] && TD_Inbox_Message::TYPE_API === $message['type'] ) {
$found = 1;
unset( $this->_existing_list[ $msg_id ] );
}
}
if ( $found ) {
return $this->_update();
}
return false;
}
/**
* Bulk update notifications read
*/
public function bulk_read() {
$this->_refresh_messages();
foreach ( $this->_existing_list as $id => $notification ) {
if ( isset( $notification['read'] ) ) {
$this->_existing_list[ $id ]['read'] = 1;
}
}
return $this->_update();
}
/**
* Add to the beginning of the list
*
* @param $message
*
* @throws Exception
*/
public function prepend( $message ) {
if ( ! $message instanceof TD_Inbox_Message ) {
throw new Exception( __( __METHOD__ . ' must be instanceof TD_Inbox_Message. ', 'thrive-dash' ) );
}
$message_id = $message->get_property( 'id' );
try {
if ( $this->_message_exists( $message_id ) ) {
throw new Exception( __METHOD__ . __( " Could not save, [{$message_id}] already exists.", 'thrive-dash' ) );
}
} catch ( Exception $e ) {
throw new Exception( ( $e->getMessage() ) );
}
$this->list = array( $message_id => $message->to_array() ) + $this->list;
}
/**
* Add to the end of the list
*
* @param $message
*
* @throws Exception
*/
public function append( $message ) {
if ( ! $message instanceof TD_Inbox_Message ) {
throw new Exception( __METHOD__ . __( ' message must be instanceof TD_Inbox_Message. ', 'thrive-dash' ) );
}
$message_id = $message->get_property( 'id' );
try {
if ( $this->_message_exists( $message_id ) ) {
throw new Exception( __METHOD__ . __( " Could not save, [{$message_id}] already exists.", 'thrive-dash' ) );
}
} catch ( Exception $e ) {
throw new Exception( ( $e->getMessage() ) );
}
$this->list[ $message_id ] = $message->to_array();
}
/**
* Get all or inbox type option inbox data
*
* @return array
*/
public function get_data( $type = '' ) {
$data = (array) get_option( self::INBOX_OPTION_NAME, array() );
if ( ! empty( $type ) && TD_Inbox_Message::TYPE_INBOX === $type ) {
foreach ( $data as $msg_id => $message ) {
if ( isset( $message['type'] ) && TD_Inbox_Message::TYPE_API === $message['type'] ) {
unset( $data[ $msg_id ] );
}
}
}
return $data;
}
/**
* @param $offset
* @param int $length
*
* @return array
*/
public function load_more( $offset, $length = 10 ) {
$this->_refresh_messages();
return array_slice( $this->_existing_list, $offset, $length );
}
/**
* Count the sent list or regenerate and count
*
* @param array $data
*
* @return int
*/
public function count_unread( $data = array(), $type = TD_Inbox_Message::TYPE_INBOX ) {
$cnt = 0;
if ( empty( $data ) ) {
$this->_refresh_messages();
$data = $this->_existing_list;
}
foreach ( $data as $notification ) {
if ( ! empty( $notification['type'] ) && $type === $notification['type'] && 0 === $notification['read'] ) {
$cnt ++;
}
}
return $cnt;
}
/**
* @return mixed|void
*/
public function added_messages() {
return $this->list;
}
/**
* @return bool
* @throws Exception
*/
public function push_notifications() {
if ( empty( $this->list ) ) {
throw new Exception( __( 'Could not push_notification with empty arguments', 'thrive-dash' ) );
}
return $this->_save();
}
/**
* Save errors into DB
*
* @param $message
*
* @return bool
*/
public function error( $message ) {
if ( empty( $message ) ) {
return false;
}
$messages = (array) get_option( self::INBOX_OPTION_ERRORS, array() );
$messages[ date( 'Y-m-d H:i:s' ) ] = $message;
update_option( self::INBOX_OPTION_ERRORS, $messages );
}
/**
* @param $slug
*
* @return array|mixed
*/
public function get_by_slug( $slug ) {
if ( empty( $slug ) || ! is_string( $slug ) ) {
return array();
}
$this->_refresh_messages();
foreach ( $this->_existing_list as $id => $notification ) {
if ( ! empty( $notification['slug'] ) && $notification['slug'] === $slug ) {
return $notification;
}
}
return array();
}
/**
* Verify if the message is already saved into the DB
* based on the message id { md5( $message['title') ] }
*
* @param $msg_id
*
* @return bool
* @throws Exception
*/
private function _message_exists( $msg_id ) {
if ( ! $msg_id ) {
throw new Exception( __METHOD__ . __( ' $msg_id can\'t be empty.', 'thrive-dash' ) );
}
// Set / refresh existing DB data to $_existing_list array
$this->_refresh_messages();
if ( isset( $this->_existing_list[ $msg_id ] ) ) {
return true;
}
return false;
}
/**
* Grab the latest messages from DB
*/
private function _refresh_messages() {
$this->_existing_list = $this->get_data();
}
/**
* @return bool
*/
private function _save() {
if ( empty( $this->list ) ) {
return false;
}
$this->_refresh_messages();
$all_data = $this->list + $this->_existing_list;
return ! empty( $all_data ) ? update_option( self::INBOX_OPTION_NAME, $all_data ) : false;
}
/**
* @return bool
*/
private function _update() {
return ! empty( $this->_existing_list ) ? update_option( self::INBOX_OPTION_NAME, $this->_existing_list ) : false;
}
}

View File

@@ -0,0 +1,147 @@
<?php
/**
* Thrive Themes - https://thrivethemes.com
*
* @package thrive-dashboard
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Silence is golden!
}
/**
* Class TD_Inbox_Message
*
* Build the Message object, required for push_notification
*/
class TD_Inbox_Message {
/**
* Type of the message [used on displaying in API Connections]
*/
const TYPE_API = 'api_connections';
/**
* Message inbox type [used on displaying in Dash Inbox]
*/
const TYPE_INBOX = 'inbox';
/**
* @var string
*/
private $id;
/**
* @var string
*/
private $title;
/**
* @var string
*/
private $info;
/**
* @var int
*/
private $read = 0;
/**
* @var string
*/
private $date;
/**
* @var null
*/
private $slug = null;
/**
* @var null
*/
private $type = null;
/**
* TD_Inbox_Message constructor.
*
* @param $data
*
* @throws Exception
*/
public function __construct( $data ) {
if ( ! is_array( $data ) ) {
throw new Exception( __METHOD__ . __( ' message must be array ', 'thrive-dash' ) );
}
if ( empty( $data['title'] ) ) {
throw new Exception( __METHOD__ . __( ' title can not be empty.. ', 'thrive-dash' ) );
}
$this->_set( $data );
}
/**
* Returns objects properties as array
*
* @return array
*/
public function to_array() {
return (array) $this->_get_data();
}
/**
* Returns objects properties as json
*
* @return false|mixed|string|void
*/
public function to_json() {
return json_encode( $this->_get_data() );
}
/**
* @param $property
*
* @return bool
*/
public function get_property( $property ) {
if ( ! isset( $this->{$property} ) ) {
return false;
}
return $this->{$property};
}
/**
* Returns all object accessible non-static properties in this scope
*
* @return array
*/
private function _get_data() {
return get_object_vars( $this );
}
/**
* @param $data
*/
private function _set( $data ) {
foreach ( $data as $key => $value ) {
if ( property_exists( $this, $key ) ) {
$this->{$key} = $value;
}
}
if ( $this->title ) {
$this->id = md5( $this->title );
}
$this->date = date( 'jS F Y' );
$this->read = 0;
}
}

View File

@@ -0,0 +1,13 @@
<div class="tvd-ni-inbox-detail">
<div class="tvd-ni-single-header">
<span class="ni-go-back"><?php echo __( 'Notification', 'thrive-dash' ) ?></span>
<span class="tvd-ni-close"></span>
</div>
<div class="tvd-ni-detail-title">
<#= model.get('title') #>
</div>
<div class="tvd-ni-detail-data">
<#= model.get('info') #>
</div>
<span class="ni-go-back">&lt;&nbsp;<?php echo __( 'Back to the Notifications Lists', 'thrive-dash' ) ?></span>
</div>

View File

@@ -0,0 +1,6 @@
<div class="td-inbox-item td-inbox-item-<#= model.get('read') #>" data-id="<#= model.get('id') #>">
<span class="td-inbox-status-<#= model.get('read') #>"></span>
<span class="td-inbox-title"><#= model.get('title') #></span>
<span class="td-inbox-date"><#= model.get('date') #></span>
</div>

View File

@@ -0,0 +1,3 @@
<span class="tvd-ni-box-title"><?php echo __( 'Notifications', 'thrive-dash' ) ?></span>
<span class="tvd-ni-mark-read"><?php echo __( 'Mark all as read', 'thrive-dash' ) ?></span>
<span class="tvd-ni-close"></span>

View File

@@ -0,0 +1,16 @@
<?php
/**
* Thrive Themes - https://thrivethemes.com
*
* @package thrive-dashboard
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Silence is golden!
}
?>
<li class="ni-inbox-counter">
<a id="tvd-notifications-btn" href="javascript:void(0)" class="tvd-ni-notifications"></a>
<span class="ni-counter-holder" style="display: none;"></span>
</li>