ThemeGrill Demo Importer - Version 1.0

Version Description

Download this release

Release Info

Developer ThemeGrill
Plugin Icon 128x128 ThemeGrill Demo Importer
Version 1.0
Comparing to
See all releases

Version 1.0

Files changed (30) hide show
  1. assets/css/demo-importer.css +1 -0
  2. assets/css/demo-importer.scss +154 -0
  3. assets/images/colormag/colormag-free.jpg +0 -0
  4. assets/images/flash/flash-construction.jpg +0 -0
  5. assets/images/flash/flash-default.jpg +0 -0
  6. assets/images/flash/flash-food.jpg +0 -0
  7. assets/images/flash/flash-onepage.jpg +0 -0
  8. assets/images/spacious/spacious-free.jpg +0 -0
  9. assets/js/admin/demo-importer.js +96 -0
  10. assets/js/admin/demo-importer.min.js +1 -0
  11. assets/js/jquery-tiptip/jquery.tipTip.js +191 -0
  12. assets/js/jquery-tiptip/jquery.tipTip.min.js +1 -0
  13. includes/class-demo-importer.php +690 -0
  14. includes/includes/admin/class-demo-installer-skin.php +64 -0
  15. includes/includes/admin/class-demo-upgrader.php +349 -0
  16. includes/includes/admin/views/html-admin-page-importer-previews.php +40 -0
  17. includes/includes/admin/views/html-admin-page-importer-uploaded.php +72 -0
  18. includes/includes/admin/views/html-admin-page-importer-welcome.php +29 -0
  19. includes/includes/admin/views/html-admin-page-importer.php +63 -0
  20. includes/includes/class-customizer-importer.php +176 -0
  21. includes/includes/class-widget-importer.php +237 -0
  22. includes/includes/customize/class-oc-customize-demo-importer-setting.php +24 -0
  23. includes/includes/functions-demo-importer.php +272 -0
  24. includes/includes/importers/class-wxr-importer.php +1232 -0
  25. includes/includes/importers/class-wxr-parsers.php +693 -0
  26. languages/themegrill-demo-importer.pot +485 -0
  27. license.txt +702 -0
  28. readme.txt +44 -0
  29. themegrill-demo-importer.php +190 -0
  30. uninstall.php +18 -0
assets/css/demo-importer.css ADDED
@@ -0,0 +1 @@
1
+ .appearance_page_demo-importer .wp-filter{padding:0 20px}.appearance_page_demo-importer .wp-filter .filter-links li>a:focus{box-shadow:none}.theme-browser .theme .theme-actions span.spinner{display:none}.theme-browser .theme .theme-actions.imported,.theme-browser .theme .theme-actions.importing{opacity:1}.theme-browser .theme .theme-actions.imported .button,.theme-browser .theme .theme-actions.importing .button,.theme-browser .theme:not(.active) .theme-actions .preview{display:none;visibility:hidden}.theme-browser .theme:not(.active) .theme-actions.imported .preview{display:block;visibility:visible}.theme-browser .theme .theme-actions.importing span.spinner.is-active{width:auto;display:block;font-size:12px;padding-right:25px;background-position:right center}@media only screen and (max-width:780px){.theme-browser .theme .theme-actions.imported{opacity:0}}.theme .notice,.theme .notice.is-dismissible{left:0;margin:0;position:absolute;right:0;top:0}.theme .notice-success p::before{color:#79ba49;content:'\f147';margin-right:6px;vertical-align:top;display:inline-block;font:400 20px/1 dashicons;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.tips{cursor:help;text-decoration:none}img.tips{padding:5px 0 0}#tiptip_holder{display:none;position:absolute;top:0;left:0;z-index:9999999}#tiptip_holder.tip_top{padding-bottom:5px}#tiptip_holder.tip_top #tiptip_arrow_inner{margin-top:-7px;margin-left:-6px;border-top-color:#333}#tiptip_holder.tip_bottom{padding-top:5px}#tiptip_holder.tip_bottom #tiptip_arrow_inner{margin-top:-5px;margin-left:-6px;border-bottom-color:#333}#tiptip_holder.tip_right{padding-left:5px}#tiptip_holder.tip_right #tiptip_arrow_inner{margin-top:-6px;margin-left:-5px;border-right-color:#333}#tiptip_holder.tip_left{padding-right:5px}#tiptip_holder.tip_left #tiptip_arrow_inner{margin-top:-6px;margin-left:-7px;border-left-color:#333}#tiptip_content{color:#fff;font-size:.8em;max-width:150px;background:#333;text-align:center;border-radius:3px;padding:.618em 1em;box-shadow:0 1px 3px rgba(0,0,0,.2)}#tiptip_content code{padding:1px;background:#888}#tiptip_arrow,#tiptip_arrow_inner{position:absolute;border-color:transparent;border-style:solid;border-width:6px;height:0;width:0}
assets/css/demo-importer.scss ADDED
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Styling begins.
3
+ */
4
+ .appearance_page_demo-importer .wp-filter {
5
+ padding: 0 20px;
6
+
7
+ .filter-links li > a:focus {
8
+ box-shadow: none;
9
+ }
10
+ }
11
+
12
+ .theme-browser .theme .theme-actions span.spinner {
13
+ display: none;
14
+ }
15
+
16
+ .theme-browser .theme .theme-actions.imported,
17
+ .theme-browser .theme .theme-actions.importing {
18
+ opacity: 1;
19
+ }
20
+
21
+ .theme-browser .theme .theme-actions.imported .button,
22
+ .theme-browser .theme .theme-actions.importing .button,
23
+ .theme-browser .theme:not( .active ) .theme-actions .preview {
24
+ display: none;
25
+ visibility: hidden;
26
+ }
27
+
28
+ .theme-browser .theme:not( .active ) .theme-actions.imported .preview {
29
+ display: block;
30
+ visibility: visible;
31
+ }
32
+
33
+ .theme-browser .theme .theme-actions.importing span.spinner.is-active {
34
+ width: auto;
35
+ display: block;
36
+ font-size: 12px;
37
+ padding-right: 25px;
38
+ background-position: right center;
39
+ }
40
+
41
+ @media only screen and (max-width: 780px) {
42
+ .theme-browser .theme .theme-actions.imported {
43
+ opacity: 0;
44
+ }
45
+ }
46
+
47
+ /* Position admin messages */
48
+ .theme .notice,
49
+ .theme .notice.is-dismissible {
50
+ left: 0;
51
+ margin: 0;
52
+ position: absolute;
53
+ right: 0;
54
+ top: 0;
55
+ }
56
+
57
+ .theme .notice-success p::before {
58
+ color: #79ba49;
59
+ content: '\f147';
60
+ margin-right: 6px;
61
+ vertical-align: top;
62
+ display: inline-block;
63
+ font: normal 20px/1 'dashicons';
64
+ -webkit-font-smoothing: antialiased;
65
+ -moz-osx-font-smoothing: grayscale;
66
+ }
67
+
68
+ /**
69
+ * Tooltips
70
+ */
71
+ .tips {
72
+ cursor: help;
73
+ text-decoration: none;
74
+ }
75
+
76
+ img.tips {
77
+ padding: 5px 0 0;
78
+ }
79
+
80
+ #tiptip_holder {
81
+ display: none;
82
+ position: absolute;
83
+ top: 0;
84
+ left: 0;
85
+ z-index: 9999999;
86
+ }
87
+
88
+ #tiptip_holder {
89
+ &.tip_top {
90
+ padding-bottom: 5px;
91
+
92
+ #tiptip_arrow_inner {
93
+ margin-top: -7px;
94
+ margin-left: -6px;
95
+ border-top-color: #333;
96
+ }
97
+ }
98
+
99
+ &.tip_bottom {
100
+ padding-top: 5px;
101
+
102
+ #tiptip_arrow_inner {
103
+ margin-top: -5px;
104
+ margin-left: -6px;
105
+ border-bottom-color: #333;
106
+ }
107
+ }
108
+
109
+ &.tip_right {
110
+ padding-left: 5px;
111
+
112
+ #tiptip_arrow_inner {
113
+ margin-top: -6px;
114
+ margin-left: -5px;
115
+ border-right-color: #333;
116
+ }
117
+ }
118
+
119
+ &.tip_left {
120
+ padding-right: 5px;
121
+
122
+ #tiptip_arrow_inner {
123
+ margin-top: -6px;
124
+ margin-left: -7px;
125
+ border-left-color: #333;
126
+ }
127
+ }
128
+ }
129
+
130
+ #tiptip_content {
131
+ color: #fff;
132
+ font-size: 0.8em;
133
+ max-width: 150px;
134
+ background: #333;
135
+ text-align: center;
136
+ border-radius: 3px;
137
+ padding: 0.618em 1em;
138
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
139
+
140
+ code {
141
+ padding: 1px;
142
+ background: #888;
143
+ }
144
+ }
145
+
146
+ #tiptip_arrow,
147
+ #tiptip_arrow_inner {
148
+ position: absolute;
149
+ border-color: transparent;
150
+ border-style: solid;
151
+ border-width: 6px;
152
+ height: 0;
153
+ width: 0;
154
+ }
assets/images/colormag/colormag-free.jpg ADDED
Binary file
assets/images/flash/flash-construction.jpg ADDED
Binary file
assets/images/flash/flash-default.jpg ADDED
Binary file
assets/images/flash/flash-food.jpg ADDED
Binary file
assets/images/flash/flash-onepage.jpg ADDED
Binary file
assets/images/spacious/spacious-free.jpg ADDED
Binary file
assets/js/admin/demo-importer.js ADDED
@@ -0,0 +1,96 @@
1
+ /* global demo_importer_params */
2
+ jQuery( function ( $ ) {
3
+
4
+ var tg_demo_importer = {
5
+ init: function() {
6
+ this.uploader();
7
+ this.init_tiptip();
8
+
9
+ // Trigger importer events.
10
+ $( '.theme-actions' ).on( 'click', '.import', this.process_import );
11
+ $( '.notice.is-dismissible' ).on( 'click', '.notice-dismiss', this.dismiss_notice );
12
+ },
13
+ uploader: function() {
14
+ var uploadViewToggle = $( '.upload-view-toggle' ),
15
+ $body = $( document.body );
16
+
17
+ uploadViewToggle.on( 'click', function() {
18
+ // Toggle the upload view.
19
+ $body.toggleClass( 'show-upload-view' );
20
+ // Toggle the `aria-expanded` button attribute.
21
+ uploadViewToggle.attr( 'aria-expanded', $body.hasClass( 'show-upload-view' ) );
22
+ });
23
+ },
24
+ init_tiptip: function() {
25
+ $( '#tiptip_holder' ).removeAttr( 'style' );
26
+ $( '#tiptip_arrow' ).removeAttr( 'style' );
27
+ $( '.tips' ).tipTip({ 'attribute': 'data-tip', 'fadeIn': 50, 'fadeOut': 50, 'delay': 200 });
28
+ },
29
+ process_import: function( e ) {
30
+ e.preventDefault();
31
+
32
+ var $this_el = $( this );
33
+
34
+ if ( ! $this_el.hasClass( 'disabled' ) ) {
35
+ if ( window.confirm( demo_importer_params.i18n_import_dummy_data ) ) {
36
+
37
+ var data = {
38
+ action: 'tg_import_demo_data',
39
+ demo_id: $this_el.data( 'demo_id' ),
40
+ security: demo_importer_params.import_demo_data_nonce
41
+ };
42
+
43
+ $.ajax({
44
+ url: demo_importer_params.ajax_url,
45
+ data: data,
46
+ type: 'POST',
47
+ beforeSend: function() {
48
+ $this_el.parent().addClass( 'importing' );
49
+ $this_el.parent().find( '.spinner' ).addClass( 'is-active' );
50
+ },
51
+ success: function( response ) {
52
+ $this_el.closest( '.theme' ).find( '.notice' ).remove();
53
+ $this_el.parent().find( '.spinner' ).removeClass( 'is-active' );
54
+ $this_el.parent().removeClass( 'importing' ).addClass( 'imported' );
55
+
56
+ // Display import message.
57
+ if ( true === response.success ) {
58
+ $this_el.closest( '.theme' ).append( '<div class="notice notice-success notice-alt"><p>' + response.data.message + '</p></div>' );
59
+ } else {
60
+ $this_el.closest( '.theme' ).append( '<div class="update-message notice notice-error notice-alt"><p>' + demo_importer_params.i18n_import_data_error + '</p></div>' );
61
+ }
62
+ },
63
+ error: function( jqXHR, textStatus, errorThrown ) {
64
+ $this_el.closest( '.theme' ).find( '.notice' ).remove();
65
+ $this_el.parent().find( '.spinner' ).removeClass( 'is-active' );
66
+ $this_el.parent().removeClass( 'importing' ).addClass( 'imported' );
67
+
68
+ // Display error message.
69
+ $this_el.closest( '.theme' ).append( '<div class="update-message notice notice-error notice-alt"><p>' + errorThrown + '</p></div>' );
70
+ }
71
+ });
72
+ }
73
+
74
+ return false;
75
+ }
76
+ },
77
+ dismiss_notice: function( e ) {
78
+ e.preventDefault();
79
+
80
+ var $this_el = $( this );
81
+
82
+ if ( $this_el.parent().attr( 'id' ) === 'undefined' ) {
83
+ return;
84
+ }
85
+
86
+ $.post( demo_importer_params.ajax_url, {
87
+ action: 'tg_dismiss_notice',
88
+ notice_id: $this_el.parent().data( 'notice_id' )
89
+ });
90
+
91
+ return false;
92
+ }
93
+ };
94
+
95
+ tg_demo_importer.init();
96
+ });
assets/js/admin/demo-importer.min.js ADDED
@@ -0,0 +1 @@
1
+ jQuery(function(a){var b={init:function(){this.uploader(),this.init_tiptip(),a(".theme-actions").on("click",".import",this.process_import),a(".notice.is-dismissible").on("click",".notice-dismiss",this.dismiss_notice)},uploader:function(){var b=a(".upload-view-toggle"),c=a(document.body);b.on("click",function(){c.toggleClass("show-upload-view"),b.attr("aria-expanded",c.hasClass("show-upload-view"))})},init_tiptip:function(){a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200})},process_import:function(b){b.preventDefault();var c=a(this);if(!c.hasClass("disabled")){if(window.confirm(demo_importer_params.i18n_import_dummy_data)){var d={action:"tg_import_demo_data",demo_id:c.data("demo_id"),security:demo_importer_params.import_demo_data_nonce};a.ajax({url:demo_importer_params.ajax_url,data:d,type:"POST",beforeSend:function(){c.parent().addClass("importing"),c.parent().find(".spinner").addClass("is-active")},success:function(a){c.closest(".theme").find(".notice").remove(),c.parent().find(".spinner").removeClass("is-active"),c.parent().removeClass("importing").addClass("imported"),!0===a.success?c.closest(".theme").append('<div class="notice notice-success notice-alt"><p>'+a.data.message+"</p></div>"):c.closest(".theme").append('<div class="update-message notice notice-error notice-alt"><p>'+demo_importer_params.i18n_import_data_error+"</p></div>")},error:function(a,b,d){c.closest(".theme").find(".notice").remove(),c.parent().find(".spinner").removeClass("is-active"),c.parent().removeClass("importing").addClass("imported"),c.closest(".theme").append('<div class="update-message notice notice-error notice-alt"><p>'+d+"</p></div>")}})}return!1}},dismiss_notice:function(b){b.preventDefault();var c=a(this);if("undefined"!==c.parent().attr("id"))return a.post(demo_importer_params.ajax_url,{action:"tg_dismiss_notice",notice_id:c.parent().data("notice_id")}),!1}};b.init()});
assets/js/jquery-tiptip/jquery.tipTip.js ADDED
@@ -0,0 +1,191 @@
1
+ /*
2
+ * TipTip
3
+ * Copyright 2010 Drew Wilson
4
+ * www.drewwilson.com
5
+ * code.drewwilson.com/entry/tiptip-jquery-plugin
6
+ *
7
+ * Version 1.3 - Updated: Mar. 23, 2010
8
+ *
9
+ * This Plug-In will create a custom tooltip to replace the default
10
+ * browser tooltip. It is extremely lightweight and very smart in
11
+ * that it detects the edges of the browser window and will make sure
12
+ * the tooltip stays within the current window size. As a result the
13
+ * tooltip will adjust itself to be displayed above, below, to the left
14
+ * or to the right depending on what is necessary to stay within the
15
+ * browser window. It is completely customizable as well via CSS.
16
+ *
17
+ * This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses:
18
+ * http://www.opensource.org/licenses/mit-license.php
19
+ * http://www.gnu.org/licenses/gpl.html
20
+ */
21
+
22
+ (function($){
23
+ $.fn.tipTip = function(options) {
24
+ var defaults = {
25
+ activation: "hover",
26
+ keepAlive: false,
27
+ maxWidth: "200px",
28
+ edgeOffset: 3,
29
+ defaultPosition: "bottom",
30
+ delay: 400,
31
+ fadeIn: 200,
32
+ fadeOut: 200,
33
+ attribute: "title",
34
+ content: false, // HTML or String to fill TipTIp with
35
+ enter: function(){},
36
+ exit: function(){}
37
+ };
38
+ var opts = $.extend(defaults, options);
39
+
40
+ // Setup tip tip elements and render them to the DOM
41
+ if($("#tiptip_holder").length <= 0){
42
+ var tiptip_holder = $('<div id="tiptip_holder" style="max-width:'+ opts.maxWidth +';"></div>');
43
+ var tiptip_content = $('<div id="tiptip_content"></div>');
44
+ var tiptip_arrow = $('<div id="tiptip_arrow"></div>');
45
+ $("body").append(tiptip_holder.html(tiptip_content).prepend(tiptip_arrow.html('<div id="tiptip_arrow_inner"></div>')));
46
+ } else {
47
+ var tiptip_holder = $("#tiptip_holder");
48
+ var tiptip_content = $("#tiptip_content");
49
+ var tiptip_arrow = $("#tiptip_arrow");
50
+ }
51
+
52
+ return this.each(function(){
53
+ var org_elem = $(this);
54
+ if(opts.content){
55
+ var org_title = opts.content;
56
+ } else {
57
+ var org_title = org_elem.attr(opts.attribute);
58
+ }
59
+ if(org_title != ""){
60
+ if(!opts.content){
61
+ org_elem.removeAttr(opts.attribute); //remove original Attribute
62
+ }
63
+ var timeout = false;
64
+
65
+ if(opts.activation == "hover"){
66
+ org_elem.hover(function(){
67
+ active_tiptip();
68
+ }, function(){
69
+ if(!opts.keepAlive){
70
+ deactive_tiptip();
71
+ }
72
+ });
73
+ if(opts.keepAlive){
74
+ tiptip_holder.hover(function(){}, function(){
75
+ deactive_tiptip();
76
+ });
77
+ }
78
+ } else if(opts.activation == "focus"){
79
+ org_elem.focus(function(){
80
+ active_tiptip();
81
+ }).blur(function(){
82
+ deactive_tiptip();
83
+ });
84
+ } else if(opts.activation == "click"){
85
+ org_elem.click(function(){
86
+ active_tiptip();
87
+ return false;
88
+ }).hover(function(){},function(){
89
+ if(!opts.keepAlive){
90
+ deactive_tiptip();
91
+ }
92
+ });
93
+ if(opts.keepAlive){
94
+ tiptip_holder.hover(function(){}, function(){
95
+ deactive_tiptip();
96
+ });
97
+ }
98
+ }
99
+
100
+ function active_tiptip(){
101
+ opts.enter.call(this);
102
+ tiptip_content.html(org_title);
103
+ tiptip_holder.hide().removeAttr("class").css("margin","0");
104
+ tiptip_arrow.removeAttr("style");
105
+
106
+ var top = parseInt(org_elem.offset()['top']);
107
+ var left = parseInt(org_elem.offset()['left']);
108
+ var org_width = parseInt(org_elem.outerWidth());
109
+ var org_height = parseInt(org_elem.outerHeight());
110
+ var tip_w = tiptip_holder.outerWidth();
111
+ var tip_h = tiptip_holder.outerHeight();
112
+ var w_compare = Math.round((org_width - tip_w) / 2);
113
+ var h_compare = Math.round((org_height - tip_h) / 2);
114
+ var marg_left = Math.round(left + w_compare);
115
+ var marg_top = Math.round(top + org_height + opts.edgeOffset);
116
+ var t_class = "";
117
+ var arrow_top = "";
118
+ var arrow_left = Math.round(tip_w - 12) / 2;
119
+
120
+ if(opts.defaultPosition == "bottom"){
121
+ t_class = "_bottom";
122
+ } else if(opts.defaultPosition == "top"){
123
+ t_class = "_top";
124
+ } else if(opts.defaultPosition == "left"){
125
+ t_class = "_left";
126
+ } else if(opts.defaultPosition == "right"){
127
+ t_class = "_right";
128
+ }
129
+
130
+ var right_compare = (w_compare + left) < parseInt($(window).scrollLeft());
131
+ var left_compare = (tip_w + left) > parseInt($(window).width());
132
+
133
+ if((right_compare && w_compare < 0) || (t_class == "_right" && !left_compare) || (t_class == "_left" && left < (tip_w + opts.edgeOffset + 5))){
134
+ t_class = "_right";
135
+ arrow_top = Math.round(tip_h - 13) / 2;
136
+ arrow_left = -12;
137
+ marg_left = Math.round(left + org_width + opts.edgeOffset);
138
+ marg_top = Math.round(top + h_compare);
139
+ } else if((left_compare && w_compare < 0) || (t_class == "_left" && !right_compare)){
140
+ t_class = "_left";
141
+ arrow_top = Math.round(tip_h - 13) / 2;
142
+ arrow_left = Math.round(tip_w);
143
+ marg_left = Math.round(left - (tip_w + opts.edgeOffset + 5));
144
+ marg_top = Math.round(top + h_compare);
145
+ }
146
+
147
+ var top_compare = (top + org_height + opts.edgeOffset + tip_h + 8) > parseInt($(window).height() + $(window).scrollTop());
148
+ var bottom_compare = ((top + org_height) - (opts.edgeOffset + tip_h + 8)) < 0;
149
+
150
+ if(top_compare || (t_class == "_bottom" && top_compare) || (t_class == "_top" && !bottom_compare)){
151
+ if(t_class == "_top" || t_class == "_bottom"){
152
+ t_class = "_top";
153
+ } else {
154
+ t_class = t_class+"_top";
155
+ }
156
+ arrow_top = tip_h;
157
+ marg_top = Math.round(top - (tip_h + 5 + opts.edgeOffset));
158
+ } else if(bottom_compare | (t_class == "_top" && bottom_compare) || (t_class == "_bottom" && !top_compare)){
159
+ if(t_class == "_top" || t_class == "_bottom"){
160
+ t_class = "_bottom";
161
+ } else {
162
+ t_class = t_class+"_bottom";
163
+ }
164
+ arrow_top = -12;
165
+ marg_top = Math.round(top + org_height + opts.edgeOffset);
166
+ }
167
+
168
+ if(t_class == "_right_top" || t_class == "_left_top"){
169
+ marg_top = marg_top + 5;
170
+ } else if(t_class == "_right_bottom" || t_class == "_left_bottom"){
171
+ marg_top = marg_top - 5;
172
+ }
173
+ if(t_class == "_left_top" || t_class == "_left_bottom"){
174
+ marg_left = marg_left + 5;
175
+ }
176
+ tiptip_arrow.css({"margin-left": arrow_left+"px", "margin-top": arrow_top+"px"});
177
+ tiptip_holder.css({"margin-left": marg_left+"px", "margin-top": marg_top+"px"}).attr("class","tip"+t_class);
178
+
179
+ if (timeout){ clearTimeout(timeout); }
180
+ timeout = setTimeout(function(){ tiptip_holder.stop(true,true).fadeIn(opts.fadeIn); }, opts.delay);
181
+ }
182
+
183
+ function deactive_tiptip(){
184
+ opts.exit.call(this);
185
+ if (timeout){ clearTimeout(timeout); }
186
+ tiptip_holder.fadeOut(opts.fadeOut);
187
+ }
188
+ }
189
+ });
190
+ }
191
+ })(jQuery);
assets/js/jquery-tiptip/jquery.tipTip.min.js ADDED
@@ -0,0 +1 @@
1
+ !function(a){a.fn.tipTip=function(b){var c={activation:"hover",keepAlive:!1,maxWidth:"200px",edgeOffset:3,defaultPosition:"bottom",delay:400,fadeIn:200,fadeOut:200,attribute:"title",content:!1,enter:function(){},exit:function(){}},d=a.extend(c,b);if(a("#tiptip_holder").length<=0){var e=a('<div id="tiptip_holder" style="max-width:'+d.maxWidth+';"></div>'),f=a('<div id="tiptip_content"></div>'),g=a('<div id="tiptip_arrow"></div>');a("body").append(e.html(f).prepend(g.html('<div id="tiptip_arrow_inner"></div>')))}else var e=a("#tiptip_holder"),f=a("#tiptip_content"),g=a("#tiptip_arrow");return this.each(function(){function b(){d.enter.call(this),f.html(i),e.hide().removeAttr("class").css("margin","0"),g.removeAttr("style");var b=parseInt(h.offset().top),c=parseInt(h.offset().left),k=parseInt(h.outerWidth()),l=parseInt(h.outerHeight()),m=e.outerWidth(),n=e.outerHeight(),o=Math.round((k-m)/2),p=Math.round((l-n)/2),q=Math.round(c+o),r=Math.round(b+l+d.edgeOffset),s="",t="",u=Math.round(m-12)/2;"bottom"==d.defaultPosition?s="_bottom":"top"==d.defaultPosition?s="_top":"left"==d.defaultPosition?s="_left":"right"==d.defaultPosition&&(s="_right");var v=o+c<parseInt(a(window).scrollLeft()),w=m+c>parseInt(a(window).width());v&&o<0||"_right"==s&&!w||"_left"==s&&c<m+d.edgeOffset+5?(s="_right",t=Math.round(n-13)/2,u=-12,q=Math.round(c+k+d.edgeOffset),r=Math.round(b+p)):(w&&o<0||"_left"==s&&!v)&&(s="_left",t=Math.round(n-13)/2,u=Math.round(m),q=Math.round(c-(m+d.edgeOffset+5)),r=Math.round(b+p));var x=b+l+d.edgeOffset+n+8>parseInt(a(window).height()+a(window).scrollTop()),y=b+l-(d.edgeOffset+n+8)<0;x||"_bottom"==s&&x||"_top"==s&&!y?("_top"==s||"_bottom"==s?s="_top":s+="_top",t=n,r=Math.round(b-(n+5+d.edgeOffset))):(y|("_top"==s&&y)||"_bottom"==s&&!x)&&("_top"==s||"_bottom"==s?s="_bottom":s+="_bottom",t=-12,r=Math.round(b+l+d.edgeOffset)),"_right_top"==s||"_left_top"==s?r+=5:"_right_bottom"!=s&&"_left_bottom"!=s||(r-=5),"_left_top"!=s&&"_left_bottom"!=s||(q+=5),g.css({"margin-left":u+"px","margin-top":t+"px"}),e.css({"margin-left":q+"px","margin-top":r+"px"}).attr("class","tip"+s),j&&clearTimeout(j),j=setTimeout(function(){e.stop(!0,!0).fadeIn(d.fadeIn)},d.delay)}function c(){d.exit.call(this),j&&clearTimeout(j),e.fadeOut(d.fadeOut)}var h=a(this);if(d.content)var i=d.content;else var i=h.attr(d.attribute);if(""!=i){d.content||h.removeAttr(d.attribute);var j=!1;"hover"==d.activation?(h.hover(function(){b()},function(){d.keepAlive||c()}),d.keepAlive&&e.hover(function(){},function(){c()})):"focus"==d.activation?h.focus(function(){b()}).blur(function(){c()}):"click"==d.activation&&(h.click(function(){return b(),!1}).hover(function(){},function(){d.keepAlive||c()}),d.keepAlive&&e.hover(function(){},function(){c()}))}})}}(jQuery);
includes/class-demo-importer.php ADDED
@@ -0,0 +1,690 @@
1
+ <?php
2
+ /**
3
+ * ThemeGrill Demo Importer.
4
+ *
5
+ * @class TG_Demo_Importer
6
+ * @version 1.0.0
7
+ * @package Importer/Classes
8
+ * @category Admin
9
+ * @author ThemeGrill
10
+ */
11
+
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+
16
+ /**
17
+ * TG_Demo_Importer Class.
18
+ */
19
+ class TG_Demo_Importer {
20
+
21
+ /**
22
+ * Demo config.
23
+ * @var array
24
+ */
25
+ public $demo_config;
26
+
27
+ /**
28
+ * Demo packages.
29
+ * @var array
30
+ */
31
+ public $demo_packages;
32
+
33
+ /**
34
+ * Constructor.
35
+ */
36
+ public function __construct() {
37
+ add_action( 'init', array( $this, 'setup' ), 5 );
38
+ add_action( 'init', array( $this, 'includes' ) );
39
+
40
+ // Add Demo Importer menu.
41
+ if ( apply_filters( 'themegrill_show_demo_importer_page', true ) ) {
42
+ add_action( 'admin_menu', array( $this, 'demo_importer_menu' ) );
43
+ }
44
+
45
+ // Add Demo Importer filterable content.
46
+ add_action( 'themegrill_demo_importer_welcome', array( $this, 'welcome_panel' ) );
47
+ add_action( 'themegrill_demo_importer_uploaded', array( $this, 'output_uploaded' ) );
48
+ add_action( 'themegrill_demo_importer_previews', array( $this, 'output_previews' ) );
49
+
50
+ // AJAX Events to dismiss notice and import demo data.
51
+ add_action( 'wp_ajax_tg_dismiss_notice', array( $this, 'dismissible_notice' ) );
52
+ add_action( 'wp_ajax_tg_import_demo_data', array( $this, 'import_demo_data' ) );
53
+
54
+ // Update custom nav menu items and siteorigin panel data.
55
+ add_action( 'themegrill_ajax_demo_imported', array( $this, 'update_nav_menu_items' ) );
56
+ add_action( 'themegrill_ajax_demo_imported', array( $this, 'update_siteorigin_data' ), 10, 2 );
57
+
58
+ // Update widget and customizer demo import settings data.
59
+ add_filter( 'themegrill_widget_demo_import_settings', array( $this, 'update_widget_data' ), 10, 4 );
60
+ add_filter( 'themegrill_customizer_demo_import_settings', array( $this, 'update_customizer_data' ), 10, 2 );
61
+ }
62
+
63
+ /**
64
+ * Demo importer setup.
65
+ */
66
+ public function setup() {
67
+ $this->demo_config = apply_filters( 'themegrill_demo_importer_config', array() );
68
+ $this->demo_packages = apply_filters( 'themegrill_demo_importer_packages', array() );
69
+ }
70
+
71
+ /**
72
+ * Include required core files.
73
+ */
74
+ public function includes() {
75
+ include_once( dirname( __FILE__ ) . '/includes/functions-demo-importer.php' );
76
+ include_once( dirname( __FILE__ ) . '/includes/class-customizer-importer.php' );
77
+ include_once( dirname( __FILE__ ) . '/includes/class-widget-importer.php' );
78
+ }
79
+
80
+ /**
81
+ * Get the import file URL.
82
+ *
83
+ * @param string $demo_dir demo dir.
84
+ * @param string $filename import filename.
85
+ * @return string the demo import data file URL.
86
+ */
87
+ private function import_file_url( $demo_dir, $filename ) {
88
+ $working_dir = tg_get_demo_file_url( $demo_dir );
89
+
90
+ // If enabled demo pack, load from upload dir.
91
+ if ( $this->is_enabled_demo_pack( $demo_dir ) ) {
92
+ $upload_dir = wp_upload_dir();
93
+ $working_dir = $upload_dir['baseurl'] . '/tg-demo-pack/' . $demo_dir;
94
+ }
95
+
96
+ return trailingslashit( $working_dir ) . sanitize_file_name( $filename );
97
+ }
98
+
99
+ /**
100
+ * Get the import file path.
101
+ *
102
+ * @param string $demo_dir demo dir.
103
+ * @param string $filename import filename.
104
+ * @return string the import data file path.
105
+ */
106
+ private function import_file_path( $demo_dir, $filename ) {
107
+ $working_dir = tg_get_demo_file_path( $demo_dir );
108
+
109
+ // If enabled demo pack, load from upload dir.
110
+ if ( $this->is_enabled_demo_pack( $demo_dir ) ) {
111
+ $upload_dir = wp_upload_dir();
112
+ $working_dir = $upload_dir['basedir'] . '/tg-demo-pack/' . $demo_dir . '/dummy-data';
113
+ }
114
+
115
+ return trailingslashit( $working_dir ) . sanitize_file_name( $filename );
116
+ }
117
+
118
+ /**
119
+ * Check if demo pack is enabled.
120
+ * @param array $demo_id
121
+ * @return bool
122
+ */
123
+ public function is_enabled_demo_pack( $demo_id ) {
124
+ if ( isset( $this->demo_config[ $demo_id ]['demo_pack'] ) && true === $this->demo_config[ $demo_id ]['demo_pack'] ) {
125
+ return true;
126
+ }
127
+
128
+ return false;
129
+ }
130
+
131
+ /**
132
+ * Add menu item.
133
+ */
134
+ public function demo_importer_menu() {
135
+ $page = add_theme_page( __( 'Demo Importer', 'themegrill-demo-importer' ), __( 'Demo Importer', 'themegrill-demo-importer' ), 'switch_themes', 'demo-importer', array( $this, 'demo_importer' ) );
136
+ add_action( 'admin_print_styles-' . $page, array( $this, 'enqueue_styles' ) );
137
+ }
138
+
139
+ /**
140
+ * Enqueue styles.
141
+ */
142
+ public function enqueue_styles() {
143
+ $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
144
+ $assets_path = tg_get_demo_importer_assets_path();
145
+
146
+ // Register Scripts
147
+ wp_register_script( 'jquery-tiptip', $assets_path . 'js/jquery-tiptip/jquery.tipTip' . $suffix . '.js', array( 'jquery' ), '1.3', true );
148
+
149
+ // Enqueue Scripts
150
+ wp_enqueue_style( 'tg-demo-importer', $assets_path . 'css/demo-importer.css', array() );
151
+ wp_enqueue_script( 'tg-demo-importer', $assets_path . 'js/admin/demo-importer' . $suffix . '.js', array( 'jquery', 'jquery-tiptip' ), '1.0.0' );
152
+
153
+ wp_localize_script( 'tg-demo-importer', 'demo_importer_params', array(
154
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
155
+ 'import_demo_data_nonce' => wp_create_nonce( 'import-demo-data' ),
156
+ 'i18n_import_data_error' => esc_js( __( 'Importing Failed. Try again!', 'themegrill-demo-importer' ) ),
157
+ 'i18n_import_dummy_data' => esc_js( __( 'Importing demo content will replicate the live demo and overwrites your current customizer, widgets and other settings. It might take few minutes to complete the demo import. Are you sure you want to import this demo?', 'themegrill-demo-importer' ) ),
158
+ ) );
159
+ }
160
+
161
+ /**
162
+ * Demo Importer page output.
163
+ */
164
+ public function demo_importer() {
165
+ global $current_tab;
166
+
167
+ $current_tab = empty( $_GET['tab'] ) ? 'welcome' : sanitize_title( $_GET['tab'] );
168
+
169
+ if ( isset( $_GET['action'] ) && 'upload-demo' === $_GET['action'] ) {
170
+ $this->upload_demo_pack();
171
+ } else {
172
+ include_once( dirname( __FILE__ ) . '/includes/admin/views/html-admin-page-importer.php' );
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Output welcome panel page.
178
+ */
179
+ public function welcome_panel() {
180
+ include_once( dirname( __FILE__ ) . '/includes/admin/views/html-admin-page-importer-welcome.php' );
181
+ }
182
+
183
+ /**
184
+ * Output demo uploaded page.
185
+ */
186
+ public function output_uploaded() {
187
+ include_once( dirname( __FILE__ ) . '/includes/admin/views/html-admin-page-importer-uploaded.php' );
188
+ }
189
+
190
+ /**
191
+ * Output demo previews page.
192
+ */
193
+ public function output_previews() {
194
+ include_once( dirname( __FILE__ ) . '/includes/admin/views/html-admin-page-importer-previews.php' );
195
+ }
196
+
197
+ /**
198
+ * Upload demo pack.
199
+ */
200
+ private function upload_demo_pack() {
201
+ include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
202
+
203
+ if ( ! current_user_can( 'upload_files' ) ) {
204
+ wp_die( __( 'Sorry, you are not allowed to install demo on this site.', 'themegrill-demo-importer' ) );
205
+ }
206
+
207
+ check_admin_referer( 'demo-upload' );
208
+
209
+ $file_upload = new File_Upload_Upgrader( 'demozip', 'package' );
210
+
211
+ $title = sprintf( __( 'Installing Demo from uploaded file: %s', 'themegrill-demo-importer' ), esc_html( basename( $file_upload->filename ) ) );
212
+ $nonce = 'demo-upload';
213
+ $url = add_query_arg( array( 'package' => $file_upload->id ), 'themes.php?page=demo-importer&action=upload-demo' );
214
+ $type = 'upload'; // Install demo type, From Web or an Upload.
215
+
216
+ // Demo Upgrader Class.
217
+ include_once( dirname( __FILE__ ) . '/includes/admin/class-demo-upgrader.php' );
218
+ include_once( dirname( __FILE__ ) . '/includes/admin/class-demo-installer-skin.php' );
219
+
220
+ $upgrader = new TG_Demo_Upgrader( new TG_Demo_Installer_Skin( compact( 'type', 'title', 'nonce', 'url' ) ) );
221
+ $result = $upgrader->install( $file_upload->package );
222
+
223
+ if ( $result || is_wp_error( $result ) ) {
224
+ $file_upload->cleanup();
225
+ }
226
+ }
227
+
228
+ /**
229
+ * AJAX Dismissible notice.
230
+ */
231
+ public function dismissible_notice() {
232
+ if ( ! current_user_can( 'manage_options' ) ) {
233
+ die( -1 );
234
+ }
235
+
236
+ $notice_id = sanitize_text_field( stripslashes( $_POST['notice_id'] ) );
237
+
238
+ if ( ! empty( $notice_id ) && 'demo-importer' == $notice_id ) {
239
+ update_option( 'themegrill_demo_imported_notice_dismiss', 1 );
240
+ }
241
+
242
+ die();
243
+ }
244
+
245
+ /**
246
+ * AJAX Import demo/dummy data.
247
+ */
248
+ public function import_demo_data() {
249
+ ob_start();
250
+
251
+ check_ajax_referer( 'import-demo-data', 'security' );
252
+
253
+ if ( ! defined( 'WP_LOAD_IMPORTERS' ) ) {
254
+ define( 'WP_LOAD_IMPORTERS', true );
255
+ }
256
+
257
+ if ( ! current_user_can( 'manage_options' ) ) {
258
+ die( -1 );
259
+ }
260
+
261
+ $demo_id = sanitize_text_field( stripslashes( $_POST['demo_id'] ) );
262
+ $demo_data = isset( $this->demo_config[ $demo_id ] ) ? $this->demo_config[ $demo_id ] : array();
263
+
264
+ do_action( 'themegrill_ajax_before_demo_import' );
265
+
266
+ if ( ! empty( $demo_data ) ) {
267
+ $this->import_dummy_xml( $demo_id, $demo_data );
268
+ $this->import_core_options( $demo_id, $demo_data );
269
+ $this->import_customizer_data( $demo_id, $demo_data );
270
+ $this->import_widget_settings( $demo_id, $demo_data );
271
+
272
+ update_option( 'themegrill_demo_imported_id', $demo_id );
273
+
274
+ do_action( 'themegrill_ajax_demo_imported', $demo_id, $demo_data );
275
+
276
+ wp_send_json_success( array(
277
+ 'demo_id' => $demo_id,
278
+ 'message' => __( 'Successfully Imported', 'themegrill-demo-importer' ),
279
+ ) );
280
+ }
281
+
282
+ die();
283
+ }
284
+
285
+ /**
286
+ * Import dummy content from a XML file.
287
+ * @param string $demo_id
288
+ * @param array $demo_data
289
+ * @return bool
290
+ */
291
+ public function import_dummy_xml( $demo_id, $demo_data ) {
292
+ $import_file = $this->import_file_path( $demo_id, 'dummy-data.xml' );
293
+
294
+ // Load Importer API
295
+ require_once ABSPATH . 'wp-admin/includes/import.php';
296
+
297
+ if ( ! class_exists( 'WP_Importer' ) ) {
298
+ $class_wp_importer = ABSPATH . 'wp-admin/includes/class-wp-importer.php';
299
+
300
+ if ( file_exists( $class_wp_importer ) ) {
301
+ require $class_wp_importer;
302
+ }
303
+ }
304
+
305
+ // Include WXR Importer.
306
+ require dirname( __FILE__ ) . '/includes/importers/class-wxr-importer.php';
307
+
308
+ do_action( 'themegrill_ajax_before_dummy_xml_import', $demo_data, $demo_id );
309
+
310
+ // Import XML file demo content.
311
+ if ( is_file( $import_file ) ) {
312
+ $wp_import = new TG_WXR_Importer();
313
+ $wp_import->fetch_attachments = true;
314
+
315
+ ob_start();
316
+ $wp_import->import( $import_file );
317
+ ob_end_clean();
318
+
319
+ do_action( 'themegrill_ajax_dummy_xml_imported', $demo_data, $demo_id );
320
+
321
+ flush_rewrite_rules();
322
+ } else {
323
+ wp_send_json_error( array( 'message' => __( 'The XML file containing the dummy content is not available.', 'themegrill-demo-importer' ) ) );
324
+ exit;
325
+ }
326
+
327
+ return true;
328
+ }
329
+
330
+ /**
331
+ * Import site core options from its ID.
332
+ * @param string $demo_id
333
+ * @param array $demo_data
334
+ * @return bool
335
+ */
336
+ public function import_core_options( $demo_id, $demo_data ) {
337
+ if ( ! empty( $demo_data['core_options'] ) ) {
338
+ foreach ( $demo_data['core_options'] as $option_key => $option_value ) {
339
+ if ( ! in_array( $option_key, array( 'blogname', 'blogdescription', 'show_on_front', 'page_on_front', 'page_for_posts' ) ) ) {
340
+ continue;
341
+ }
342
+
343
+ // Format the value based on option key.
344
+ switch ( $option_key ) {
345
+ case 'show_on_front':
346
+ if ( in_array( $option_value, array( 'posts', 'page' ) ) ) {
347
+ update_option( 'show_on_front', $option_value );
348
+ }
349
+ break;
350
+ case 'page_on_front':
351
+ case 'page_for_posts':
352
+ $page = get_page_by_title( $option_value );
353
+
354
+ if ( is_object( $page ) && $page->ID ) {
355
+ update_option( $option_key, $page->ID );
356
+ update_option( 'show_on_front', 'page' );
357
+ }
358
+ break;
359
+ default:
360
+ update_option( $option_key, sanitize_text_field( $option_value ) );
361
+ break;
362
+ }
363
+ }
364
+ }
365
+
366
+ return true;
367
+ }
368
+
369
+ /**
370
+ * Import customizer data from a DAT file.
371
+ * @param string $demo_id
372
+ * @param array $demo_data
373
+ * @return bool
374
+ */
375
+ public function import_customizer_data( $demo_id, $demo_data ) {
376
+ $import_file = $this->import_file_path( $demo_id, 'dummy-customizer.dat' );
377
+
378
+ if ( is_file( $import_file ) ) {
379
+ $results = TG_Customizer_Importer::import( $import_file, $demo_id, $demo_data );
380
+
381
+ if ( is_wp_error( $results ) ) {
382
+ return false;
383
+ }
384
+ }
385
+
386
+ return true;
387
+ }
388
+
389
+ /**
390
+ * Import widgets settings from WIE or JSON file.
391
+ * @param string $demo_id
392
+ * @param array $demo_data
393
+ * @return bool
394
+ */
395
+ public function import_widget_settings( $demo_id, $demo_data ) {
396
+ $import_file = $this->import_file_path( $demo_id, 'dummy-widgets.wie' );
397
+
398
+ if ( is_file( $import_file ) ) {
399
+ $results = TG_Widget_Importer::import( $import_file, $demo_id, $demo_data );
400
+
401
+ if ( is_wp_error( $results ) ) {
402
+ return false;
403
+ }
404
+ }
405
+
406
+ return true;
407
+ }
408
+
409
+ /**
410
+ * Update custom nav menu items URL.
411
+ */
412
+ public function update_nav_menu_items() {
413
+ $menu_locations = get_nav_menu_locations();
414
+
415
+ foreach ( $menu_locations as $location => $menu_id ) {
416
+
417
+ if ( is_nav_menu( $menu_id ) ) {
418
+ $menu_items = wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'any' ) );
419
+
420
+ if ( ! empty( $menu_items ) ) {
421
+ foreach ( $menu_items as $menu_item ) {
422
+ if ( isset( $menu_item->url ) && isset( $menu_item->db_id ) && 'custom' == $menu_item->type ) {
423
+ $site_parts = parse_url( home_url( '/' ) );
424
+ $menu_parts = parse_url( $menu_item->url );
425
+
426
+ // Update existing custom nav menu item URL.
427
+ if ( isset( $menu_parts['path'] ) && isset( $menu_parts['host'] ) && apply_filters( 'themegrill_demo_importer_nav_menu_item_url_hosts', in_array( $menu_parts['host'], array( 'demo.themegrill.com' ) ) ) ) {
428
+ $menu_item->url = str_replace( array( $menu_parts['scheme'], $menu_parts['host'], $menu_parts['path'] ), array( $site_parts['scheme'], $site_parts['host'], trailingslashit( $site_parts['path'] ) ), $menu_item->url );
429
+ update_post_meta( $menu_item->db_id, '_menu_item_url', esc_url_raw( $menu_item->url ) );
430
+ }
431
+ }
432
+ }
433
+ }
434
+ }
435
+ }
436
+ }
437
+
438
+ /**
439
+ * Updates widgets settings data.
440
+ * @param array $widget
441
+ * @param string $widget_type
442
+ * @param int $instance_id
443
+ * @param array $demo_data
444
+ * @return array
445
+ */
446
+ public function update_widget_data( $widget, $widget_type, $instance_id, $demo_data ) {
447
+ if ( 'nav_menu' == $widget_type ) {
448
+ $nav_menu = wp_get_nav_menu_object( $widget['title'] );
449
+
450
+ if ( is_object( $nav_menu ) && $nav_menu->term_id ) {
451
+ $widget['nav_menu'] = $nav_menu->term_id;
452
+ }
453
+ } elseif ( ! empty( $demo_data['widgets_data_update'] ) ) {
454
+ foreach ( $demo_data['widgets_data_update'] as $dropdown_type => $dropdown_data ) {
455
+ if ( ! in_array( $dropdown_type, array( 'dropdown_pages', 'dropdown_categories' ) ) ) {
456
+ continue;
457
+ }
458
+
459
+ // Format the value based on dropdown type.
460
+ switch ( $dropdown_type ) {
461
+ case 'dropdown_pages':
462
+ foreach ( $dropdown_data as $widget_id => $widget_data ) {
463
+ if ( ! empty( $widget_data[ $instance_id ] ) && $widget_id == $widget_type ) {
464
+ foreach ( $widget_data[ $instance_id ] as $widget_key => $widget_value ) {
465
+ $page = get_page_by_title( $widget_value );
466
+
467
+ if ( is_object( $page ) && $page->ID ) {
468
+ $widget[ $widget_key ] = $page->ID;
469
+ }
470
+ }
471
+ }
472
+ }
473
+ break;
474
+ case 'dropdown_categories':
475
+ foreach ( $dropdown_data as $taxonomy => $taxonomy_data ) {
476
+ if ( ! taxonomy_exists( $taxonomy ) ) {
477
+ continue;
478
+ }
479
+
480
+ foreach ( $taxonomy_data as $widget_id => $widget_data ) {
481
+ if ( ! empty( $widget_data[ $instance_id ] ) && $widget_id == $widget_type ) {
482
+ foreach ( $widget_data[ $instance_id ] as $widget_key => $widget_value ) {
483
+ $term = get_term_by( 'name', $widget_value, $taxonomy );
484
+
485
+ if ( is_object( $term ) && $term->term_id ) {
486
+ $widget[ $widget_key ] = $term->term_id;
487
+ }
488
+ }
489
+ }
490
+ }
491
+ }
492
+ break;
493
+ }
494
+ }
495
+ }
496
+
497
+ return $widget;
498
+ }
499
+
500
+ /**
501
+ * Update customizer settings data.
502
+ * @param array $data
503
+ * @param array $demo_data
504
+ * @return array
505
+ */
506
+ public function update_customizer_data( $data, $demo_data ) {
507
+ if ( ! empty( $demo_data['customizer_data_update'] ) ) {
508
+ foreach ( $demo_data['customizer_data_update'] as $data_type => $data_value ) {
509
+ if ( ! in_array( $data_type, array( 'pages', 'categories', 'nav_menu_locations' ) ) ) {
510
+ continue;
511
+ }
512
+
513
+ // Format the value based on data type.
514
+ switch ( $data_type ) {
515
+ case 'pages':
516
+ foreach ( $data_value as $option_key => $option_value ) {
517
+ if ( ! empty( $data['mods'][ $option_key ] ) ) {
518
+ $page = get_page_by_title( $option_value );
519
+
520
+ if ( is_object( $page ) && $page->ID ) {
521
+ $data['mods'][ $option_key ] = $page->ID;
522
+ }
523
+ }
524
+ }
525
+ break;
526
+ case 'categories':
527
+ foreach ( $data_value as $taxonomy => $taxonomy_data ) {
528
+ if ( ! taxonomy_exists( $taxonomy ) ) {
529
+ continue;
530
+ }
531
+
532
+ foreach ( $taxonomy_data as $option_key => $option_value ) {
533
+ if ( ! empty( $data['mods'][ $option_key ] ) ) {
534
+ $term = get_term_by( 'name', $option_value, $taxonomy );
535
+
536
+ if ( is_object( $term ) && $term->term_id ) {
537
+ $data['mods'][ $option_key ] = $term->term_id;
538
+ }
539
+ }
540
+ }
541
+ }
542
+ break;
543
+ case 'nav_menu_locations':
544
+ $nav_menus = wp_get_nav_menus();
545
+
546
+ if ( ! empty( $nav_menus ) ) {
547
+ foreach ( $nav_menus as $nav_menu ) {
548
+ if ( is_object( $nav_menu ) ) {
549
+ foreach ( $data_value as $location => $location_name ) {
550
+ if ( $nav_menu->name == $location_name ) {
551
+ $data['mods'][ $data_type ][ $location ] = $nav_menu->term_id;
552
+ }
553
+ }
554
+ }
555
+ }
556
+ }
557
+ break;
558
+ }
559
+ }
560
+ }
561
+
562
+ return $data;
563
+ }
564
+
565
+ /**
566
+ * Update siteorigin panel settings data.
567
+ * @param string $demo_id
568
+ * @param array $demo_data
569
+ */
570
+ public function update_siteorigin_data( $demo_id, $demo_data ) {
571
+ if ( ! empty( $demo_data['siteorigin_panels_data_update'] ) ) {
572
+ foreach ( $demo_data['siteorigin_panels_data_update'] as $data_type => $data_value ) {
573
+ if ( ! empty( $data_value['post_title'] ) ) {
574
+ $page = get_page_by_title( $data_value['post_title'] );
575
+
576
+ if ( is_object( $page ) && $page->ID ) {
577
+ $panels_data = get_post_meta( $page->ID, 'panels_data', true );
578
+
579
+ if ( ! empty( $panels_data ) ) {
580
+ foreach ( $panels_data as $panel_type => $panel_data ) {
581
+ if ( ! in_array( $panel_type, array( 'grids', 'widgets' ) ) ) {
582
+ continue;
583
+ }
584
+
585
+ // Format the value based on panel type.
586
+ switch ( $panel_type ) {
587
+ case 'grids':
588
+ foreach ( $panel_data as $instance_id => $grid_instance ) {
589
+ if ( ! empty( $data_value['data_update']['grids_data'] ) ) {
590
+ foreach ( $data_value['data_update']['grids_data'] as $grid_id => $grid_data ) {
591
+ if ( ! empty( $grid_data['style'] ) && $instance_id === $grid_id ) {
592
+ foreach ( $grid_data['style'] as $style_key => $style_value ) {
593
+ if ( empty( $style_value ) ) {
594
+ continue;
595
+ }
596
+
597
+ // Format the value based on style key.
598
+ switch ( $style_key ) {
599
+ case 'background_image_attachment':
600
+ $attachment_id = tg_get_attachment_id( $style_value );
601
+
602
+ if ( 0 !== $attachment_id ) {
603
+ $grid_instance['style'][ $style_key ] = $attachment_id;
604
+ }
605
+ break;
606
+ default:
607
+ $grid_instance['style'][ $style_key ] = $style_value;
608
+ break;
609
+ }
610
+ }
611
+ }
612
+ }
613
+ }
614
+
615
+ // Update panel grids data.
616
+ $panels_data['grids'][ $instance_id ] = $grid_instance;
617
+ }
618
+ break;
619
+ case 'widgets':
620
+ foreach ( $panel_data as $instance_id => $widget_instance ) {
621
+ if ( isset( $widget_instance['nav_menu'] ) && isset( $widget_instance['title'] ) ) {
622
+ $nav_menu = wp_get_nav_menu_object( $widget_instance['title'] );
623
+
624
+ if ( is_object( $nav_menu ) && $nav_menu->term_id ) {
625
+ $widget_instance['nav_menu'] = $nav_menu->term_id;
626
+ }
627
+ } elseif ( ! empty( $data_value['data_update']['widgets_data'] ) ) {
628
+ $instance_class = $widget_instance['panels_info']['class'];
629
+
630
+ foreach ( $data_value['data_update']['widgets_data'] as $dropdown_type => $dropdown_data ) {
631
+ if ( ! in_array( $dropdown_type, array( 'dropdown_pages', 'dropdown_categories' ) ) ) {
632
+ continue;
633
+ }
634
+
635
+ // Format the value based on dropdown type.
636
+ switch ( $dropdown_type ) {
637
+ case 'dropdown_pages':
638
+ foreach ( $dropdown_data as $widget_id => $widget_data ) {
639
+ if ( ! empty( $widget_data[ $instance_id ] ) && $widget_id == $instance_class ) {
640
+ foreach ( $widget_data[ $instance_id ] as $widget_key => $widget_value ) {
641
+ $page = get_page_by_title( $widget_value );
642
+
643
+ if ( is_object( $page ) && $page->ID ) {
644
+ $widget_instance[ $widget_key ] = $page->ID;
645
+ }
646
+ }
647
+ }
648
+ }
649
+ break;
650
+ case 'dropdown_categories':
651
+ foreach ( $dropdown_data as $taxonomy => $taxonomy_data ) {
652
+ if ( ! taxonomy_exists( $taxonomy ) ) {
653
+ continue;
654
+ }
655
+
656
+ foreach ( $taxonomy_data as $widget_id => $widget_data ) {
657
+ if ( ! empty( $widget_data[ $instance_id ] ) && $widget_id == $instance_class ) {
658
+ foreach ( $widget_data[ $instance_id ] as $widget_key => $widget_value ) {
659
+ $term = get_term_by( 'name', $widget_value, $taxonomy );
660
+
661
+ if ( is_object( $term ) && $term->term_id ) {
662
+ $widget_instance[ $widget_key ] = $term->term_id;
663
+ }
664
+ }
665
+ }
666
+ }
667
+ }
668
+ break;
669
+ }
670
+ }
671
+ }
672
+
673
+ // Update panel widgets data.
674
+ $panels_data['widgets'][ $instance_id ] = $widget_instance;
675
+ }
676
+ break;
677
+ }
678
+ }
679
+ }
680
+
681
+ // Update siteorigin panels data.
682
+ update_post_meta( $page->ID, 'panels_data', $panels_data );
683
+ }
684
+ }
685
+ }
686
+ }
687
+ }
688
+ }
689
+
690
+ new TG_Demo_Importer();
includes/includes/admin/class-demo-installer-skin.php ADDED
@@ -0,0 +1,64 @@
1
+ <?php
2
+ /**
3
+ * Upgrader API: Plugin_Upgrader_Skin class
4
+ *
5
+ * Demo Installer Skin for the WordPress Demo Importer.
6
+ *
7
+ * @class TG_Demo_Installer_Skin
8
+ * @extends WP_Upgrader_Skin
9
+ * @version 1.0.0
10
+ * @package Importer/Classes
11
+ * @category Admin
12
+ * @author ThemeGrill
13
+ */
14
+
15
+ if ( ! defined( 'ABSPATH' ) ) {
16
+ exit;
17
+ }
18
+
19
+ /**
20
+ * TG_Demo_Installer_Skin Class.
21
+ */
22
+ class TG_Demo_Installer_Skin extends WP_Upgrader_Skin {
23
+ public $type;
24
+
25
+ /**
26
+ *
27
+ * @param array $args
28
+ */
29
+ public function __construct( $args = array() ) {
30
+ $defaults = array( 'type' => 'web', 'url' => '', 'demo' => '', 'nonce' => '', 'title' => '' );
31
+ $args = wp_parse_args( $args, $defaults );
32
+
33
+ $this->type = $args['type'];
34
+
35
+ parent::__construct( $args );
36
+ }
37
+
38
+ /**
39
+ * @access public
40
+ */
41
+ public function after() {
42
+ $install_actions = array();
43
+
44
+ $from = isset( $_GET['from'] ) ? wp_unslash( $_GET['from'] ) : 'demos';
45
+
46
+ if ( 'web' == $this->type ) {
47
+ $install_actions['demos_page'] = '<a href="' . admin_url( 'themes.php?page=demo-importer&tab=uploaded' ) . '" target="_parent">' . __( 'Return to Demo Importer', 'themegrill-demo-importer' ) . '</a>';
48
+ } elseif ( 'upload' == $this->type && 'demos' == $from ) {
49
+ $install_actions['demos_page'] = '<a href="' . admin_url( 'themes.php?page=demo-importer&tab=uploaded' ) . '">' . __( 'Return to Demo Importer', 'themegrill-demo-importer' ) . '</a>';
50
+ } else {
51
+ $install_actions['demos_page'] = '<a href="' . admin_url( 'themes.php?page=demo-importer&tab=uploaded' ) . '" target="_parent">' . __( 'Return to Demos page', 'themegrill-demo-importer' ) . '</a>';
52
+ }
53
+
54
+ /**
55
+ * Filters the list of action links available following a single demo installation.
56
+ * @param array $install_actions Array of demo action links.
57
+ */
58
+ $install_actions = apply_filters( 'themegrill_demo_install_complete_actions', $install_actions );
59
+
60
+ if ( ! empty( $install_actions ) ) {
61
+ $this->feedback( implode( ' | ', (array) $install_actions ) );
62
+ }
63
+ }
64
+ }
includes/includes/admin/class-demo-upgrader.php ADDED
@@ -0,0 +1,349 @@
1
+ <?php
2
+ /**
3
+ * Upgrade API: TG_Demo_Upgrader class
4
+ *
5
+ * Core class used for upgrading/installing demos.
6
+ *
7
+ * It is designed to upgrade/install demo from a local zip, remote zip URL,
8
+ * or uploaded zip file.
9
+ *
10
+ * @see WP_Upgrader
11
+ */
12
+ class TG_Demo_Upgrader extends WP_Upgrader {
13
+
14
+ /**
15
+ * Result of the demo upgrade offer.
16
+ *
17
+ * @since 2.8.0
18
+ * @access public
19
+ * @var array|WP_Error $result
20
+ * @see WP_Upgrader::$result
21
+ */
22
+ public $result;
23
+
24
+ /**
25
+ * Whether multiple demos are being upgraded/installed in bulk.
26
+ *
27
+ * @since 2.9.0
28
+ * @access public
29
+ * @var bool $bulk
30
+ */
31
+ public $bulk = false;
32
+
33
+ /**
34
+ * Initialize the install strings.
35
+ *
36
+ * @since 2.8.0
37
+ * @access public
38
+ */
39
+ public function install_strings() {
40
+ $this->strings['no_package'] = __( 'Install package not available.', 'themegrill-demo-importer' );
41
+ $this->strings['downloading_package'] = __( 'Downloading install package from <span class="code">%s</span>&#8230;', 'themegrill-demo-importer' );
42
+ $this->strings['unpack_package'] = __( 'Unpacking the package&#8230;', 'themegrill-demo-importer' );
43
+ $this->strings['installing_package'] = __( 'Installing the demo&#8230;', 'themegrill-demo-importer' );
44
+ $this->strings['no_files'] = __( 'The demo contains no files.', 'themegrill-demo-importer' );
45
+ $this->strings['process_failed'] = __( 'Demo install failed.', 'themegrill-demo-importer' );
46
+ $this->strings['process_success'] = __( 'Demo installed successfully.', 'themegrill-demo-importer' );
47
+ }
48
+
49
+ /**
50
+ * Install a demo package.
51
+ *
52
+ * @since 2.8.0
53
+ * @since 3.7.0 The `$args` parameter was added, making clearing the update cache optional.
54
+ * @access public
55
+ *
56
+ * @param string $package The full local path or URI of the package.
57
+ * @param array $args {
58
+ * Optional. Other arguments for installing a demo package. Default empty array.
59
+ *
60
+ * @type bool $clear_update_cache Whether to clear the updates cache if successful.
61
+ * Default true.
62
+ * }
63
+ *
64
+ * @return bool|WP_Error True if the install was successful, false or a WP_Error object otherwise.
65
+ */
66
+ public function install( $package, $args = array() ) {
67
+ $upload_dir = wp_upload_dir();
68
+
69
+ $defaults = array(
70
+ 'clear_update_cache' => true,
71
+ );
72
+ $parsed_args = wp_parse_args( $args, $defaults );
73
+
74
+ $this->init();
75
+ $this->install_strings();
76
+
77
+ add_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
78
+
79
+ $this->run( array(
80
+ 'package' => $package,
81
+ 'destination' => $upload_dir['basedir'] . '/tg-demo-pack',
82
+ 'clear_destination' => false, // Do not overwrite files.
83
+ 'protect_destination' => true,
84
+ 'clear_working' => true,
85
+ 'hook_extra' => array(
86
+ 'type' => 'demo',
87
+ 'action' => 'install',
88
+ ),
89
+ ) );
90
+
91
+ remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
92
+
93
+ if ( ! $this->result || is_wp_error( $this->result ) ) {
94
+ return $this->result;
95
+ }
96
+
97
+ return true;
98
+ }
99
+
100
+ /**
101
+ * Check that the package source contains a valid demo.
102
+ *
103
+ * Hooked to the {@see 'upgrader_source_selection'} filter by TG_Demo_Upgrader::install().
104
+ * It will return an error if the demo doesn't have tg-demo-config.php
105
+ * files.
106
+ *
107
+ * @since 3.3.0
108
+ * @access public
109
+ *
110
+ * @global WP_Filesystem_Base $wp_filesystem Subclass
111
+ * @global array $wp_theme_directories
112
+ *
113
+ * @param string $source The full path to the package source.
114
+ * @return string|WP_Error The source or a WP_Error.
115
+ */
116
+ public function check_package( $source ) {
117
+ global $wp_filesystem, $wp_theme_directories;
118
+
119
+ if ( is_wp_error( $source ) )
120
+ return $source;
121
+
122
+ // Check the folder contains a valid demo.
123
+ $working_directory = str_replace( $wp_filesystem->wp_content_dir(), trailingslashit( WP_CONTENT_DIR ), $source );
124
+ if ( ! is_dir( $working_directory ) ) // Sanity check, if the above fails, let's not prevent installation.
125
+ return $source;
126
+
127
+ // A proper archive should have a tg-demo-config.php file in the single subdirectory
128
+ if ( ! file_exists( $working_directory . 'tg-demo-config.php' ) ) {
129
+ return new WP_Error( 'incompatible_archive_no_demos', $this->strings['incompatible_archive'], __( 'No valid demos were found.', 'themegrill-demo-importer' ) );
130
+ }
131
+
132
+ return $source;
133
+ }
134
+
135
+ /**
136
+ * Install a package.
137
+ *
138
+ * Copies the contents of a package form a source directory, and installs them in
139
+ * a destination directory. Optionally removes the source. It can also optionally
140
+ * clear out the destination folder if it already exists.
141
+ *
142
+ * Stuck with this until a fix for https://core.trac.wordpress.org/ticket/38946.
143
+ * We use a custom upgrader, just like WordPress does.
144
+ *
145
+ * @since 2.8.0
146
+ * @access public
147
+ *
148
+ * @global WP_Filesystem_Base $wp_filesystem Subclass
149
+ * @global array $wp_theme_directories
150
+ *
151
+ * @param array|string $args {
152
+ * Optional. Array or string of arguments for installing a package. Default empty array.
153
+ *
154
+ * @type string $source Required path to the package source. Default empty.
155
+ * @type string $destination Required path to a folder to install the package in.
156
+ * Default empty.
157
+ * @type bool $clear_destination Whether to delete any files already in the destination
158
+ * folder. Default false.
159
+ * @type bool $clear_working Whether to delete the files from the working directory
160
+ * after copying to the destination. Default false.
161
+ * @type bool $protect_destination Whether to protect against deleting any files already
162
+ * in the destination folder. Default false.
163
+ * @type bool $abort_if_destination_exists Whether to abort the installation if
164
+ * the destination folder already exists. Default true.
165
+ * @type array $hook_extra Extra arguments to pass to the filter hooks called by
166
+ * WP_Upgrader::install_package(). Default empty array.
167
+ * }
168
+ *
169
+ * @return array|WP_Error The result (also stored in `WP_Upgrader::$result`), or a WP_Error on failure.
170
+ */
171
+ public function install_package( $args = array() ) {
172
+ global $wp_filesystem, $wp_theme_directories;
173
+
174
+ $defaults = array(
175
+ 'source' => '', // Please always pass this
176
+ 'destination' => '', // and this
177
+ 'clear_destination' => false,
178
+ 'clear_working' => false,
179
+ 'protect_destination' => true, // If fixed in core then it will be false :)
180
+ 'abort_if_destination_exists' => true,
181
+ 'hook_extra' => array(),
182
+ );
183
+
184
+ $args = wp_parse_args( $args, $defaults );
185
+
186
+ // These were previously extract()'d.
187
+ $source = $args['source'];
188
+ $destination = $args['destination'];
189
+ $clear_destination = $args['clear_destination'];
190
+
191
+ @set_time_limit( 300 );
192
+
193
+ if ( empty( $source ) || empty( $destination ) ) {
194
+ return new WP_Error( 'bad_request', $this->strings['bad_request'] );
195
+ }
196
+ $this->skin->feedback( 'installing_package' );
197
+
198
+ /**
199
+ * Filters the install response before the installation has started.
200
+ *
201
+ * Returning a truthy value, or one that could be evaluated as a WP_Error
202
+ * will effectively short-circuit the installation, returning that value
203
+ * instead.
204
+ *
205
+ * @since 2.8.0
206
+ *
207
+ * @param bool|WP_Error $response Response.
208
+ * @param array $hook_extra Extra arguments passed to hooked filters.
209
+ */
210
+ $res = apply_filters( 'upgrader_pre_install', true, $args['hook_extra'] );
211
+
212
+ if ( is_wp_error( $res ) ) {
213
+ return $res;
214
+ }
215
+
216
+ // Retain the Original source and destinations
217
+ $remote_source = $args['source'];
218
+ $local_destination = $destination;
219
+
220
+ $source_files = array_keys( $wp_filesystem->dirlist( $remote_source ) );
221
+ $remote_destination = $wp_filesystem->find_folder( $local_destination );
222
+
223
+ // Locate which directory to copy to the new folder, This is based on the actual folder holding the files.
224
+ if ( 1 == count( $source_files ) && $wp_filesystem->is_dir( trailingslashit( $args['source'] ) . $source_files[0] . '/' ) ) { // Only one folder? Then we want its contents.
225
+ $source = trailingslashit( $args['source'] ) . trailingslashit( $source_files[0] );
226
+ } elseif ( count( $source_files ) == 0 ) {
227
+ return new WP_Error( 'incompatible_archive_empty', $this->strings['incompatible_archive'], $this->strings['no_files'] ); // There are no files?
228
+ } else { // It's only a single file, the upgrader will use the folder name of this file as the destination folder. Folder name is based on zip filename.
229
+ $source = trailingslashit( $args['source'] );
230
+ }
231
+
232
+ /**
233
+ * Filters the source file location for the upgrade package.
234
+ *
235
+ * @since 2.8.0
236
+ * @since 4.4.0 The $hook_extra parameter became available.
237
+ *
238
+ * @param string $source File source location.
239
+ * @param string $remote_source Remote file source location.
240
+ * @param WP_Upgrader $this WP_Upgrader instance.
241
+ * @param array $hook_extra Extra arguments passed to hooked filters.
242
+ */
243
+ $source = apply_filters( 'upgrader_source_selection', $source, $remote_source, $this, $args['hook_extra'] );
244
+
245
+ if ( is_wp_error( $source ) ) {
246
+ return $source;
247
+ }
248
+
249
+ // Has the source location changed? If so, we need a new source_files list.
250
+ if ( $source !== $remote_source ) {
251
+ $source_files = array_keys( $wp_filesystem->dirlist( $source ) );
252
+ }
253
+
254
+ /*
255
+ * Protection against deleting files in any important base directories.
256
+ * Theme_Upgrader & Plugin_Upgrader also trigger this, as they pass the
257
+ * destination directory (WP_PLUGIN_DIR / wp-content/themes) intending
258
+ * to copy the directory into the directory, whilst they pass the source
259
+ * as the actual files to copy.
260
+ */
261
+ $protected_directories = array( ABSPATH, WP_CONTENT_DIR, WP_PLUGIN_DIR, WP_CONTENT_DIR . '/themes' );
262
+
263
+ if ( is_array( $wp_theme_directories ) ) {
264
+ $protected_directories = array_merge( $protected_directories, $wp_theme_directories );
265
+ }
266
+
267
+ if ( in_array( $destination, $protected_directories ) || $args['protect_destination'] ) {
268
+ $remote_destination = trailingslashit( $remote_destination ) . trailingslashit( basename( $source ) );
269
+ $destination = trailingslashit( $destination ) . trailingslashit( basename( $source ) );
270
+ }
271
+
272
+ if ( $clear_destination ) {
273
+ // We're going to clear the destination if there's something there.
274
+ $this->skin->feedback( 'remove_old' );
275
+
276
+ $removed = $this->clear_destination( $remote_destination );
277
+
278
+ /**
279
+ * Filters whether the upgrader cleared the destination.
280
+ *
281
+ * @since 2.8.0
282
+ *
283
+ * @param mixed $removed Whether the destination was cleared. true on success, WP_Error on failure
284
+ * @param string $local_destination The local package destination.
285
+ * @param string $remote_destination The remote package destination.
286
+ * @param array $hook_extra Extra arguments passed to hooked filters.
287
+ */
288
+ $removed = apply_filters( 'upgrader_clear_destination', $removed, $local_destination, $remote_destination, $args['hook_extra'] );
289
+
290
+ if ( is_wp_error( $removed ) ) {
291
+ return $removed;
292
+ }
293
+ } elseif ( $args['abort_if_destination_exists'] && $wp_filesystem->exists( $remote_destination ) ) {
294
+ // If we're not clearing the destination folder and something exists there already, Bail.
295
+ // But first check to see if there are actually any files in the folder.
296
+ $_files = $wp_filesystem->dirlist( $remote_destination );
297
+ if ( ! empty( $_files ) ) {
298
+ $wp_filesystem->delete( $remote_source, true ); // Clear out the source files.
299
+ return new WP_Error( 'folder_exists', $this->strings['folder_exists'], $remote_destination );
300
+ }
301
+ }
302
+
303
+ // Create destination if needed
304
+ if ( ! $wp_filesystem->exists( $remote_destination ) ) {
305
+ if ( ! $wp_filesystem->mkdir( $remote_destination, FS_CHMOD_DIR ) ) {
306
+ return new WP_Error( 'mkdir_failed_destination', $this->strings['mkdir_failed'], $remote_destination );
307
+ }
308
+ }
309
+ // Copy new version of item into place.
310
+ $result = copy_dir( $source, $remote_destination );
311
+ if ( is_wp_error( $result ) ) {
312
+ if ( $args['clear_working'] ) {
313
+ $wp_filesystem->delete( $remote_source, true );
314
+ }
315
+ return $result;
316
+ }
317
+
318
+ // Clear the Working folder?
319
+ if ( $args['clear_working'] ) {
320
+ $wp_filesystem->delete( $remote_source, true );
321
+ }
322
+
323
+ $destination_name = basename( str_replace( $local_destination, '', $destination ) );
324
+ if ( '.' == $destination_name ) {
325
+ $destination_name = '';
326
+ }
327
+
328
+ $this->result = compact( 'source', 'source_files', 'destination', 'destination_name', 'local_destination', 'remote_destination', 'clear_destination' );
329
+
330
+ /**
331
+ * Filters the install response after the installation has finished.
332
+ *
333
+ * @since 2.8.0
334
+ *
335
+ * @param bool $response Install response.
336
+ * @param array $hook_extra Extra arguments passed to hooked filters.
337
+ * @param array $result Installation result data.
338
+ */
339
+ $res = apply_filters( 'upgrader_post_install', true, $args['hook_extra'], $this->result );
340
+
341
+ if ( is_wp_error( $res ) ) {
342
+ $this->result = $res;
343
+ return $res;
344
+ }
345
+
346
+ // Bombard the calling function will all the info which we've just used.
347
+ return $this->result;
348
+ }
349
+ }
includes/includes/admin/views/html-admin-page-importer-previews.php ADDED
@@ -0,0 +1,40 @@
1
+ <?php
2
+ /**
3
+ * Admin View: Page - Demo Previews
4
+ */
5
+
6
+ if ( ! defined( 'ABSPATH' ) ) {
7
+ exit;
8
+ }
9
+
10
+ global $current_tab;
11
+
12
+ $template = get_option( 'template' );
13
+ $assets_path = tg_get_demo_importer_assets_path();
14
+
15
+ ?>
16
+ <h2 class="screen-reader-text hide-if-no-js"><?php _e( 'Theme demos list', 'themegrill-demo-importer' ); ?></h2>
17
+
18
+ <div class="theme-browser content-filterable">
19
+ <div class="themes wp-clearfix">
20
+ <?php foreach ( $this->demo_packages as $pack_id => $pack_data ) : ?>
21
+ <div class="theme active" tabindex="0">
22
+ <?php if ( $screenshot = "{$assets_path}images/{$template}/{$pack_id}.jpg" ) : ?>
23
+ <div class="theme-screenshot">
24
+ <?php if ( file_is_displayable_image( $screenshot ) ) : ?>
25
+ <img src="<?php echo esc_url( $screenshot ); ?>" alt="" />
26
+ <?php endif; ?>
27
+ </div>
28
+ <?php else : ?>
29
+ <div class="theme-screenshot blank"></div>
30
+ <?php endif; ?>
31
+
32
+ <h2 class="theme-name" id="demo-name"><?php echo esc_html( $pack_data['name'] ); ?></h2>
33
+
34
+ <div class="theme-actions">
35
+ <a class="button button-primary live-preview" target="_blank" href="<?php echo esc_url( $pack_data['preview'] ); ?>"><?php _e( 'Live Preview', 'themegrill-demo-importer' ); ?></a>
36
+ </div>
37
+ </div>
38
+ <?php endforeach; ?>
39
+ </div>
40
+ </div>
includes/includes/admin/views/html-admin-page-importer-uploaded.php ADDED
@@ -0,0 +1,72 @@
1
+ <?php
2
+ /**
3
+ * Admin View: Page - Demo Uploaded
4
+ */
5
+
6
+ if ( ! defined( 'ABSPATH' ) ) {
7
+ exit;
8
+ }
9
+
10
+ global $current_tab;
11
+
12
+ $template = get_option( 'template' );
13
+ $demo_imported_id = get_option( 'themegrill_demo_imported_id' );
14
+
15
+ ?>
16
+ <h2 class="screen-reader-text hide-if-no-js"><?php _e( 'Available demos list', 'themegrill-demo-importer' ); ?></h2>
17
+
18
+ <div class="theme-browser content-filterable">
19
+ <div class="themes wp-clearfix">
20
+ <?php foreach ( $this->demo_config as $demo_id => $demo_data ) : ?>
21
+ <div class="theme<?php if ( $demo_id == $demo_imported_id ) echo ' active'; ?>" tabindex="0">
22
+ <?php if ( $screenshot = $this->import_file_url( $demo_id, 'screenshot.jpg' ) ) : ?>
23
+ <div class="theme-screenshot">
24
+ <?php if ( file_is_displayable_image( $screenshot ) ) : ?>
25
+ <img src="<?php echo esc_url( $screenshot ); ?>" alt="" />
26
+ <?php endif; ?>
27
+ </div>
28
+ <?php else : ?>
29
+ <div class="theme-screenshot blank"></div>
30
+ <?php endif; ?>
31
+
32
+ <?php if ( ! empty( $demo_data['plugins_list'] ) ) : ?>
33
+ <div class="notice inline notice-<?php echo isset( $demo_data['notice_type'] ) ? esc_attr( $demo_data['notice_type'] ) : 'info'; ?> notice-alt">
34
+ <?php if ( ! empty( $demo_data['plugins_list']['required'] ) && $plugins_required = tg_get_plugins_links( $demo_data['plugins_list']['required'] ) ) : ?>
35
+ <p><?php printf( __( '<strong>Required Plugins:</strong> %s', 'themegrill-demo-importer' ), $plugins_required ); ?></p>
36
+ <?php endif; ?>
37
+ <?php if ( ! empty( $demo_data['plugins_list']['recommended'] ) && $plugins_recommended = tg_get_plugins_links( $demo_data['plugins_list']['recommended'] ) ) : ?>
38
+ <p><?php printf( __( '<strong>Recommended Plugins:</strong> %s', 'themegrill-demo-importer' ), $plugins_recommended ); ?></p>
39
+ <?php endif; ?>
40
+ </div>
41
+ <?php endif; ?>
42
+
43
+ <?php if ( $demo_id == $demo_imported_id ) { ?>
44
+ <h2 class="theme-name" id="demo-name"><?php
45
+ /* translators: %s: demo name */
46
+ printf( __( '<span>Imported:</span> %s', 'themegrill-demo-importer' ), esc_html( $demo_data['name'] ) );
47
+ ?></h2>
48
+ <?php } else { ?>
49
+ <h2 class="theme-name" id="demo-name"><?php echo esc_html( $demo_data['name'] ); ?></h2>
50
+ <?php } ?>
51
+ <div class="theme-actions">
52
+ <?php if ( $demo_id !== $demo_imported_id ) : ?>
53
+ <?php if ( isset( $demo_data['template'] ) && $template !== $demo_data['template'] ) : ?>
54
+ <a class="button button-secondary tips import disabled" href="#" data-demo_id="<?php echo $demo_id; ?>" data-tip="<?php printf( esc_attr( 'Required %s theme must be activated to import this demo.', 'themegrill-demo-importer' ), wp_get_theme()->get( 'Name' ) ); ?>"><?php _e( 'Import', 'themegrill-demo-importer' ); ?></a>
55
+ <?php elseif ( ! empty( $demo_data['plugins_list'] ) ) : ?>
56
+ <?php if ( ! empty( $demo_data['plugins_list']['required'] ) && tg_is_plugins_active( $demo_data['plugins_list']['required'] ) ) : ?>
57
+ <a class="button button-secondary tips import disabled" href="#" data-demo_id="<?php echo $demo_id; ?>" data-tip="<?php esc_attr_e( 'Required Plugin must be activated to import this demo.', 'themegrill-demo-importer' ); ?>"><?php _e( 'Import', 'themegrill-demo-importer' ); ?></a>
58
+ <?php else : ?>
59
+ <a class="button button-secondary import plugins-ready" href="#" data-demo_id="<?php echo $demo_id; ?>"><?php _e( 'Import', 'themegrill-demo-importer' ); ?></a>
60
+ <?php endif; ?>
61
+ <?php else : ?>
62
+ <a class="button button-secondary import no-plugins-needed" href="#" data-demo_id="<?php echo $demo_id; ?>"><?php _e( 'Import', 'themegrill-demo-importer' ); ?></a>
63
+ <?php endif; ?>
64
+ <a class="button button-primary live-preview" target="_blank" href="<?php echo esc_url( $demo_data['demo_url'] ); ?>"><?php _e( 'Live Preview', 'themegrill-demo-importer' ); ?></a>
65
+ <?php endif; ?>
66
+ <a class="button button-primary preview" target="_blank" href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php _e( 'Preview', 'themegrill-demo-importer' ); ?></a>
67
+ <span class="spinner"><?php _e( 'Please Wait&hellip;', 'themegrill-demo-importer' ); ?></span>
68
+ </div>
69
+ </div>
70
+ <?php endforeach; ?>
71
+ </div>
72
+ </div>
includes/includes/admin/views/html-admin-page-importer-welcome.php ADDED
@@ -0,0 +1,29 @@
1
+ <?php
2
+ /**
3
+ * Admin View: Page - Welcome
4
+ */
5
+
6
+ if ( ! defined( 'ABSPATH' ) ) {
7
+ exit;
8
+ }
9
+
10
+ ?>
11
+ <div class="themegrill-demo-BlankState">
12
+ <div id="welcome-panel" class="welcome-panel">
13
+ <div class="welcome-panel-content">
14
+ <h2><?php _e( 'Welcome to ThemeGrill Demo Importer!', 'themegrill-demo-importer' ); ?></h2>
15
+ <h3><?php _e( 'Get Started','themegrill-demo-importer' ); ?></h3>
16
+ <div class="welcome-panel-column-container">
17
+ <div class="welcome-panel-column">
18
+ <ul>
19
+ <li><?php printf( __( '1. Visit <a href="%s" target="_blank"><strong>this page</strong></a> and download demo zip file.','themegrill-demo-importer' ),esc_url( 'http://themegrill.com/theme-demo-file-downloads/' ) ); ?></li>
20
+ <li><?php _e( '2. Click <strong>Upload Demo</strong> button on the top of this Page.','themegrill-demo-importer' ); ?></li>
21
+ <li><?php _e( '3. Browse the demo zip file and click <strong>Install Now</strong>.','themegrill-demo-importer' ); ?></li>
22
+ <li><?php _e( '4. Go to <strong>Available Demos</strong> tab.','themegrill-demo-importer' ); ?></li>
23
+ <li><?php _e( '5. Click <strong>Import</strong> button and wait for few minutes. Done!','themegrill-demo-importer' ); ?></li>
24
+ </ul>
25
+ </div>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </div>
includes/includes/admin/views/html-admin-page-importer.php ADDED
@@ -0,0 +1,63 @@
1
+ <?php
2
+ /**
3
+ * Admin View: Page - Importer
4
+ */
5
+
6
+ if ( ! defined( 'ABSPATH' ) ) {
7
+ exit;
8
+ }
9
+
10
+ $demo_imported_id = get_option( 'themegrill_demo_imported_id' );
11
+ $demo_filter_links = apply_filters( 'themegrill_demo_importer_filter_links_array', array(
12
+ 'welcome' => __( 'Welcome', 'themegrill-demo-importer' ),
13
+ 'uploaded' => __( 'Available Demos', 'themegrill-demo-importer' ),
14
+ 'previews' => __( 'Theme Demos', 'themegrill-demo-importer' ),
15
+ ) );
16
+
17
+ ?>
18
+ <div class="wrap demo-importer">
19
+ <h1><?php
20
+ esc_html_e( 'Demo Importer', 'themegrill-demo-importer' );
21
+ if ( current_user_can( 'upload_files' ) ) {
22
+ echo ' <button type="button" class="upload-view-toggle page-title-action hide-if-no-js tg-demo-upload" aria-expanded="false">' . __( 'Upload Demo', 'themegrill-demo-importer' ) . '</button>';
23
+ }
24
+ ?></h1>
25
+ <?php if ( ! get_option( 'themegrill_demo_imported_notice_dismiss' ) && in_array( $demo_imported_id, array_keys( $this->demo_config ) ) ) : ?>
26
+ <div id="message" class="notice notice-info is-dismissible" data-notice_id="demo-importer">
27
+ <p><?php printf( __( '<strong>Notice</strong> &#8211; If you want to completely remove a demo installation after importing it, you can use a plugin like %1$sWordPress Reset%2$s.', 'themegrill-demo-importer' ), '<a target="_blank" href="' . esc_url( 'https://wordpress.org/plugins/wordpress-reset/' ) . '">', '</a>' ); ?></p>
28
+ </div>
29
+ <?php endif; ?>
30
+ <div class="error hide-if-js">
31
+ <p><?php _e( 'The Demo Importer screen requires JavaScript.', 'themegrill-demo-importer' ); ?></p>
32
+ </div>
33
+ <div class="upload-theme">
34
+ <p class="install-help"><?php _e( 'If you have a demo pack in a .zip format, you may install it by uploading it here.', 'themegrill-demo-importer' ); ?></p>
35
+ <form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo self_admin_url( 'themes.php?page=demo-importer&action=upload-demo' ); ?>">
36
+ <?php wp_nonce_field( 'demo-upload' ); ?>
37
+ <label class="screen-reader-text" for="demozip"><?php _e( 'Demo zip file', 'themegrill-demo-importer' ); ?></label>
38
+ <input type="file" id="demozip" name="demozip" />
39
+ <?php submit_button( __( 'Install Now', 'themegrill-demo-importer' ), 'button', 'install-demo-submit', false ); ?>
40
+ </form>
41
+ </div>
42
+
43
+ <h2 class="screen-reader-text hide-if-no-js"><?php _e( 'Filter demos list', 'themegrill-demo-importer' ); ?></h2>
44
+
45
+ <div class="wp-filter hide-if-no-js">
46
+ <div class="filter-count">
47
+ <span class="count demo-count"><?php echo 'previews' == $current_tab ? count( $this->demo_packages ) : count( $this->demo_config ); ?></span>
48
+ </div>
49
+
50
+ <ul class="filter-links">
51
+ <?php
52
+ foreach ( $demo_filter_links as $name => $label ) {
53
+ if ( ( empty( $this->demo_config ) && 'uploaded' == $name ) || ( empty( $this->demo_packages ) && 'previews' == $name ) ) {
54
+ continue;
55
+ }
56
+ echo '<li><a href="' . admin_url( 'themes.php?page=demo-importer&tab=' . $name ) . '" class="demo-tab ' . ( $current_tab == $name ? 'current' : '' ) . '">' . $label . '</a></li>';
57
+ }
58
+ do_action( 'themegrill_demo_importer_filter_links' );
59
+ ?>
60
+ </ul>
61
+ </div>
62
+ <?php do_action( 'themegrill_demo_importer_' . $current_tab ); ?>
63
+ </div>
includes/includes/class-customizer-importer.php ADDED
@@ -0,0 +1,176 @@
1
+ <?php
2
+ /**
3
+ * Customizer importer - import customizer settings.
4
+ *
5
+ * Code adapted from the "Customizer Export/Import" plugin.
6
+ *
7
+ * @class TG_Customizer_Importer
8
+ * @version 1.0.0
9
+ * @package Importer/Classes
10
+ * @category Admin
11
+ * @author ThemeGrill
12
+ */
13
+
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
+
18
+ /**
19
+ * TG_Customizer_Importer Class.
20
+ */
21
+ class TG_Customizer_Importer {
22
+
23
+ /**
24
+ * Imports uploaded mods and calls WordPress core customize_save actions so
25
+ * themes that hook into them can act before mods are saved to the database.
26
+ *
27
+ * Update: WP core customize_save actions were removed, because of some errors.
28
+ *
29
+ * @param string $import_file Path to the import file.
30
+ * @param string $demo_id The ID of demo being imported.
31
+ * @param array $demo_data The data of demo being imported.
32
+ * @return void|WP_Error
33
+ */
34
+ public static function import( $import_file, $demo_id, $demo_data ) {
35
+ global $wp_customize;
36
+
37
+ $temp = get_template();
38
+ $data = maybe_unserialize( file_get_contents( $import_file ) );
39
+
40
+ // Data checks.
41
+ if ( ! is_array( $data ) && ( ! isset( $data['template'] ) || ! isset( $data['mods'] ) ) ) {
42
+ return new WP_Error( 'themegrill_customizer_import_data_error', __( 'The customizer import file is not in a correct format. Please make sure to use the correct customizer import file.', 'themegrill-demo-importer' ) );
43
+ }
44
+
45
+ if ( $data['template'] !== $temp ) {
46
+ return new WP_Error( 'themegrill_customizer_import_wrong_theme', __( 'The customizer import file is not suitable for current theme. You can only import customizer settings for the same theme or a child theme.', 'themegrill-demo-importer' ) );
47
+ }
48
+
49
+ // Import Images.
50
+ if ( apply_filters( 'themegrill_customizer_import_images', true ) ) {
51
+ $data['mods'] = self::import_customizer_images( $data['mods'] );
52
+ }
53
+
54
+ // Modify settings array.
55
+ $data = apply_filters( 'themegrill_customizer_demo_import_settings', $data, $demo_data, $demo_id );
56
+
57
+ // Import custom options.
58
+ if ( isset( $data['options'] ) ) {
59
+
60
+ // Load WordPress Customize Setting Class.
61
+ if ( ! class_exists( 'WP_Customize_Setting' ) ) {
62
+ require_once( ABSPATH . WPINC . '/class-wp-customize-setting.php' );
63
+ }
64
+
65
+ // Include Customizer Demo Importer Setting class.
66
+ include_once( dirname( __FILE__ ) . '/customize/class-oc-customize-demo-importer-setting.php' );
67
+
68
+ foreach ( $data['options'] as $option_key => $option_value ) {
69
+ $option = new OC_Customize_Demo_Importer_Setting( $wp_customize, $option_key, array(
70
+ 'default' => '',
71
+ 'type' => 'option',
72
+ 'capability' => 'edit_theme_options',
73
+ ) );
74
+
75
+ $option->import( $option_value );
76
+ }
77
+ }
78
+
79
+ // Loop through theme mods and update them.
80
+ if ( ! empty( $data['mods'] ) ) {
81
+ foreach ( $data['mods'] as $key => $value ) {
82
+ set_theme_mod( $key, $value );
83
+ }
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Imports images for settings saved as mods.
89
+ *
90
+ * @param array $mods An array of customizer mods.
91
+ * @return array The mods array with any new import data.
92
+ */
93
+ private static function import_customizer_images( $mods ) {
94
+ foreach ( $mods as $key => $value ) {
95
+ if ( self::is_image_url( $value ) ) {
96
+ $data = self::media_handle_sideload( $value );
97
+ if ( ! is_wp_error( $data ) ) {
98
+ $mods[ $key ] = $data->url;
99
+
100
+ // Handle header image controls.
101
+ if ( isset( $mods[ $key . '_data' ] ) ) {
102
+ $mods[ $key . '_data' ] = $data;
103
+ update_post_meta( $data->attachment_id, '_wp_attachment_is_custom_header', get_stylesheet() );
104
+ }
105