(function( $ ) { /** * The list table used on the current page. * plugins.php : .wp-list-table.plugins * update-core.php : #update-plugins-table * @type {Object} */ const $listTable = $( '#update-plugins-table,.wp-list-table.plugins' ); /** * Class representing a single plugin in the context of a list table of plugin updates. * * @param {object} data * @param {Plugin|undefined} parent * @constructor */ const Plugin = function( data, parent ) { /** * Data provided by the server. * @type {Object} */ this.data = data; /** * Parent Plugin instance, if representing an add-on. * @type {Plugin|undefined} */ this.parent = parent; /** * Object for the checkbox allowing the plugin to be submitted for update. * @type {Object} jQuery */ this.$check = $listTable.find( '.check-column [value="' + data.basename + '"]' ); /** * Object for the primary list table row for this plugin. * @type {Object} jQuery */ this.$row = this.$check.closest( 'tr' ); /** * Object for the container which holds update notices for this plugin. * This container represents the main difference between the two list tables. * * This property is only initialized for plugins with license errors. * * @type {Object} jQuery */ this.$noticeContainer = null; }; /** * Get the html for this plugin's check license again link. * * @returns {string} */ Plugin.prototype.checkAgainLink = function() { return ' ' + as3cf_dbrains.strings.check_licence_again + ''; }; /** * Does this plugin have any errors for its license? * * @returns {boolean} */ Plugin.prototype.hasLicenseErrors = function() { const license = this.isAddon() ? this.parent.data.license : this.data.license; return !_.isEmpty( license.errors ); }; /** * Disable the plugin's list table checkbox. */ Plugin.prototype.disableUpdateCheckbox = function() { if ( $listTable.is( '#update-plugins-table' ) ) { this.$check.prop( { disabled: true, checked: false } ); } }; /** * Enable the plugin's list table checkbox. */ Plugin.prototype.enableUpdateCheckbox = function() { if ( $listTable.is( '#update-plugins-table' ) ) { this.$check.prop( { disabled: false } ); } }; /** * Set the update notice with the given html. * * @param {string} html */ Plugin.prototype.setNotice = function( html ) { this.$noticeContainer.find( '.as3cf-licence-notice' ).remove(); this.$noticeContainer.append( '
' + '

' + html + this.checkAgainLink() + '

' + '
' ); }; /** * Fade out our license notice and remove it, then restore WP update notices, if any. */ Plugin.prototype.clearNotice = function() { const plugin = this; const $notice = this.$noticeContainer.find( '.as3cf-licence-notice' ); $.when( $notice.fadeOut() ).done( function() { $notice.remove(); plugin.$row.children().css( 'box-shadow', '' ); plugin.$noticeContainer.find( '.update-message' ).show(); } ); }; /** * Render the plugin's state to the DOM. */ Plugin.prototype.render = function() { if ( this.hasLicenseErrors() ) { this.initNoticeContainer(); this.disableUpdateCheckbox(); this.$noticeContainer.find( '.update-message:not(".as3cf-licence-notice")' ).hide(); this.setNotice( this.getLicenseNotice() ); } else if ( this.$noticeContainer ) { this.enableUpdateCheckbox(); this.clearNotice(); } if ( !this.isAddon() ) { _.invoke( this.addons, 'render' ); } }; /** * Initialize the notice container. */ Plugin.prototype.initNoticeContainer = function() { if ( this.$noticeContainer ) { return; } // Check if it is the Plugins update table if ( !$listTable.is( '#update-plugins-table' ) ) { // Check for an existing plugin-update notice row to use. const $noticeRow = $listTable.find( '.plugin-update-tr[data-plugin="' + this.data.basename + '"]' ); if ( $noticeRow.length ) { this.$noticeContainer = $noticeRow.find( '.plugin-update' ); } else { const colspan = this.$row.children().length; // If there is no plugin-update row, the plugin did not have an update, so inject a row to use. this.$row.after( '' + '' + '' ); // The border between rows comes from a box-shadow on the children of the row above this.$row.children().css( 'box-shadow', 'none' ); this.$noticeContainer = $listTable.find( '.plugin-update-tr[data-plugin="' + this.data.basename + '"] .plugin-update' ); } } else { // Updates this.$noticeContainer = this.$row.find( '.plugin-title' ); } // Finally, bind the click handler for ajax license checking this.$noticeContainer.on( 'click', '.as3cf-dbrains-check-my-licence-again a', _.bind( this.checkLicenseAgain, this ) ); }; /** * Get the text for the license notice. * * @returns {string} */ Plugin.prototype.getLicenseNotice = function() { let message = ''; if ( this.data.update_available ) { message = as3cf_dbrains.strings.update_available + ' '; } if ( this.isAddon() ) { return message + as3cf_dbrains.strings.requires_parent_licence.replace( '%s', this.parent.data.name ); } return message + _.values( this.data.license.errors ).join( '' ); }; /** * Event listener callback to handle the check the license again for this plugin. * * @param {Event} event */ Plugin.prototype.checkLicenseAgain = function( event ) { const plugin = this; const $link = $( event.target ); const $spinner = $( '' ); event.preventDefault(); $link.hide().after( $spinner ); this.ajaxCheckLicense() .done( function( data ) { if ( plugin.isAddon() ) { plugin.parent.data.license.errors = data.errors; plugin.parent.render(); } else { plugin.data.license.errors = data.errors; plugin.render(); } } ) .fail( function() { plugin.setNotice( as3cf_dbrains.strings.licence_check_problem ); } ) .always( function() { $spinner.remove(); } ) ; }; /** * Send an ajax request to the server to check the plugin's license. * * @return {jqXHR} jQuery XHR Promise object */ Plugin.prototype.ajaxCheckLicense = function() { const prefix = this.isAddon() ? this.parent.data.prefix : this.data.prefix; return $.ajax( { url: ajaxurl, type: 'POST', dataType: 'json', cache: false, data: { action: prefix + '_check_licence', nonce: as3cf_dbrains.nonces.check_licence } } ); }; /** * Initialize the plugin instance. */ Plugin.prototype.init = function() { this.render(); if ( !this.isAddon() ) { this.initAddons(); } }; /** * Does this instance represent an add-on? * * @returns {boolean} */ Plugin.prototype.isAddon = function() { return !!this.parent; }; /** * Initialize Plugin add-ons. */ Plugin.prototype.initAddons = function() { const parent = this; this.addons = _.map( this.data.addons, function( addonData ) { return new Plugin( addonData, parent ); } ); _.invoke( this.addons, 'init' ); }; /** * Instantiate and initialize plugin instances. */ function initialize() { _.chain( as3cf_dbrains.plugins ) .map( function( pluginData ) { return new Plugin( pluginData ); } ) .invoke( 'init' ); } if ( $listTable.length ) { $( initialize ); } })( jQuery );