updated plugin Menu Icons version 0.12.8

This commit is contained in:
KawaiiPunk 2021-07-25 23:25:06 +00:00 committed by Gitium
parent 3ef36355e9
commit a2480e23b7
63 changed files with 1153 additions and 1499 deletions

View File

@ -1,5 +1,16 @@
##### [Version 0.12.8](https://github.com/codeinwp/wp-menu-icons/compare/v0.12.7...v0.12.8) (2021-05-12)
### v0.12.5 - 2020-08-18 * Fix issue when the image is not accessible to fetch the width/height metadata.
##### [Version 0.12.7](https://github.com/codeinwp/wp-menu-icons/compare/v0.12.6...v0.12.7) (2021-05-07)
Fix PHP fatal error when uploading SVG with the image uploader
##### [Version 0.12.6](https://github.com/codeinwp/wp-menu-icons/compare/v0.12.5...v0.12.6) (2021-05-05)
* Adds explicit width/height to icons to prevent layout shifts issues
### v0.12.5 - 2020-08-18
**Changes:** **Changes:**
### v0.12.4 - 2020-07-13 ### v0.12.4 - 2020-07-13
@ -46,4 +57,3 @@
**Changes:** **Changes:**
* Change ownership to ThemeIsle. * Change ownership to ThemeIsle.
* Improves compatibility with various ThemeIsle products. * Improves compatibility with various ThemeIsle products.

View File

@ -0,0 +1,13 @@
## Releasing
This repository uses conventional [changelog commit](https://github.com/Codeinwp/conventional-changelog-simple-preset) messages to trigger release
How to release a new version:
- Clone the master branch
- Do your changes
- Send a PR to master and merge it using the following subject message
- `release: <release short description>` - for patch release
- `release(minor): <release short description>` - for minor release
- `release(major): <release short description>` - for major release
The release notes will inherit the body of the commit message which triggered the release. For more details check the [simple-preset](https://github.com/Codeinwp/conventional-changelog-simple-preset) that we use.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

View File

@ -420,10 +420,45 @@ final class Menu_Icons_Front_End {
$classes = sprintf( '%s _svg', self::get_icon_classes( $meta ) ); $classes = sprintf( '%s _svg', self::get_icon_classes( $meta ) );
$style = self::get_icon_style( $meta, array( 'svg_width', 'vertical_align' ) ); $style = self::get_icon_style( $meta, array( 'svg_width', 'vertical_align' ) );
$svg_icon = esc_url( wp_get_attachment_url( $meta['icon'] ) );
$width = '';
$height = '';
if ( 'image/svg+xml' === get_post_mime_type( $meta['icon'] ) ) {
// Check `WP_Filesystem` function exists OR not.
require_once ABSPATH . '/wp-admin/includes/file.php';
\WP_Filesystem();
global $wp_filesystem;
$svg_icon = get_attached_file( $meta['icon'] );
$svg_icon_content = $wp_filesystem->get_contents( $svg_icon );
if ( $svg_icon_content ) {
$xmlget = simplexml_load_string( $svg_icon_content );
$xmlattributes = $xmlget->attributes();
$width = (string) $xmlattributes->width;
$width = (int) filter_var( $xmlattributes->width, FILTER_SANITIZE_NUMBER_INT );
$height = (string) $xmlattributes->height;
$height = (int) filter_var( $xmlattributes->height, FILTER_SANITIZE_NUMBER_INT );
}
} else {
$attachment_meta = wp_get_attachment_metadata( $meta['icon'] );
if ( $attachment_meta ) {
$width = isset( $attachment_meta['width'] ) ? $attachment_meta['width'] : $width;
$height = isset( $attachment_meta['height'] ) ? $attachment_meta['height'] : $height;
}
}
if ( ! empty( $width ) ) {
$width = sprintf( ' width="%dpx"', $width );
}
if ( ! empty( $height ) ) {
$height = sprintf( ' height="%dpx"', $height );
}
return sprintf( return sprintf(
'<img src="%s" class="%s" aria-hidden="true"%s />', '<img src="%s" class="%s" aria-hidden="true"%s%s%s/>',
esc_url( wp_get_attachment_url( $meta['icon'] ) ), esc_url( wp_get_attachment_url( $meta['icon'] ) ),
esc_attr( $classes ), esc_attr( $classes ),
$width,
$height,
$style $style
); );
} }

View File

@ -186,9 +186,9 @@ final class Menu_Icons_Picker {
return; return;
} }
if( ! function_exists( 'get_current_screen' ) ) { if ( ! function_exists( 'get_current_screen' ) ) {
return; return;
} }
$screen = get_current_screen(); $screen = get_current_screen();
if ( ! $screen instanceof WP_Screen || 'nav-menus' !== $screen->id ) { if ( ! $screen instanceof WP_Screen || 'nav-menus' !== $screen->id ) {

View File

@ -11,7 +11,7 @@
* Plugin name: Menu Icons * Plugin name: Menu Icons
* Plugin URI: https://github.com/Codeinwp/wp-menu-icons * Plugin URI: https://github.com/Codeinwp/wp-menu-icons
* Description: Spice up your navigation menus with pretty icons, easily. * Description: Spice up your navigation menus with pretty icons, easily.
* Version: 0.12.5 * Version: 0.12.8
* Author: ThemeIsle * Author: ThemeIsle
* Author URI: https://themeisle.com * Author URI: https://themeisle.com
* License: GPLv2 * License: GPLv2
@ -27,7 +27,7 @@
*/ */
final class Menu_Icons { final class Menu_Icons {
const VERSION = '0.12.5'; const VERSION = '0.12.8';
/** /**
* Holds plugin data * Holds plugin data

View File

@ -2,7 +2,7 @@
Contributors: codeinwp, themeisle Contributors: codeinwp, themeisle
Tags: menu, nav-menu, icons, navigation Tags: menu, nav-menu, icons, navigation
Requires at least: 4.3 Requires at least: 4.3
Tested up to: 5.4 Tested up to: 5.7
Stable tag: trunk Stable tag: trunk
License: GPLv2 License: GPLv2
License URI: http://www.gnu.org/licenses/gpl-2.0.html License URI: http://www.gnu.org/licenses/gpl-2.0.html
@ -224,8 +224,24 @@ add_filter( 'menu_icons_menu_settings', 'my_menu_icons_menu_settings', 10, 2 );
Read [this blog post](http://kucrut.org/add-custom-image-sizes-right-way/). Read [this blog post](http://kucrut.org/add-custom-image-sizes-right-way/).
== Changelog == == Changelog ==
= 0.12.5 - 2020-08-18 =
##### [Version 0.12.8](https://github.com/codeinwp/wp-menu-icons/compare/v0.12.7...v0.12.8) (2021-05-12)
* Fix issue when the image is not accessible to fetch the width/height metadata.
##### [Version 0.12.7](https://github.com/codeinwp/wp-menu-icons/compare/v0.12.6...v0.12.7) (2021-05-07)
Fix PHP fatal error when uploading SVG with the image uploader
##### [Version 0.12.6](https://github.com/codeinwp/wp-menu-icons/compare/v0.12.5...v0.12.6) (2021-05-05)
* Adds explicit width/height to icons to prevent layout shifts issues
= 0.12.4 - 2020-07-13 = = 0.12.4 - 2020-07-13 =

View File

@ -2,6 +2,6 @@
// autoload.php @generated by Composer // autoload.php @generated by Composer
require_once __DIR__ . '/composer' . '/autoload_real.php'; require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitabef56b0da707c7e3eaebd0d256cca29::getLoader(); return ComposerAutoloaderInit45b19aab4a02085424168fe90bd9d9df::getLoader();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 557 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

View File

@ -337,4 +337,6 @@ final class Icon_Picker {
$this->is_admin_loaded = true; $this->is_admin_loaded = true;
} }
} }
add_action( 'plugins_loaded', array( 'Icon_Picker', 'instance' ), 7 ); if ( function_exists( 'add_action' ) ) {
add_action( 'plugins_loaded', array( 'Icon_Picker', 'instance' ), 7 );
}

View File

@ -1,101 +0,0 @@
require( './media/manifest' );
( function( $ ) {
var l10n = wp.media.view.l10n.iconPicker,
templates = {},
frame, selectIcon, removeIcon, getFrame, updateField, updatePreview, $field;
getFrame = function() {
if ( ! frame ) {
frame = new wp.media.view.MediaFrame.IconPicker();
frame.target.on( 'change', updateField );
}
return frame;
};
updateField = function( model ) {
_.each( model.get( 'inputs' ), function( $input, key ) {
$input.val( model.get( key ) );
});
model.clear({ silent: true });
$field.trigger( 'ipf:update' );
};
updatePreview = function( e ) {
var $el = $( e.currentTarget ),
$select = $el.find( 'a.ipf-select' ),
$remove = $el.find( 'a.ipf-remove' ),
type = $el.find( 'input.ipf-type' ).val(),
icon = $el.find( 'input.ipf-icon' ).val(),
url = $el.find( 'input.url' ).val(),
template;
if ( type === '' || icon === '' || ! _.has( iconPicker.types, type ) ) {
$remove.addClass( 'hidden' );
$select
.removeClass( 'has-icon' )
.addClass( 'button' )
.text( l10n.selectIcon )
.attr( 'title', '' );
return;
}
if ( templates[ type ]) {
template = templates[ type ];
} else {
template = templates[ type ] = wp.template( 'iconpicker-' + iconPicker.types[ type ].templateId + '-icon' );
}
$remove.removeClass( 'hidden' );
$select
.attr( 'title', l10n.selectIcon )
.addClass( 'has-icon' )
.removeClass( 'button' )
.html( template({
type: type,
icon: icon,
url: url
}) );
};
selectIcon = function( e ) {
var frame = getFrame(),
model = { inputs: {} };
e.preventDefault();
$field = $( e.currentTarget ).closest( '.ipf' );
model.id = $field.attr( 'id' );
// Collect input fields and use them as the model's attributes.
$field.find( 'input' ).each( function() {
var $input = $( this ),
key = $input.attr( 'class' ).replace( 'ipf-', '' ),
value = $input.val();
model[ key ] = value;
model.inputs[ key ] = $input;
});
frame.target.set( model, { silent: true });
frame.open();
};
removeIcon = function( e ) {
var $el = $( e.currentTarget ).closest( 'div.ipf' );
$el.find( 'input' ).val( '' );
$el.trigger( 'ipf:update' );
};
$( document )
.on( 'click', 'a.ipf-select', selectIcon )
.on( 'click', 'a.ipf-remove', removeIcon )
.on( 'ipf:update', 'div.ipf', updatePreview );
$( 'div.ipf' ).trigger( 'ipf:update' );
}( jQuery ) );

View File

@ -1,69 +0,0 @@
/**
* wp.media.controller.IconPickerFont
*
* @class
* @augments wp.media.controller.State
* @augments Backbone.Model
* @mixes wp.media.controller.iconPickerMixin
*/
var IconPickerFont = wp.media.controller.State.extend( _.extend({}, wp.media.controller.iconPickerMixin, {
defaults: {
multiple: false,
menu: 'default',
toolbar: 'select',
baseType: 'font'
},
initialize: function() {
var data = this.get( 'data' );
this.set( 'groups', new Backbone.Collection( data.groups ) );
this.set( 'library', new wp.media.model.IconPickerFonts( data.items ) );
this.set( 'selection', new wp.media.model.Selection( null, {
multiple: this.get( 'multiple' )
}) );
},
activate: function() {
this.frame.on( 'open', this.updateSelection, this );
this.resetFilter();
this.updateSelection();
},
deactivate: function() {
this.frame.off( 'open', this.updateSelection, this );
},
resetFilter: function() {
this.get( 'library' ).props.set( 'group', 'all' );
},
updateSelection: function() {
var selection = this.get( 'selection' ),
library = this.get( 'library' ),
target = this.frame.target,
icon = target.get( 'icon' ),
type = target.get( 'type' ),
selected;
if ( this.id === type ) {
selected = library.findWhere({ id: icon });
}
selection.reset( selected ? selected : null );
},
getContentView: function() {
return new wp.media.view.IconPickerFontBrowser( _.extend({
controller: this.frame,
model: this,
groups: this.get( 'groups' ),
collection: this.get( 'library' ),
selection: this.get( 'selection' ),
baseType: this.get( 'baseType' ),
type: this.get( 'id' )
}, this.ipGetSidebarOptions() ) );
}
}) );
module.exports = IconPickerFont;

View File

@ -1,148 +0,0 @@
var Library = wp.media.controller.Library,
l10n = wp.media.view.l10n,
models = wp.media.model,
views = wp.media.view,
IconPickerImg;
/**
* wp.media.controller.IconPickerImg
*
* @augments wp.media.controller.Library
* @augments wp.media.controller.State
* @augments Backbone.Model
* @mixes media.selectionSync
* @mixes wp.media.controller.iconPickerMixin
*/
IconPickerImg = Library.extend( _.extend({}, wp.media.controller.iconPickerMixin, {
defaults: _.defaults({
id: 'image',
baseType: 'image',
syncSelection: false
}, Library.prototype.defaults ),
initialize: function( options ) {
var selection = this.get( 'selection' );
this.options = options;
this.set( 'library', wp.media.query({ type: options.data.mimeTypes }) );
this.routers = {
upload: {
text: l10n.uploadFilesTitle,
priority: 20
},
browse: {
text: l10n.mediaLibraryTitle,
priority: 40
}
};
if ( ! ( selection instanceof models.Selection ) ) {
this.set( 'selection', new models.Selection( selection, {
multiple: false
}) );
}
Library.prototype.initialize.apply( this, arguments );
},
activate: function() {
Library.prototype.activate.apply( this, arguments );
this.get( 'library' ).observe( wp.Uploader.queue );
this.frame.on( 'open', this.updateSelection, this );
this.updateSelection();
},
deactivate: function() {
Library.prototype.deactivate.apply( this, arguments );
this.get( 'library' ).unobserve( wp.Uploader.queue );
this.frame.off( 'open', this.updateSelection, this );
},
getContentView: function( mode ) {
var content = ( mode === 'upload' ) ? this.uploadContent() : this.browseContent();
this.frame.$el.removeClass( 'hide-toolbar' );
return content;
},
/**
* Media library content
*
* @returns {wp.media.view.IconPickerImgBrowser} "Browse" content view.
*/
browseContent: function() {
var options = _.extend({
model: this,
controller: this.frame,
collection: this.get( 'library' ),
selection: this.get( 'selection' ),
sortable: this.get( 'sortable' ),
search: this.get( 'searchable' ),
filters: this.get( 'filterable' ),
dragInfo: this.get( 'dragInfo' ),
idealColumnWidth: this.get( 'idealColumnWidth' ),
suggestedWidth: this.get( 'suggestedWidth' ),
suggestedHeight: this.get( 'suggestedHeight' )
}, this.ipGetSidebarOptions() );
if ( this.id === 'svg' ) {
options.AttachmentView = views.IconPickerSvgItem;
}
return new views.IconPickerImgBrowser( options );
},
/**
* Render callback for the content region in the `upload` mode.
*
* @returns {wp.media.view.UploaderInline} "Upload" content view.
*/
uploadContent: function() {
return new wp.media.view.UploaderInline({
controller: this.frame
});
},
updateSelection: function() {
var selection = this.get( 'selection' ),
target = this.frame.target,
icon = target.get( 'icon' ),
type = target.get( 'type' ),
selected;
if ( this.id === type ) {
selected = models.Attachment.get( icon );
this.dfd = selected.fetch();
}
selection.reset( selected ? selected : null );
},
/**
* Get image icon URL
*
* @param {object} model - Selected icon model.
* @param {string} size - Image size.
*
* @returns {string} Icon URL.
*/
ipGetIconUrl: function( model, size ) {
var url = model.get( 'url' ),
sizes = model.get( 'sizes' );
if ( undefined === size ) {
size = 'thumbnail';
}
if ( sizes && sizes[ size ]) {
url = sizes[ size ].url;
}
return url;
}
}) );
module.exports = IconPickerImg;

View File

@ -1,35 +0,0 @@
/**
* Methods for the state
*
* @mixin
*/
var iconPickerMixin = {
/**
* @returns {object}
*/
ipGetSidebarOptions: function() {
var frameOptions = this.frame.options,
options = {};
if ( frameOptions.SidebarView && frameOptions.SidebarView.prototype instanceof wp.media.view.IconPickerSidebar ) {
options.sidebar = true;
options.SidebarView = frameOptions.SidebarView;
} else {
options.sidebar = false;
}
return options;
},
/**
* Get image icon URL
*
* @returns {string}
*/
ipGetIconUrl: function() {
return '';
}
};
module.exports = iconPickerMixin;

View File

@ -1,16 +0,0 @@
wp.media.model.IconPickerTarget = require( './models/target.js' );
wp.media.model.IconPickerFonts = require( './models/fonts.js' );
wp.media.controller.iconPickerMixin = require( './controllers/mixin.js' );
wp.media.controller.IconPickerFont = require( './controllers/font.js' );
wp.media.controller.IconPickerImg = require( './controllers/img.js' );
wp.media.view.IconPickerBrowser = require( './views/browser.js' );
wp.media.view.IconPickerSidebar = require( './views/sidebar.js' );
wp.media.view.IconPickerFontItem = require( './views/font-item.js' );
wp.media.view.IconPickerFontLibrary = require( './views/font-library.js' );
wp.media.view.IconPickerFontFilter = require( './views/font-filter.js' );
wp.media.view.IconPickerFontBrowser = require( './views/font-browser.js' );
wp.media.view.IconPickerImgBrowser = require( './views/img-browser.js' );
wp.media.view.IconPickerSvgItem = require( './views/svg-item.js' );
wp.media.view.MediaFrame.IconPicker = require( './views/frame.js' );

View File

@ -1,77 +0,0 @@
/**
* wp.media.model.IconPickerFonts
*/
var IconPickerFonts = Backbone.Collection.extend({
constructor: function() {
Backbone.Collection.prototype.constructor.apply( this, arguments );
this.items = new Backbone.Collection( this.models );
this.props = new Backbone.Model({
group: 'all',
search: ''
});
this.props.on( 'change', this.refresh, this );
},
/**
* Refresh library when props is changed
*
* @param {Backbone.Model} props
*/
refresh: function( props ) {
let items = _.clone( this.items.models );
_.each( props.toJSON(), ( value, filter ) => {
const method = this.filters[ filter ];
if ( method ) {
items = items.filter( item => {
return method( item, value );
});
}
});
this.reset( items );
},
filters: {
/**
* @static
*
* @param {Backbone.Model} item Item model.
* @param {string} group Group ID.
*
* @returns {Boolean}
*/
group: function( item, group ) {
return ( group === 'all' || item.get( 'group' ) === group || item.get( 'group' ) === '' );
},
/**
* @static
*
* @param {Backbone.Model} item Item model.
* @param {string} term Search term.
*
* @returns {Boolean}
*/
search: function( item, term ) {
let result;
if ( term === '' ) {
result = true;
} else {
result = _.any([ 'id', 'name' ], attribute => {
const value = item.get( attribute );
return value && value.search( term ) >= 0;
}, term );
}
return result;
}
}
});
module.exports = IconPickerFonts;

View File

@ -1,18 +0,0 @@
/**
* wp.media.model.IconPickerTarget
*
* A target where the picked icon should be sent to
*
* @augments Backbone.Model
*/
var IconPickerTarget = Backbone.Model.extend({
defaults: {
type: '',
group: 'all',
icon: '',
url: '',
sizes: []
}
});
module.exports = IconPickerTarget;

View File

@ -1,15 +0,0 @@
/**
* Methods for the browser views
*/
var IconPickerBrowser = {
createSidebar: function() {
this.sidebar = new this.options.SidebarView({
controller: this.controller,
selection: this.options.selection
});
this.views.add( this.sidebar );
}
};
module.exports = IconPickerBrowser;

View File

@ -1,63 +0,0 @@
/**
* wp.media.view.IconPickerFontBrowser
*/
var IconPickerFontBrowser = wp.media.View.extend( _.extend({
className: function() {
var className = 'attachments-browser iconpicker-fonts-browser';
if ( ! this.options.sidebar ) {
className += ' hide-sidebar';
}
return className;
},
initialize: function() {
this.groups = this.options.groups;
this.createToolbar();
this.createLibrary();
if ( this.options.sidebar ) {
this.createSidebar();
}
},
createLibrary: function() {
this.items = new wp.media.view.IconPickerFontLibrary({
controller: this.controller,
collection: this.collection,
selection: this.options.selection,
baseType: this.options.baseType,
type: this.options.type
});
// Add keydown listener to the instance of the library view
this.views.add( this.items );
},
createToolbar: function() {
this.toolbar = new wp.media.view.Toolbar({
controller: this.controller
});
this.views.add( this.toolbar );
// Dropdown filter
this.toolbar.set( 'filters', new wp.media.view.IconPickerFontFilter({
controller: this.controller,
model: this.collection.props,
priority: - 80
}).render() );
// Search field
this.toolbar.set( 'search', new wp.media.view.Search({
controller: this.controller,
model: this.collection.props,
priority: 60
}).render() );
}
}, wp.media.view.IconPickerBrowser ) );
module.exports = IconPickerFontBrowser;

View File

@ -1,33 +0,0 @@
/**
* wp.media.view.IconPickerFontFilter
*/
var IconPickerFontFilter = wp.media.view.AttachmentFilters.extend({
createFilters: function() {
var groups = this.controller.state().get( 'groups' ),
filters = {};
filters.all = {
text: wp.media.view.l10n.iconPicker.allFilter,
props: { group: 'all' }
};
groups.each( function( group ) {
filters[ group.id ] = {
text: group.get( 'name' ),
props: { group: group.id }
};
});
this.filters = filters;
},
change: function() {
var filter = this.filters[ this.el.value ];
if ( filter ) {
this.model.set( 'group', filter.props.group );
}
}
});
module.exports = IconPickerFontFilter;

View File

@ -1,30 +0,0 @@
var Attachment = wp.media.view.Attachment.Library,
IconPickerFontItem;
/**
* wp.media.view.IconPickerFontItem
*/
IconPickerFontItem = Attachment.extend({
className: 'attachment iconpicker-item',
initialize: function() {
this.template = wp.media.template( 'iconpicker-' + this.options.baseType + '-item' );
Attachment.prototype.initialize.apply( this, arguments );
},
render: function() {
var options = _.defaults( this.model.toJSON(), {
baseType: this.options.baseType,
type: this.options.type
});
this.views.detach();
this.$el.html( this.template( options ) );
this.updateSelect();
this.views.render();
return this;
}
});
module.exports = IconPickerFontItem;

View File

@ -1,100 +0,0 @@
var $ = jQuery,
Attachments = wp.media.view.Attachments,
IconPickerFontLibrary;
/**
* wp.media.view.IconPickerFontLibrary
*/
IconPickerFontLibrary = Attachments.extend({
className: 'attachments iconpicker-items clearfix',
initialize: function() {
Attachments.prototype.initialize.apply( this, arguments );
_.bindAll( this, 'scrollToSelected' );
_.defer( this.scrollToSelected, this );
this.controller.on( 'open', this.scrollToSelected, this );
$( this.options.scrollElement ).off( 'scroll', this.scroll );
},
_addItem: function( model ) {
this.views.add( this.createAttachmentView( model ), {
at: this.collection.indexOf( model )
});
},
_removeItem: function( model ) {
var view = this._viewsByCid[ model.cid ];
delete this._viewsByCid[ model.cid ];
if ( view ) {
view.remove();
}
},
render: function() {
_.each( this._viewsByCid, this._removeItem, this );
this.collection.each( this._addItem, this );
return this;
},
createAttachmentView: function( model ) {
var view = new wp.media.view.IconPickerFontItem({
controller: this.controller,
model: model,
collection: this.collection,
selection: this.options.selection,
baseType: this.options.baseType,
type: this.options.type
});
return this._viewsByCid[ view.cid ] = view;
},
/**
* Scroll to selected item
*/
scrollToSelected: function() {
var selected = this.options.selection.single(),
singleView, distance;
if ( ! selected ) {
return;
}
singleView = this.getView( selected );
if ( singleView && ! this.isInView( singleView.$el ) ) {
distance = (
singleView.$el.offset().top -
parseInt( singleView.$el.css( 'paddingTop' ), 10 ) -
this.$el.offset().top +
this.$el.scrollTop() -
parseInt( this.$el.css( 'paddingTop' ), 10 )
);
this.$el.scrollTop( distance );
}
},
getView: function( model ) {
return _.findWhere( this._viewsByCid, { model: model });
},
isInView: function( $elem ) {
var docViewTop = this.$window.scrollTop(),
docViewBottom = docViewTop + this.$window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
return ( ( elemBottom <= docViewBottom ) && ( elemTop >= docViewTop ) );
},
prepare: function() {},
ready: function() {},
initSortable: function() {},
scroll: function() {}
});
module.exports = IconPickerFontLibrary;

View File

@ -1,118 +0,0 @@
/**
* wp.media.view.MediaFrame.IconPicker
*
* A frame for selecting an icon.
*
* @class
* @augments wp.media.view.MediaFrame.Select
* @augments wp.media.view.MediaFrame
* @augments wp.media.view.Frame
* @augments wp.media.View
* @augments wp.Backbone.View
* @augments Backbone.View
* @mixes wp.media.controller.StateMachine
*/
var l10n = wp.media.view.l10n,
Select = wp.media.view.MediaFrame.Select,
IconPicker;
IconPicker = Select.extend({
initialize: function() {
_.defaults( this.options, {
title: l10n.iconPicker.frameTitle,
multiple: false,
ipTypes: iconPicker.types,
target: null,
SidebarView: null
});
if ( this.options.target instanceof wp.media.model.IconPickerTarget ) {
this.target = this.options.target;
} else {
this.target = new wp.media.model.IconPickerTarget();
}
Select.prototype.initialize.apply( this, arguments );
},
createStates: function() {
var Controller;
_.each( this.options.ipTypes, function( props ) {
if ( ! wp.media.controller.hasOwnProperty( 'IconPicker' + props.controller ) ) {
return;
}
Controller = wp.media.controller[ 'IconPicker' + props.controller ];
this.states.add( new Controller({
id: props.id,
content: props.id,
title: props.name,
data: props.data
}) );
}, this );
},
/**
* Bind region mode event callbacks.
*/
bindHandlers: function() {
this.on( 'router:create:browse', this.createRouter, this );
this.on( 'router:render:browse', this.browseRouter, this );
this.on( 'content:render', this.ipRenderContent, this );
this.on( 'toolbar:create:select', this.createSelectToolbar, this );
this.on( 'open', this._ipSetState, this );
this.on( 'select', this._ipUpdateTarget, this );
},
/**
* Set state based on the target's icon type
*/
_ipSetState: function() {
var stateId = this.target.get( 'type' );
if ( ! stateId || ! this.states.findWhere({ id: stateId }) ) {
stateId = this.states.at( 0 ).id;
}
this.setState( stateId );
},
/**
* Update target's attributes after selecting an icon
*/
_ipUpdateTarget: function() {
var state = this.state(),
selected = state.get( 'selection' ).single(),
props;
props = {
type: state.id,
icon: selected.get( 'id' ),
sizes: selected.get( 'sizes' ),
url: state.ipGetIconUrl( selected )
};
this.target.set( props );
},
browseRouter: function( routerView ) {
var routers = this.state().routers;
if ( routers ) {
routerView.set( routers );
}
},
ipRenderContent: function() {
var state = this.state(),
mode = this.content.mode(),
content = state.getContentView( mode );
this.content.set( content );
}
});
module.exports = IconPicker;

View File

@ -1,6 +0,0 @@
/**
* wp.media.view.IconPickerImgBrowser
*/
var IconPickerImgBrowser = wp.media.view.AttachmentsBrowser.extend( wp.media.view.IconPickerBrowser );
module.exports = IconPickerImgBrowser;

View File

@ -1,29 +0,0 @@
/**
* wp.media.view.IconPickerSidebar
*/
var IconPickerSidebar = wp.media.view.Sidebar.extend({
initialize: function() {
var selection = this.options.selection;
wp.media.view.Sidebar.prototype.initialize.apply( this, arguments );
selection.on( 'selection:single', this.createSingle, this );
selection.on( 'selection:unsingle', this.disposeSingle, this );
if ( selection.single() ) {
this.createSingle();
}
},
/**
* @abstract
*/
createSingle: function() {},
/**
* @abstract
*/
disposeSingle: function() {}
});
module.exports = IconPickerSidebar;

View File

@ -1,8 +0,0 @@
/**
* wp.media.view.IconPickerSvgItem
*/
var IconPickerSvgItem = wp.media.view.Attachment.Library.extend({
template: wp.template( 'iconpicker-svg-item' )
});
module.exports = IconPickerSvgItem;

View File

@ -1,17 +0,0 @@
<?xml version="1.0"?>
<ruleset name="Icon Picker Coding Standards">
<config name="installed_paths" value="vendor/wp-coding-standards/wpcs" />
<exclude-pattern>*/node_modules/*</exclude-pattern>
<exclude-pattern>*/vendor/*</exclude-pattern>
<rule ref="WordPress-VIP">
<!-- ...Except for VIP-specific things -->
<exclude name="WordPress.VIP.FileSystemWritesDisallow" />
<exclude name="WordPress.VIP.RestrictedFunctions" />
<exclude name="WordPress.VIP.RestrictedVariables" />
<exclude name="WordPress.VIP.SuperGlobalInputUsage" />
<exclude name="WordPress.VIP.ValidatedSanitizedInput" />
<exclude name="WordPress.VIP.DirectDatabaseQuery" />
</rule>
</ruleset>

View File

@ -1,85 +0,0 @@
<!-- DO NOT EDIT THIS FILE; it is auto-generated from readme.txt -->
# Icon Picker
Pick an icon of your choice.
**Contributors:** [kucrut](https://profiles.wordpress.org/kucrut)
**Tags:** [icons](https://wordpress.org/plugins/tags/icons), [image](https://wordpress.org/plugins/tags/image), [svg](https://wordpress.org/plugins/tags/svg)
**Requires at least:** 4.3
**Tested up to:** 4.7.2
**Stable tag:** 0.5.0
**License:** [GPLv2](http://www.gnu.org/licenses/gpl-2.0.html)
**Donate Link:** http://kucrut.org/#coffee
[![Build Status](https://travis-ci.org/kucrut/wp-icon-picker.svg?branch=master)](https://travis-ci.org/kucrut/wp-icon-picker) [![Built with Grunt](https://cdn.gruntjs.com/builtwith.svg)](http://gruntjs.com)
## Description ##
An icon picker library plugin.
## Screenshots ##
### Icon selector
![Icon selector](assets/screenshot-1.png)
### Icon fields in a post meta box using [CMB](https://github.com/humanmade/Custom-Meta-Boxes/)
![Icon fields in a post meta box using [CMB](https://github.com/humanmade/Custom-Meta-Boxes/)](assets/screenshot-2.png)
## Frequently Asked Questions ##
### How do I use css file from CDN? ###
You can use the `icon_picker_icon_type_stylesheet_uri` filter, eg:
```php
/**
* Load Font Awesome's CSS from CDN
*
* @param string $stylesheet_uri Icon type's stylesheet URI.
* @param string $icon_type_id Icon type's ID.
* @param Icon_Picker_Type_Font $icon_type Icon type's instance.
*
* @return string
*/
function myprefix_font_awesome_css_from_cdn( $stylesheet_uri, $icon_type_id, $icon_type ) {
if ( 'fa' === $icon_type_id ) {
$stylesheet_uri = sprintf(
'https://maxcdn.bootstrapcdn.com/font-awesome/%s/css/font-awesome.min.css',
$icon_type->version
);
}
return $stylesheet_uri;
}
add_filter( 'icon_picker_icon_type_stylesheet_uri', 'myprefix_font_awesome_css_from_cdn', 10, 3 );
```
## Changelog ##
### 0.5.0 ###
* Update Font Awesome to 4.7.0.
* Switch to Webpack.
* Various [bug fixes and enhancements](https://github.com/kucrut/wp-icon-picker/issues?q=is%3Aissue+milestone%3A0.5.0+is%3Aclosed).
### 0.4.1 ###
* Improve support for CMB: Make the field usable in a repeatable field.
### 0.4.0 ###
* Introduce `icon_picker_icon_type_stylesheet_uri` filter hook.
* Font Awesome 4.6.1
### 0.3.0 ###
* Fix CSS classname conflicts.
### 0.2.0 ###
* Introduce `icon_picker_field()`.
* Add support for [CMB](https://github.com/humanmade/Custom-Meta-Boxes/).
### 0.1.1 ###
* Load translation, props [Eduardo Larequi](https://wordpress.org/support/profile/elarequi).
### 0.1.0 ###
* Initial

View File

@ -17,7 +17,7 @@
* Text Domain: menu-item-custom-fields * Text Domain: menu-item-custom-fields
*/ */
if ( ! class_exists( 'Menu_Item_Custom_Fields' ) && ! version_compare( get_bloginfo( 'version' ), '5.4', '>=' ) ) : if ( ! class_exists( 'Menu_Item_Custom_Fields' ) && ( function_exists('get_bloginfo') && ! version_compare( get_bloginfo( 'version' ), '5.4', '>=' ) ) ) :
/** /**
* Menu Item Custom Fields Loader * Menu Item Custom Fields Loader
*/ */

View File

@ -1,18 +0,0 @@
<?xml version="1.0"?>
<ruleset name="Icon Picker Coding Standards">
<config name="installed_paths" value="vendor/wp-coding-standards/wpcs" />
<exclude-pattern>*/node_modules/*</exclude-pattern>
<exclude-pattern>*/vendor/*</exclude-pattern>
<rule ref="WordPress-VIP">
<!-- ...Except for VIP-specific things -->
<exclude name="Squiz.PHP.CommentedOutCode.Found" />
<exclude name="WordPress.VIP.FileSystemWritesDisallow" />
<exclude name="WordPress.VIP.RestrictedFunctions" />
<exclude name="WordPress.VIP.RestrictedVariables" />
<exclude name="WordPress.VIP.SuperGlobalInputUsage" />
<exclude name="WordPress.VIP.ValidatedSanitizedInput" />
<exclude name="WordPress.VIP.DirectDatabaseQuery" />
</rule>
</ruleset>

View File

@ -1,66 +0,0 @@
<!-- DO NOT EDIT THIS FILE; it is auto-generated from readme.txt -->
# Menu Item Custom Fields
Easily add custom fields to nav menu items.
**Contributors:** [kucrut](https://profiles.wordpress.org/kucrut)
**Tags:** [menu](https://wordpress.org/plugins/tags/menu), [nav-menu](https://wordpress.org/plugins/tags/nav-menu), [custom-fields](https://wordpress.org/plugins/tags/custom-fields), [metadata](https://wordpress.org/plugins/tags/metadata)
**Requires at least:** 3.8
**Tested up to:** 4.7.2
**Stable tag:** 1.0.0
**License:** [GPLv2](http://www.gnu.org/licenses/gpl-2.0.html)
**Donate Link:** https://www.paypal.me/kucrut
[![Build Status](https://travis-ci.org/kucrut/wp-menu-item-custom-fields.svg?branch=master)](https://travis-ci.org/kucrut/wp-menu-item-custom-fields)
## Description ##
### Breaking Change ###
Since version `1.0.0`, the first parameter passed to the `wp_nav_menu_item_custom_fields` is the menu item ID, instead of the nav menu ID. This should not have a big impact, since the nav menu ID passed was always `0` (not used by core).
This is a *library* plugin. It doesn't do anything visible on its own. It was written to allow other plugins/themes to add custom fields to menu items *easily*. See **Installation**.
Development of this plugin is done on [GitHub](https://github.com/kucrut/wp-menu-item-custom-fields). **Pull requests welcome**. Please see [issues reported](https://github.com/kucrut/wp-menu-item-custom-fields/issues) there before going to the plugin forum.
## Installation ##
### As regular plugin ###
1. Upload `menu-item-custom-fields` to the `/wp-content/plugins/` directory
1. Activate the plugin through the 'Plugins' menu in WordPress
### As library in your plugin/theme ###
Simply copy `menu-item-custom-fields` to your plugin directory and require the main plugin file, eg:
`
require_once dirname( __FILE__ ) . '/menu-item-custom-fields/menu-item-custom-fields.php';
`
### Usage ###
Copy (and customize) and include the `menu-item-custom-fields-example.php` file found in the `doc/` directory of this plugin into your plugin/theme.
## Changelog ##
### 1.0.0 ###
* Pass correct parameters to the `wp_nav_menu_item_custom_fields` hook, props [@helgatheviking](https://github.com/helgatheviking).
### 0.4.0 ###
* Support WordPress 4.7, props [rahulnever2far](https://github.com/rahulnever2far).
### 0.3.0 ###
* Use `wp_nav_menu_item_custom_fields` as walker hook. See this [blog post](http://shazdeh.me/2014/06/25/custom-fields-nav-menu-items/).
* Update example plugin
### 0.2.1 ###
* Update compatibility info
### 0.2.0 ###
* Improve walker class loader
### 0.1.1 ###
* Move custom fields up (before `<p.field-move />`)
### 0.1.0 ###
* Initial public release

View File

@ -1,3 +1,25 @@
##### [Version 3.2.20](https://github.com/Codeinwp/themeisle-sdk/compare/v3.2.19...v3.2.20) (2021-03-30)
add wp-config support
##### [Version 3.2.19](https://github.com/Codeinwp/themeisle-sdk/compare/v3.2.18...v3.2.19) (2021-03-12)
* Adds compatibility with latest PHPCS coding standards.
* Adds compatibility with core auto-update.
##### [Version 3.2.18](https://github.com/Codeinwp/themeisle-sdk/compare/v3.2.17...v3.2.18) (2021-03-04)
* Fix regression on rollback order
##### [Version 3.2.17](https://github.com/Codeinwp/themeisle-sdk/compare/v3.2.16...v3.2.17) (2021-03-04)
* Fix compatibility with PHP 8 due to usort
##### [Version 3.2.16](https://github.com/Codeinwp/themeisle-sdk/compare/v3.2.15...v3.2.16) (2020-11-17)
* Fix long texts on rollback.
* Fix RTL mode for uninstall feedback.
##### [Version 3.2.15](https://github.com/Codeinwp/themeisle-sdk/compare/v3.2.14...v3.2.15) (2020-07-23) ##### [Version 3.2.15](https://github.com/Codeinwp/themeisle-sdk/compare/v3.2.14...v3.2.15) (2020-07-23)
* remove no redundant module * remove no redundant module

View File

@ -14,7 +14,7 @@ if ( ! defined( 'ABSPATH' ) ) {
return; return;
} }
// Current SDK version and path. // Current SDK version and path.
$themeisle_sdk_version = '3.2.15'; $themeisle_sdk_version = '3.2.20';
$themeisle_sdk_path = dirname( __FILE__ ); $themeisle_sdk_path = dirname( __FILE__ );
global $themeisle_sdk_max_version; global $themeisle_sdk_max_version;

View File

@ -37,14 +37,14 @@ abstract class Abstract_Module {
* *
* @return bool Should load module? * @return bool Should load module?
*/ */
public abstract function can_load( $product ); abstract public function can_load( $product );
/** /**
* Bootstrap the module. * Bootstrap the module.
* *
* @param Product $product Product object. * @param Product $product Product object.
*/ */
public abstract function load( $product ); abstract public function load( $product );
/** /**
* Check if the product is from partner. * Check if the product is from partner.
@ -63,4 +63,21 @@ abstract class Abstract_Module {
return array_key_exists( $product->get_slug(), Module_Factory::$slugs ); return array_key_exists( $product->get_slug(), Module_Factory::$slugs );
} }
/**
* Wrapper for wp_remote_get on VIP environments.
*
* @param string $url Url to check.
* @param array $args Option params.
*
* @return array|\WP_Error
*/
public function safe_get( $url, $args = array() ) {
return function_exists( 'vip_safe_wp_remote_get' )
? vip_safe_wp_remote_get( $url )
: wp_remote_get( //phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.wp_remote_get_wp_remote_get, Already used.
$url,
$args
);
}
} }

View File

@ -88,7 +88,7 @@ class Module_Factory {
* *
* @var Abstract_Module $module_object Module instance. * @var Abstract_Module $module_object Module instance.
*/ */
$module_object = new $class( $product ); $module_object = new $class( $product );
if ( ! $module_object->can_load( $product ) ) { if ( ! $module_object->can_load( $product ) ) {
continue; continue;

View File

@ -96,7 +96,7 @@ class Dashboard_Widget extends Abstract_Module {
* *
* @return string|void * @return string|void
*/ */
function add_widget() { public function add_widget() {
global $wp_meta_boxes; global $wp_meta_boxes;
if ( isset( $wp_meta_boxes['dashboard']['normal']['core']['themeisle'] ) ) { if ( isset( $wp_meta_boxes['dashboard']['normal']['core']['themeisle'] ) ) {
return; return;
@ -114,7 +114,7 @@ class Dashboard_Widget extends Abstract_Module {
/** /**
* Render widget content * Render widget content
*/ */
function render_dashboard_widget() { public function render_dashboard_widget() {
$this->setup_feeds(); $this->setup_feeds();
if ( empty( $this->items ) || ! is_array( $this->items ) ) { if ( empty( $this->items ) || ! is_array( $this->items ) ) {
return; return;
@ -220,19 +220,21 @@ class Dashboard_Widget extends Abstract_Module {
<li class="ti-dw-feed-item"> <li class="ti-dw-feed-item">
<a href=" <a href="
<?php <?php
echo add_query_arg( echo esc_url(
array( add_query_arg(
'utm_source' => 'wpadmin', array(
'utm_campaign' => 'feed', 'utm_source' => 'wpadmin',
'utm_medium' => 'dashboard_widget', 'utm_campaign' => 'feed',
), 'utm_medium' => 'dashboard_widget',
$item['link'] ),
$item['link']
)
); );
?> ?>
" target="_blank"> " target="_blank">
<span class="ti-dw-date-container"><span <span class="ti-dw-date-container"><span
class="ti-dw-day-container"><?php echo date( 'd', $item['date'] ); ?></span> <span class="ti-dw-day-container"><?php echo esc_attr( gmdate( 'd', $item['date'] ) ); ?></span> <span
class="ti-dw-month-container"><?php echo substr( date( 'M', $item['date'] ), 0, 3 ); ?></span></span><?php echo $item['title']; ?> class="ti-dw-month-container"><?php echo esc_attr( substr( gmdate( 'M', $item['date'] ), 0, 3 ) ); ?></span></span><?php echo esc_attr( $item['title'] ); ?>
</a> </a>
</li> </li>
<?php <?php
@ -275,26 +277,28 @@ class Dashboard_Widget extends Abstract_Module {
?> ?>
<div class="ti-dw-footer"> <div class="ti-dw-footer">
<span class="ti-dw-recommend-item "> <span class="ti-dw-recommend-item ">
<span class="ti-dw-recommend"><?php echo apply_filters( 'themeisle_sdk_dashboard_popular_label', sprintf( 'Popular %s', ucwords( $type ) ) ); ?> <span class="ti-dw-recommend"><?php echo esc_attr( apply_filters( 'themeisle_sdk_dashboard_popular_label', sprintf( 'Popular %s', ucwords( $type ) ) ) ); ?>
: </span> : </span>
<?php <?php
echo trim( echo esc_attr(
str_replace( trim(
array( str_replace(
'lite', array(
'Lite', 'lite',
'(Lite)', 'Lite',
'(lite)', '(Lite)',
), '(lite)',
'', ),
$recommend['name'] '',
$recommend['name']
)
) )
); );
?> ?>
(<a class="thickbox open-plugin-details-modal" (<a class="thickbox open-plugin-details-modal"
href="<?php echo $url . '&TB_iframe=true&width=600&height=500'; ?>"><?php echo apply_filters( 'themeisle_sdk_dashboard_install_label', 'Install' ); ?></a>) href="<?php echo esc_url( $url . '&TB_iframe=true&width=600&height=500' ); ?>"><?php echo esc_attr( apply_filters( 'themeisle_sdk_dashboard_install_label', 'Install' ) ); ?></a>)
</span> </span>
<span class="ti-dw-powered-by"><span><?php echo apply_filters( 'themeisle_sdk_dashboard_widget_powered_by', esc_attr( sprintf( 'Powered by %s', $this->product->get_friendly_name() ) ) ); ?></span></span> <span class="ti-dw-powered-by"><span><?php echo esc_attr( apply_filters( 'themeisle_sdk_dashboard_widget_powered_by', sprintf( 'Powered by %s', $this->product->get_friendly_name() ) ) ); ?></span></span>
</div> </div>
<?php <?php
@ -305,7 +309,7 @@ class Dashboard_Widget extends Abstract_Module {
* Setup feed items. * Setup feed items.
*/ */
private function setup_feeds() { private function setup_feeds() {
if ( false === ( $items_normalized = get_transient( 'themeisle_sdk_feed_items' ) ) ) { if ( false === ( $items_normalized = get_transient( 'themeisle_sdk_feed_items' ) ) ) { //phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure
// Load SimplePie Instance. // Load SimplePie Instance.
$feed = fetch_feed( $this->feeds ); $feed = fetch_feed( $this->feeds );
// TODO report error when is an error loading the feed. // TODO report error when is an error loading the feed.
@ -353,7 +357,7 @@ class Dashboard_Widget extends Abstract_Module {
/** /**
* Contact the API and fetch the recommended plugins/themes * Contact the API and fetch the recommended plugins/themes
*/ */
function recommend_plugin_or_theme() { public function recommend_plugin_or_theme() {
$products = $this->get_product_from_api(); $products = $this->get_product_from_api();
if ( ! is_array( $products ) ) { if ( ! is_array( $products ) ) {
$products = array(); $products = array();
@ -374,8 +378,8 @@ class Dashboard_Widget extends Abstract_Module {
* *
* @return array|mixed The list of products to use in recomended section. * @return array|mixed The list of products to use in recomended section.
*/ */
function get_product_from_api() { public function get_product_from_api() {
if ( false === ( $products = get_transient( 'themeisle_sdk_products' ) ) ) { if ( false === ( $products = get_transient( 'themeisle_sdk_products' ) ) ) { //phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure
$products = array(); $products = array();
$all_themes = $this->get_themes_from_wporg( 'themeisle' ); $all_themes = $this->get_themes_from_wporg( 'themeisle' );
$all_plugins = $this->get_plugins_from_wporg( 'themeisle' ); $all_plugins = $this->get_plugins_from_wporg( 'themeisle' );
@ -429,8 +433,8 @@ class Dashboard_Widget extends Abstract_Module {
* *
* @return array The list of themes. * @return array The list of themes.
*/ */
function get_themes_from_wporg( $author ) { public function get_themes_from_wporg( $author ) {
$products = wp_remote_get( $products = $this->safe_get(
'https://api.wordpress.org/themes/info/1.1/?action=query_themes&request[author]=' . $author . '&request[per_page]=30&request[fields][active_installs]=true' 'https://api.wordpress.org/themes/info/1.1/?action=query_themes&request[author]=' . $author . '&request[per_page]=30&request[fields][active_installs]=true'
); );
$products = json_decode( wp_remote_retrieve_body( $products ) ); $products = json_decode( wp_remote_retrieve_body( $products ) );
@ -450,8 +454,8 @@ class Dashboard_Widget extends Abstract_Module {
* *
* @return array The list of plugins for the selected author. * @return array The list of plugins for the selected author.
*/ */
function get_plugins_from_wporg( $author ) { public function get_plugins_from_wporg( $author ) {
$products = wp_remote_get( $products = $this->safe_get(
'https://api.wordpress.org/plugins/info/1.1/?action=query_plugins&request[author]=' . $author . '&request[per_page]=40&request[fields][active_installs]=true' 'https://api.wordpress.org/plugins/info/1.1/?action=query_plugins&request[author]=' . $author . '&request[per_page]=40&request[fields][active_installs]=true'
); );
$products = json_decode( wp_remote_retrieve_body( $products ) ); $products = json_decode( wp_remote_retrieve_body( $products ) );

View File

@ -62,6 +62,12 @@ class Licenser extends Abstract_Module {
* @var null Local license object. * @var null Local license object.
*/ */
private $license_local = null; private $license_local = null;
/**
* Product namespace, used for fixed name filters/cli commands.
*
* @var string $namespace Product namespace.
*/
private $namespace = null;
/** /**
* Disable wporg updates for premium products. * Disable wporg updates for premium products.
@ -71,7 +77,7 @@ class Licenser extends Abstract_Module {
* *
* @return mixed List of themes to check for update. * @return mixed List of themes to check for update.
*/ */
function disable_wporg_update( $r, $url ) { public function disable_wporg_update( $r, $url ) {
if ( 0 !== strpos( $url, 'https://api.wordpress.org/themes/update-check/' ) ) { if ( 0 !== strpos( $url, 'https://api.wordpress.org/themes/update-check/' ) ) {
return $r; return $r;
@ -83,7 +89,7 @@ class Licenser extends Abstract_Module {
unset( $themes->themes->{$this->product->get_slug()} ); unset( $themes->themes->{$this->product->get_slug()} );
// Encode the updated JSON response. // Encode the updated JSON response.
$r['body']['themes'] = json_encode( $themes ); $r['body']['themes'] = wp_json_encode( $themes );
return $r; return $r;
} }
@ -172,18 +178,18 @@ class Licenser extends Abstract_Module {
<?php <?php
echo sprintf( echo sprintf(
'<p>%s<input class="themeisle-sdk-license-input %s" type="text" id="%s_license" name="%s_license" value="%s" /><a class="%s">%s</a>&nbsp;&nbsp;&nbsp;<button name="%s_btn_trigger" class="button button-primary themeisle-sdk-licenser-button-cta" value="yes" type="submit" >%s</button></p><p class="description">%s</p>%s', '<p>%s<input class="themeisle-sdk-license-input %s" type="text" id="%s_license" name="%s_license" value="%s" /><a class="%s">%s</a>&nbsp;&nbsp;&nbsp;<button name="%s_btn_trigger" class="button button-primary themeisle-sdk-licenser-button-cta" value="yes" type="submit" >%s</button></p><p class="description">%s</p>%s',
( ( 'valid' === $status ) ? sprintf( '<input type="hidden" value="%s" name="%s_license" />', $value, $this->product->get_key() ) : '' ), ( ( 'valid' === $status ) ? sprintf( '<input type="hidden" value="%s" name="%s_license" />', esc_attr( $value ), esc_attr( $this->product->get_key() ) ) : '' ),
( ( 'valid' === $status ) ? 'themeisle-sdk-text-input-valid' : '' ), ( ( 'valid' === $status ) ? 'themeisle-sdk-text-input-valid' : '' ),
$this->product->get_key(), esc_attr( $this->product->get_key() ),
( ( 'valid' === $status ) ? $this->product->get_key() . '_mask' : $this->product->get_key() ), esc_attr( ( ( 'valid' === $status ) ? $this->product->get_key() . '_mask' : $this->product->get_key() ) ),
( ( 'valid' === $status ) ? ( str_repeat( '*', 30 ) . substr( $value, - 5 ) ) : $value ), esc_attr( ( ( 'valid' === $status ) ? ( str_repeat( '*', 30 ) . substr( $value, - 5 ) ) : $value ) ),
( 'valid' === $status ? 'themeisle-sdk-license-deactivate-cta' : 'themeisle-sdk-license-activate-cta' ), esc_attr( ( 'valid' === $status ? 'themeisle-sdk-license-deactivate-cta' : 'themeisle-sdk-license-activate-cta' ) ),
( 'valid' === $status ? $valid_string : $invalid_string ), esc_attr( 'valid' === $status ? $valid_string : $invalid_string ),
$this->product->get_key(), esc_attr( $this->product->get_key() ),
( 'valid' === $status ? $deactivate_string : $activate_string ), esc_attr( 'valid' === $status ? $deactivate_string : $activate_string ),
sprintf( $license_message, '<a href="' . $this->get_api_url() . '">' . $this->get_distributor_name() . '</a> ', $this->product->get_type() ), sprintf( wp_kses_data( $license_message ), '<a href="' . esc_url( $this->get_api_url() ) . '">' . esc_attr( $this->get_distributor_name() ) . '</a> ', esc_attr( $this->product->get_type() ) ),
empty( $error_message ) ? '' : sprintf( '<p style="color:#dd3d36">%s</p>', $error_message ) wp_kses_data( empty( $error_message ) ? '' : sprintf( '<p style="color:#dd3d36">%s</p>', ( $error_message ) ) )
); ) . wp_nonce_field( $this->product->get_key() . 'nonce', $this->product->get_key() . 'nonce_field', false, false );//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
} }
@ -210,17 +216,12 @@ class Licenser extends Abstract_Module {
} }
/** /**
* License price id. * Return the last error message.
* *
* @return int License plan. * @return mixed Error message.
*/ */
public function get_plan() { public function get_error() {
$license_data = get_option( $this->product->get_key() . '_license_data', '' ); return get_transient( $this->product->get_key() . 'act_err' );
if ( ! isset( $license_data->price_id ) ) {
return -1;
}
return (int) $license_data->price_id;
} }
/** /**
@ -249,12 +250,26 @@ class Licenser extends Abstract_Module {
return $this->product->get_store_name(); return $this->product->get_store_name();
} }
/**
* License price id.
*
* @return int License plan.
*/
public function get_plan() {
$license_data = get_option( $this->product->get_key() . '_license_data', '' );
if ( ! isset( $license_data->price_id ) ) {
return - 1;
}
return (int) $license_data->price_id;
}
/** /**
* Show the admin notice regarding the license status. * Show the admin notice regarding the license status.
* *
* @return bool Should we show the notice ? * @return bool Should we show the notice ?
*/ */
function show_notice() { public function show_notice() {
if ( ! is_admin() ) { if ( ! is_admin() ) {
return false; return false;
} }
@ -274,10 +289,10 @@ class Licenser extends Abstract_Module {
<p><strong> <p><strong>
<?php <?php
echo sprintf( echo sprintf(
$no_activations_string, wp_kses_data( $no_activations_string ),
$this->product->get_name(), esc_attr( $this->product->get_name() ),
$this->product->get_name(), esc_attr( $this->product->get_name() ),
'<a href="' . $this->get_api_url() . '" target="_blank">' . $this->get_distributor_name() . '</a>' '<a href="' . esc_url( $this->get_api_url() ) . '" target="_blank">' . esc_attr( $this->get_distributor_name() ) . '</a>'
); );
?> ?>
</strong> </strong>
@ -292,7 +307,7 @@ class Licenser extends Abstract_Module {
?> ?>
<div class="error"> <div class="error">
<p> <p>
<strong><?php echo sprintf( $expired_license_string, $this->product->get_name() . ' ' . $this->product->get_type(), $this->get_api_url() . '?license=' . $this->license_key ); ?> </strong> <strong><?php echo sprintf( wp_kses_data( $expired_license_string ), esc_attr( $this->product->get_name() . ' ' . $this->product->get_type() ), esc_url( $this->get_api_url() . '?license=' . $this->license_key ) ); ?> </strong>
</p> </p>
</div> </div>
<?php <?php
@ -304,7 +319,7 @@ class Licenser extends Abstract_Module {
?> ?>
<div class="error"> <div class="error">
<p> <p>
<strong><?php echo sprintf( $no_valid_string, $this->product->get_name() . ' ' . $this->product->get_type(), $this->get_api_url(), admin_url( 'options-general.php' ) . '#' . $this->product->get_key() . '_license' ); ?> </strong> <strong><?php echo sprintf( wp_kses_data( $no_valid_string ), esc_attr( $this->product->get_name() . ' ' . $this->product->get_type() ), esc_url( $this->get_api_url() ), esc_url( admin_url( 'options-general.php' ) . '#' . $this->product->get_key() . '_license' ) ); ?> </strong>
</p> </p>
</div> </div>
<?php <?php
@ -335,7 +350,7 @@ class Licenser extends Abstract_Module {
* *
* @return bool * @return bool
*/ */
function check_expiration() { public function check_expiration() {
$license_data = get_option( $this->product->get_key() . '_license_data', '' ); $license_data = get_option( $this->product->get_key() . '_license_data', '' );
if ( '' === $license_data ) { if ( '' === $license_data ) {
return false; return false;
@ -355,7 +370,7 @@ class Licenser extends Abstract_Module {
* *
* @return string The renew url. * @return string The renew url.
*/ */
function renew_url() { public function renew_url() {
$license_data = get_option( $this->product->get_key() . '_license_data', '' ); $license_data = get_option( $this->product->get_key() . '_license_data', '' );
if ( '' === $license_data ) { if ( '' === $license_data ) {
return $this->get_api_url(); return $this->get_api_url();
@ -371,7 +386,7 @@ class Licenser extends Abstract_Module {
* Run the license check call. * Run the license check call.
*/ */
public function product_valid() { public function product_valid() {
if ( false !== ( $license = get_transient( $this->product->get_key() . '_license_data' ) ) ) { if ( false !== ( $license = get_transient( $this->product->get_key() . '_license_data' ) ) ) { //phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure
return; return;
} }
$license = $this->check_license(); $license = $this->check_license();
@ -423,42 +438,6 @@ class Licenser extends Abstract_Module {
} }
/**
* Increment the failed checks.
*/
private function increment_failed_checks() {
$this->failed_checks ++;
update_option( $this->product->get_key() . '_failed_checks', $this->failed_checks );
}
/**
* Reset the failed checks
*/
private function reset_failed_checks() {
$this->failed_checks = 1;
update_option( $this->product->get_key() . '_failed_checks', $this->failed_checks );
}
/**
* Set license validation error message.
*
* @param string $message Error message.
*/
public function set_error( $message = '' ) {
set_transient( $this->product->get_key() . 'act_err', $message, MINUTE_IN_SECONDS );
return;
}
/**
* Return the last error message.
*
* @return mixed Error message.
*/
public function get_error() {
return get_transient( $this->product->get_key() . 'act_err' );
}
/** /**
* Do license activation/deactivation. * Do license activation/deactivation.
* *
@ -486,7 +465,7 @@ class Licenser extends Abstract_Module {
// Call the custom API. // Call the custom API.
if ( 'check' === $action ) { if ( 'check' === $action ) {
$response = wp_remote_get( sprintf( '%slicense/check/%s/%s/%s/%s', Product::API_URL, rawurlencode( $this->product->get_name() ), $license, rawurlencode( home_url() ), Loader::get_cache_token() ) ); $response = $this->safe_get( sprintf( '%slicense/check/%s/%s/%s/%s', Product::API_URL, rawurlencode( $this->product->get_name() ), $license, rawurlencode( home_url() ), Loader::get_cache_token() ) );
} else { } else {
$response = wp_remote_post( $response = wp_remote_post(
sprintf( '%slicense/%s/%s/%s', Product::API_URL, $action, rawurlencode( $this->product->get_name() ), $license ), sprintf( '%slicense/%s/%s/%s', Product::API_URL, $action, rawurlencode( $this->product->get_name() ), $license ),
@ -550,15 +529,42 @@ class Licenser extends Abstract_Module {
return true; return true;
} }
/**
* Reset the failed checks
*/
private function reset_failed_checks() {
$this->failed_checks = 1;
update_option( $this->product->get_key() . '_failed_checks', $this->failed_checks );
}
/**
* Increment the failed checks.
*/
private function increment_failed_checks() {
$this->failed_checks ++;
update_option( $this->product->get_key() . '_failed_checks', $this->failed_checks );
}
/** /**
* Activate the license remotely. * Activate the license remotely.
*/ */
function process_license() { public function process_license() {
// listen for our activate button to be clicked. // listen for our activate button to be clicked.
if ( ! isset( $_POST[ $this->product->get_key() . '_btn_trigger' ] ) ) { if ( ! isset( $_POST[ $this->product->get_key() . '_btn_trigger' ] ) ) {
return; return;
} }
$license = $_POST[ $this->product->get_key() . '_license' ]; if ( ! isset( $_POST[ $this->product->get_key() . 'nonce_field' ] )
|| ! wp_verify_nonce( $_POST[ $this->product->get_key() . 'nonce_field' ], $this->product->get_key() . 'nonce' ) //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
) {
return;
}
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$license = isset( $_POST[ $this->product->get_key() . '_license' ] )
? sanitize_text_field( $_POST[ $this->product->get_key() . '_license' ] )
: '';
$response = $this->do_license_process( $license, 'toggle' ); $response = $this->do_license_process( $license, 'toggle' );
if ( is_wp_error( $response ) ) { if ( is_wp_error( $response ) ) {
$this->set_error( $response->get_error_message() ); $this->set_error( $response->get_error_message() );
@ -568,14 +574,22 @@ class Licenser extends Abstract_Module {
if ( true === $response ) { if ( true === $response ) {
$this->set_error( '' ); $this->set_error( '' );
} }
}
/**
* Set license validation error message.
*
* @param string $message Error message.
*/
public function set_error( $message = '' ) {
set_transient( $this->product->get_key() . 'act_err', $message, MINUTE_IN_SECONDS );
return;
} }
/** /**
* Load the Themes screen. * Load the Themes screen.
*/ */
function load_themes_screen() { public function load_themes_screen() {
add_thickbox(); add_thickbox();
add_action( 'admin_notices', array( &$this, 'update_nag' ) ); add_action( 'admin_notices', array( &$this, 'update_nag' ) );
} }
@ -583,7 +597,7 @@ class Licenser extends Abstract_Module {
/** /**
* Alter the nag for themes update. * Alter the nag for themes update.
*/ */
function update_nag() { public function update_nag() {
$theme = wp_get_theme( $this->product->get_slug() ); $theme = wp_get_theme( $this->product->get_slug() );
$api_response = get_transient( $this->product_key ); $api_response = get_transient( $this->product_key );
if ( false === $api_response || ! isset( $api_response->new_version ) ) { if ( false === $api_response || ! isset( $api_response->new_version ) ) {
@ -596,16 +610,16 @@ class Licenser extends Abstract_Module {
echo '<div id="update-nag">'; echo '<div id="update-nag">';
printf( printf(
'<strong>%1$s %2$s</strong> is available. <a href="%3$s" class="thickbox" title="%4s">Check out what\'s new</a> or <a href="%5$s"%6$s>update now</a>.', '<strong>%1$s %2$s</strong> is available. <a href="%3$s" class="thickbox" title="%4s">Check out what\'s new</a> or <a href="%5$s"%6$s>update now</a>.',
$theme->get( 'Name' ), esc_attr( $theme->get( 'Name' ) ),
$api_response->new_version, esc_attr( $api_response->new_version ),
sprintf( '%s&TB_iframe=true&amp;width=1024&amp;height=800', $this->product->get_changelog() ), esc_url( sprintf( '%s&TB_iframe=true&amp;width=1024&amp;height=800', $this->product->get_changelog() ) ),
$theme->get( 'Name' ), esc_attr( $theme->get( 'Name' ) ),
$update_url, esc_url( $update_url ),
$update_onclick $update_onclick // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Already escaped.
); );
echo '</div>'; echo '</div>';
echo '<div id="' . $this->product->get_slug() . '_' . 'changelog" style="display:none;">'; echo '<div id="' . esc_attr( $this->product->get_slug() ) . '_changelog" style="display:none;">';
echo wpautop( $api_response->sections['changelog'] ); echo wp_kses_data( wpautop( $api_response->sections['changelog'] ) );
echo '</div>'; echo '</div>';
} }
} }
@ -617,7 +631,7 @@ class Licenser extends Abstract_Module {
* *
* @return mixed * @return mixed
*/ */
function theme_update_transient( $value ) { public function theme_update_transient( $value ) {
$update_data = $this->check_for_update(); $update_data = $this->check_for_update();
if ( $update_data ) { if ( $update_data ) {
$value->response[ $this->product->get_slug() ] = $update_data; $value->response[ $this->product->get_slug() ] = $update_data;
@ -631,7 +645,7 @@ class Licenser extends Abstract_Module {
* *
* @return array|bool Either the update data or false in case of failure. * @return array|bool Either the update data or false in case of failure.
*/ */
function check_for_update() { public function check_for_update() {
$update_data = get_transient( $this->product_key ); $update_data = get_transient( $this->product_key );
if ( false === $update_data ) { if ( false === $update_data ) {
@ -669,7 +683,7 @@ class Licenser extends Abstract_Module {
*/ */
private function get_version_data() { private function get_version_data() {
$response = wp_remote_get( $response = $this->safe_get(
sprintf( sprintf(
'%slicense/version/%s/%s/%s/%s', '%slicense/version/%s/%s/%s/%s',
Product::API_URL, Product::API_URL,
@ -679,7 +693,7 @@ class Licenser extends Abstract_Module {
rawurlencode( home_url() ) rawurlencode( home_url() )
), ),
array( array(
'timeout' => 15, 'timeout' => 15, //phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout, Inherited by wp_remote_get only, for vip environment we use defaults.
'sslverify' => false, 'sslverify' => false,
) )
); );
@ -706,8 +720,8 @@ class Licenser extends Abstract_Module {
/** /**
* Delete the update transient * Delete the update transient
*/ */
function delete_theme_update_transient() { public function delete_theme_update_transient() {
delete_transient( $this->product_key ); return delete_transient( $this->product_key );
} }
/** /**
@ -727,6 +741,8 @@ class Licenser extends Abstract_Module {
if ( false !== $api_response && is_object( $api_response ) && isset( $api_response->new_version ) ) { if ( false !== $api_response && is_object( $api_response ) && isset( $api_response->new_version ) ) {
if ( version_compare( $this->product->get_version(), $api_response->new_version, '<' ) ) { if ( version_compare( $this->product->get_version(), $api_response->new_version, '<' ) ) {
$_transient_data->response[ $this->product->get_slug() . '/' . $this->product->get_file() ] = $api_response; $_transient_data->response[ $this->product->get_slug() . '/' . $this->product->get_file() ] = $api_response;
} else {
$_transient_data->no_update[ $this->product->get_slug() . '/' . $this->product->get_file() ] = $api_response;
} }
} }
@ -782,7 +798,7 @@ class Licenser extends Abstract_Module {
* *
* @return array $array * @return array $array
*/ */
function http_request_args( $args, $url ) { public function http_request_args( $args, $url ) {
// If it is an https request and we are performing a package download, disable ssl verification. // If it is an https request and we are performing a package download, disable ssl verification.
if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) { if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
$args['sslverify'] = false; $args['sslverify'] = false;
@ -829,6 +845,7 @@ class Licenser extends Abstract_Module {
$namespace = apply_filters( 'themesle_sdk_namespace_' . md5( $product->get_basefile() ), false ); $namespace = apply_filters( 'themesle_sdk_namespace_' . md5( $product->get_basefile() ), false );
if ( false !== $namespace ) { if ( false !== $namespace ) {
$this->namespace = $namespace;
add_filter( 'themeisle_sdk_license_process_' . $namespace, [ $this, 'do_license_process' ], 10, 2 ); add_filter( 'themeisle_sdk_license_process_' . $namespace, [ $this, 'do_license_process' ], 10, 2 );
add_filter( 'product_' . $namespace . '_license_status', [ $this, 'get_license_status' ], PHP_INT_MAX ); add_filter( 'product_' . $namespace . '_license_status', [ $this, 'get_license_status' ], PHP_INT_MAX );
add_filter( 'product_' . $namespace . '_license_key', [ $this->product, 'get_license' ] ); add_filter( 'product_' . $namespace . '_license_key', [ $this->product, 'get_license' ] );
@ -850,17 +867,17 @@ class Licenser extends Abstract_Module {
] ]
); );
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 ); add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
add_filter( 'http_request_args', array( $this, 'http_request_args' ), 10, 2 ); add_filter( 'http_request_args', array( $this, 'http_request_args' ), 10, 2 ); //phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args
return $this; return $this;
} }
if ( $this->product->is_theme() ) { if ( $this->product->is_theme() ) {
add_filter( 'site_transient_update_themes', array( &$this, 'theme_update_transient' ) ); add_filter( 'site_transient_update_themes', array( &$this, 'theme_update_transient' ) );
add_filter( 'delete_site_transient_update_themes', array( &$this, 'delete_theme_update_transient' ) ); add_action( 'delete_site_transient_update_themes', array( &$this, 'delete_theme_update_transient' ) );
add_action( 'load-update-core.php', array( &$this, 'delete_theme_update_transient' ) ); add_action( 'load-update-core.php', array( &$this, 'delete_theme_update_transient' ) );
add_action( 'load-themes.php', array( &$this, 'delete_theme_update_transient' ) ); add_action( 'load-themes.php', array( &$this, 'delete_theme_update_transient' ) );
add_action( 'load-themes.php', array( &$this, 'load_themes_screen' ) ); add_action( 'load-themes.php', array( &$this, 'load_themes_screen' ) );
add_filter( 'http_request_args', array( $this, 'disable_wporg_update' ), 5, 2 ); add_filter( 'http_request_args', array( $this, 'disable_wporg_update' ), 5, 2 ); //phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args
return $this; return $this;
@ -870,42 +887,74 @@ class Licenser extends Abstract_Module {
} }
/** /**
* Run license activation on plugin activate. * Register license fields for the products.
*/ */
public function auto_activate() { public function register_license_hooks() {
if ( ! current_user_can( 'switch_themes' ) ) { add_action( 'admin_init', array( $this, 'register_settings' ) );
return; add_action( 'admin_init', array( $this, 'process_license' ) );
} add_action( 'admin_init', array( $this, 'product_valid' ), 99999999 );
$status = $this->get_license_status(); add_action( 'admin_notices', array( $this, 'show_notice' ) );
if ( 'not_active' !== $status ) { add_filter( $this->product->get_key() . '_license_status', array( $this, 'get_license_status' ) );
return; }
}
/**
* Check license on filesystem.
*
* @return mixed License key.
*/
public function get_file_license() {
$license_file = dirname( $this->product->get_basefile() ) . '/license.json'; $license_file = dirname( $this->product->get_basefile() ) . '/license.json';
global $wp_filesystem; global $wp_filesystem;
if ( ! is_file( $license_file ) ) { if ( ! is_file( $license_file ) ) {
return; return false;
} }
require_once( ABSPATH . '/wp-admin/includes/file.php' ); require_once ABSPATH . '/wp-admin/includes/file.php';
\WP_Filesystem(); \WP_Filesystem();
$content = json_decode( $wp_filesystem->get_contents( $license_file ) ); $content = json_decode( $wp_filesystem->get_contents( $license_file ) );
if ( ! is_object( $content ) ) { if ( ! is_object( $content ) ) {
return; return false;
} }
if ( ! isset( $content->key ) ) { if ( ! isset( $content->key ) ) {
return false;
}
return $content->key;
}
/**
* Run license activation on plugin activate.
*/
public function auto_activate() {
$status = $this->get_license_status();
if ( 'not_active' !== $status ) {
return false;
}
if ( ! empty( $this->namespace ) ) {
$license_key = apply_filters( 'product_' . $this->namespace . '_license_key_constant', '' );
}
if ( empty( $license_key ) ) {
$license_key = $this->get_file_license();
}
if ( empty( $license_key ) ) {
return; return;
} }
$this->license_local = $content;
$this->license_local = $license_key;
$lock_key = $this->product->get_key() . '_autoactivated'; $lock_key = $this->product->get_key() . '_autoactivated';
if ( 'yes' === get_option( $lock_key, '' ) ) { if ( 'yes' === get_option( $lock_key, '' ) ) {
return; return;
} }
$response = $this->do_license_process( $content->key, 'activate' ); if ( 'yes' === get_transient( $lock_key ) ) {
return;
}
$response = $this->do_license_process( $license_key, 'activate' );
update_option( $lock_key, 'yes' ); set_transient( $lock_key, 'yes', 6 * HOUR_IN_SECONDS );
if ( apply_filters( $this->product->get_key() . '_hide_license_notices', false ) ) { if ( apply_filters( $this->product->get_key() . '_hide_license_notices', false ) ) {
return; return;
@ -922,7 +971,7 @@ class Licenser extends Abstract_Module {
public function autoactivate_notice() { public function autoactivate_notice() {
?> ?>
<div class="notice notice-success is-dismissible"> <div class="notice notice-success is-dismissible">
<p><?php echo sprintf( '<strong>%s</strong> has been successfully activated using <strong>%s</strong> license !', $this->product->get_name(), str_repeat( '*', 20 ) . substr( $this->license_local->key, - 10 ) ); ?></p> <p><?php echo sprintf( '<strong>%s</strong> has been successfully activated using <strong>%s</strong> license !', esc_attr( $this->product->get_name() ), esc_attr( str_repeat( '*', 20 ) . substr( $this->license_local, - 10 ) ) ); ?></p>
</div> </div>
<?php <?php
} }
@ -989,15 +1038,4 @@ class Licenser extends Abstract_Module {
\WP_CLI::halt( 1 ); \WP_CLI::halt( 1 );
} }
/**
* Register license fields for the products.
*/
public function register_license_hooks() {
add_action( 'admin_init', array( $this, 'register_settings' ) );
add_action( 'admin_init', array( $this, 'process_license' ) );
add_action( 'admin_init', array( $this, 'product_valid' ), 99999999 );
add_action( 'admin_notices', array( $this, 'show_notice' ) );
add_filter( $this->product->get_key() . '_license_status', array( $this, 'get_license_status' ) );
}
} }

View File

@ -78,7 +78,7 @@ class Logger extends Abstract_Module {
} }
$action_key = $this->product->get_key() . '_log_activity'; $action_key = $this->product->get_key() . '_log_activity';
if ( ! wp_next_scheduled( $action_key ) ) { if ( ! wp_next_scheduled( $action_key ) ) {
wp_schedule_single_event( time() + ( rand( 1, 24 ) * 3600 ), $action_key ); wp_schedule_single_event( time() + ( wp_rand( 1, 24 ) * 3600 ), $action_key );
} }
add_action( $action_key, array( $this, 'send_log' ) ); add_action( $action_key, array( $this, 'send_log' ) );

View File

@ -84,7 +84,7 @@ class Notification extends Abstract_Module {
$notification_html = self::get_notification_html( $notification_details ); $notification_html = self::get_notification_html( $notification_details );
do_action( $notification_details['id'] . '_before_render' ); do_action( $notification_details['id'] . '_before_render' );
echo $notification_html; echo $notification_html; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, already escaped internally.
do_action( $notification_details['id'] . '_after_render' ); do_action( $notification_details['id'] . '_after_render' );
self::render_snippets(); self::render_snippets();
@ -340,7 +340,7 @@ class Notification extends Abstract_Module {
$.post( $.post(
ajaxurl, ajaxurl,
{ {
'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>', 'nonce': '<?php echo esc_attr( wp_create_nonce( (string) __CLASS__ ) ); ?>',
'action': 'themeisle_sdk_dismiss_notice', 'action': 'themeisle_sdk_dismiss_notice',
'id': notification_id, 'id': notification_id,
'confirm': confirm 'confirm': confirm
@ -365,7 +365,7 @@ class Notification extends Abstract_Module {
/** /**
* Dismiss the notification. * Dismiss the notification.
*/ */
static function dismiss() { public static function dismiss() {
check_ajax_referer( (string) __CLASS__, 'nonce' ); check_ajax_referer( (string) __CLASS__, 'nonce' );
$id = isset( $_POST['id'] ) ? sanitize_text_field( $_POST['id'] ) : ''; $id = isset( $_POST['id'] ) ? sanitize_text_field( $_POST['id'] ) : '';

View File

@ -64,7 +64,7 @@ class Recommendation extends Abstract_Module {
* @param array $strings - list of translated strings. * @param array $strings - list of translated strings.
* @param array $preferences - list of preferences. * @param array $preferences - list of preferences.
*/ */
function render_products_box( $plugins_list, $themes_list, $strings, $preferences = array() ) { public function render_products_box( $plugins_list, $themes_list, $strings, $preferences = array() ) {
if ( empty( $plugins_list ) && empty( $themes_list ) ) { if ( empty( $plugins_list ) && empty( $themes_list ) ) {
return; return;
@ -90,7 +90,7 @@ class Recommendation extends Abstract_Module {
foreach ( $list as $theme ) { foreach ( $list as $theme ) {
echo '<div class="plugin_box">'; echo '<div class="plugin_box">';
echo ' <img class="theme-banner" src="' . $theme->screenshot_url . '">'; echo ' <img class="theme-banner" src="' . esc_url( $theme->screenshot_url ) . '">';
echo ' <div class="title-action-wrapper">'; echo ' <div class="title-action-wrapper">';
echo ' <span class="plugin-name">' . esc_html( $theme->custom_name ) . '</span>'; echo ' <span class="plugin-name">' . esc_html( $theme->custom_name ) . '</span>';
if ( ! isset( $preferences['description'] ) || ( isset( $preferences['description'] ) && $preferences['description'] ) ) { if ( ! isset( $preferences['description'] ) || ( isset( $preferences['description'] ) && $preferences['description'] ) ) {
@ -118,7 +118,7 @@ class Recommendation extends Abstract_Module {
foreach ( $list as $current_plugin ) { foreach ( $list as $current_plugin ) {
echo '<div class="plugin_box">'; echo '<div class="plugin_box">';
echo ' <img class="plugin-banner" src="' . $current_plugin->custom_image . '">'; echo ' <img class="plugin-banner" src="' . esc_url( $current_plugin->custom_image ) . '">';
echo ' <div class="title-action-wrapper">'; echo ' <div class="title-action-wrapper">';
echo ' <span class="plugin-name">' . esc_html( $current_plugin->custom_name ) . '</span>'; echo ' <span class="plugin-name">' . esc_html( $current_plugin->custom_name ) . '</span>';
if ( ! isset( $preferences['description'] ) || ( isset( $preferences['description'] ) && $preferences['description'] ) ) { if ( ! isset( $preferences['description'] ) || ( isset( $preferences['description'] ) && $preferences['description'] ) ) {
@ -185,7 +185,7 @@ class Recommendation extends Abstract_Module {
return $theme; return $theme;
} }
$products = wp_remote_get( $products = $this->safe_get(
'https://api.wordpress.org/themes/info/1.1/?action=query_themes&request[theme]=' . $slug . '&request[per_page]=1' 'https://api.wordpress.org/themes/info/1.1/?action=query_themes&request[theme]=' . $slug . '&request[per_page]=1'
); );
$products = json_decode( wp_remote_retrieve_body( $products ) ); $products = json_decode( wp_remote_retrieve_body( $products ) );
@ -246,7 +246,7 @@ class Recommendation extends Abstract_Module {
* @return array|mixed|object * @return array|mixed|object
*/ */
private function call_plugin_api( $slug ) { private function call_plugin_api( $slug ) {
include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
$call_api = get_transient( 'ti_plugin_info_' . $slug ); $call_api = get_transient( 'ti_plugin_info_' . $slug );
@ -303,27 +303,30 @@ class Recommendation extends Abstract_Module {
} }
.recommend-product .theme-banner { .recommend-product .theme-banner {
width:200px; width: 200px;
margin: auto; margin: auto;
} }
.recommend-product .plugin-banner { .recommend-product .plugin-banner {
width: 100px; width: 100px;
margin: auto; margin: auto;
} }
.recommend-product .plugin_box .button span{ .recommend-product .plugin_box .button span {
margin-top: 2px; margin-top: 2px;
margin-right: 7px; margin-right: 7px;
} }
.recommend-product .plugin_box .button{
margin-bottom:10px; .recommend-product .plugin_box .button {
margin-bottom: 10px;
} }
.recommend-product .plugin_box { .recommend-product .plugin_box {
margin-bottom: 20px; margin-bottom: 20px;
padding-top: 5px; padding-top: 5px;
display: flex; display: flex;
box-shadow: 0px 0px 10px -5px rgba(0,0,0,0.55); box-shadow: 0px 0px 10px -5px rgba(0, 0, 0, 0.55);
background: #fff; background: #fff;
border-radius: 5px; border-radius: 5px;
flex-direction: column; flex-direction: column;

View File

@ -120,7 +120,9 @@ class Rollback extends Abstract_Module {
if ( empty( $url ) ) { if ( empty( $url ) ) {
return []; return [];
} }
$response = wp_remote_get( $url ); $response = function_exists( 'wp_remote_get_wp_remote_get' )
? wp_remote_get_wp_remote_get( $url )
: wp_remote_get( $url ); //phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.wp_remote_get_wp_remote_get
if ( is_wp_error( $response ) ) { if ( is_wp_error( $response ) ) {
return array(); return array();
} }
@ -191,7 +193,7 @@ class Rollback extends Abstract_Module {
* Start the rollback operation. * Start the rollback operation.
*/ */
public function start_rollback() { public function start_rollback() {
if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], $this->product->get_key() . '_rollback' ) ) { if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], $this->product->get_key() . '_rollback' ) ) { //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
wp_nonce_ays( '' ); wp_nonce_ays( '' );
} }
@ -228,9 +230,12 @@ class Rollback extends Abstract_Module {
$transient = get_transient( $this->product->get_key() . '_warning_rollback' ); $transient = get_transient( $this->product->get_key() . '_warning_rollback' );
// Style fix for the api link that gets outside the content.
echo '<style>body#error-page{word-break:break-word;}</style>';
if ( false === $transient ) { if ( false === $transient ) {
set_transient( $this->product->get_key() . '_warning_rollback', 'in progress', 30 ); set_transient( $this->product->get_key() . '_warning_rollback', 'in progress', 30 );
require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ); require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
$title = sprintf( apply_filters( $this->product->get_key() . '_rollback_message', 'Rolling back %s to v%s' ), $this->product->get_name(), $version ); $title = sprintf( apply_filters( $this->product->get_key() . '_rollback_message', 'Rolling back %s to v%s' ), $this->product->get_name(), $version );
$plugin = $plugin_folder . '/' . $plugin_file; $plugin = $plugin_folder . '/' . $plugin_file;
$nonce = 'upgrade-plugin_' . $plugin; $nonce = 'upgrade-plugin_' . $plugin;
@ -241,7 +246,7 @@ class Rollback extends Abstract_Module {
delete_transient( $this->product->get_key() . '_warning_rollback' ); delete_transient( $this->product->get_key() . '_warning_rollback' );
wp_die( wp_die(
'', '',
$title, esc_attr( $title ),
array( array(
'response' => 200, 'response' => 200,
) )
@ -268,9 +273,12 @@ class Rollback extends Abstract_Module {
$transient = get_transient( $this->product->get_key() . '_warning_rollback' ); $transient = get_transient( $this->product->get_key() . '_warning_rollback' );
// Style fix for the api link that gets outside the content.
echo '<style>body#error-page{word-break:break-word;}</style>';
if ( false === $transient ) { if ( false === $transient ) {
set_transient( $this->product->get_key() . '_warning_rollback', 'in progress', 30 ); set_transient( $this->product->get_key() . '_warning_rollback', 'in progress', 30 );
require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ); require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
$title = sprintf( apply_filters( $this->product->get_key() . '_rollback_message', 'Rolling back %s to v%s' ), $this->product->get_name(), $version ); $title = sprintf( apply_filters( $this->product->get_key() . '_rollback_message', 'Rolling back %s to v%s' ), $this->product->get_name(), $version );
$theme = $folder . '/style.css'; $theme = $folder . '/style.css';
$nonce = 'upgrade-theme_' . $theme; $nonce = 'upgrade-theme_' . $theme;
@ -281,7 +289,7 @@ class Rollback extends Abstract_Module {
delete_transient( $this->product->get_key() . '_warning_rollback' ); delete_transient( $this->product->get_key() . '_warning_rollback' );
wp_die( wp_die(
'', '',
$title, esc_attr( $title ),
array( array(
'response' => 200, 'response' => 200,
) )
@ -335,7 +343,7 @@ class Rollback extends Abstract_Module {
* @return bool Which version is greater? * @return bool Which version is greater?
*/ */
public function sort_rollback_array( $a, $b ) { public function sort_rollback_array( $a, $b ) {
return version_compare( $a['version'], $b['version'], '<' ) > 0; return version_compare( $b['version'], $a['version'] );
} }
/** /**

View File

@ -805,7 +805,7 @@ class Translate extends Abstract_Module {
$translations = get_transient( $cache_key ); $translations = get_transient( $cache_key );
if ( false === $translations ) { if ( false === $translations ) {
require_once( ABSPATH . 'wp-admin/includes/translation-install.php' ); require_once ABSPATH . 'wp-admin/includes/translation-install.php';
$translations = translations_api( $translations = translations_api(
$product->get_type() . 's', $product->get_type() . 's',
array( array(

View File

@ -132,7 +132,7 @@ class Uninstall_Feedback extends Abstract_Module {
/** /**
* Loads the additional resources * Loads the additional resources
*/ */
function load_resources() { public function load_resources() {
$screen = get_current_screen(); $screen = get_current_screen();
if ( ! $screen || ! in_array( $screen->id, array( 'theme-install', 'plugins' ) ) ) { if ( ! $screen || ! in_array( $screen->id, array( 'theme-install', 'plugins' ) ) ) {
@ -178,7 +178,7 @@ class Uninstall_Feedback extends Abstract_Module {
echo wp_kses_post( $info_disclosure_link ); echo wp_kses_post( $info_disclosure_link );
echo wp_kses_post( $this->get_disclosure_labels() ); echo wp_kses_post( $this->get_disclosure_labels() );
echo '<div class="buttons">'; echo '<div class="buttons">';
echo get_submit_button( echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function has an internal sanitization.
$button_submit, $button_submit,
'secondary', 'secondary',
$this->product->get_key() . 'ti-deactivate-yes', $this->product->get_key() . 'ti-deactivate-yes',
@ -236,7 +236,7 @@ class Uninstall_Feedback extends Abstract_Module {
} }
.ti-feedback .popup--form input[type="radio"] { .ti-feedback .popup--form input[type="radio"] {
margin: 0 10px 0 0; <?php echo is_rtl() ? 'margin: 0 0 0 10px;' : 'margin: 0 10px 0 0;'; ?>
} }
.ti-feedback .popup--form input[type="radio"]:checked ~ textarea { .ti-feedback .popup--form input[type="radio"]:checked ~ textarea {
@ -314,7 +314,7 @@ class Uninstall_Feedback extends Abstract_Module {
} }
.ti-feedback .buttons input:last-child { .ti-feedback .buttons input:last-child {
margin-left: auto; <?php echo is_rtl() ? 'margin-right: auto;' : 'margin-left: auto;'; ?>
} }
.ti-theme-uninstall-feedback-drawer { .ti-theme-uninstall-feedback-drawer {
@ -366,13 +366,19 @@ class Uninstall_Feedback extends Abstract_Module {
content: ""; content: "";
display: block; display: block;
position: absolute; position: absolute;
border: 20px solid #23A1CE;
left: -10px;
top: 50%; top: 50%;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-left: 0;
transform: translateY(-50%); transform: translateY(-50%);
<?php
echo is_rtl() ?
'right: -10px;
border-top: 20px solid transparent;
border-left: 20px solid #23A1CE;
border-bottom: 20px solid transparent;' :
'left: -10px;
border-top: 20px solid transparent;
border-right: 20px solid #23A1CE;
border-bottom: 20px solid transparent;';
?>
} }
.ti-plugin-uninstall-feedback-popup { .ti-plugin-uninstall-feedback-popup {
@ -380,7 +386,7 @@ class Uninstall_Feedback extends Abstract_Module {
position: absolute; position: absolute;
white-space: normal; white-space: normal;
width: 400px; width: 400px;
left: 100%; <?php echo is_rtl() ? 'right: calc( 100% + 15px );' : 'left: calc( 100% + 15px );'; ?>
top: -15px; top: -15px;
} }
@ -408,7 +414,7 @@ class Uninstall_Feedback extends Abstract_Module {
display: block; display: block;
} }
tr[data-plugin^="<?php echo $this->product->get_slug(); ?>"] .deactivate { tr[data-plugin^="<?php echo esc_attr( $this->product->get_slug() ); ?>"] .deactivate {
position: relative; position: relative;
} }
@ -469,20 +475,20 @@ class Uninstall_Feedback extends Abstract_Module {
var radio = $(this); var radio = $(this);
if (radio.parent().find('textarea').length > 0 && if (radio.parent().find('textarea').length > 0 &&
radio.parent().find('textarea').val().length === 0) { radio.parent().find('textarea').val().length === 0) {
$('#<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled'); $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
radio.parent().find('textarea').on('keyup', function (e) { radio.parent().find('textarea').on('keyup', function (e) {
if ($(this).val().length === 0) { if ($(this).val().length === 0) {
$('#<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled'); $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
} else { } else {
$('#<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled'); $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').removeAttr('disabled');
} }
}); });
} else { } else {
$('#<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled'); $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').removeAttr('disabled');
} }
}); });
$('#<?php echo $key; ?>ti-deactivate-yes').on('click', function (e) { $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').on('click', function (e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@ -490,7 +496,7 @@ class Uninstall_Feedback extends Abstract_Module {
'.ti-theme-uninstall-feedback-drawer input[name="ti-deactivate-option"]:checked'); '.ti-theme-uninstall-feedback-drawer input[name="ti-deactivate-option"]:checked');
$.post(ajaxurl, { $.post(ajaxurl, {
'action': '<?php echo esc_attr( $key ) . '_uninstall_feedback'; ?>', 'action': '<?php echo esc_attr( $key ) . '_uninstall_feedback'; ?>',
'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>', 'nonce': '<?php echo esc_attr( wp_create_nonce( (string) __CLASS__ ) ); ?>',
'id': selectedOption.parent().attr('ti-option-id'), 'id': selectedOption.parent().attr('ti-option-id'),
'msg': selectedOption.parent().find('textarea').val(), 'msg': selectedOption.parent().find('textarea').val(),
'type': 'theme', 'type': 'theme',
@ -523,12 +529,12 @@ class Uninstall_Feedback extends Abstract_Module {
<li ti-option-id="<?php echo esc_attr( $attributes['id'] ); ?>"> <li ti-option-id="<?php echo esc_attr( $attributes['id'] ); ?>">
<input type="radio" name="ti-deactivate-option" id="<?php echo esc_attr( $key . $attributes['id'] ); ?>"> <input type="radio" name="ti-deactivate-option" id="<?php echo esc_attr( $key . $attributes['id'] ); ?>">
<label for="<?php echo esc_attr( $key . $attributes['id'] ); ?>"> <label for="<?php echo esc_attr( $key . $attributes['id'] ); ?>">
<?php echo str_replace( '{theme}', $this->product->get_name(), $title ); ?> <?php echo esc_attr( str_replace( '{theme}', $this->product->get_name(), $title ) ); ?>
</label> </label>
<?php <?php
if ( array_key_exists( 'type', $attributes ) ) { if ( array_key_exists( 'type', $attributes ) ) {
$placeholder = array_key_exists( 'placeholder', $attributes ) ? $attributes['placeholder'] : ''; $placeholder = array_key_exists( 'placeholder', $attributes ) ? $attributes['placeholder'] : '';
echo '<textarea width="100%" rows="' . $inputs_row_map[ $attributes['type'] ] . '" name="comments" placeholder="' . esc_attr( $placeholder ) . '"></textarea>'; echo '<textarea width="100%" rows="' . esc_attr( $inputs_row_map[ $attributes['type'] ] ) . '" name="comments" placeholder="' . esc_attr( $placeholder ) . '"></textarea>';
} }
?> ?>
</li> </li>
@ -561,13 +567,13 @@ class Uninstall_Feedback extends Abstract_Module {
echo wp_kses_post( $info_disclosure_link ); echo wp_kses_post( $info_disclosure_link );
echo wp_kses_post( $this->get_disclosure_labels() ); echo wp_kses_post( $this->get_disclosure_labels() );
echo '<div class="buttons">'; echo '<div class="buttons">';
echo get_submit_button( echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function internals are escaped.
$button_cancel, $button_cancel,
'secondary', 'secondary',
$this->product->get_key() . 'ti-deactivate-no', $this->product->get_key() . 'ti-deactivate-no',
false false
); );
echo get_submit_button( echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function internals are escaped.
$button_submit, $button_submit,
'primary', 'primary',
$this->product->get_key() . 'ti-deactivate-yes', $this->product->get_key() . 'ti-deactivate-yes',
@ -596,7 +602,7 @@ class Uninstall_Feedback extends Abstract_Module {
<script type="text/javascript" id="ti-deactivate-js"> <script type="text/javascript" id="ti-deactivate-js">
(function ($) { (function ($) {
$(document).ready(function () { $(document).ready(function () {
var targetElement = 'tr[data-plugin^="<?php echo $this->product->get_slug(); ?>/"] span.deactivate a'; var targetElement = 'tr[data-plugin^="<?php echo esc_attr( $this->product->get_slug() ); ?>/"] span.deactivate a';
var redirectUrl = $(targetElement).attr('href'); var redirectUrl = $(targetElement).attr('href');
if ($('.ti-feedback-overlay').length === 0) { if ($('.ti-feedback-overlay').length === 0) {
$('body').prepend('<div class="ti-feedback-overlay"></div>'); $('body').prepend('<div class="ti-feedback-overlay"></div>');
@ -622,20 +628,20 @@ class Uninstall_Feedback extends Abstract_Module {
var radio = $(this); var radio = $(this);
if (radio.parent().find('textarea').length > 0 && if (radio.parent().find('textarea').length > 0 &&
radio.parent().find('textarea').val().length === 0) { radio.parent().find('textarea').val().length === 0) {
$('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled'); $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
radio.parent().find('textarea').on('keyup', function (e) { radio.parent().find('textarea').on('keyup', function (e) {
if ($(this).val().length === 0) { if ($(this).val().length === 0) {
$('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled'); $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
} else { } else {
$('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled'); $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').removeAttr('disabled');
} }
}); });
} else { } else {
$('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled'); $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').removeAttr('disabled');
} }
}); });
$('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-no').on('click', function (e) { $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-no').on('click', function (e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
$(targetElement).unbind('click'); $(targetElement).unbind('click');
@ -646,7 +652,7 @@ class Uninstall_Feedback extends Abstract_Module {
} }
}); });
$('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').on('click', function (e) { $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').on('click', function (e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
$(targetElement).unbind('click'); $(targetElement).unbind('click');
@ -654,7 +660,7 @@ class Uninstall_Feedback extends Abstract_Module {
'<?php echo esc_attr( $popup_id ); ?> input[name="ti-deactivate-option"]:checked'); '<?php echo esc_attr( $popup_id ); ?> input[name="ti-deactivate-option"]:checked');
var data = { var data = {
'action': '<?php echo esc_attr( $key ) . '_uninstall_feedback'; ?>', 'action': '<?php echo esc_attr( $key ) . '_uninstall_feedback'; ?>',
'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>', 'nonce': '<?php echo esc_attr( wp_create_nonce( (string) __CLASS__ ) ); ?>',
'id': selectedOption.parent().attr('ti-option-id'), 'id': selectedOption.parent().attr('ti-option-id'),
'msg': selectedOption.parent().find('textarea').val(), 'msg': selectedOption.parent().find('textarea').val(),
'type': 'plugin', 'type': 'plugin',
@ -719,7 +725,7 @@ class Uninstall_Feedback extends Abstract_Module {
* *
* @param array $options The options array. * @param array $options The options array.
*/ */
function randomize_options( $options ) { public function randomize_options( $options ) {
$new = array(); $new = array();
$keys = array_keys( $options ); $keys = array_keys( $options );
shuffle( $keys ); shuffle( $keys );
@ -734,7 +740,7 @@ class Uninstall_Feedback extends Abstract_Module {
/** /**
* Called when the deactivate button is clicked. * Called when the deactivate button is clicked.
*/ */
function post_deactivate() { public function post_deactivate() {
check_ajax_referer( (string) __CLASS__, 'nonce' ); check_ajax_referer( (string) __CLASS__, 'nonce' );
$this->post_deactivate_or_cancel(); $this->post_deactivate_or_cancel();
@ -748,8 +754,8 @@ class Uninstall_Feedback extends Abstract_Module {
$this->call_api( $this->call_api(
array( array(
'type' => 'deactivate', 'type' => 'deactivate',
'id' => $_POST['id'], 'id' => sanitize_key( $_POST['id'] ),
'comment' => isset( $_POST['msg'] ) ? $_POST['msg'] : '', 'comment' => isset( $_POST['msg'] ) ? sanitize_textarea_field( $_POST['msg'] ) : '',
) )
); );
wp_send_json( [] ); wp_send_json( [] );
@ -760,14 +766,14 @@ class Uninstall_Feedback extends Abstract_Module {
* Called when the deactivate/cancel button is clicked. * Called when the deactivate/cancel button is clicked.
*/ */
private function post_deactivate_or_cancel() { private function post_deactivate_or_cancel() {
if ( ! isset( $_POST['type'] ) || ! isset( $_POST['key'] ) ) { if ( ! isset( $_POST['type'] ) || ! isset( $_POST['key'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing, Nonce already present in caller function.
return; return;
} }
if ( 'theme' !== $_POST['type'] ) { if ( 'theme' !== $_POST['type'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing, Nonce already present in caller function.
return; return;
} }
set_transient( 'ti_sdk_pause_' . $_POST['key'], true, self::PAUSE_DEACTIVATE_WINDOW_DAYS * DAY_IN_SECONDS ); set_transient( 'ti_sdk_pause_' . sanitize_text_field( $_POST['key'] ), true, self::PAUSE_DEACTIVATE_WINDOW_DAYS * DAY_IN_SECONDS );//phpcs:ignore WordPress.Security.NonceVerification.Missing, Nonce already present in caller function.
} }

View File

@ -157,7 +157,7 @@ class Product {
* *
* @return string $name The normalized string. * @return string $name The normalized string.
*/ */
static function key_ready_name( $string ) { public static function key_ready_name( $string ) {
return str_replace( '-', '_', strtolower( trim( $string ) ) ); return str_replace( '-', '_', strtolower( trim( $string ) ) );
} }

View File

@ -13,25 +13,25 @@ namespace ThemeisleSDK;
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
$products = apply_filters( 'themeisle_sdk_products', array() ); $products = apply_filters( 'themeisle_sdk_products', array() );
$path = dirname( __FILE__ ); $themeisle_library_path = dirname( __FILE__ );
$files_to_load = [ $files_to_load = [
$path . '/src/' . 'Loader.php', $themeisle_library_path . '/src/Loader.php',
$path . '/src/' . 'Product.php', $themeisle_library_path . '/src/Product.php',
$path . '/src/' . 'Common/Abstract_module.php', $themeisle_library_path . '/src/Common/Abstract_module.php',
$path . '/src/' . 'Common/Module_factory.php', $themeisle_library_path . '/src/Common/Module_factory.php',
$path . '/src/' . 'Modules/Dashboard_widget.php', $themeisle_library_path . '/src/Modules/Dashboard_widget.php',
$path . '/src/' . 'Modules/Rollback.php', $themeisle_library_path . '/src/Modules/Rollback.php',
$path . '/src/' . 'Modules/Uninstall_feedback.php', $themeisle_library_path . '/src/Modules/Uninstall_feedback.php',
$path . '/src/' . 'Modules/Licenser.php', $themeisle_library_path . '/src/Modules/Licenser.php',
$path . '/src/' . 'Modules/Endpoint.php', $themeisle_library_path . '/src/Modules/Endpoint.php',
$path . '/src/' . 'Modules/Notification.php', $themeisle_library_path . '/src/Modules/Notification.php',
$path . '/src/' . 'Modules/Logger.php', $themeisle_library_path . '/src/Modules/Logger.php',
$path . '/src/' . 'Modules/Translate.php', $themeisle_library_path . '/src/Modules/Translate.php',
$path . '/src/' . 'Modules/Review.php', $themeisle_library_path . '/src/Modules/Review.php',
$path . '/src/' . 'Modules/Recommendation.php', $themeisle_library_path . '/src/Modules/Recommendation.php',
]; ];
$files_to_load = array_merge( $files_to_load, apply_filters( 'themeisle_sdk_required_files', [] ) ); $files_to_load = array_merge( $files_to_load, apply_filters( 'themeisle_sdk_required_files', [] ) );

View File

@ -37,11 +37,13 @@ namespace Composer\Autoload;
* *
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be> * @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/ * @see https://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/ * @see https://www.php-fig.org/psr/psr-4/
*/ */
class ClassLoader class ClassLoader
{ {
private $vendorDir;
// PSR-4 // PSR-4
private $prefixLengthsPsr4 = array(); private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array(); private $prefixDirsPsr4 = array();
@ -53,13 +55,21 @@ class ClassLoader
private $useIncludePath = false; private $useIncludePath = false;
private $classMap = array(); private $classMap = array();
private $classMapAuthoritative = false; private $classMapAuthoritative = false;
private $missingClasses = array();
private $apcuPrefix;
private static $registeredLoaders = array();
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
}
public function getPrefixes() public function getPrefixes()
{ {
if (!empty($this->prefixesPsr0)) { if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0); return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
} }
return array(); return array();
@ -271,6 +281,26 @@ class ClassLoader
return $this->classMapAuthoritative; return $this->classMapAuthoritative;
} }
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/** /**
* Registers this instance as an autoloader. * Registers this instance as an autoloader.
* *
@ -279,6 +309,17 @@ class ClassLoader
public function register($prepend = false) public function register($prepend = false)
{ {
spl_autoload_register(array($this, 'loadClass'), true, $prepend); spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
} }
/** /**
@ -287,6 +328,10 @@ class ClassLoader
public function unregister() public function unregister()
{ {
spl_autoload_unregister(array($this, 'loadClass')); spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
} }
/** /**
@ -313,34 +358,49 @@ class ClassLoader
*/ */
public function findFile($class) public function findFile($class)
{ {
// work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
if ('\\' == $class[0]) {
$class = substr($class, 1);
}
// class map lookup // class map lookup
if (isset($this->classMap[$class])) { if (isset($this->classMap[$class])) {
return $this->classMap[$class]; return $this->classMap[$class];
} }
if ($this->classMapAuthoritative) { if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false; return false;
} }
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php'); $file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM // Search for Hack files if we are running on HHVM
if ($file === null && defined('HHVM_VERSION')) { if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh'); $file = $this->findFileWithExtension($class, '.hh');
} }
if ($file === null) { if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist. // Remember that this class does not exist.
return $this->classMap[$class] = false; $this->missingClasses[$class] = true;
} }
return $file; return $file;
} }
/**
* Returns the currently registered loaders indexed by their corresponding vendor directories.
*
* @return self[]
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
private function findFileWithExtension($class, $ext) private function findFileWithExtension($class, $ext)
{ {
// PSR-4 lookup // PSR-4 lookup
@ -348,10 +408,14 @@ class ClassLoader
$first = $class[0]; $first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) { if (isset($this->prefixLengthsPsr4[$first])) {
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { $subPath = $class;
if (0 === strpos($class, $prefix)) { while (false !== $lastPos = strrpos($subPath, '\\')) {
foreach ($this->prefixDirsPsr4[$prefix] as $dir) { $subPath = substr($subPath, 0, $lastPos);
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { $search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file; return $file;
} }
} }
@ -399,6 +463,8 @@ class ClassLoader
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file; return $file;
} }
return false;
} }
} }

View File

@ -0,0 +1,331 @@
<?php
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
class InstalledVersions
{
private static $installed = array (
'root' =>
array (
'pretty_version' => 'v0.12.8',
'version' => '0.12.8.0',
'aliases' =>
array (
),
'reference' => 'f61cb2a3f967814d168c9a2a7725bbad1d26859a',
'name' => 'codeinwp/wp-menu-icons',
),
'versions' =>
array (
'codeinwp/gutenberg-menu-icons' =>
array (
'pretty_version' => '1.0.4',
'version' => '1.0.4.0',
'aliases' =>
array (
),
'reference' => '121ef82c57a556301265cbd1032d28619235e488',
),
'codeinwp/icon-picker' =>
array (
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'aliases' =>
array (
0 => '9999999-dev',
),
'reference' => '0c60ce3a41653e41a20e710c4d5a6a2104c85020',
),
'codeinwp/menu-item-custom-fields' =>
array (
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'aliases' =>
array (
0 => '9999999-dev',
),
'reference' => 'f491fcfa873e92006e3d92a4ede8775e9cf53bae',
),
'codeinwp/themeisle-sdk' =>
array (
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'aliases' =>
array (
0 => '9999999-dev',
),
'reference' => '24668ab249d8fb6596cc908c323205648aad0ed8',
),
'codeinwp/wp-menu-icons' =>
array (
'pretty_version' => 'v0.12.8',
'version' => '0.12.8.0',
'aliases' =>
array (
),
'reference' => 'f61cb2a3f967814d168c9a2a7725bbad1d26859a',
),
'composer/installers' =>
array (
'replaced' =>
array (
0 => '*',
),
),
),
);
private static $canGetVendors;
private static $installedByVendor = array();
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
public static function isInstalled($packageName)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return true;
}
}
return false;
}
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints($constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
public static function getRawData()
{
return self::$installed;
}
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
}
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
}
}
}
$installed[] = self::$installed;
return $installed;
}
}

View File

@ -1,5 +1,5 @@
Copyright (c) 2016 Nils Adermann, Jordi Boggiano Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir); $baseDir = dirname($vendorDir);
return array( return array(
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
); );

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer // autoload_real.php @generated by Composer
class ComposerAutoloaderInitabef56b0da707c7e3eaebd0d256cca29 class ComposerAutoloaderInit45b19aab4a02085424168fe90bd9d9df
{ {
private static $loader; private static $loader;
@ -13,43 +13,57 @@ class ComposerAutoloaderInitabef56b0da707c7e3eaebd0d256cca29
} }
} }
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader() public static function getLoader()
{ {
if (null !== self::$loader) { if (null !== self::$loader) {
return self::$loader; return self::$loader;
} }
spl_autoload_register(array('ComposerAutoloaderInitabef56b0da707c7e3eaebd0d256cca29', 'loadClassLoader'), true, true); spl_autoload_register(array('ComposerAutoloaderInit45b19aab4a02085424168fe90bd9d9df', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
spl_autoload_unregister(array('ComposerAutoloaderInitabef56b0da707c7e3eaebd0d256cca29', 'loadClassLoader')); spl_autoload_unregister(array('ComposerAutoloaderInit45b19aab4a02085424168fe90bd9d9df', 'loadClassLoader'));
$map = require __DIR__ . '/autoload_namespaces.php'; $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
foreach ($map as $namespace => $path) { if ($useStaticLoader) {
$loader->set($namespace, $path); require __DIR__ . '/autoload_static.php';
}
$map = require __DIR__ . '/autoload_psr4.php'; call_user_func(\Composer\Autoload\ComposerStaticInit45b19aab4a02085424168fe90bd9d9df::getInitializer($loader));
foreach ($map as $namespace => $path) { } else {
$loader->setPsr4($namespace, $path); $map = require __DIR__ . '/autoload_namespaces.php';
} foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php'; $map = require __DIR__ . '/autoload_psr4.php';
if ($classMap) { foreach ($map as $namespace => $path) {
$loader->addClassMap($classMap); $loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
} }
$loader->register(true); $loader->register(true);
$includeFiles = require __DIR__ . '/autoload_files.php'; if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit45b19aab4a02085424168fe90bd9d9df::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) { foreach ($includeFiles as $fileIdentifier => $file) {
composerRequireabef56b0da707c7e3eaebd0d256cca29($fileIdentifier, $file); composerRequire45b19aab4a02085424168fe90bd9d9df($fileIdentifier, $file);
} }
return $loader; return $loader;
} }
} }
function composerRequireabef56b0da707c7e3eaebd0d256cca29($fileIdentifier, $file) function composerRequire45b19aab4a02085424168fe90bd9d9df($fileIdentifier, $file)
{ {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file; require $file;

View File

@ -0,0 +1,27 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInit45b19aab4a02085424168fe90bd9d9df
{
public static $files = array (
'2c2d2fe92db4cd03403dbb108ac263b7' => __DIR__ . '/..' . '/codeinwp/gutenberg-menu-icons/load.php',
'0498965e576e4ec1efaedeccfee8b5f0' => __DIR__ . '/..' . '/codeinwp/menu-item-custom-fields/menu-item-custom-fields.php',
'347e48cf03d89942a6ddafc17d247b11' => __DIR__ . '/..' . '/codeinwp/icon-picker/icon-picker.php',
'5a095c604245b0e67e4573f0a3b240cd' => __DIR__ . '/..' . '/codeinwp/themeisle-sdk/load.php',
);
public static $classMap = array (
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->classMap = ComposerStaticInit45b19aab4a02085424168fe90bd9d9df::$classMap;
}, null, ClassLoader::class);
}
}

View File

@ -1,164 +1,187 @@
[ {
{ "packages": [
"name": "codeinwp/icon-picker", {
"version": "dev-master", "name": "codeinwp/gutenberg-menu-icons",
"version_normalized": "9999999-dev", "version": "1.0.4",
"source": { "version_normalized": "1.0.4.0",
"type": "git", "source": {
"url": "https://github.com/Codeinwp/icon-picker.git", "type": "git",
"reference": "980abcd0325414f6264ac62320990bf10a3ceb8f" "url": "https://github.com/Codeinwp/gutenberg-menu-icons.git",
"reference": "121ef82c57a556301265cbd1032d28619235e488"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Codeinwp/gutenberg-menu-icons/zipball/121ef82c57a556301265cbd1032d28619235e488",
"reference": "121ef82c57a556301265cbd1032d28619235e488",
"shasum": ""
},
"require-dev": {
"automattic/vipwpcs": "^0.3.0 || ^1.0.0",
"dealerdirect/phpcodesniffer-composer-installer": "0.6.2",
"phpcompatibility/php-compatibility": "^9",
"squizlabs/php_codesniffer": "^3.3",
"wp-coding-standards/wpcs": "^1"
},
"time": "2020-05-17T21:08:46+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"files": [
"load.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0-or-later"
],
"authors": [
{
"name": "ThemeIsle team",
"email": "friends@themeisle.com",
"homepage": "https://themeisle.com"
}
],
"description": "Menu Icons for Gutenberg",
"homepage": "https://github.com/Codeinwp/gutenberg-menu-icons",
"support": {
"issues": "https://github.com/Codeinwp/gutenberg-menu-icons/issues",
"source": "https://github.com/Codeinwp/gutenberg-menu-icons/tree/v1.0.4"
},
"install-path": "../codeinwp/gutenberg-menu-icons"
}, },
"dist": { {
"type": "zip", "name": "codeinwp/icon-picker",
"url": "https://api.github.com/repos/Codeinwp/icon-picker/zipball/980abcd0325414f6264ac62320990bf10a3ceb8f", "version": "dev-master",
"reference": "980abcd0325414f6264ac62320990bf10a3ceb8f", "version_normalized": "dev-master",
"shasum": "" "source": {
"type": "git",
"url": "https://github.com/Codeinwp/icon-picker.git",
"reference": "0c60ce3a41653e41a20e710c4d5a6a2104c85020"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Codeinwp/icon-picker/zipball/0c60ce3a41653e41a20e710c4d5a6a2104c85020",
"reference": "0c60ce3a41653e41a20e710c4d5a6a2104c85020",
"shasum": ""
},
"require": {
"composer/installers": "~1.0"
},
"require-dev": {
"wp-coding-standards/wpcs": "^0.10.0"
},
"time": "2021-05-05T18:52:26+00:00",
"default-branch": true,
"type": "wordpress-plugin",
"installation-source": "dist",
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0"
],
"description": "Pick an icon of your choice.",
"homepage": "https://github.com/codeinwp/icon-picker",
"keywords": [
"dashicons",
"elusive",
"font-awesome",
"foundation-icons",
"genericons",
"icons",
"plugin",
"wordpress"
],
"support": {
"source": "https://github.com/Codeinwp/icon-picker/tree/master"
},
"install-path": "../codeinwp/icon-picker"
}, },
"require": { {
"composer/installers": "~1.0" "name": "codeinwp/menu-item-custom-fields",
"version": "dev-master",
"version_normalized": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/Codeinwp/menu-item-custom-fields.git",
"reference": "f491fcfa873e92006e3d92a4ede8775e9cf53bae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Codeinwp/menu-item-custom-fields/zipball/f491fcfa873e92006e3d92a4ede8775e9cf53bae",
"reference": "f491fcfa873e92006e3d92a4ede8775e9cf53bae",
"shasum": ""
},
"require": {
"composer/installers": "~1.0"
},
"require-dev": {
"wp-coding-standards/wpcs": "^0.10.0"
},
"time": "2021-05-05T18:49:57+00:00",
"default-branch": true,
"type": "wordpress-plugin",
"installation-source": "dist",
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0"
],
"description": "Easily add custom fields to nav menu items.",
"homepage": "https://github.com/Codeinwp/wp-menu-item-custom-fields",
"keywords": [
"custom-fields",
"menu",
"plugin",
"wordpress"
],
"support": {
"source": "https://github.com/Codeinwp/menu-item-custom-fields/tree/master"
},
"install-path": "../codeinwp/menu-item-custom-fields"
}, },
"require-dev": { {
"wp-coding-standards/wpcs": "^0.10.0" "name": "codeinwp/themeisle-sdk",
}, "version": "dev-master",
"time": "2019-11-15 16:51:01", "version_normalized": "dev-master",
"type": "wordpress-plugin", "source": {
"installation-source": "source", "type": "git",
"notification-url": "https://packagist.org/downloads/", "url": "https://github.com/Codeinwp/themeisle-sdk.git",
"license": [ "reference": "24668ab249d8fb6596cc908c323205648aad0ed8"
"GPL-2.0" },
], "dist": {
"description": "Pick an icon of your choice.", "type": "zip",
"homepage": "https://github.com/codeinwp/icon-picker", "url": "https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/24668ab249d8fb6596cc908c323205648aad0ed8",
"keywords": [ "reference": "24668ab249d8fb6596cc908c323205648aad0ed8",
"dashicons", "shasum": ""
"elusive", },
"font-awesome", "require-dev": {
"foundation-icons", "codeinwp/phpcs-ruleset": "dev-main"
"genericons", },
"icons", "time": "2021-05-05T17:45:51+00:00",
"plugin", "default-branch": true,
"wordpress" "type": "library",
] "installation-source": "dist",
}, "notification-url": "https://packagist.org/downloads/",
{ "license": [
"name": "codeinwp/menu-item-custom-fields", "GPL-2.0+"
"version": "dev-master", ],
"version_normalized": "9999999-dev", "authors": [
"source": { {
"type": "git", "name": "ThemeIsle team",
"url": "https://github.com/Codeinwp/menu-item-custom-fields.git", "email": "friends@themeisle.com",
"reference": "26a5849e5b60556fe577afa3622fff512b5826c4" "homepage": "https://themeisle.com"
}, }
"dist": { ],
"type": "zip", "description": "ThemeIsle SDK",
"url": "https://api.github.com/repos/Codeinwp/menu-item-custom-fields/zipball/26a5849e5b60556fe577afa3622fff512b5826c4", "homepage": "https://github.com/Codeinwp/themeisle-sdk",
"reference": "26a5849e5b60556fe577afa3622fff512b5826c4", "keywords": [
"shasum": "" "wordpress"
}, ],
"require": { "support": {
"composer/installers": "~1.0" "issues": "https://github.com/Codeinwp/themeisle-sdk/issues",
}, "source": "https://github.com/Codeinwp/themeisle-sdk/tree/master"
"require-dev": { },
"wp-coding-standards/wpcs": "^0.10.0" "install-path": "../codeinwp/themeisle-sdk"
}, }
"time": "2020-04-27 19:54:38", ],
"type": "wordpress-plugin", "dev": false,
"installation-source": "source", "dev-package-names": []
"notification-url": "https://packagist.org/downloads/", }
"license": [
"GPL-2.0"
],
"description": "Easily add custom fields to nav menu items.",
"homepage": "https://github.com/Codeinwp/wp-menu-item-custom-fields",
"keywords": [
"custom-fields",
"menu",
"plugin",
"wordpress"
]
},
{
"name": "codeinwp/themeisle-sdk",
"version": "3.2.15",
"version_normalized": "3.2.15.0",
"source": {
"type": "git",
"url": "https://github.com/Codeinwp/themeisle-sdk.git",
"reference": "95b7447a5f4faba410c281c4bf278fbd740fed71"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/95b7447a5f4faba410c281c4bf278fbd740fed71",
"reference": "95b7447a5f4faba410c281c4bf278fbd740fed71",
"shasum": ""
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
"squizlabs/php_codesniffer": "^3.1",
"wp-coding-standards/wpcs": "^1.0.0"
},
"time": "2020-07-23 15:02:10",
"type": "library",
"installation-source": "dist",
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0+"
],
"authors": [
{
"name": "ThemeIsle team",
"email": "friends@themeisle.com",
"homepage": "https://themeisle.com"
}
],
"description": "ThemeIsle SDK.",
"homepage": "https://github.com/Codeinwp/themeisle-sdk",
"keywords": [
"wordpress"
]
},
{
"name": "codeinwp/gutenberg-menu-icons",
"version": "1.0.4",
"version_normalized": "1.0.4.0",
"source": {
"type": "git",
"url": "https://github.com/Codeinwp/gutenberg-menu-icons.git",
"reference": "121ef82c57a556301265cbd1032d28619235e488"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Codeinwp/gutenberg-menu-icons/zipball/121ef82c57a556301265cbd1032d28619235e488",
"reference": "121ef82c57a556301265cbd1032d28619235e488",
"shasum": ""
},
"require-dev": {
"automattic/vipwpcs": "^0.3.0 || ^1.0.0",
"dealerdirect/phpcodesniffer-composer-installer": "0.6.2",
"phpcompatibility/php-compatibility": "^9",
"squizlabs/php_codesniffer": "^3.3",
"wp-coding-standards/wpcs": "^1"
},
"time": "2020-05-17 21:08:46",
"type": "library",
"installation-source": "dist",
"autoload": {
"files": [
"load.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0-or-later"
],
"authors": [
{
"name": "ThemeIsle team",
"email": "friends@themeisle.com",
"homepage": "https://themeisle.com"
}
],
"description": "Menu Icons for Gutenberg",
"homepage": "https://github.com/Codeinwp/gutenberg-menu-icons"
}
]

View File

@ -0,0 +1,70 @@
<?php return array (
'root' =>
array (
'pretty_version' => 'v0.12.8',
'version' => '0.12.8.0',
'aliases' =>
array (
),
'reference' => 'f61cb2a3f967814d168c9a2a7725bbad1d26859a',
'name' => 'codeinwp/wp-menu-icons',
),
'versions' =>
array (
'codeinwp/gutenberg-menu-icons' =>
array (
'pretty_version' => '1.0.4',
'version' => '1.0.4.0',
'aliases' =>
array (
),
'reference' => '121ef82c57a556301265cbd1032d28619235e488',
),
'codeinwp/icon-picker' =>
array (
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'aliases' =>
array (
0 => '9999999-dev',
),
'reference' => '0c60ce3a41653e41a20e710c4d5a6a2104c85020',
),
'codeinwp/menu-item-custom-fields' =>
array (
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'aliases' =>
array (
0 => '9999999-dev',
),
'reference' => 'f491fcfa873e92006e3d92a4ede8775e9cf53bae',
),
'codeinwp/themeisle-sdk' =>
array (
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'aliases' =>
array (
0 => '9999999-dev',
),
'reference' => '24668ab249d8fb6596cc908c323205648aad0ed8',
),
'codeinwp/wp-menu-icons' =>
array (
'pretty_version' => 'v0.12.8',
'version' => '0.12.8.0',
'aliases' =>
array (
),
'reference' => 'f61cb2a3f967814d168c9a2a7725bbad1d26859a',
),
'composer/installers' =>
array (
'replaced' =>
array (
0 => '*',
),
),
),
);