Hotel Raxa - Advanced Booking System Implementation
🏨 Hotel Booking Enhancements: - Implemented Eagle Booking Advanced Pricing add-on - Added Booking.com-style rate management system - Created professional calendar interface for pricing - Integrated deals and discounts functionality 💰 Advanced Pricing Features: - Dynamic pricing models (per room, per person, per adult) - Base rates, adult rates, and child rates management - Length of stay discounts and early bird deals - Mobile rates and secret deals implementation - Seasonal promotions and flash sales 📅 Availability Management: - Real-time availability tracking - Stop sell and restriction controls - Closed to arrival/departure functionality - Minimum/maximum stay requirements - Automatic sold-out management 💳 Payment Integration: - Maintained Redsys payment gateway integration - Seamless integration with existing Eagle Booking - No modifications to core Eagle Booking plugin 🛠️ Technical Implementation: - Custom database tables for advanced pricing - WordPress hooks and filters integration - AJAX-powered admin interface - Data migration from existing Eagle Booking - Professional calendar view for revenue management 📊 Admin Interface: - Booking.com-style management dashboard - Visual rate and availability calendar - Bulk operations for date ranges - Statistics and analytics dashboard - Modal dialogs for quick editing 🔧 Code Quality: - WordPress coding standards compliance - Secure database operations with prepared statements - Proper input validation and sanitization - Error handling and logging - Responsive admin interface 🤖 Generated with Claude Code (https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
284
wp-content/plugins/envato-market/js/envato-market.js
Normal file
284
wp-content/plugins/envato-market/js/envato-market.js
Normal file
@@ -0,0 +1,284 @@
|
||||
/* global _envatoMarket, tb_click */
|
||||
|
||||
/**
|
||||
* Envato Market sripts.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
(function( $ ) {
|
||||
'use strict';
|
||||
var dialog, envatoMarket = {
|
||||
|
||||
cache: {},
|
||||
|
||||
init: function () {
|
||||
this.bindEvents()
|
||||
},
|
||||
|
||||
bindEvents: function () {
|
||||
const self = this
|
||||
|
||||
self.addItem()
|
||||
self.removeItem()
|
||||
self.tabbedNav()
|
||||
|
||||
$(document).on('click', '.envato-card a.thickbox', function () {
|
||||
tb_click.call(this)
|
||||
$('#TB_title').css({ 'background-color': '#23282d', color: '#cfcfcf' })
|
||||
return false
|
||||
})
|
||||
},
|
||||
|
||||
addItem: function () {
|
||||
$(document).on('click', '.add-envato-market-item', function (event) {
|
||||
const id = 'envato-market-dialog-form'
|
||||
event.preventDefault()
|
||||
|
||||
if ($('#' + id).length === 0) {
|
||||
$('body').append(wp.template(id))
|
||||
}
|
||||
|
||||
dialog = $('#' + id).dialog({
|
||||
autoOpen: true,
|
||||
modal: true,
|
||||
width: 350,
|
||||
buttons: {
|
||||
Save: {
|
||||
text: _envatoMarket.i18n.save,
|
||||
click: function () {
|
||||
const form = $(this)
|
||||
let request; let token; let input_id
|
||||
|
||||
form.on('submit', function (event) {
|
||||
event.preventDefault()
|
||||
})
|
||||
|
||||
token = form.find('input[name="token"]').val()
|
||||
input_id = form.find('input[name="id"]').val()
|
||||
|
||||
request = wp.ajax.post(_envatoMarket.action + '_add_item', {
|
||||
nonce: _envatoMarket.nonce,
|
||||
token,
|
||||
id: input_id
|
||||
})
|
||||
|
||||
request.done(function (response) {
|
||||
const item = wp.template('envato-market-item')
|
||||
const card = wp.template('envato-market-card')
|
||||
const button = wp.template('envato-market-auth-check-button')
|
||||
|
||||
$('.nav-tab-wrapper').find('[data-id="' + response.type + '"]').removeClass('hidden')
|
||||
|
||||
response.item.type = response.type
|
||||
$('#' + response.type + 's').append(card(response.item)).removeClass('hidden')
|
||||
|
||||
$('#envato-market-items').append(item({
|
||||
name: response.name,
|
||||
token: response.token,
|
||||
id: response.id,
|
||||
key: response.key,
|
||||
type: response.type,
|
||||
authorized: response.authorized
|
||||
}))
|
||||
|
||||
if ($('.auth-check-button').length === 0) {
|
||||
$('p.submit').append(button)
|
||||
}
|
||||
|
||||
dialog.dialog('close')
|
||||
envatoMarket.addReadmore()
|
||||
})
|
||||
|
||||
request.fail(function (response) {
|
||||
const template = wp.template('envato-market-dialog-error')
|
||||
const data = {
|
||||
message: (response.message ? response.message : _envatoMarket.i18n.error)
|
||||
}
|
||||
|
||||
dialog.find('.notice').remove()
|
||||
dialog.find('form').prepend(template(data))
|
||||
dialog.find('.notice').fadeIn('fast')
|
||||
})
|
||||
}
|
||||
},
|
||||
Cancel: {
|
||||
text: _envatoMarket.i18n.cancel,
|
||||
click: function () {
|
||||
dialog.dialog('close')
|
||||
}
|
||||
}
|
||||
},
|
||||
close: function () {
|
||||
dialog.find('.notice').remove()
|
||||
dialog.find('form')[0].reset()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
removeItem: function () {
|
||||
$(document).on('click', '#envato-market-items .item-delete', function (event) {
|
||||
const self = this; const id = 'envato-market-dialog-remove'
|
||||
event.preventDefault()
|
||||
|
||||
if ($('#' + id).length === 0) {
|
||||
$('body').append(wp.template(id))
|
||||
}
|
||||
|
||||
dialog = $('#' + id).dialog({
|
||||
autoOpen: true,
|
||||
modal: true,
|
||||
width: 350,
|
||||
buttons: {
|
||||
Save: {
|
||||
text: _envatoMarket.i18n.remove,
|
||||
click: function () {
|
||||
const form = $(this)
|
||||
let request; let id
|
||||
|
||||
form.on('submit', function (submit_event) {
|
||||
submit_event.preventDefault()
|
||||
})
|
||||
|
||||
id = $(self).parents('li').data('id')
|
||||
|
||||
request = wp.ajax.post(_envatoMarket.action + '_remove_item', {
|
||||
nonce: _envatoMarket.nonce,
|
||||
id
|
||||
})
|
||||
|
||||
request.done(function () {
|
||||
const item = $('.col[data-id="' + id + '"]')
|
||||
const type = item.find('.envato-card').hasClass('theme') ? 'theme' : 'plugin'
|
||||
|
||||
item.remove()
|
||||
|
||||
if ($('#' + type + 's').find('.col').length === 0) {
|
||||
$('.nav-tab-wrapper').find('[data-id="' + type + '"]').addClass('hidden')
|
||||
$('#' + type + 's').addClass('hidden')
|
||||
}
|
||||
|
||||
$(self).parents('li').remove()
|
||||
|
||||
$('#envato-market-items li').each(function (index) {
|
||||
$(this).find('input').each(function () {
|
||||
$(this).attr('name', $(this).attr('name').replace(/\[\d\]/g, '[' + index + ']'))
|
||||
})
|
||||
})
|
||||
|
||||
if ($('.auth-check-button').length !== 0 && $('#envato-market-items li').length === 0) {
|
||||
$('p.submit .auth-check-button').remove()
|
||||
}
|
||||
|
||||
dialog.dialog('close')
|
||||
})
|
||||
|
||||
request.fail(function (response) {
|
||||
const template = wp.template('envato-market-dialog-error')
|
||||
const data = {
|
||||
message: response.message ? response.message : _envatoMarket.i18n.error
|
||||
}
|
||||
|
||||
dialog.find('.notice').remove()
|
||||
dialog.find('form').prepend(template(data))
|
||||
dialog.find('.notice').fadeIn('fast')
|
||||
})
|
||||
}
|
||||
},
|
||||
Cancel: {
|
||||
text: _envatoMarket.i18n.cancel,
|
||||
click: function () {
|
||||
dialog.dialog('close')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
tabbedNav: function () {
|
||||
const self = this
|
||||
const $wrap = $('.about-wrap')
|
||||
|
||||
// Hide all panels
|
||||
$('div.panel', $wrap).hide()
|
||||
|
||||
const tab = self.getParameterByName('tab')
|
||||
const hashTab = window.location.hash.substr(1)
|
||||
|
||||
// Listen for the click event.
|
||||
$(document, $wrap).on('click', '.nav-tab-wrapper a', function () {
|
||||
// Deactivate and hide all tabs & panels.
|
||||
$('.nav-tab-wrapper a', $wrap).removeClass('nav-tab-active')
|
||||
$('div.panel', $wrap).hide()
|
||||
|
||||
// Activate and show the selected tab and panel.
|
||||
$(this).addClass('nav-tab-active')
|
||||
$('div' + $(this).attr('href'), $wrap).show()
|
||||
|
||||
self.maybeLoadhealthcheck()
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
if (tab) {
|
||||
$('.nav-tab-wrapper a[href="#' + tab + '"]', $wrap).click()
|
||||
} else if (hashTab) {
|
||||
$('.nav-tab-wrapper a[href="#' + hashTab + '"]', $wrap).click()
|
||||
} else {
|
||||
$('div.panel:not(.hidden)', $wrap).first().show()
|
||||
}
|
||||
},
|
||||
|
||||
getParameterByName: function (name) {
|
||||
let regex, results
|
||||
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]')
|
||||
regex = new RegExp('[\\?&]' + name + '=([^&#]*)')
|
||||
results = regex.exec(location.search)
|
||||
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '))
|
||||
},
|
||||
|
||||
maybeLoadhealthcheck: function () {
|
||||
// We only load the health check ajax call when the envato-market-healthcheck div is visible on the page.
|
||||
const $healthCheckOutput = $('.envato-market-healthcheck')
|
||||
if ($healthCheckOutput.is(':visible')) {
|
||||
$healthCheckOutput.text('Loading...')
|
||||
|
||||
// Use our existing wp.ajax.post pattern from above to call the healthcheck API endpoint
|
||||
const request = wp.ajax.post(_envatoMarket.action + '_healthcheck', {
|
||||
nonce: _envatoMarket.nonce
|
||||
})
|
||||
|
||||
request.done(function (response) {
|
||||
if (response && response.limits) {
|
||||
const $healthCheckUL = $('<ul></ul>')
|
||||
const limits = Object.keys(response.limits)
|
||||
for (let i = 0; i < limits.length; i++) {
|
||||
const $healthCheckLI = $('<li></li>')
|
||||
const healthCheckItem = response.limits[limits[i]]
|
||||
$healthCheckLI.addClass(healthCheckItem.ok ? 'healthcheck-ok' : 'healthcheck-error')
|
||||
$healthCheckLI.attr('data-limit', limits[i])
|
||||
$healthCheckLI.append('<span class="healthcheck-item-title">' + healthCheckItem.title + '</span>')
|
||||
$healthCheckLI.append('<span class="healthcheck-item-message">' + healthCheckItem.message + '</span>')
|
||||
$healthCheckUL.append($healthCheckLI)
|
||||
}
|
||||
$healthCheckOutput.html($healthCheckUL)
|
||||
} else {
|
||||
window.console.log(response)
|
||||
$healthCheckOutput.text('Health check failed to load. Please check console for errors.')
|
||||
}
|
||||
})
|
||||
|
||||
request.fail(function (response) {
|
||||
window.console.log(response)
|
||||
$healthCheckOutput.text('Health check failed to load. Please check console for errors.')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$(window).on('load', function () {
|
||||
envatoMarket.init()
|
||||
})
|
||||
})(jQuery)
|
||||
1
wp-content/plugins/envato-market/js/envato-market.min.js
vendored
Normal file
1
wp-content/plugins/envato-market/js/envato-market.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(r){"use strict";var o,i={cache:{},init:function(){this.bindEvents()},bindEvents:function(){var e=this;e.addItem(),e.removeItem(),e.tabbedNav(),r(document).on("click",".envato-card a.thickbox",function(){return tb_click.call(this),r("#TB_title").css({"background-color":"#23282d",color:"#cfcfcf"}),!1})},addItem:function(){r(document).on("click",".add-envato-market-item",function(e){var t="envato-market-dialog-form";e.preventDefault(),0===r("#"+t).length&&r("body").append(wp.template(t)),o=r("#"+t).dialog({autoOpen:!0,modal:!0,width:350,buttons:{Save:{text:_envatoMarket.i18n.save,click:function(){var e,t=r(this);t.on("submit",function(e){e.preventDefault()}),e=t.find('input[name="token"]').val(),t=t.find('input[name="id"]').val(),(e=wp.ajax.post(_envatoMarket.action+"_add_item",{nonce:_envatoMarket.nonce,token:e,id:t})).done(function(e){var t=wp.template("envato-market-item"),a=wp.template("envato-market-card"),n=wp.template("envato-market-auth-check-button");r(".nav-tab-wrapper").find('[data-id="'+e.type+'"]').removeClass("hidden"),e.item.type=e.type,r("#"+e.type+"s").append(a(e.item)).removeClass("hidden"),r("#envato-market-items").append(t({name:e.name,token:e.token,id:e.id,key:e.key,type:e.type,authorized:e.authorized})),0===r(".auth-check-button").length&&r("p.submit").append(n),o.dialog("close"),i.addReadmore()}),e.fail(function(e){var t=wp.template("envato-market-dialog-error"),e={message:e.message||_envatoMarket.i18n.error};o.find(".notice").remove(),o.find("form").prepend(t(e)),o.find(".notice").fadeIn("fast")})}},Cancel:{text:_envatoMarket.i18n.cancel,click:function(){o.dialog("close")}}},close:function(){o.find(".notice").remove(),o.find("form")[0].reset()}})})},removeItem:function(){r(document).on("click","#envato-market-items .item-delete",function(e){const n=this;var t="envato-market-dialog-remove";e.preventDefault(),0===r("#"+t).length&&r("body").append(wp.template(t)),o=r("#"+t).dialog({autoOpen:!0,modal:!0,width:350,buttons:{Save:{text:_envatoMarket.i18n.remove,click:function(){var e=r(this);let a;e.on("submit",function(e){e.preventDefault()}),a=r(n).parents("li").data("id"),(e=wp.ajax.post(_envatoMarket.action+"_remove_item",{nonce:_envatoMarket.nonce,id:a})).done(function(){var e=r('.col[data-id="'+a+'"]'),t=e.find(".envato-card").hasClass("theme")?"theme":"plugin";e.remove(),0===r("#"+t+"s").find(".col").length&&(r(".nav-tab-wrapper").find('[data-id="'+t+'"]').addClass("hidden"),r("#"+t+"s").addClass("hidden")),r(n).parents("li").remove(),r("#envato-market-items li").each(function(e){r(this).find("input").each(function(){r(this).attr("name",r(this).attr("name").replace(/\[\d\]/g,"["+e+"]"))})}),0!==r(".auth-check-button").length&&0===r("#envato-market-items li").length&&r("p.submit .auth-check-button").remove(),o.dialog("close")}),e.fail(function(e){var t=wp.template("envato-market-dialog-error"),e={message:e.message||_envatoMarket.i18n.error};o.find(".notice").remove(),o.find("form").prepend(t(e)),o.find(".notice").fadeIn("fast")})}},Cancel:{text:_envatoMarket.i18n.cancel,click:function(){o.dialog("close")}}}})})},tabbedNav:function(){const e=this,t=r(".about-wrap");r("div.panel",t).hide();var a=e.getParameterByName("tab"),n=window.location.hash.substr(1);r(document,t).on("click",".nav-tab-wrapper a",function(){return r(".nav-tab-wrapper a",t).removeClass("nav-tab-active"),r("div.panel",t).hide(),r(this).addClass("nav-tab-active"),r("div"+r(this).attr("href"),t).show(),e.maybeLoadhealthcheck(),!1}),a?r('.nav-tab-wrapper a[href="#'+a+'"]',t).click():n?r('.nav-tab-wrapper a[href="#'+n+'"]',t).click():r("div.panel:not(.hidden)",t).first().show()},getParameterByName:function(e){return e=e.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]"),null===(e=new RegExp("[\\?&]"+e+"=([^&#]*)").exec(location.search))?"":decodeURIComponent(e[1].replace(/\+/g," "))},maybeLoadhealthcheck:function(){const c=r(".envato-market-healthcheck");var e;c.is(":visible")&&(c.text("Loading..."),(e=wp.ajax.post(_envatoMarket.action+"_healthcheck",{nonce:_envatoMarket.nonce})).done(function(t){if(t&&t.limits){var a=r("<ul></ul>"),n=Object.keys(t.limits);for(let e=0;e<n.length;e++){var o=r("<li></li>"),i=t.limits[n[e]];o.addClass(i.ok?"healthcheck-ok":"healthcheck-error"),o.attr("data-limit",n[e]),o.append('<span class="healthcheck-item-title">'+i.title+"</span>"),o.append('<span class="healthcheck-item-message">'+i.message+"</span>"),a.append(o)}c.html(a)}else window.console.log(t),c.text("Health check failed to load. Please check console for errors.")}),e.fail(function(e){window.console.log(e),c.text("Health check failed to load. Please check console for errors.")}))}};r(window).on("load",function(){i.init()})}(jQuery);
|
||||
597
wp-content/plugins/envato-market/js/updates.js
Normal file
597
wp-content/plugins/envato-market/js/updates.js
Normal file
@@ -0,0 +1,597 @@
|
||||
/* global tb_remove, JSON */
|
||||
window.wp = window.wp || {};
|
||||
|
||||
(function ($, wp) {
|
||||
'use strict'
|
||||
|
||||
wp.envato = {}
|
||||
|
||||
/**
|
||||
* User nonce for ajax calls.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
wp.envato.ajaxNonce = window._wpUpdatesSettings.ajax_nonce
|
||||
|
||||
/**
|
||||
* Whether filesystem credentials need to be requested from the user.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
wp.envato.shouldRequestFilesystemCredentials = null
|
||||
|
||||
/**
|
||||
* Filesystem credentials to be packaged along with the request.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
wp.envato.filesystemCredentials = {
|
||||
ftp: {
|
||||
host: null,
|
||||
username: null,
|
||||
password: null,
|
||||
connectionType: null
|
||||
},
|
||||
ssh: {
|
||||
publicKey: null,
|
||||
privateKey: null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag if we're waiting for an update to complete.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
wp.envato.updateLock = false
|
||||
|
||||
/**
|
||||
* * Flag if we've done an update successfully.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
wp.envato.updateDoneSuccessfully = false
|
||||
|
||||
/**
|
||||
* If the user tries to update a plugin while an update is
|
||||
* already happening, it can be placed in this queue to perform later.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
wp.envato.updateQueue = []
|
||||
|
||||
/**
|
||||
* Store a jQuery reference to return focus to when exiting the request credentials modal.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var jQuery object
|
||||
*/
|
||||
wp.envato.$elToReturnFocusToFromCredentialsModal = null
|
||||
|
||||
/**
|
||||
* Decrement update counts throughout the various menus.
|
||||
*
|
||||
* @since 3.9.0
|
||||
*
|
||||
* @param {string} upgradeType
|
||||
*/
|
||||
wp.envato.decrementCount = function (upgradeType) {
|
||||
var count
|
||||
var pluginCount
|
||||
const $adminBarUpdateCount = $('#wp-admin-bar-updates .ab-label')
|
||||
const $dashboardNavMenuUpdateCount = $('a[href="update-core.php"] .update-plugins')
|
||||
const $pluginsMenuItem = $('#menu-plugins')
|
||||
|
||||
count = $adminBarUpdateCount.text()
|
||||
count = parseInt(count, 10) - 1
|
||||
if (count < 0 || isNaN(count)) {
|
||||
return
|
||||
}
|
||||
$('#wp-admin-bar-updates .ab-item').removeAttr('title')
|
||||
$adminBarUpdateCount.text(count)
|
||||
|
||||
$dashboardNavMenuUpdateCount.each(function (index, elem) {
|
||||
elem.className = elem.className.replace(/count-\d+/, 'count-' + count)
|
||||
})
|
||||
$dashboardNavMenuUpdateCount.removeAttr('title')
|
||||
$dashboardNavMenuUpdateCount.find('.update-count').text(count)
|
||||
|
||||
if (upgradeType === 'plugin') {
|
||||
pluginCount = $pluginsMenuItem.find('.plugin-count').eq(0).text()
|
||||
pluginCount = parseInt(pluginCount, 10) - 1
|
||||
if (pluginCount < 0 || isNaN(pluginCount)) {
|
||||
return
|
||||
}
|
||||
$pluginsMenuItem.find('.plugin-count').text(pluginCount)
|
||||
$pluginsMenuItem.find('.update-plugins').each(function (index, elem) {
|
||||
elem.className = elem.className.replace(/count-\d+/, 'count-' + pluginCount)
|
||||
})
|
||||
|
||||
if (pluginCount > 0) {
|
||||
$('.subsubsub .upgrade .count').text('(' + pluginCount + ')')
|
||||
} else {
|
||||
$('.subsubsub .upgrade').remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an Ajax request to the server to update a plugin.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param {string} plugin
|
||||
* @param {string} slug
|
||||
*/
|
||||
wp.envato.updatePlugin = function (plugin, slug) {
|
||||
let data
|
||||
const $message = $('.envato-card-' + slug).find('.update-now')
|
||||
const name = $message.data('name')
|
||||
|
||||
const updatingMessage = wp.i18n.sprintf(wp.i18n.__('Updating %s...', 'envato-market'), name)
|
||||
$message.attr('aria-label', updatingMessage)
|
||||
|
||||
$message.addClass('updating-message')
|
||||
if ($message.html() !== updatingMessage) {
|
||||
$message.data('originaltext', $message.html())
|
||||
}
|
||||
|
||||
$message.text(updatingMessage)
|
||||
|
||||
if (wp.envato.updateLock) {
|
||||
wp.envato.updateQueue.push({
|
||||
type: 'update-plugin',
|
||||
data: {
|
||||
plugin,
|
||||
slug
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
wp.envato.updateLock = true
|
||||
|
||||
data = {
|
||||
_ajax_nonce: wp.envato.ajaxNonce,
|
||||
plugin,
|
||||
slug,
|
||||
username: wp.envato.filesystemCredentials.ftp.username,
|
||||
password: wp.envato.filesystemCredentials.ftp.password,
|
||||
hostname: wp.envato.filesystemCredentials.ftp.hostname,
|
||||
connection_type: wp.envato.filesystemCredentials.ftp.connectionType,
|
||||
public_key: wp.envato.filesystemCredentials.ssh.publicKey,
|
||||
private_key: wp.envato.filesystemCredentials.ssh.privateKey
|
||||
}
|
||||
|
||||
wp.ajax.post('update-plugin', data)
|
||||
.done(wp.envato.updateSuccess)
|
||||
.fail(wp.envato.updateError)
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an Ajax request to the server to update a theme.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param {string} plugin
|
||||
* @param {string} slug
|
||||
*/
|
||||
wp.envato.updateTheme = function (slug) {
|
||||
let data
|
||||
const $message = $('.envato-card-' + slug).find('.update-now')
|
||||
const name = $message.data('name')
|
||||
|
||||
const updatingMessage = wp.i18n.sprintf(wp.i18n.__('Updating %s...', 'envato-market'), name)
|
||||
$message.attr('aria-label', updatingMessage)
|
||||
|
||||
$message.addClass('updating-message')
|
||||
if ($message.html() !== updatingMessage) {
|
||||
$message.data('originaltext', $message.html())
|
||||
}
|
||||
|
||||
$message.text(updatingMessage)
|
||||
|
||||
if (wp.envato.updateLock) {
|
||||
wp.envato.updateQueue.push({
|
||||
type: 'update-theme',
|
||||
data: {
|
||||
theme: slug
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
wp.envato.updateLock = true
|
||||
|
||||
data = {
|
||||
_ajax_nonce: wp.envato.ajaxNonce,
|
||||
theme: slug,
|
||||
slug,
|
||||
username: wp.envato.filesystemCredentials.ftp.username,
|
||||
password: wp.envato.filesystemCredentials.ftp.password,
|
||||
hostname: wp.envato.filesystemCredentials.ftp.hostname,
|
||||
connection_type: wp.envato.filesystemCredentials.ftp.connectionType,
|
||||
public_key: wp.envato.filesystemCredentials.ssh.publicKey,
|
||||
private_key: wp.envato.filesystemCredentials.ssh.privateKey
|
||||
}
|
||||
|
||||
wp.ajax.post('update-theme', data)
|
||||
.done(wp.envato.updateSuccess)
|
||||
.fail(wp.envato.updateError)
|
||||
}
|
||||
|
||||
/**
|
||||
* On a successful plugin update, update the UI with the result.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param {object} response
|
||||
*/
|
||||
wp.envato.updateSuccess = function (response) {
|
||||
let $card, $updateColumn, $updateMessage, $updateVersion, name, version, versionText
|
||||
|
||||
$card = $('.envato-card-' + response.slug)
|
||||
$updateColumn = $card.find('.column-update')
|
||||
$updateMessage = $card.find('.update-now')
|
||||
$updateVersion = $card.find('.version')
|
||||
|
||||
name = $updateMessage.data('name')
|
||||
version = $updateMessage.data('version')
|
||||
versionText = $updateVersion.attr('aria-label').replace('%s', version)
|
||||
|
||||
$updateMessage.addClass('disabled')
|
||||
|
||||
const updateMessage = wp.i18n.sprintf(wp.i18n.__('Updating %s...', 'envato-market'), name)
|
||||
$updateMessage.attr('aria-label', updateMessage)
|
||||
$updateVersion.text(versionText)
|
||||
|
||||
$updateMessage.removeClass('updating-message').addClass('updated-message')
|
||||
$updateMessage.text(wp.i18n.__('Updated!', 'envato-market'))
|
||||
wp.a11y.speak(updateMessage)
|
||||
$updateColumn.addClass('update-complete').delay(1000).fadeOut()
|
||||
|
||||
wp.envato.decrementCount('plugin')
|
||||
|
||||
wp.envato.updateDoneSuccessfully = true
|
||||
|
||||
/*
|
||||
* The lock can be released since the update was successful,
|
||||
* and any other updates can commence.
|
||||
*/
|
||||
wp.envato.updateLock = false
|
||||
|
||||
$(document).trigger('envato-update-success', response)
|
||||
|
||||
wp.envato.queueChecker()
|
||||
}
|
||||
|
||||
/**
|
||||
* On a plugin update error, update the UI appropriately.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param {object} response
|
||||
*/
|
||||
wp.envato.updateError = function (response) {
|
||||
let $message, name
|
||||
wp.envato.updateDoneSuccessfully = false
|
||||
if (response.errorCode && response.errorCode === 'unable_to_connect_to_filesystem' && wp.envato.shouldRequestFilesystemCredentials) {
|
||||
wp.envato.credentialError(response, 'update-plugin')
|
||||
return
|
||||
}
|
||||
$message = $('.envato-card-' + response.slug).find('.update-now')
|
||||
|
||||
name = $message.data('name')
|
||||
$message.attr('aria-label', wp.i18n.__('Updating failed', 'envato-market'))
|
||||
|
||||
$message.removeClass('updating-message')
|
||||
$message.html(wp.i18n.sprintf(wp.i18n.__('Updating failed %s...', 'envato-market'), typeof 'undefined' !== response.errorMessage ? response.errorMessage : response.error))
|
||||
|
||||
/*
|
||||
* The lock can be released since this failure was
|
||||
* after the credentials form.
|
||||
*/
|
||||
wp.envato.updateLock = false
|
||||
|
||||
$(document).trigger('envato-update-error', response)
|
||||
|
||||
wp.envato.queueChecker()
|
||||
}
|
||||
|
||||
/**
|
||||
* Show an error message in the request for credentials form.
|
||||
*
|
||||
* @param {string} message
|
||||
* @since 1.0.0
|
||||
*/
|
||||
wp.envato.showErrorInCredentialsForm = function (message) {
|
||||
const $modal = $('.notification-dialog')
|
||||
|
||||
// Remove any existing error.
|
||||
$modal.find('.error').remove()
|
||||
|
||||
$modal.find('h3').after('<div class="error">' + message + '</div>')
|
||||
}
|
||||
|
||||
/**
|
||||
* Events that need to happen when there is a credential error
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
wp.envato.credentialError = function (response, type) {
|
||||
wp.envato.updateQueue.push({
|
||||
type,
|
||||
data: {
|
||||
|
||||
// Not cool that we're depending on response for this data.
|
||||
// This would feel more whole in a view all tied together.
|
||||
plugin: response.plugin,
|
||||
slug: response.slug
|
||||
}
|
||||
})
|
||||
wp.envato.showErrorInCredentialsForm(response.error)
|
||||
wp.envato.requestFilesystemCredentials()
|
||||
}
|
||||
|
||||
/**
|
||||
* If an update job has been placed in the queue, queueChecker pulls it out and runs it.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
wp.envato.queueChecker = function () {
|
||||
let job
|
||||
|
||||
if (wp.envato.updateLock || wp.envato.updateQueue.length <= 0) {
|
||||
return
|
||||
}
|
||||
|
||||
job = wp.envato.updateQueue.shift()
|
||||
|
||||
wp.envato.updatePlugin(job.data.plugin, job.data.slug)
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the users filesystem credentials if we don't have them already.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
wp.envato.requestFilesystemCredentials = function (event) {
|
||||
if (wp.envato.updateDoneSuccessfully === false) {
|
||||
wp.envato.$elToReturnFocusToFromCredentialsModal = $(event.target)
|
||||
|
||||
wp.envato.updateLock = true
|
||||
|
||||
wp.envato.requestForCredentialsModalOpen()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Keydown handler for the request for credentials modal.
|
||||
*
|
||||
* Close the modal when the escape key is pressed.
|
||||
* Constrain keyboard navigation to inside the modal.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
wp.envato.keydown = function (event) {
|
||||
if (event.keyCode === 27) {
|
||||
wp.envato.requestForCredentialsModalCancel()
|
||||
} else if (event.keyCode === 9) {
|
||||
// #upgrade button must always be the last focusable element in the dialog.
|
||||
if (event.target.id === 'upgrade' && !event.shiftKey) {
|
||||
$('#hostname').focus()
|
||||
event.preventDefault()
|
||||
} else if (event.target.id === 'hostname' && event.shiftKey) {
|
||||
$('#upgrade').focus()
|
||||
event.preventDefault()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the request for credentials modal.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
wp.envato.requestForCredentialsModalOpen = function () {
|
||||
const $modal = $('#request-filesystem-credentials-dialog')
|
||||
$('body').addClass('modal-open')
|
||||
$modal.show()
|
||||
|
||||
$modal.find('input:enabled:first').focus()
|
||||
$modal.keydown(wp.envato.keydown)
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the request for credentials modal.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
wp.envato.requestForCredentialsModalClose = function () {
|
||||
$('#request-filesystem-credentials-dialog').hide()
|
||||
$('body').removeClass('modal-open')
|
||||
wp.envato.$elToReturnFocusToFromCredentialsModal.focus()
|
||||
}
|
||||
|
||||
/**
|
||||
* The steps that need to happen when the modal is canceled out
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
wp.envato.requestForCredentialsModalCancel = function () {
|
||||
let slug, $message
|
||||
|
||||
// No updateLock and no updateQueue means we already have cleared things up
|
||||
if (wp.envato.updateLock === false && wp.envato.updateQueue.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
slug = wp.envato.updateQueue[0].data.slug,
|
||||
|
||||
// Remove the lock, and clear the queue
|
||||
wp.envato.updateLock = false
|
||||
wp.envato.updateQueue = []
|
||||
|
||||
wp.envato.requestForCredentialsModalClose()
|
||||
$message = $('.envato-card-' + slug).find('.update-now')
|
||||
|
||||
$message.removeClass('updating-message')
|
||||
$message.html($message.data('originaltext'))
|
||||
}
|
||||
/**
|
||||
* Potentially add an AYS to a user attempting to leave the page
|
||||
*
|
||||
* If an update is on-going and a user attempts to leave the page,
|
||||
* open an "Are you sure?" alert.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
wp.envato.beforeunload = function () {
|
||||
if (wp.envato.updateLock) {
|
||||
return wp.i18n.__('Update in progress, really leave?', 'envato-market')
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
/*
|
||||
* Check whether a user needs to submit filesystem credentials based on whether
|
||||
* the form was output on the page server-side.
|
||||
*
|
||||
* @see {wp_print_request_filesystem_credentials_modal() in PHP}
|
||||
*/
|
||||
wp.envato.shouldRequestFilesystemCredentials = !(($('#request-filesystem-credentials-dialog').length <= 0))
|
||||
|
||||
// File system credentials form submit noop-er / handler.
|
||||
$('#request-filesystem-credentials-dialog form').on('submit', function () {
|
||||
// Persist the credentials input by the user for the duration of the page load.
|
||||
wp.envato.filesystemCredentials.ftp.hostname = $('#hostname').val()
|
||||
wp.envato.filesystemCredentials.ftp.username = $('#username').val()
|
||||
wp.envato.filesystemCredentials.ftp.password = $('#password').val()
|
||||
wp.envato.filesystemCredentials.ftp.connectionType = $('input[name="connection_type"]:checked').val()
|
||||
wp.envato.filesystemCredentials.ssh.publicKey = $('#public_key').val()
|
||||
wp.envato.filesystemCredentials.ssh.privateKey = $('#private_key').val()
|
||||
|
||||
wp.envato.requestForCredentialsModalClose()
|
||||
|
||||
// Unlock and invoke the queue.
|
||||
wp.envato.updateLock = false
|
||||
wp.envato.queueChecker()
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
// Close the request credentials modal when
|
||||
$('#request-filesystem-credentials-dialog [data-js-action="close"], .notification-dialog-background').on('click', function () {
|
||||
wp.envato.requestForCredentialsModalCancel()
|
||||
})
|
||||
|
||||
// Hide SSH fields when not selected
|
||||
$('#request-filesystem-credentials-dialog input[name="connection_type"]').on('change', function () {
|
||||
$(this).parents('form').find('#private_key, #public_key').parents('label').toggle(($(this).val() === 'ssh'))
|
||||
}).change()
|
||||
|
||||
// Click handler for plugin updates.
|
||||
$('.envato-card.plugin').on('click', '.update-now', function (e) {
|
||||
const $button = $(e.target)
|
||||
e.preventDefault()
|
||||
|
||||
if (wp.envato.shouldRequestFilesystemCredentials && !wp.envato.updateLock) {
|
||||
wp.envato.requestFilesystemCredentials(e)
|
||||
}
|
||||
|
||||
wp.envato.updatePlugin($button.data('plugin'), $button.data('slug'))
|
||||
})
|
||||
|
||||
// Click handler for theme updates.
|
||||
$('.envato-card.theme').on('click', '.update-now', function (e) {
|
||||
const $button = $(e.target)
|
||||
e.preventDefault()
|
||||
|
||||
if (wp.envato.shouldRequestFilesystemCredentials && !wp.envato.updateLock) {
|
||||
wp.envato.requestFilesystemCredentials(e)
|
||||
}
|
||||
|
||||
wp.envato.updateTheme($button.data('slug'))
|
||||
})
|
||||
|
||||
// @todo
|
||||
$('#plugin_update_from_iframe').on('click', function (e) {
|
||||
let target, data
|
||||
|
||||
target = window.parent === window ? null : window.parent,
|
||||
$.support.postMessage = !!window.postMessage
|
||||
|
||||
if ($.support.postMessage === false || target === null || window.parent.location.pathname.indexOf('update-core.php') !== -1) {
|
||||
return
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
|
||||
data = {
|
||||
action: 'updatePlugin',
|
||||
slug: $(this).data('slug')
|
||||
}
|
||||
|
||||
target.postMessage(JSON.stringify(data), window.location.origin)
|
||||
})
|
||||
})
|
||||
|
||||
$(window).on('message', function (e) {
|
||||
const event = e.originalEvent
|
||||
let message
|
||||
const loc = document.location
|
||||
const expectedOrigin = loc.protocol + '//' + loc.hostname
|
||||
|
||||
if (event.origin !== expectedOrigin) {
|
||||
return
|
||||
}
|
||||
|
||||
if (event.data) {
|
||||
try {
|
||||
message = $.parseJSON(event.data)
|
||||
} catch (error) {
|
||||
message = event.data
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof message.action === 'undefined') {
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
switch (message.action) {
|
||||
case 'decrementUpdateCount' :
|
||||
wp.envato.decrementCount(message.upgradeType)
|
||||
break
|
||||
case 'updatePlugin' :
|
||||
tb_remove()
|
||||
$('.envato-card-' + message.slug).find('h4 a').focus()
|
||||
$('.envato-card-' + message.slug).find('[data-slug="' + message.slug + '"]').trigger('click')
|
||||
break
|
||||
default:
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$(window).on('beforeunload', wp.envato.beforeunload)
|
||||
})(jQuery, window.wp, window.ajaxurl)
|
||||
1
wp-content/plugins/envato-market/js/updates.min.js
vendored
Normal file
1
wp-content/plugins/envato-market/js/updates.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user