This commit is contained in:
KhaiNguyen
2020-02-13 10:39:37 +07:00
commit 59401cb805
12867 changed files with 4646216 additions and 0 deletions

View File

@@ -0,0 +1,360 @@
/* Overriding WordPress native styles */
.ocdi {
max-width: none;
}
.ocdi h2 {
text-align: inherit;
}
.ocdi h2:first-child,
.ocdi h3:first-child {
margin-top: 0;
}
.ocdi hr {
margin: 2.62em 0;
}
.feature-section + hr {
margin-top: 0;
}
#wpbody select {
height: auto;
padding: .62em;
line-height: inherit;
}
.ocdi .notice {
display: block !important;
}
/* Plugin elements */
.ocdi__demo-import-files {
width: 100%;
}
.ocdi__demo-import-preview-image-message {
font-style: italic;
}
/* Plugin title */
.ocdi__title:before {
width: auto;
height: auto;
font-size: inherit;
}
/* Plugin intro text */
.ocdi__intro-text ul {
padding: 0 4%;
list-style-type: square;
}
/* Plugin multi select import and Plugin file upload containers */
.ocdi__file-upload,
.ocdi__multi-select-import,
.ocdi__demo-import-notice:not(:empty) {
padding: 4%;
margin: 1.62em 0;
background-color: #ffffff;
border: 1px solid #e5e5e5;
}
.ocdi__file-upload {
margin: 0;
margin-bottom: -1px;
}
.ocdi__file-upload span {
font-size: .81em;
font-weight: normal;
opacity: .66;
}
.ocdi__demo-import-notice:not(:empty) {
border: 0;
border-left: 4px solid #00a0d2;
-webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
}
[dir="rtl"] .ocdi__demo-import-notice:not(:empty) {
border: 0;
border-right: 4px solid #00a0d2;
}
/* Plugin button */
.ocdi__button-container {
margin-top: 1.62em;
}
/* AJAX loader */
p.ocdi__ajax-loader {
font-size: 1.5em;
display: none;
}
.ocdi__ajax-loader .spinner {
display: inline-block;
float: none;
visibility: visible;
margin-bottom: 6px;
}
/* New grid layout */
.ocdi__gl-navigation li a {
-webkit-box-shadow: none;
box-shadow: none;
}
.ocdi__gl-item {
float: left;
width: 100%;
margin: 0 0 20px 0;
position: relative;
border: 1px solid #ddd;
-webkit-box-shadow: 0 1px 1px -1px rgba(0,0,0,0.1);
box-shadow: 0 1px 1px -1px rgba(0,0,0,0.1);
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.ocdi__gl-item-image-container {
display: block;
overflow: hidden;
position: relative;
-webkit-backface-visibility: hidden;
-webkit-transition: opacity 0.2s ease-in-out;
transition: opacity 0.2s ease-in-out;
}
.ocdi__gl-item-image-container::after {
content: "";
display: block;
padding-top: 60%;
}
.ocdi__gl-item-image {
height: auto;
position: absolute;
left: 0;
top: 0;
width: 100%;
-webkit-transition: opacity 0.2s ease-in-out;
transition: opacity 0.2s ease-in-out;
}
.ocdi__gl-item-image--no-image {
display: inline-block;
width: 50%;
text-align: center;
position: absolute;
top: 45%;
right: 25%;
left: 25%;
}
.ocdi__gl-item-footer {
height: 30px;
margin: 0;
padding: 10px;
-webkit-box-shadow: inset 0 1px 0 rgba(0,0,0,0.1);
box-shadow: inset 0 1px 0 rgba(0,0,0,0.1);
background: #ffffff;
background: rgba(255,255,255,0.65);
}
h4.ocdi__gl-item-title {
width: 70%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
display: inline-block;
margin: 6px 0 0 0;
}
.ocdi__gl-item-footer--with-preview h4.ocdi__gl-item-title {
width: calc(100% - 140px);
}
.ocdi__gl-item-button {
float: right;
}
.ocdi__gl-item-button + .ocdi__gl-item-button {
margin-right: 5px;
}
@media (max-width: 782px) {
h4.ocdi__gl-item-title,
.ocdi__gl-item-footer--with-preview h4.ocdi__gl-item-title {
width: 100%;
margin-bottom: 10px;
}
.ocdi__gl-item-button {
width: calc(50% - 10px);
margin-bottom: 10px;
}
.ocdi__gl-item-button + .ocdi__gl-item-button {
float: left;
}
.ocdi__gl-item-footer {
height: 72px;
}
}
.ocdi__gl-header {
display: inline-block;
width: calc(100% - 40px);
background-color: #ffffff;
margin-bottom: 20px;
padding: 0 20px;
}
.ocdi__gl-navigation {
font-size: 13px;
width: 100%;
float: left;
}
.ocdi__gl-navigation ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
}
.ocdi__gl-navigation li {
float: left;
margin: 0 15px;
}
.ocdi__gl-navigation li.active a,
.ocdi__gl-navigation li.active a:hover {
border-bottom: 4px solid #666666;
}
.ocdi__gl-navigation li a {
display: block;
text-align: center;
text-decoration: none;
color: #444444;
border-bottom: 4px solid #ffffff;
padding: 15px 0;
}
.ocdi__gl-navigation li a:hover {
color: #00a0d2;
border-bottom: 4px solid #ffffff;
cursor:pointer;
}
.ocdi__gl-search-input {
width: 100%;
margin: 10px 0;
}
@media (min-width: 640px) {
.ocdi__gl-navigation {
width: calc(100% - 180px);
}
.ocdi__gl-navigation li {
margin: 0;
}
.ocdi__gl-navigation li a {
padding: 15px;
}
.ocdi__gl-search-input {
display: inline-block;
width: 180px;
height: 30px;
margin: 0;
margin-top: 11px;
}
.ocdi__gl-item-container {
margin-right: -20px;
}
.ocdi__gl-item {
width: calc(50% - 20px);
margin: 0 20px 20px 0;
}
}
@media (min-width: 1120px) {
.ocdi__gl-item-container {
margin-right: -30px;
}
.ocdi__gl-item {
width: calc(33.333% - 30px);
margin: 0 30px 30px 0;
}
}
/* Grid animations */
@keyframes ocdi-fade {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.ocdi-is-fadeout {
animation: ocdi-fade linear 200ms 1 forwards;
}
.ocdi-is-fadein {
animation: ocdi-fade linear 200ms 1 reverse forwards;
}
/* Grid layout modal window */
.ocdi__modal-image-container {
width: 100%;
height: 180px;
margin: 0;
overflow: hidden;
}
.ocdi__modal-item-title {
margin-top: 0.5em;
font-weight: bold;
}
.ocdi__modal-image-container img {
width: 100%;
}
.ocdi__modal-notice.ocdi__demo-import-notice:not(:empty) {
border: 1px solid #e5e5e5;
border-left: 4px solid #00a0d2;
margin: 1em 0 0;
}
/* Redux */
.ocdi__redux-option-name-label {
margin-right: 5px;
}

View File

@@ -0,0 +1,329 @@
jQuery( function ( $ ) {
'use strict';
/**
* ---------------------------------------
* ------------- Events ------------------
* ---------------------------------------
*/
/**
* No or Single predefined demo import button click.
*/
$( '.js-ocdi-import-data' ).on( 'click', function () {
// Reset response div content.
$( '.js-ocdi-ajax-response' ).empty();
// Prepare data for the AJAX call
var data = new FormData();
data.append( 'action', 'ocdi_import_demo_data' );
data.append( 'security', ocdi.ajax_nonce );
data.append( 'selected', $( '#ocdi__demo-import-files' ).val() );
if ( $('#ocdi__content-file-upload').length ) {
data.append( 'content_file', $('#ocdi__content-file-upload')[0].files[0] );
}
if ( $('#ocdi__widget-file-upload').length ) {
data.append( 'widget_file', $('#ocdi__widget-file-upload')[0].files[0] );
}
if ( $('#ocdi__customizer-file-upload').length ) {
data.append( 'customizer_file', $('#ocdi__customizer-file-upload')[0].files[0] );
}
if ( $('#ocdi__redux-file-upload').length ) {
data.append( 'redux_file', $('#ocdi__redux-file-upload')[0].files[0] );
data.append( 'redux_option_name', $('#ocdi__redux-option-name').val() );
}
// AJAX call to import everything (content, widgets, before/after setup)
ajaxCall( data );
});
/**
* Grid Layout import button click.
*/
$( '.js-ocdi-gl-import-data' ).on( 'click', function () {
var selectedImportID = $( this ).val();
var $itemContainer = $( this ).closest( '.js-ocdi-gl-item' );
// If the import confirmation is enabled, then do that, else import straight away.
if ( ocdi.import_popup ) {
displayConfirmationPopup( selectedImportID, $itemContainer );
}
else {
gridLayoutImport( selectedImportID, $itemContainer );
}
});
/**
* Grid Layout categories navigation.
*/
(function () {
// Cache selector to all items
var $items = $( '.js-ocdi-gl-item-container' ).find( '.js-ocdi-gl-item' ),
fadeoutClass = 'ocdi-is-fadeout',
fadeinClass = 'ocdi-is-fadein',
animationDuration = 200;
// Hide all items.
var fadeOut = function () {
var dfd = jQuery.Deferred();
$items
.addClass( fadeoutClass );
setTimeout( function() {
$items
.removeClass( fadeoutClass )
.hide();
dfd.resolve();
}, animationDuration );
return dfd.promise();
};
var fadeIn = function ( category, dfd ) {
var filter = category ? '[data-categories*="' + category + '"]' : 'div';
if ( 'all' === category ) {
filter = 'div';
}
$items
.filter( filter )
.show()
.addClass( 'ocdi-is-fadein' );
setTimeout( function() {
$items
.removeClass( fadeinClass );
dfd.resolve();
}, animationDuration );
};
var animate = function ( category ) {
var dfd = jQuery.Deferred();
var promise = fadeOut();
promise.done( function () {
fadeIn( category, dfd );
} );
return dfd;
};
$( '.js-ocdi-nav-link' ).on( 'click', function( event ) {
event.preventDefault();
// Remove 'active' class from the previous nav list items.
$( this ).parent().siblings().removeClass( 'active' );
// Add the 'active' class to this nav list item.
$( this ).parent().addClass( 'active' );
var category = this.hash.slice(1);
// show/hide the right items, based on category selected
var $container = $( '.js-ocdi-gl-item-container' );
$container.css( 'min-width', $container.outerHeight() );
var promise = animate( category );
promise.done( function () {
$container.removeAttr( 'style' );
} );
} );
}());
/**
* Grid Layout search functionality.
*/
$( '.js-ocdi-gl-search' ).on( 'keyup', function( event ) {
if ( 0 < $(this).val().length ) {
// Hide all items.
$( '.js-ocdi-gl-item-container' ).find( '.js-ocdi-gl-item' ).hide();
// Show just the ones that have a match on the import name.
$( '.js-ocdi-gl-item-container' ).find( '.js-ocdi-gl-item[data-name*="' + $(this).val().toLowerCase() + '"]' ).show();
}
else {
$( '.js-ocdi-gl-item-container' ).find( '.js-ocdi-gl-item' ).show();
}
} );
/**
* ---------------------------------------
* --------Helper functions --------------
* ---------------------------------------
*/
/**
* Prepare grid layout import data and execute the AJAX call.
*
* @param int selectedImportID The selected import ID.
* @param obj $itemContainer The jQuery selected item container object.
*/
function gridLayoutImport( selectedImportID, $itemContainer ) {
// Reset response div content.
$( '.js-ocdi-ajax-response' ).empty();
// Hide all other import items.
$itemContainer.siblings( '.js-ocdi-gl-item' ).fadeOut( 500 );
$itemContainer.animate({
opacity: 0
}, 500, 'swing', function () {
$itemContainer.animate({
opacity: 1
}, 500 )
});
// Hide the header with category navigation and search box.
$itemContainer.closest( '.js-ocdi-gl' ).find( '.js-ocdi-gl-header' ).fadeOut( 500 );
// Append a title for the selected demo import.
$itemContainer.parent().prepend( '<h3>' + ocdi.texts.selected_import_title + '</h3>' );
// Remove the import button of the selected item.
$itemContainer.find( '.js-ocdi-gl-import-data' ).remove();
// Prepare data for the AJAX call
var data = new FormData();
data.append( 'action', 'ocdi_import_demo_data' );
data.append( 'security', ocdi.ajax_nonce );
data.append( 'selected', selectedImportID );
// AJAX call to import everything (content, widgets, before/after setup)
ajaxCall( data );
}
/**
* Display the confirmation popup.
*
* @param int selectedImportID The selected import ID.
* @param obj $itemContainer The jQuery selected item container object.
*/
function displayConfirmationPopup( selectedImportID, $itemContainer ) {
var $dialogContiner = $( '#js-ocdi-modal-content' );
var currentFilePreviewImage = ocdi.import_files[ selectedImportID ]['import_preview_image_url'] || ocdi.theme_screenshot;
var previewImageContent = '';
var importNotice = ocdi.import_files[ selectedImportID ]['import_notice'] || '';
var importNoticeContent = '';
var dialogOptions = $.extend(
{
'dialogClass': 'wp-dialog',
'resizable': false,
'width': '632',
'height': 'auto',
'modal': true
},
ocdi.dialog_options,
{
'buttons':
[
{
text: ocdi.texts.dialog_no,
class: 'kdadmin-button',
click: function() {
$(this).dialog('close');
}
},
{
text: ocdi.texts.dialog_yes,
class: 'kdadmin-button',
click: function() {
$(this).dialog('close');
gridLayoutImport( selectedImportID, $itemContainer );
}
}
]
});
if ( '' === currentFilePreviewImage ) {
previewImageContent = '<p>' + ocdi.texts.missing_preview_image + '</p>';
}
else {
previewImageContent = '<div class="ocdi__modal-image-container"><img src="' + currentFilePreviewImage + '" alt="' + ocdi.import_files[ selectedImportID ]['import_file_name'] + '"></div>'
}
// Prepare notice output.
if( '' !== importNotice ) {
importNoticeContent = '<div class="ocdi__modal-notice ocdi__demo-import-notice">' + importNotice + '</div>';
}
// Populate the dialog content.
$dialogContiner.prop( 'title', ocdi.texts.dialog_title );
$dialogContiner.html(
'<p class="ocdi__modal-item-title">' + ocdi.import_files[ selectedImportID ]['import_file_name'] + '</p>' +
previewImageContent +
importNoticeContent
);
// Display the confirmation popup.
$dialogContiner.dialog( dialogOptions );
}
/**
* The main AJAX call, which executes the import process.
*
* @param FormData data The data to be passed to the AJAX call.
*/
function ajaxCall( data ) {
$.ajax({
method: 'POST',
url: ocdi.ajax_url,
data: data,
contentType: false,
processData: false,
beforeSend: function() {
$( '.js-ocdi-ajax-loader' ).show();
}
})
.done( function( response ) {
if ( 'undefined' !== typeof response.status && 'newAJAX' === response.status ) {
ajaxCall( data );
}
else if ( 'undefined' !== typeof response.status && 'customizerAJAX' === response.status ) {
// Fix for data.set and data.delete, which they are not supported in some browsers.
var newData = new FormData();
newData.append( 'action', 'ocdi_import_customizer_data' );
newData.append( 'security', ocdi.ajax_nonce );
// Set the wp_customize=on only if the plugin filter is set to true.
if ( true === ocdi.wp_customize_on ) {
newData.append( 'wp_customize', 'on' );
}
ajaxCall( newData );
}
else if ( 'undefined' !== typeof response.status && 'afterAllImportAJAX' === response.status ) {
// Fix for data.set and data.delete, which they are not supported in some browsers.
var newData = new FormData();
newData.append( 'action', 'ocdi_after_import_data' );
newData.append( 'security', ocdi.ajax_nonce );
ajaxCall( newData );
}
else if ( 'undefined' !== typeof response.message ) {
$( '.js-ocdi-ajax-response' ).append( '<p>' + response.message + '</p>' );
$( '.js-ocdi-ajax-loader' ).hide();
// Trigger custom event, when OCDI import is complete.
$( document ).trigger( 'ocdiImportComplete' );
}
else {
$( '.js-ocdi-ajax-response' ).append( '<div class="notice notice-error is-dismissible"><p>' + response + '</p></div>' );
$( '.js-ocdi-ajax-loader' ).hide();
}
})
.fail( function( error ) {
$( '.js-ocdi-ajax-response' ).append( '<div class="notice notice-error is-dismissible"><p>Error: ' + error.statusText + ' (' + error.status + ')' + '</p></div>' );
$( '.js-ocdi-ajax-loader' ).hide();
});
}
} );

View File

@@ -0,0 +1,241 @@
<?php
/**
* Class for the customizer importer used in the One Click Demo Import plugin.
*
* Code is mostly from the Customizer Export/Import plugin.
*
* @see https://wordpress.org/plugins/customizer-export-import/
* @package ocdi
*/
namespace OCDI;
class CustomizerImporter {
/**
* Import customizer from a DAT file, generated by the Customizer Export/Import plugin.
*
* @param string $customizer_import_file_path path to the customizer import file.
*/
public static function import( $customizer_import_file_path ) {
$ocdi = OneClickDemoImport::get_instance();
$log_file_path = $ocdi->get_log_file_path();
// Try to import the customizer settings.
$results = self::import_customizer_options( $customizer_import_file_path );
// Check for errors, else write the results to the log file.
if ( is_wp_error( $results ) ) {
$error_message = $results->get_error_message();
// Add any error messages to the frontend_error_messages variable in OCDI main class.
$ocdi->append_to_frontend_error_messages( $error_message );
// Write error to log file.
Helpers::append_to_file(
$error_message,
$log_file_path,
esc_html__( 'Importing customizer settings', 'pt-ocdi' )
);
}
else {
// Add this message to log file.
$log_added = Helpers::append_to_file(
esc_html__( 'Customizer settings import finished!', 'pt-ocdi' ),
$log_file_path,
esc_html__( 'Importing customizer settings' , 'pt-ocdi' )
);
}
}
/**
* Imports uploaded mods and calls WordPress core customize_save actions so
* themes that hook into them can act before mods are saved to the database.
*
* Update: WP core customize_save actions were removed, because of some errors.
*
* @since 1.1.1
* @param string $import_file_path Path to the import file.
* @return void|WP_Error
*/
public static function import_customizer_options( $import_file_path ) {
// Setup global vars.
global $wp_customize;
// Setup internal vars.
$template = get_template();
// Make sure we have an import file.
if ( ! file_exists( $import_file_path ) ) {
return new \WP_Error(
'missing_cutomizer_import_file',
sprintf(
esc_html__( 'Error: The customizer import file is missing! File path: %s', 'pt-ocdi' ),
$import_file_path
)
);
}
// Get the upload data.
$raw = Helpers::data_from_file( $import_file_path );
// Make sure we got the data.
if ( is_wp_error( $raw ) ) {
return $raw;
}
$data = unserialize( $raw );
// Data checks.
if ( ! is_array( $data ) && ( ! isset( $data['template'] ) || ! isset( $data['mods'] ) ) ) {
return new \WP_Error(
'customizer_import_data_error',
esc_html__( 'Error: The customizer import file is not in a correct format. Please make sure to use the correct customizer import file.', 'pt-ocdi' )
);
}
if ( $data['template'] !== $template ) {
return new \WP_Error(
'customizer_import_wrong_theme',
esc_html__( 'Error: The customizer import file is not suitable for current theme. You can only import customizer settings for the same theme or a child theme.', 'pt-ocdi' )
);
}
// Import images.
if ( apply_filters( 'pt-ocdi/customizer_import_images', true ) ) {
$data['mods'] = self::import_customizer_images( $data['mods'] );
}
// Import custom options.
if ( isset( $data['options'] ) ) {
// Require modified customizer options class.
if ( ! class_exists( '\WP_Customize_Setting' ) ) {
require_once ABSPATH . 'wp-includes/class-wp-customize-setting.php';
}
foreach ( $data['options'] as $option_key => $option_value ) {
$option = new CustomizerOption( $wp_customize, $option_key, array(
'default' => '',
'type' => 'option',
'capability' => 'edit_theme_options',
) );
$option->import( $option_value );
}
}
// Should the customizer import use the WP customize_save* hooks?
$use_wp_customize_save_hooks = apply_filters( 'pt-ocdi/enable_wp_customize_save_hooks', false );
if ( $use_wp_customize_save_hooks ) {
do_action( 'customize_save', $wp_customize );
}
// Loop through the mods and save the mods.
foreach ( $data['mods'] as $key => $val ) {
if ( $use_wp_customize_save_hooks ) {
do_action( 'customize_save_' . $key, $wp_customize );
}
set_theme_mod( $key, $val );
}
if ( $use_wp_customize_save_hooks ) {
do_action( 'customize_save_after', $wp_customize );
}
}
/**
* Helper function: Customizer import - imports images for settings saved as mods.
*
* @since 1.1.1
* @param array $mods An array of customizer mods.
* @return array The mods array with any new import data.
*/
private static function import_customizer_images( $mods ) {
foreach ( $mods as $key => $val ) {
if ( self::customizer_is_image_url( $val ) ) {
$data = self::customizer_sideload_image( $val );
if ( ! is_wp_error( $data ) ) {
$mods[ $key ] = $data->url;
// Handle header image controls.
if ( isset( $mods[ $key . '_data' ] ) ) {
$mods[ $key . '_data' ] = $data;
update_post_meta( $data->attachment_id, '_wp_attachment_is_custom_header', get_stylesheet() );
}
}
}
}
return $mods;
}
/**
* Helper function: Customizer import
* Taken from the core media_sideload_image function and
* modified to return an array of data instead of html.
*
* @since 1.1.1.
* @param string $file The image file path.
* @return array An array of image data.
*/
private static function customizer_sideload_image( $file ) {
$data = new \stdClass();
if ( ! function_exists( 'media_handle_sideload' ) ) {
require_once( ABSPATH . 'wp-admin/includes/media.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/image.php' );
}
if ( ! empty( $file ) ) {
// Set variables for storage, fix file filename for query strings.
preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches );
$file_array = array();
$file_array['name'] = basename( $matches[0] );
// Download file to temp location.
$file_array['tmp_name'] = download_url( $file );
// If error storing temporarily, return the error.
if ( is_wp_error( $file_array['tmp_name'] ) ) {
return $file_array['tmp_name'];
}
// Do the validation and storage stuff.
$id = media_handle_sideload( $file_array, 0 );
// If error storing permanently, unlink.
if ( is_wp_error( $id ) ) {
unlink( $file_array['tmp_name'] );
return $id;
}
// Build the object to return.
$meta = wp_get_attachment_metadata( $id );
$data->attachment_id = $id;
$data->url = wp_get_attachment_url( $id );
$data->thumbnail_url = wp_get_attachment_thumb_url( $id );
$data->height = $meta['height'];
$data->width = $meta['width'];
}
return $data;
}
/**
* Checks to see whether a string is an image url or not.
*
* @since 1.1.1
* @param string $string The string to check.
* @return bool Whether the string is an image url or not.
*/
private static function customizer_is_image_url( $string = '' ) {
if ( is_string( $string ) ) {
if ( preg_match( '/\.(jpg|jpeg|png|gif)/i', $string ) ) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* A class that extends WP_Customize_Setting so we can access
* the protected updated method when importing options.
*
* Used in the Customizer importer.
*
* @since 1.1.1
* @package ocdi
*/
namespace OCDI;
final class CustomizerOption extends \WP_Customize_Setting {
/**
* Import an option value for this setting.
*
* @since 1.1.1
* @param mixed $value The option value.
* @return void
*/
public function import( $value ) {
$this->update( $value );
}
}

View File

@@ -0,0 +1,138 @@
<?php
/**
* Class for downloading a file from a given URL.
*
* @package ocdi
*/
namespace OCDI;
class Downloader {
/**
* Holds full path to where the files will be saved.
*
* @var string
*/
private $download_directory_path = '';
/**
* Constructor method.
*
* @param string $download_directory_path Full path to where the files will be saved.
*/
public function __construct( $download_directory_path = '' ) {
$this->set_download_directory_path( $download_directory_path );
}
/**
* Download file from a given URL.
*
* @param string $url URL of file to download.
* @param string $filename Filename of the file to save.
* @return string|WP_Error Full path to the downloaded file or WP_Error object with error message.
*/
public function download_file( $url, $filename ) {
$content = $this->get_content_from_url( $url );
// Check if there was an error and break out.
if ( is_wp_error( $content ) ) {
return $content;
}
return Helpers::write_to_file( $content, $this->download_directory_path . $filename );
}
/**
* Helper function: get content from an URL.
*
* @param string $url URL to the content file.
* @return string|WP_Error, content from the URL or WP_Error object with error message.
*/
private function get_content_from_url( $url ) {
// Test if the URL to the file is defined.
if ( empty( $url ) ) {
return new \WP_Error(
'missing_url',
__( 'Missing URL for downloading a file!', 'pt-ocdi' )
);
}
// Get file content from the server.
$response = wp_remote_get(
$url,
array( 'timeout' => apply_filters( 'pt-ocdi/timeout_for_downloading_import_file', 20 ) )
);
// Test if the get request was not successful.
if ( is_wp_error( $response ) || 200 !== $response['response']['code'] ) {
// Collect the right format of error data (array or WP_Error).
$response_error = $this->get_error_from_response( $response );
return new \WP_Error(
'download_error',
sprintf(
__( 'An error occurred while fetching file from: %1$s%2$s%3$s!%4$sReason: %5$s - %6$s.', 'pt-ocdi' ),
'<strong>',
$url,
'</strong>',
'<br>',
$response_error['error_code'],
$response_error['error_message']
) . '<br>' .
apply_filters( 'pt-ocdi/message_after_file_fetching_error', '' )
);
}
// Return content retrieved from the URL.
return wp_remote_retrieve_body( $response );
}
/**
* Helper function: get the right format of response errors.
*
* @param array|WP_Error $response Array or WP_Error or the response.
* @return array Error code and error message.
*/
private function get_error_from_response( $response ) {
$response_error = array();
if ( is_array( $response ) ) {
$response_error['error_code'] = $response['response']['code'];
$response_error['error_message'] = $response['response']['message'];
}
else {
$response_error['error_code'] = $response->get_error_code();
$response_error['error_message'] = $response->get_error_message();
}
return $response_error;
}
/**
* Get download_directory_path attribute.
*/
public function get_download_directory_path() {
return $this->download_directory_path;
}
/**
* Set download_directory_path attribute.
* If no valid path is specified, the default WP upload directory will be used.
*
* @param string $download_directory_path Path, where the files will be saved.
*/
public function set_download_directory_path( $download_directory_path ) {
if ( file_exists( $download_directory_path ) ) {
$this->download_directory_path = $download_directory_path;
}
else {
$upload_dir = wp_upload_dir();
$this->download_directory_path = apply_filters( 'pt-ocdi/upload_file_path', trailingslashit( $upload_dir['path'] ) );
}
}
}

View File

@@ -0,0 +1,650 @@
<?php
/**
* Static functions used in the OCDI plugin.
*
* @package ocdi
*/
namespace OCDI;
/**
* Class with static helper functions.
*/
class Helpers {
/**
* Holds the date and time string for demo import and log file.
*
* @var string
*/
public static $demo_import_start_time = '';
/**
* Filter through the array of import files and get rid of those who do not comply.
*
* @param array $import_files list of arrays with import file details.
* @return array list of filtered arrays.
*/
public static function validate_import_file_info( $import_files ) {
$filtered_import_file_info = array();
foreach ( $import_files as $import_file ) {
if ( self::is_import_file_info_format_correct( $import_file ) ) {
$filtered_import_file_info[] = $import_file;
}
}
return $filtered_import_file_info;
}
/**
* Helper function: a simple check for valid import file format.
*
* @param array $import_file_info array with import file details.
* @return boolean
*/
private static function is_import_file_info_format_correct( $import_file_info ) {
if ( empty( $import_file_info['import_file_name'] ) ) {
return false;
}
return true;
}
/**
* Download import files. Content .xml and widgets .wie|.json files.
*
* @param array $import_file_info array with import file details.
* @return array|WP_Error array of paths to the downloaded files or WP_Error object with error message.
*/
public static function download_import_files( $import_file_info ) {
$downloaded_files = array(
'content' => '',
'widgets' => '',
'customizer' => '',
'redux' => '',
);
$downloader = new Downloader();
// ----- Set content file path -----
// Check if 'import_file_url' is not defined. That would mean a local file.
if ( empty( $import_file_info['import_file_url'] ) ) {
if ( file_exists( $import_file_info['local_import_file'] ) ) {
$downloaded_files['content'] = $import_file_info['local_import_file'];
}
}
else {
// Set the filename string for content import file.
$content_filename = apply_filters( 'pt-ocdi/downloaded_content_file_prefix', 'demo-content-import-file_' ) . self::$demo_import_start_time . apply_filters( 'pt-ocdi/downloaded_content_file_suffix_and_file_extension', '.xml' );
// Download the content import file.
$downloaded_files['content'] = $downloader->download_file( $import_file_info['import_file_url'], $content_filename );
// Return from this function if there was an error.
if ( is_wp_error( $downloaded_files['content'] ) ) {
return $downloaded_files['content'];
}
}
// ----- Set widget file path -----
// Get widgets file as well. If defined!
if ( ! empty( $import_file_info['import_widget_file_url'] ) ) {
// Set the filename string for widgets import file.
$widget_filename = apply_filters( 'pt-ocdi/downloaded_widgets_file_prefix', 'demo-widgets-import-file_' ) . self::$demo_import_start_time . apply_filters( 'pt-ocdi/downloaded_widgets_file_suffix_and_file_extension', '.json' );
// Download the widgets import file.
$downloaded_files['widgets'] = $downloader->download_file( $import_file_info['import_widget_file_url'], $widget_filename );
// Return from this function if there was an error.
if ( is_wp_error( $downloaded_files['widgets'] ) ) {
return $downloaded_files['widgets'];
}
}
else if ( ! empty( $import_file_info['local_import_widget_file'] ) ) {
if ( file_exists( $import_file_info['local_import_widget_file'] ) ) {
$downloaded_files['widgets'] = $import_file_info['local_import_widget_file'];
}
}
// ----- Set customizer file path -----
// Get customizer import file as well. If defined!
if ( ! empty( $import_file_info['import_customizer_file_url'] ) ) {
// Setup filename path to save the customizer content.
$customizer_filename = apply_filters( 'pt-ocdi/downloaded_customizer_file_prefix', 'demo-customizer-import-file_' ) . self::$demo_import_start_time . apply_filters( 'pt-ocdi/downloaded_customizer_file_suffix_and_file_extension', '.dat' );
// Download the customizer import file.
$downloaded_files['customizer'] = $downloader->download_file( $import_file_info['import_customizer_file_url'], $customizer_filename );
// Return from this function if there was an error.
if ( is_wp_error( $downloaded_files['customizer'] ) ) {
return $downloaded_files['customizer'];
}
}
else if ( ! empty( $import_file_info['local_import_customizer_file'] ) ) {
if ( file_exists( $import_file_info['local_import_customizer_file'] ) ) {
$downloaded_files['customizer'] = $import_file_info['local_import_customizer_file'];
}
}
// ----- Set Redux file paths -----
// Get Redux import file as well. If defined!
if ( ! empty( $import_file_info['import_redux'] ) && is_array( $import_file_info['import_redux'] ) ) {
$redux_items = array();
// Setup filename paths to save the Redux content.
foreach ( $import_file_info['import_redux'] as $index => $redux_item ) {
$redux_filename = apply_filters( 'pt-ocdi/downloaded_redux_file_prefix', 'demo-redux-import-file_' ) . $index . '-' . self::$demo_import_start_time . apply_filters( 'pt-ocdi/downloaded_redux_file_suffix_and_file_extension', '.json' );
// Download the Redux import file.
$file_path = $downloader->download_file( $redux_item['file_url'], $redux_filename );
// Return from this function if there was an error.
if ( is_wp_error( $file_path ) ) {
return $file_path;
}
$redux_items[] = array(
'option_name' => $redux_item['option_name'],
'file_path' => $file_path,
);
}
// Download the Redux import file.
$downloaded_files['redux'] = $redux_items;
}
else if ( ! empty( $import_file_info['local_import_redux'] ) ) {
$redux_items = array();
// Setup filename paths to save the Redux content.
foreach ( $import_file_info['local_import_redux'] as $redux_item ) {
if ( file_exists( $redux_item['file_path'] ) ) {
$redux_items[] = $redux_item;
}
}
// Download the Redux import file.
$downloaded_files['redux'] = $redux_items;
}
return $downloaded_files;
}
/**
* Write content to a file.
*
* @param string $content content to be saved to the file.
* @param string $file_path file path where the content should be saved.
* @return string|WP_Error path to the saved file or WP_Error object with error message.
*/
public static function write_to_file( $content, $file_path ) {
// Verify WP file-system credentials.
$verified_credentials = self::check_wp_filesystem_credentials();
if ( is_wp_error( $verified_credentials ) ) {
return $verified_credentials;
}
// By this point, the $wp_filesystem global should be working, so let's use it to create a file.
global $wp_filesystem;
if ( ! $wp_filesystem->put_contents( $file_path, $content ) ) {
return new \WP_Error(
'failed_writing_file_to_server',
sprintf(
__( 'An error occurred while writing file to your server! Tried to write a file to: %s%s.', 'pt-ocdi' ),
'<br>',
$file_path
)
);
}
// Return the file path on successful file write.
return $file_path;
}
/**
* Append content to the file.
*
* @param string $content content to be saved to the file.
* @param string $file_path file path where the content should be saved.
* @param string $separator_text separates the existing content of the file with the new content.
* @return boolean|WP_Error, path to the saved file or WP_Error object with error message.
*/
public static function append_to_file( $content, $file_path, $separator_text = '' ) {
// Verify WP file-system credentials.
$verified_credentials = self::check_wp_filesystem_credentials();
if ( is_wp_error( $verified_credentials ) ) {
return $verified_credentials;
}
// By this point, the $wp_filesystem global should be working, so let's use it to create a file.
global $wp_filesystem;
$existing_data = '';
if ( file_exists( $file_path ) ) {
$existing_data = $wp_filesystem->get_contents( $file_path );
}
// Style separator.
$separator = PHP_EOL . '---' . $separator_text . '---' . PHP_EOL;
if ( ! $wp_filesystem->put_contents( $file_path, $existing_data . $separator . $content . PHP_EOL ) ) {
return new \WP_Error(
'failed_writing_file_to_server',
sprintf(
__( 'An error occurred while writing file to your server! Tried to write a file to: %s%s.', 'pt-ocdi' ),
'<br>',
$file_path
)
);
}
return true;
}
/**
* Get data from a file
*
* @param string $file_path file path where the content should be saved.
* @return string $data, content of the file or WP_Error object with error message.
*/
public static function data_from_file( $file_path ) {
// Verify WP file-system credentials.
$verified_credentials = self::check_wp_filesystem_credentials();
if ( is_wp_error( $verified_credentials ) ) {
return $verified_credentials;
}
// By this point, the $wp_filesystem global should be working, so let's use it to read a file.
global $wp_filesystem;
$data = $wp_filesystem->get_contents( $file_path );
if ( ! $data ) {
return new \WP_Error(
'failed_reading_file_from_server',
sprintf(
__( 'An error occurred while reading a file from your server! Tried reading file from path: %s%s.', 'pt-ocdi' ),
'<br>',
$file_path
)
);
}
// Return the file data.
return $data;
}
/**
* Helper function: check for WP file-system credentials needed for reading and writing to a file.
*
* @return boolean|WP_Error
*/
private static function check_wp_filesystem_credentials() {
// Check if the file-system method is 'direct', if not display an error.
if ( ! ( 'direct' === get_filesystem_method() ) ) {
return new \WP_Error(
'no_direct_file_access',
sprintf(
__( 'This WordPress page does not have %sdirect%s write file access. This plugin needs it in order to save the demo import xml file to the upload directory of your site. You can change this setting with these instructions: %s.', 'pt-ocdi' ),
'<strong>',
'</strong>',
'<a href="http://gregorcapuder.com/wordpress-how-to-set-direct-filesystem-method/" target="_blank">How to set <strong>direct</strong> filesystem method</a>'
)
);
}
// Get plugin page settings.
$plugin_page_setup = apply_filters( 'pt-ocdi/plugin_page_setup', array(
'parent_slug' => 'themes.php',
'page_title' => esc_html__( 'One Click Demo Import' , 'pt-ocdi' ),
'menu_title' => esc_html__( 'Import Demo Data' , 'pt-ocdi' ),
'capability' => 'import',
'menu_slug' => 'pt-one-click-demo-import',
)
);
// Get user credentials for WP file-system API.
$demo_import_page_url = wp_nonce_url( $plugin_page_setup['parent_slug'] . '?page=' . $plugin_page_setup['menu_slug'], $plugin_page_setup['menu_slug'] );
if ( false === ( $creds = request_filesystem_credentials( $demo_import_page_url, '', false, false, null ) ) ) {
return new \WP_error(
'filesystem_credentials_could_not_be_retrieved',
__( 'An error occurred while retrieving reading/writing permissions to your server (could not retrieve WP filesystem credentials)!', 'pt-ocdi' )
);
}
// Now we have credentials, try to get the wp_filesystem running.
if ( ! WP_Filesystem( $creds ) ) {
return new \WP_Error(
'wrong_login_credentials',
__( 'Your WordPress login credentials don\'t allow to use WP_Filesystem!', 'pt-ocdi' )
);
}
return true;
}
/**
* Get log file path
*
* @return string, path to the log file
*/
public static function get_log_path() {
$upload_dir = wp_upload_dir();
$upload_path = apply_filters( 'pt-ocdi/upload_file_path', trailingslashit( $upload_dir['path'] ) );
$log_path = $upload_path . apply_filters( 'pt-ocdi/log_file_prefix', 'log_file_' ) . self::$demo_import_start_time . apply_filters( 'pt-ocdi/log_file_suffix_and_file_extension', '.txt' );
self::register_file_as_media_attachment( $log_path );
return $log_path;
}
/**
* Register file as attachment to the Media page.
*
* @param string $log_path log file path.
* @return void
*/
public static function register_file_as_media_attachment( $log_path ) {
// Check the type of file.
$log_mimes = array( 'txt' => 'text/plain' );
$filetype = wp_check_filetype( basename( $log_path ), apply_filters( 'pt-ocdi/file_mimes', $log_mimes ) );
// Prepare an array of post data for the attachment.
$attachment = array(
'guid' => self::get_log_url( $log_path ),
'post_mime_type' => $filetype['type'],
'post_title' => apply_filters( 'pt-ocdi/attachment_prefix', esc_html__( 'One Click Demo Import - ', 'pt-ocdi' ) ) . preg_replace( '/\.[^.]+$/', '', basename( $log_path ) ),
'post_content' => '',
'post_status' => 'inherit',
);
// Insert the file as attachment in Media page.
$attach_id = wp_insert_attachment( $attachment, $log_path );
}
/**
* Get log file url
*
* @param string $log_path log path to use for the log filename.
* @return string, url to the log file.
*/
public static function get_log_url( $log_path ) {
$upload_dir = wp_upload_dir();
$upload_url = apply_filters( 'pt-ocdi/upload_file_url', trailingslashit( $upload_dir['url'] ) );
return $upload_url . basename( $log_path );
}
/**
* Check if the AJAX call is valid.
*/
public static function verify_ajax_call() {
check_ajax_referer( 'ocdi-ajax-verification', 'security' );
// Check if user has the WP capability to import data.
if ( ! current_user_can( 'import' ) ) {
wp_die(
sprintf(
__( '%sYour user role isn\'t high enough. You don\'t have permission to import demo data.%s', 'pt-ocdi' ),
'<div class="notice notice-error"><p>',
'</p></div>'
)
);
}
}
/**
* Process uploaded files and return the paths to these files.
*
* @param array $uploaded_files $_FILES array form an AJAX request.
* @param string $log_file_path path to the log file.
* @return array of paths to the content import and widget import files.
*/
public static function process_uploaded_files( $uploaded_files, $log_file_path ) {
// Variable holding the paths to the uploaded files.
$selected_import_files = array(
'content' => '',
'widgets' => '',
'customizer' => '',
'redux' => '',
);
// Upload settings to disable form and type testing for AJAX uploads.
$upload_overrides = array(
'test_form' => false,
'test_type' => false,
);
// Handle demo content and widgets file upload.
$content_file_info = wp_handle_upload( $_FILES['content_file'], $upload_overrides );
$widget_file_info = wp_handle_upload( $_FILES['widget_file'], $upload_overrides );
$customizer_file_info = wp_handle_upload( $_FILES['customizer_file'], $upload_overrides );
$redux_file_info = wp_handle_upload( $_FILES['redux_file'], $upload_overrides );
// Process content import file.
if ( $content_file_info && ! isset( $content_file_info['error'] ) ) {
// Set uploaded content file.
$selected_import_files['content'] = $content_file_info['file'];
}
else {
// Add this error to log file.
$log_added = self::append_to_file(
sprintf(
__( 'Content file was not uploaded. Error: %s', 'pt-ocdi' ),
$widget_file_info['error']
),
$log_file_path,
esc_html__( 'Upload files' , 'pt-ocdi' )
);
}
// Process widget import file.
if ( $widget_file_info && ! isset( $widget_file_info['error'] ) ) {
// Set uploaded widget file.
$selected_import_files['widgets'] = $widget_file_info['file'];
}
else {
// Add this error to log file.
$log_added = self::append_to_file(
sprintf(
__( 'Widget file was not uploaded. Error: %s', 'pt-ocdi' ),
$widget_file_info['error']
),
$log_file_path,
esc_html__( 'Upload files' , 'pt-ocdi' )
);
}
// Process Customizer import file.
if ( $customizer_file_info && ! isset( $customizer_file_info['error'] ) ) {
// Set uploaded customizer file.
$selected_import_files['customizer'] = $customizer_file_info['file'];
}
else {
// Add this error to log file.
$log_added = self::append_to_file(
sprintf(
__( 'Customizer file was not uploaded. Error: %s', 'pt-ocdi' ),
$customizer_file_info['error']
),
$log_file_path,
esc_html__( 'Upload files' , 'pt-ocdi' )
);
}
// Process Redux import file.
if ( $redux_file_info && ! isset( $redux_file_info['error'] ) ) {
if ( isset( $_POST['redux_option_name'] ) && empty( $_POST['redux_option_name'] ) ) {
// Write error to log file and send an AJAX response with the error.
self::log_error_and_send_ajax_response(
esc_html__( 'Missing Redux option name! Please also enter the Redux option name!', 'pt-ocdi' ),
$log_file_path,
esc_html__( 'Upload files', 'pt-ocdi' )
);
}
// Set uploaded Redux file.
$selected_import_files['redux'] = array(
array(
'option_name' => $_POST['redux_option_name'],
'file_path' => $redux_file_info['file'],
),
);
}
else {
// Add this error to log file.
$log_added = self::append_to_file(
sprintf(
__( 'Redux file was not uploaded. Error: %s', 'pt-ocdi' ),
$redux_file_info['error']
),
$log_file_path,
esc_html__( 'Upload files' , 'pt-ocdi' )
);
}
// Add this message to log file.
$log_added = self::append_to_file(
__( 'The import files were successfully uploaded!', 'pt-ocdi' ) . self::import_file_info( $selected_import_files ),
$log_file_path,
esc_html__( 'Upload files' , 'pt-ocdi' )
);
// Return array with paths of uploaded files.
return $selected_import_files;
}
/**
* Get import file information and max execution time.
*
* @param array $selected_import_files array of selected import files.
*/
public static function import_file_info( $selected_import_files ) {
$redux_file_string = '';
if ( ! empty( $selected_import_files['redux'] ) ) {
$redux_file_string = array_reduce( $selected_import_files['redux'], function( $string, $item ) {
return sprintf( '%1$s%2$s -> %3$s %4$s', $string, $item['option_name'], $item['file_path'], PHP_EOL );
}, '' );
}
return PHP_EOL .
sprintf(
__( 'Initial max execution time = %s', 'pt-ocdi' ),
ini_get( 'max_execution_time' )
) . PHP_EOL .
sprintf(
__( 'Files info:%1$sSite URL = %2$s%1$sData file = %3$s%1$sWidget file = %4$s%1$sCustomizer file = %5$s%1$sRedux files:%1$s%6$s', 'pt-ocdi' ),
PHP_EOL,
get_site_url(),
empty( $selected_import_files['content'] ) ? esc_html__( 'not defined!', 'pt-ocdi' ) : $selected_import_files['content'],
empty( $selected_import_files['widgets'] ) ? esc_html__( 'not defined!', 'pt-ocdi' ) : $selected_import_files['widgets'],
empty( $selected_import_files['customizer'] ) ? esc_html__( 'not defined!', 'pt-ocdi' ) : $selected_import_files['customizer'],
empty( $redux_file_string ) ? esc_html__( 'not defined!', 'pt-ocdi' ) : $redux_file_string
);
}
/**
* Write the error to the log file and send the AJAX response.
*
* @param string $error_text text to display in the log file and in the AJAX response.
* @param string $log_file_path path to the log file.
* @param string $separator title separating the old and new content.
*/
public static function log_error_and_send_ajax_response( $error_text, $log_file_path, $separator = '' ) {
// Add this error to log file.
$log_added = self::append_to_file(
$error_text,
$log_file_path,
$separator
);
// Send JSON Error response to the AJAX call.
wp_send_json( $error_text );
}
/**
* Set the $demo_import_start_time class variable with the current date and time string.
*/
public static function set_demo_import_start_time() {
self::$demo_import_start_time = date( apply_filters( 'pt-ocdi/date_format_for_file_names', 'Y-m-d__H-i-s' ) );
}
/**
* Get the category list of all categories used in the predefined demo imports array.
*
* @param array $demo_imports Array of demo import items (arrays).
* @return array|boolean List of all the categories or false if there aren't any.
*/
public static function get_all_demo_import_categories( $demo_imports ) {
$categories = array();
foreach ( $demo_imports as $item ) {
if ( ! empty( $item['categories'] ) && is_array( $item['categories'] ) ) {
foreach ( $item['categories'] as $category ) {
$categories[ sanitize_key( $category ) ] = $category;
}
}
}
if ( empty( $categories ) ) {
return false;
}
return $categories;
}
/**
* Return the concatenated string of demo import item categories.
* These should be separated by comma and sanitized properly.
*
* @param array $item The predefined demo import item data.
* @return string The concatenated string of categories.
*/
public static function get_demo_import_item_categories( $item ) {
$sanitized_categories = array();
if ( isset( $item['categories'] ) ) {
foreach ( $item['categories'] as $category ) {
$sanitized_categories[] = sanitize_key( $category );
}
}
if ( ! empty( $sanitized_categories ) ) {
return implode( ',', $sanitized_categories );
}
return false;
}
/**
* Set the OCDI transient with the current importer data.
*
* @param array $data Data to be saved to the transient.
*/
public static function set_ocdi_import_data_transient( $data ) {
set_transient( 'ocdi_importer_data', $data, 0.1 * HOUR_IN_SECONDS );
}
}

View File

@@ -0,0 +1,163 @@
<?php
/**
* Class for the import actions used in the One Click Demo Import plugin.
* Register default WP actions for OCDI plugin.
*
* @package ocdi
*/
namespace OCDI;
class ImportActions {
/**
* Register all action hooks for this class.
*/
public function register_hooks() {
// Before content import.
add_action( 'pt-ocdi/before_content_import_execution', array( $this, 'before_content_import_action' ), 10, 3 );
// After content import.
add_action( 'pt-ocdi/after_content_import_execution', array( $this, 'before_widget_import_action' ), 10, 3 );
add_action( 'pt-ocdi/after_content_import_execution', array( $this, 'widgets_import' ), 20, 3 );
add_action( 'pt-ocdi/after_content_import_execution', array( $this, 'redux_import' ), 30, 3 );
// Customizer import.
add_action( 'pt-ocdi/customizer_import_execution', array( $this, 'customizer_import' ), 10, 1 );
// After full import action.
add_action( 'pt-ocdi/after_all_import_execution', array( $this, 'after_import_action' ), 10, 3 );
// Special widget import cases.
if ( apply_filters( 'pt_ocdi/enable_custom_menu_widget_ids_fix', true ) ) {
add_action( 'pt-ocdi/widget_settings_array', array( $this, 'fix_custom_menu_widget_ids' ) );
}
}
/**
* Change the menu IDs in the custom menu widgets in the widget import data.
* This solves the issue with custom menu widgets not having the correct (new) menu ID, because they
* have the old menu ID from the export site.
*
* @param array $widget The widget settings array.
*/
public function fix_custom_menu_widget_ids( $widget ) {
// Skip (no changes needed), if this is not a custom menu widget.
if ( ! array_key_exists( 'nav_menu', $widget ) || empty( $widget['nav_menu'] ) || ! is_int( $widget['nav_menu'] ) ) {
return $widget;
}
// Get import data, with new menu IDs.
$ocdi = OneClickDemoImport::get_instance();
$content_import_data = $ocdi->importer->get_importer_data();
$term_ids = $content_import_data['mapping']['term_id'];
// Set the new menu ID for the widget.
$widget['nav_menu'] = $term_ids[ $widget['nav_menu'] ];
return $widget;
}
/**
* Execute the widgets import.
*
* @param array $selected_import_files Actual selected import files (content, widgets, customizer, redux).
* @param array $import_files The filtered import files defined in `pt-ocdi/import_files` filter.
* @param int $selected_index Selected index of import.
*/
public function widgets_import( $selected_import_files, $import_files, $selected_index ) {
if ( ! empty( $selected_import_files['widgets'] ) ) {
WidgetImporter::import( $selected_import_files['widgets'] );
}
}
/**
* Execute the Redux import.
*
* @param array $selected_import_files Actual selected import files (content, widgets, customizer, redux).
* @param array $import_files The filtered import files defined in `pt-ocdi/import_files` filter.
* @param int $selected_index Selected index of import.
*/
public function redux_import( $selected_import_files, $import_files, $selected_index ) {
if ( ! empty( $selected_import_files['redux'] ) ) {
ReduxImporter::import( $selected_import_files['redux'] );
}
}
/**
* Execute the customizer import.
*
* @param array $selected_import_files Actual selected import files (content, widgets, customizer, redux).
* @param array $import_files The filtered import files defined in `pt-ocdi/import_files` filter.
* @param int $selected_index Selected index of import.
*/
public function customizer_import( $selected_import_files ) {
if ( ! empty( $selected_import_files['customizer'] ) ) {
CustomizerImporter::import( $selected_import_files['customizer'] );
}
}
/**
* Execute the action: 'pt-ocdi/before_content_import'.
*
* @param array $selected_import_files Actual selected import files (content, widgets, customizer, redux).
* @param array $import_files The filtered import files defined in `pt-ocdi/import_files` filter.
* @param int $selected_index Selected index of import.
*/
public function before_content_import_action( $selected_import_files, $import_files, $selected_index ) {
$this->do_import_action( 'pt-ocdi/before_content_import', $import_files[ $selected_index ] );
}
/**
* Execute the action: 'pt-ocdi/before_widgets_import'.
*
* @param array $selected_import_files Actual selected import files (content, widgets, customizer, redux).
* @param array $import_files The filtered import files defined in `pt-ocdi/import_files` filter.
* @param int $selected_index Selected index of import.
*/
public function before_widget_import_action( $selected_import_files, $import_files, $selected_index ) {
$this->do_import_action( 'pt-ocdi/before_widgets_import', $import_files[ $selected_index ] );
}
/**
* Execute the action: 'pt-ocdi/after_import'.
*
* @param array $selected_import_files Actual selected import files (content, widgets, customizer, redux).
* @param array $import_files The filtered import files defined in `pt-ocdi/import_files` filter.
* @param int $selected_index Selected index of import.
*/
public function after_import_action( $selected_import_files, $import_files, $selected_index ) {
$this->do_import_action( 'pt-ocdi/after_import', $import_files[ $selected_index ] );
}
/**
* Register the do_action hook, so users can hook to these during import.
*
* @param string $action The action name to be executed.
* @param array $selected_import The data of selected import from `pt-ocdi/import_files` filter.
*/
private function do_import_action( $action, $selected_import ) {
if ( false !== has_action( $action ) ) {
$ocdi = OneClickDemoImport::get_instance();
$log_file_path = $ocdi->get_log_file_path();
ob_start();
do_action( $action, $selected_import );
$message = ob_get_clean();
// Add this message to log file.
$log_added = Helpers::append_to_file(
$message,
$log_file_path,
$action
);
}
}
}

View File

@@ -0,0 +1,201 @@
<?php
/**
* Class for declaring the content importer used in the One Click Demo Import plugin
*
* @package ocdi
*/
namespace OCDI;
class Importer {
/**
* The importer class object used for importing content.
*
* @var object
*/
private $importer;
/**
* Time in milliseconds, marking the beginning of the import.
*
* @var float
*/
private $microtime;
/**
* The instance of the OCDI\Logger class.
*
* @var object
*/
public $logger;
/**
* The instance of the One Click Demo Import class.
*
* @var object
*/
private $ocdi;
/**
* Constructor method.
*
* @param array $importer_options Importer options.
* @param object $logger Logger object used in the importer.
*/
public function __construct( $importer_options = array(), $logger = null ) {
// Include files that are needed for WordPress Importer v2.
$this->include_required_files();
// Set the WordPress Importer v2 as the importer used in this plugin.
// More: https://github.com/humanmade/WordPress-Importer.
$this->importer = new WXRImporter( $importer_options );
// Set logger to the importer.
$this->logger = $logger;
if ( ! empty( $this->logger ) ) {
$this->set_logger( $this->logger );
}
// Get the OCDI (main plugin class) instance.
$this->ocdi = OneClickDemoImport::get_instance();
}
/**
* Include required files.
*/
private function include_required_files() {
if ( ! class_exists( '\WP_Importer' ) ) {
require ABSPATH . '/wp-admin/includes/class-wp-importer.php';
}
}
/**
* Imports content from a WordPress export file.
*
* @param string $data_file path to xml file, file with WordPress export data.
*/
public function import( $data_file ) {
$this->importer->import( $data_file );
}
/**
* Set the logger used in the import
*
* @param object $logger logger instance.
*/
public function set_logger( $logger ) {
$this->importer->set_logger( $logger );
}
/**
* Get all protected variables from the WXR_Importer needed for continuing the import.
*/
public function get_importer_data() {
return $this->importer->get_importer_data();
}
/**
* Sets all protected variables from the WXR_Importer needed for continuing the import.
*
* @param array $data with set variables.
*/
public function set_importer_data( $data ) {
$this->importer->set_importer_data( $data );
}
/**
* Import content from an WP XML file.
*
* @param string $import_file_path Path to the import file.
*/
public function import_content( $import_file_path ) {
$this->microtime = microtime( true );
// Increase PHP max execution time. Just in case, even though the AJAX calls are only 25 sec long.
set_time_limit( apply_filters( 'pt-ocdi/set_time_limit_for_demo_data_import', 300 ) );
// Disable import of authors.
add_filter( 'wxr_importer.pre_process.user', '__return_false' );
// Check, if we need to send another AJAX request and set the importing author to the current user.
add_filter( 'wxr_importer.pre_process.post', array( $this, 'new_ajax_request_maybe' ) );
// Disables generation of multiple image sizes (thumbnails) in the content import step.
if ( ! apply_filters( 'pt-ocdi/regenerate_thumbnails_in_content_import', true ) ) {
add_filter( 'intermediate_image_sizes_advanced', '__return_null' );
}
// Import content.
if ( ! empty( $import_file_path ) ) {
ob_start();
$this->import( $import_file_path );
$message = ob_get_clean();
}
// Return any error messages for the front page output (errors, critical, alert and emergency level messages only).
return $this->logger->error_output;
}
/**
* Check if we need to create a new AJAX request, so that server does not timeout.
*
* @param array $data current post data.
* @return array
*/
public function new_ajax_request_maybe( $data ) {
$time = microtime( true ) - $this->microtime;
// We should make a new ajax call, if the time is right.
if ( $time > apply_filters( 'pt-ocdi/time_for_one_ajax_call', 25 ) ) {
$response = array(
'status' => 'newAJAX',
'message' => 'Time for new AJAX request!: ' . $time,
);
// Add any output to the log file and clear the buffers.
$message = ob_get_clean();
// Add any error messages to the frontend_error_messages variable in OCDI main class.
if ( ! empty( $message ) ) {
$this->ocdi->append_to_frontend_error_messages( $message );
}
// Add message to log file.
$log_added = Helpers::append_to_file(
__( 'New AJAX call!' , 'pt-ocdi' ) . PHP_EOL . $message,
$this->ocdi->get_log_file_path(),
''
);
// Set the current importer stat, so it can be continued on the next AJAX call.
$this->set_current_importer_data();
// Send the request for a new AJAX call.
wp_send_json( $response );
}
// Set importing author to the current user.
// Fixes the [WARNING] Could not find the author for ... log warning messages.
$current_user_obj = wp_get_current_user();
$data['post_author'] = $current_user_obj->user_login;
return $data;
}
/**
* Set current state of the content importer, so we can continue the import with new AJAX request.
*/
private function set_current_importer_data() {
$data = array_merge( $this->ocdi->get_current_importer_data(), $this->get_importer_data() );
Helpers::set_ocdi_import_data_transient( $data );
}
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* Logger class used in the One Click Demo Import plugin
*
* @package ocdi
*/
namespace OCDI;
class Logger extends \ProteusThemes\WPContentImporter2\WPImporterLoggerCLI {
/**
* Variable for front-end error display.
*
* @var string
*/
public $error_output = '';
/**
* Overwritten log function from WP_Importer_Logger_CLI.
*
* Logs with an arbitrary level.
*
* @param mixed $level level of reporting.
* @param string $message log message.
* @param array $context context to the log message.
*/
public function log( $level, $message, array $context = array() ) {
// Save error messages for front-end display.
$this->error_output( $level, $message, $context = array() );
if ( $this->level_to_numeric( $level ) < $this->level_to_numeric( $this->min_level ) ) {
return;
}
printf(
'[%s] %s' . PHP_EOL,
strtoupper( $level ),
$message
);
}
/**
* Save messages for error output.
* Only the messages greater then Error.
*
* @param mixed $level level of reporting.
* @param string $message log message.
* @param array $context context to the log message.
*/
public function error_output( $level, $message, array $context = array() ) {
if ( $this->level_to_numeric( $level ) < $this->level_to_numeric( 'error' ) ) {
return;
}
$this->error_output .= sprintf(
'[%s] %s<br>',
strtoupper( $level ),
$message
);
}
}

View File

@@ -0,0 +1,551 @@
<?php
/**
* Main One Click Demo Import plugin class/file.
*
* @package ocdi
*/
namespace OCDI;
/**
* One Click Demo Import class, so we don't have to worry about namespaces.
*/
class OneClickDemoImport {
/**
* The instance *Singleton* of this class
*
* @var object
*/
private static $instance;
/**
* The instance of the OCDI\Importer class.
*
* @var object
*/
public $importer;
/**
* The resulting page's hook_suffix, or false if the user does not have the capability required.
*
* @var boolean or string
*/
private $plugin_page;
/**
* Holds the verified import files.
*
* @var array
*/
public $import_files;
/**
* The path of the log file.
*
* @var string
*/
public $log_file_path;
/**
* The index of the `import_files` array (which import files was selected).
*
* @var int
*/
private $selected_index;
/**
* The paths of the actual import files to be used in the import.
*
* @var array
*/
private $selected_import_files;
/**
* Holds any error messages, that should be printed out at the end of the import.
*
* @var string
*/
public $frontend_error_messages = array();
/**
* Was the before content import already triggered?
*
* @var boolean
*/
private $before_import_executed = false;
/**
* Returns the *Singleton* instance of this class.
*
* @return OneClickDemoImport the *Singleton* instance.
*/
public static function get_instance() {
if ( null === static::$instance ) {
static::$instance = new static();
}
return static::$instance;
}
/**
* Class construct function, to initiate the plugin.
* Protected constructor to prevent creating a new instance of the
* *Singleton* via the `new` operator from outside of this class.
*/
protected function __construct() {
// Actions.
add_action( 'admin_menu', array( $this, 'create_plugin_page' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
add_action( 'wp_ajax_ocdi_import_demo_data', array( $this, 'import_demo_data_ajax_callback' ) );
add_action( 'wp_ajax_ocdi_import_customizer_data', array( $this, 'import_customizer_data_ajax_callback' ) );
add_action( 'wp_ajax_ocdi_after_import_data', array( $this, 'after_all_import_data_ajax_callback' ) );
add_action( 'after_setup_theme', array( $this, 'setup_plugin_with_filter_data' ) );
add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
}
/**
* Private clone method to prevent cloning of the instance of the *Singleton* instance.
*
* @return void
*/
private function __clone() {}
/**
* Private unserialize method to prevent unserializing of the *Singleton* instance.
*
* @return void
*/
private function __wakeup() {}
/**
* Creates the plugin page and a submenu item in WP Appearance menu.
*/
public function create_plugin_page() {
$plugin_page_setup = apply_filters( 'pt-ocdi/plugin_page_setup', array(
'parent_slug' => 'ekko-dashboard',
'page_title' => esc_html__( 'Import Demos' , 'pt-ocdi' ),
'menu_title' => esc_html__( 'Import Demos' , 'pt-ocdi' ),
'capability' => 'import',
'menu_slug' => 'import-demos',
)
);
$this->plugin_page = add_submenu_page(
$plugin_page_setup['parent_slug'],
$plugin_page_setup['page_title'],
$plugin_page_setup['menu_title'],
$plugin_page_setup['capability'],
$plugin_page_setup['menu_slug'],
apply_filters( 'pt-ocdi/plugin_page_display_callback_function', array( $this, 'display_plugin_page' ) )
);
}
/**
* Plugin page display.
* Output (HTML) is in another file.
*/
public function display_plugin_page() {
require_once PT_OCDI_PATH . 'views/plugin-page.php';
}
/**
* Enqueue admin scripts (JS and CSS)
*
* @param string $hook holds info on which admin page you are currently loading.
*/
public function admin_enqueue_scripts( $hook ) {
// Enqueue the scripts only on the plugin page.
if ( $this->plugin_page === $hook ) {
wp_enqueue_script( 'jquery-ui-dialog' );
wp_enqueue_style( 'wp-jquery-ui-dialog' );
wp_enqueue_script( 'ocdi-main-js', PT_OCDI_URL . 'assets/js/main.js' , array( 'jquery', 'jquery-ui-dialog' ), PT_OCDI_VERSION );
// Get theme data.
$theme = wp_get_theme();
wp_localize_script( 'ocdi-main-js', 'ocdi',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'ajax_nonce' => wp_create_nonce( 'ocdi-ajax-verification' ),
'import_files' => $this->import_files,
'wp_customize_on' => apply_filters( 'pt-ocdi/enable_wp_customize_save_hooks', false ),
'import_popup' => apply_filters( 'pt-ocdi/enable_grid_layout_import_popup_confirmation', true ),
'theme_screenshot' => $theme->get_screenshot(),
'texts' => array(
'missing_preview_image' => esc_html__( 'No preview image defined for this import.', 'pt-ocdi' ),
'dialog_title' => esc_html__( 'Are you sure?', 'pt-ocdi' ),
'dialog_no' => esc_html__( 'Cancel', 'pt-ocdi' ),
'dialog_yes' => esc_html__( 'Yes, import!', 'pt-ocdi' ),
'selected_import_title' => esc_html__( 'Selected demo import:', 'pt-ocdi' ),
),
'dialog_options' => apply_filters( 'pt-ocdi/confirmation_dialog_options', array() )
)
);
wp_enqueue_style( 'ocdi-main-css', PT_OCDI_URL . 'assets/css/main.css', array() , PT_OCDI_VERSION );
}
}
/**
* Main AJAX callback function for:
* 1). prepare import files (uploaded or predefined via filters)
* 2). execute 'before content import' actions (before import WP action)
* 3). import content
* 4). execute 'after content import' actions (before widget import WP action, widget import, customizer import, after import WP action)
*/
public function import_demo_data_ajax_callback() {
// Try to update PHP memory limit (so that it does not run out of it).
ini_set( 'memory_limit', apply_filters( 'pt-ocdi/import_memory_limit', '350M' ) );
// Verify if the AJAX call is valid (checks nonce and current_user_can).
Helpers::verify_ajax_call();
// Is this a new AJAX call to continue the previous import?
$use_existing_importer_data = $this->use_existing_importer_data();
if ( ! $use_existing_importer_data ) {
// Create a date and time string to use for demo and log file names.
Helpers::set_demo_import_start_time();
// Define log file path.
$this->log_file_path = Helpers::get_log_path();
// Get selected file index or set it to 0.
$this->selected_index = empty( $_POST['selected'] ) ? 0 : absint( $_POST['selected'] );
/**
* 1). Prepare import files.
* Manually uploaded import files or predefined import files via filter: pt-ocdi/import_files
*/
if ( ! empty( $_FILES ) ) { // Using manual file uploads?
// Get paths for the uploaded files.
$this->selected_import_files = Helpers::process_uploaded_files( $_FILES, $this->log_file_path );
// Set the name of the import files, because we used the uploaded files.
$this->import_files[ $this->selected_index ]['import_file_name'] = esc_html__( 'Manually uploaded files', 'pt-ocdi' );
}
elseif ( ! empty( $this->import_files[ $this->selected_index ] ) ) { // Use predefined import files from wp filter: pt-ocdi/import_files.
// Download the import files (content, widgets and customizer files).
$this->selected_import_files = Helpers::download_import_files( $this->import_files[ $this->selected_index ] );
// Check Errors.
if ( is_wp_error( $this->selected_import_files ) ) {
// Write error to log file and send an AJAX response with the error.
Helpers::log_error_and_send_ajax_response(
$this->selected_import_files->get_error_message(),
$this->log_file_path,
esc_html__( 'Downloaded files', 'pt-ocdi' )
);
}
// Add this message to log file.
$log_added = Helpers::append_to_file(
sprintf(
__( 'The import files for: %s were successfully downloaded!', 'pt-ocdi' ),
$this->import_files[ $this->selected_index ]['import_file_name']
) . Helpers::import_file_info( $this->selected_import_files ),
$this->log_file_path,
esc_html__( 'Downloaded files' , 'pt-ocdi' )
);
}
else {
// Send JSON Error response to the AJAX call.
wp_send_json( esc_html__( 'No import files specified!', 'pt-ocdi' ) );
}
}
// Save the initial import data as a transient, so other import parts (in new AJAX calls) can use that data.
Helpers::set_ocdi_import_data_transient( $this->get_current_importer_data() );
if ( ! $this->before_import_executed ) {
$this->before_import_executed = true;
/**
* 2). Execute the actions hooked to the 'pt-ocdi/before_content_import_execution' action:
*
* Default actions:
* 1 - Before content import WP action (with priority 10).
*/
do_action( 'pt-ocdi/before_content_import_execution', $this->selected_import_files, $this->import_files, $this->selected_index );
}
/**
* 3). Import content (if the content XML file is set for this import).
* Returns any errors greater then the "warning" logger level, that will be displayed on front page.
*/
if ( ! empty( $this->selected_import_files['content'] ) ) {
$this->append_to_frontend_error_messages( $this->importer->import_content( $this->selected_import_files['content'] ) );
}
/**
* 4). Execute the actions hooked to the 'pt-ocdi/after_content_import_execution' action:
*
* Default actions:
* 1 - Before widgets import setup (with priority 10).
* 2 - Import widgets (with priority 20).
* 3 - Import Redux data (with priority 30).
*/
do_action( 'pt-ocdi/after_content_import_execution', $this->selected_import_files, $this->import_files, $this->selected_index );
// Save the import data as a transient, so other import parts (in new AJAX calls) can use that data.
Helpers::set_ocdi_import_data_transient( $this->get_current_importer_data() );
// Request the customizer import AJAX call.
if ( ! empty( $this->selected_import_files['customizer'] ) ) {
wp_send_json( array( 'status' => 'customizerAJAX' ) );
}
// Request the after all import AJAX call.
if ( false !== has_action( 'pt-ocdi/after_all_import_execution' ) ) {
wp_send_json( array( 'status' => 'afterAllImportAJAX' ) );
}
// Send a JSON response with final report.
$this->final_response();
}
/**
* AJAX callback for importing the customizer data.
* This request has the wp_customize set to 'on', so that the customizer hooks can be called
* (they can only be called with the $wp_customize instance). But if the $wp_customize is defined,
* then the widgets do not import correctly, that's why the customizer import has its own AJAX call.
*/
public function import_customizer_data_ajax_callback() {
// Verify if the AJAX call is valid (checks nonce and current_user_can).
Helpers::verify_ajax_call();
// Get existing import data.
if ( $this->use_existing_importer_data() ) {
/**
* Execute the customizer import actions.
*
* Default actions:
* 1 - Customizer import (with priority 10).
*/
do_action( 'pt-ocdi/customizer_import_execution', $this->selected_import_files );
}
// Request the after all import AJAX call.
if ( false !== has_action( 'pt-ocdi/after_all_import_execution' ) ) {
wp_send_json( array( 'status' => 'afterAllImportAJAX' ) );
}
// Send a JSON response with final report.
$this->final_response();
}
/**
* AJAX callback for the after all import action.
*/
public function after_all_import_data_ajax_callback() {
// Verify if the AJAX call is valid (checks nonce and current_user_can).
Helpers::verify_ajax_call();
// Get existing import data.
if ( $this->use_existing_importer_data() ) {
/**
* Execute the after all import actions.
*
* Default actions:
* 1 - after_import action (with priority 10).
*/
do_action( 'pt-ocdi/after_all_import_execution', $this->selected_import_files, $this->import_files, $this->selected_index );
}
// Send a JSON response with final report.
$this->final_response();
}
/**
* Send a JSON response with final report.
*/
private function final_response() {
// Delete importer data transient for current import.
delete_transient( 'ocdi_importer_data' );
// Display final messages (success or error messages).
if ( empty( $this->frontend_error_messages ) ) {
$response['message'] = '';
if ( ! apply_filters( 'pt-ocdi/disable_pt_branding', false ) ) {
$twitter_status = esc_html__( 'Just used One Click Demo Import plugin and it was awesome! Thanks @ProteusThemes! #OCDI https://www.proteusthemes.com/', 'pt-ocdi' );
$response['message'] .= sprintf(
__( '%1$s%6$sWasn\'t this a great One Click Demo Import experience?%7$s Created and maintained by %3$sProteusThemes%4$s. %2$s%5$sClick to Tweet!%4$s%8$s', 'pt-ocdi' ),
'<div class="notice notice-info"><p>',
'<br>',
'<strong><a href="https://www.proteusthemes.com/" target="_blank">',
'</a></strong>',
'<strong><a href="' . add_query_arg( 'status', urlencode( $twitter_status ), 'http://twitter.com/home' ) . '" target="_blank">',
'<strong>',
'</strong>',
'</p></div>'
);
}
$response['message'] .= sprintf(
__( '%1$s%3$sThat\'s it, all done!%4$s%2$sThe demo import has finished. Please check your page and make sure that everything has imported correctly.%5$s', 'pt-ocdi' ),
'<div class="notice notice-success"><p>',
'<br>',
'<strong>',
'</strong>',
'</p></div>'
);
}
else {
$response['message'] = $this->frontend_error_messages_display() . '<br>';
$response['message'] .= sprintf(
__( '%1$sThe demo import has finished, but there were some import errors.%2$sMore details about the errors can be found in this %3$s%5$slog file%6$s%4$s%7$s', 'pt-ocdi' ),
'<div class="notice notice-warning"><p>',
'<br>',
'<strong>',
'</strong>',
'<a href="' . Helpers::get_log_url( $this->log_file_path ) .'" target="_blank">',
'</a>',
'</p></div>'
);
}
wp_send_json( $response );
}
/**
* Get content importer data, so we can continue the import with this new AJAX request.
*
* @return boolean
*/
private function use_existing_importer_data() {
if ( $data = get_transient( 'ocdi_importer_data' ) ) {
$this->frontend_error_messages = empty( $data['frontend_error_messages'] ) ? array() : $data['frontend_error_messages'];
$this->log_file_path = empty( $data['log_file_path'] ) ? '' : $data['log_file_path'];
$this->selected_index = empty( $data['selected_index'] ) ? 0 : $data['selected_index'];
$this->selected_import_files = empty( $data['selected_import_files'] ) ? array() : $data['selected_import_files'];
$this->before_import_executed = empty( $data['before_import_executed'] ) ? false : $data['before_import_executed'];
$this->importer->set_importer_data( $data );
return true;
}
return false;
}
/**
* Get the current state of selected data.
*
* @return array
*/
public function get_current_importer_data() {
return array(
'frontend_error_messages' => $this->frontend_error_messages,
'log_file_path' => $this->log_file_path,
'selected_index' => $this->selected_index,
'selected_import_files' => $this->selected_import_files,
'before_import_executed' => $this->before_import_executed,
);
}
/**
* Getter function to retrieve the private log_file_path value.
*
* @return string The log_file_path value.
*/
public function get_log_file_path() {
return $this->log_file_path;
}
/**
* Setter function to append additional value to the private frontend_error_messages value.
*
* @param string $additional_value The additional value that will be appended to the existing frontend_error_messages.
*/
public function append_to_frontend_error_messages( $text ) {
$lines = array();
if ( ! empty( $text ) ) {
$text = str_replace( '<br>', PHP_EOL, $text );
$lines = explode( PHP_EOL, $text );
}
foreach ( $lines as $line ) {
if ( ! empty( $line ) && ! in_array( $line , $this->frontend_error_messages ) ) {
$this->frontend_error_messages[] = $line;
}
}
}
/**
* Display the frontend error messages.
*
* @return string Text with HTML markup.
*/
public function frontend_error_messages_display() {
$output = '';
if ( ! empty( $this->frontend_error_messages ) ) {
foreach ( $this->frontend_error_messages as $line ) {
$output .= esc_html( $line );
$output .= '<br>';
}
}
return $output;
}
/**
* Load the plugin textdomain, so that translations can be made.
*/
public function load_textdomain() {
load_plugin_textdomain( 'pt-ocdi', false, plugin_basename( dirname( __FILE__ ) ) . '/languages' );
}
/**
* Get data from filters, after the theme has loaded and instantiate the importer.
*/
public function setup_plugin_with_filter_data() {
// Get info of import data files and filter it.
$this->import_files = Helpers::validate_import_file_info( apply_filters( 'pt-ocdi/import_files', array() ) );
/**
* Register all default actions (before content import, widget, customizer import and other actions)
* to the 'before_content_import_execution' and the 'pt-ocdi/after_content_import_execution' action hook.
*/
$import_actions = new ImportActions();
$import_actions->register_hooks();
// Importer options array.
$importer_options = apply_filters( 'pt-ocdi/importer_options', array(
'fetch_attachments' => true,
) );
// Logger options for the logger used in the importer.
$logger_options = apply_filters( 'pt-ocdi/logger_options', array(
'logger_min_level' => 'warning',
) );
// Configure logger instance and set it to the importer.
$logger = new Logger();
$logger->min_level = $logger_options['logger_min_level'];
// Create importer instance with proper parameters.
$this->importer = new Importer( $importer_options, $logger );
}
}

View File

@@ -0,0 +1,71 @@
<?php
/**
* Class for the Redux importer used in the One Click Demo Import plugin.
*
* @see https://wordpress.org/plugins/redux-framework/
* @package ocdi
*/
namespace OCDI;
class ReduxImporter {
/**
* Import Redux data from a JSON file, generated by the Redux plugin.
*
* @param array $import_data Array of arrays. Child array contains 'option_name' and 'file_path'.
*/
public static function import( $import_data ) {
$ocdi = OneClickDemoImport::get_instance();
$log_file_path = $ocdi->get_log_file_path();
// Redux plugin is not active!
if ( ! class_exists( 'ReduxFramework' ) ) {
$error_message = esc_html__( 'The Redux plugin is not activated, so the Redux import was skipped!', 'pt-ocdi' );
// Add any error messages to the frontend_error_messages variable in OCDI main class.
$ocdi->append_to_frontend_error_messages( $error_message );
// Write error to log file.
Helpers::append_to_file(
$error_message,
$log_file_path,
esc_html__( 'Importing Redux settings' , 'pt-ocdi' )
);
return;
}
foreach ( $import_data as $redux_item ) {
$redux_options_raw_data = Helpers::data_from_file( $redux_item['file_path'] );
$redux_options_data = json_decode( $redux_options_raw_data, true );
$redux_framework = \ReduxFrameworkInstances::get_instance( $redux_item['option_name'] );
if ( isset( $redux_framework->args['opt_name'] ) ) {
// Import Redux settings.
$redux_framework->set_options( $redux_options_data );
// Add this message to log file.
$log_added = Helpers::append_to_file(
sprintf( esc_html__( 'Redux settings import for: %s finished successfully!', 'pt-ocdi' ), $redux_item['option_name'] ),
$log_file_path,
esc_html__( 'Importing Redux settings' , 'pt-ocdi' )
);
}
else {
$error_message = sprintf( esc_html__( 'The Redux option name: %s, was not found in this WP site, so it was not imported!', 'pt-ocdi' ), $redux_item['option_name'] );
// Add any error messages to the frontend_error_messages variable in OCDI main class.
$ocdi->append_to_frontend_error_messages( $error_message );
// Write error to log file.
Helpers::append_to_file(
$error_message,
$log_file_path,
esc_html__( 'Importing Redux settings' , 'pt-ocdi' )
);
}
}
}
}

View File

@@ -0,0 +1,295 @@
<?php
/**
* The class for WP-CLI commands for One Click Demo Import plugin.
*
* @package ocdi
*/
namespace OCDI;
use WP_CLI;
class WPCLICommands extends \WP_CLI_Command {
/**
* @var object Main OCDI class object.
*/
private $ocdi;
public function __construct() {
parent::__construct();
$this->ocdi = OneClickDemoImport::get_instance();
Helpers::set_demo_import_start_time();
$this->ocdi->log_file_path = Helpers::get_log_path();
}
/**
* List all predefined demo imports.
*/
public function list_predefined() {
if ( empty( $this->ocdi->import_files ) ) {
WP_CLI::error( esc_html__( 'There are no predefined demo imports for currently active theme!', 'pt-ocdi' ) );
}
WP_CLI::success( esc_html__( 'Here are the predefined demo imports:', 'pt-ocdi' ) );
foreach ( $this->ocdi->import_files as $index => $import_file ) {
WP_CLI::log( sprintf(
'%d -> %s [content: %s, widgets: %s, customizer: %s, redux: %s]',
$index,
$import_file['import_file_name'],
empty( $import_file['import_file_url'] ) && empty( $import_file['local_import_file'] ) ? 'no' : 'yes',
empty( $import_file['import_widget_file_url'] ) && empty( $import_file['local_import_widget_file'] ) ? 'no' : 'yes',
empty( $import_file['import_customizer_file_url'] ) && empty( $import_file['local_import_customizer_file'] ) ? 'no' : 'yes',
empty( $import_file['import_redux'] ) && empty( $import_file['local_import_redux'] ) ? 'no' : 'yes'
) );
}
}
/**
* Import content/widgets/customizer settings with the OCDI plugin.
*
* ## OPTIONS
*
* [--content=<file>]
* : Content file (XML), that will be used to import the content.
*
* [--widgets=<file>]
* : Widgets file (JSON or WIE), that will be used to import the widgets.
*
* [--customizer=<file>]
* : Customizer file (DAT), that will be used to import the customizer settings.
*
* [--predefined=<index>]
* : The index of the predefined demo imports (use the 'list_predefined' command to check the predefined demo imports)
*/
public function import( $args, $assoc_args ) {
if ( ! $this->any_import_options_set( $assoc_args ) ) {
WP_CLI::error( esc_html__( 'At least one of the possible options should be set! Check them with --help', 'pt-ocdi' ) );
}
if ( isset( $assoc_args['predefined'] ) ) {
$this->import_predefined( $assoc_args['predefined'] );
}
if ( ! empty( $assoc_args['content'] ) ) {
$this->import_content( $assoc_args['content'] );
}
if ( ! empty( $assoc_args['widgets'] ) ) {
$this->import_widgets( $assoc_args['widgets'] );
}
if ( ! empty( $assoc_args['customizer'] ) ) {
$this->import_customizer( $assoc_args['customizer'] );
}
}
/**
* Check if any of the possible options are set.
*
* @param array $options
*
* @return bool
*/
private function any_import_options_set( $options ) {
$possible_options = array(
'content',
'widgets',
'customizer',
'predefined',
);
foreach ( $possible_options as $option ) {
if ( array_key_exists( $option, $options ) ) {
return true;
}
}
return false;
}
/**
* Import the predefined demo content/widgets/customizer settings with OCDI.
*
* @param int $predefined_index Index of a OCDI predefined demo import.
*/
private function import_predefined( $predefined_index ) {
if ( ! is_numeric( $predefined_index ) ) {
WP_CLI::error( esc_html__( 'The "predefined" parameter should be a number (an index of the OCDI predefined demo import)!', 'pt-ocdi' ) );
}
$predefined_index = absint( $predefined_index );
if ( ! array_key_exists( $predefined_index, $this->ocdi->import_files ) ) {
WP_CLI::warning( esc_html__( 'The supplied predefined index does not exist! Please take a look at the available predefined demo imports:', 'pt-ocdi' ) );
$this->list_predefined();
return false;
}
WP_CLI::log( esc_html__( 'Predefined demo import started! All other parameters will be ignored!', 'pt-ocdi' ) );
$selected_files = $this->ocdi->import_files[ $predefined_index ];
if ( ! empty( $selected_files['import_file_name'] ) ) {
WP_CLI::log( sprintf( esc_html__( 'Selected predefined demo import: %s', 'pt-ocdi' ), $selected_files['import_file_name'] ) );
}
WP_CLI::log( esc_html__( 'Preparing the demo import files...', 'pt-ocdi' ) );
$import_files = Helpers::download_import_files( $selected_files );
if ( empty( $import_files ) ) {
WP_CLI::error( esc_html__( 'Demo import files could not be retrieved!', 'pt-ocdi' ) );
}
WP_CLI::log( esc_html__( 'Demo import files retrieved successfully!', 'pt-ocdi' ) );
WP_CLI::log( esc_html__( 'Importing...', 'pt-ocdi' ) );
if ( ! empty( $import_files['content'] ) ) {
$this->do_action( 'pt-ocdi/before_content_import_execution', $import_files, $this->ocdi->import_files, $predefined_index );
$this->import_content( $import_files['content'] );
}
if ( ! empty( $import_files['widgets'] ) ) {
$this->do_action( 'pt-ocdi/before_widgets_import', $import_files );
$this->import_widgets( $import_files['widgets'] );
}
if ( ! empty( $import_files['customizer'] ) ) {
$this->import_customizer( $import_files['customizer'] );
}
$this->do_action( 'pt-ocdi/after_all_import_execution', $import_files, $this->ocdi->import_files, $predefined_index );
WP_CLI::log( esc_html__( 'Predefined import finished!', 'pt-ocdi' ) );
}
/**
* Import the content with OCDI.
*
* @param string $relative_file_path Relative file path to the content import file.
*/
private function import_content( $relative_file_path ) {
$content_import_file_path = realpath( $relative_file_path );
if ( ! file_exists( $content_import_file_path ) ) {
WP_CLI::warning( esc_html__( 'Content import file provided does not exist! Skipping this import!', 'pt-ocdi' ) );
return false;
}
// Change the single AJAX call duration so the whole content import will be done in one go.
add_filter( 'pt-ocdi/time_for_one_ajax_call', function() {
return 3600;
} );
WP_CLI::log( esc_html__( 'Importing content (this might take a while)...', 'pt-ocdi' ) );
Helpers::append_to_file( '', $this->ocdi->log_file_path, esc_html__( 'Importing content' , 'pt-ocdi' ) );
$this->ocdi->append_to_frontend_error_messages( $this->ocdi->importer->import_content( $content_import_file_path ) );
if( empty( $this->ocdi->frontend_error_messages ) ) {
WP_CLI::success( esc_html__( 'Content import finished!', 'pt-ocdi' ) );
}
else {
WP_CLI::warning( esc_html__( 'There were some issues while importing the content!', 'pt-ocdi' ) );
foreach ( $this->ocdi->frontend_error_messages as $line ) {
WP_CLI::log( $line );
}
$this->ocdi->frontend_error_messages = array();
}
}
/**
* Import the widgets with OCDI.
*
* @param string $relative_file_path Relative file path to the widgets import file.
*/
private function import_widgets( $relative_file_path ) {
$widgets_import_file_path = realpath( $relative_file_path );
if ( ! file_exists( $widgets_import_file_path ) ) {
WP_CLI::warning( esc_html__( 'Widgets import file provided does not exist! Skipping this import!', 'pt-ocdi' ) );
return false;
}
WP_CLI::log( esc_html__( 'Importing widgets...', 'pt-ocdi' ) );
WidgetImporter::import( $widgets_import_file_path );
if( empty( $this->ocdi->frontend_error_messages ) ) {
WP_CLI::success( esc_html__( 'Widgets imported successfully!', 'pt-ocdi' ) );
}
else {
WP_CLI::warning( esc_html__( 'There were some issues while importing widgets!', 'pt-ocdi' ) );
foreach ( $this->ocdi->frontend_error_messages as $line ) {
WP_CLI::log( $line );
}
$this->ocdi->frontend_error_messages = array();
}
}
/**
* Import the customizer settings with OCDI.
*
* @param string $relative_file_path Relative file path to the customizer import file.
*/
private function import_customizer( $relative_file_path ) {
$customizer_import_file_path = realpath( $relative_file_path );
if ( ! file_exists( $customizer_import_file_path ) ) {
WP_CLI::warning( esc_html__( 'Customizer import file provided does not exist! Skipping this import!', 'pt-ocdi' ) );
return false;
}
WP_CLI::log( esc_html__( 'Importing customizer settings...', 'pt-ocdi' ) );
CustomizerImporter::import( $customizer_import_file_path );
if( empty( $this->ocdi->frontend_error_messages ) ) {
WP_CLI::success( esc_html__( 'Customizer settings imported successfully!', 'pt-ocdi' ) );
}
else {
WP_CLI::warning( esc_html__( 'There were some issues while importing customizer settings!', 'pt-ocdi' ) );
foreach ( $this->ocdi->frontend_error_messages as $line ) {
WP_CLI::log( $line );
}
$this->ocdi->frontend_error_messages = array();
}
}
/**
* Run the registered actions.
*
* @param string $action Name of the action.
* @param array $selected_files Selected import files.
* @param array $all_import_files All predefined demos.
* @param null $selected_index Selected predefined index.
*/
private function do_action( $action, $import_files = array(), $all_import_files = array(), $selected_index = null ) {
if ( false !== has_action( $action ) ) {
WP_CLI::log( sprintf( esc_html__( 'Executing action: %s ...', 'pt-ocdi' ), $action ) );
ob_start();
do_action( $action, $import_files, $all_import_files, $selected_index );
$message = ob_get_clean();
Helpers::append_to_file( $message, $this->ocdi->log_file_path, $action );
}
}
}

View File

@@ -0,0 +1,110 @@
<?php
/**
* WXR importer class used in the One Click Demo Import plugin.
* Needed to extend the WXR_Importer class to get/set the importer protected variables,
* for use in the multiple AJAX calls.
*
* @package ocdi
*/
namespace OCDI;
class WXRImporter extends \ProteusThemes\WPContentImporter2\WXRImporter {
/**
* Constructor method.
*
* @param array $options Importer options.
*/
public function __construct( $options = array() ) {
parent::__construct( $options );
// Set current user to $mapping variable.
// Fixes the [WARNING] Could not find the author for ... log warning messages.
$current_user_obj = wp_get_current_user();
$this->mapping['user_slug'][ $current_user_obj->user_login ] = $current_user_obj->ID;
// WooCommerce product attributes registration.
if ( class_exists( 'WooCommerce' ) ) {
add_filter( 'wxr_importer.pre_process.term', array( $this, 'woocommerce_product_attributes_registration' ), 10, 1 );
}
}
/**
* Get all protected variables from the WXR_Importer needed for continuing the import.
*/
public function get_importer_data() {
return array(
'mapping' => $this->mapping,
'requires_remapping' => $this->requires_remapping,
'exists' => $this->exists,
'user_slug_override' => $this->user_slug_override,
'url_remap' => $this->url_remap,
'featured_images' => $this->featured_images,
);
}
/**
* Sets all protected variables from the WXR_Importer needed for continuing the import.
*
* @param array $data with set variables.
*/
public function set_importer_data( $data ) {
$this->mapping = empty( $data['mapping'] ) ? array() : $data['mapping'];
$this->requires_remapping = empty( $data['requires_remapping'] ) ? array() : $data['requires_remapping'];
$this->exists = empty( $data['exists'] ) ? array() : $data['exists'];
$this->user_slug_override = empty( $data['user_slug_override'] ) ? array() : $data['user_slug_override'];
$this->url_remap = empty( $data['url_remap'] ) ? array() : $data['url_remap'];
$this->featured_images = empty( $data['featured_images'] ) ? array() : $data['featured_images'];
}
/**
* Hook into the pre-process term filter of the content import and register the
* custom WooCommerce product attributes, so that the terms can then be imported normally.
*
* This should probably be removed once the WP importer 2.0 support is added in WooCommerce.
*
* Fixes: [WARNING] Failed to import pa_size L warnings in content import.
* Code from: woocommerce/includes/admin/class-wc-admin-importers.php (ver 2.6.9).
*
* Github issue: https://github.com/proteusthemes/one-click-demo-import/issues/71
*
* @param array $date The term data to import.
* @return array The unchanged term data.
*/
public function woocommerce_product_attributes_registration( $data ) {
global $wpdb;
if ( strstr( $data['taxonomy'], 'pa_' ) ) {
if ( ! taxonomy_exists( $data['taxonomy'] ) ) {
$attribute_name = wc_sanitize_taxonomy_name( str_replace( 'pa_', '', $data['taxonomy'] ) );
// Create the taxonomy
if ( ! in_array( $attribute_name, wc_get_attribute_taxonomies() ) ) {
$attribute = array(
'attribute_label' => $attribute_name,
'attribute_name' => $attribute_name,
'attribute_type' => 'select',
'attribute_orderby' => 'menu_order',
'attribute_public' => 0
);
$wpdb->insert( $wpdb->prefix . 'woocommerce_attribute_taxonomies', $attribute );
delete_transient( 'wc_attribute_taxonomies' );
}
// Register the taxonomy now so that the import works!
register_taxonomy(
$data['taxonomy'],
apply_filters( 'woocommerce_taxonomy_objects_' . $data['taxonomy'], array( 'product' ) ),
apply_filters( 'woocommerce_taxonomy_args_' . $data['taxonomy'], array(
'hierarchical' => true,
'show_ui' => false,
'query_var' => true,
'rewrite' => false,
) )
);
}
}
return $data;
}
}

View File

@@ -0,0 +1,339 @@
<?php
/**
* Class for the widget importer used in the One Click Demo Import plugin.
*
* Code is mostly from the Widget Importer & Exporter plugin.
*
* @see https://wordpress.org/plugins/widget-importer-exporter/
* @package ocdi
*/
namespace OCDI;
class WidgetImporter {
/**
* Import widgets from WIE or JSON file.
*
* @param string $widget_import_file_path path to the widget import file.
*/
public static function import( $widget_import_file_path ) {
$results = array();
$ocdi = OneClickDemoImport::get_instance();
$log_file_path = $ocdi->get_log_file_path();
// Import widgets and return result.
if ( ! empty( $widget_import_file_path ) ) {
$results = self::import_widgets( $widget_import_file_path );
}
// Check for errors, else write the results to the log file.
if ( is_wp_error( $results ) ) {
$error_message = $results->get_error_message();
// Add any error messages to the frontend_error_messages variable in OCDI main class.
$ocdi->append_to_frontend_error_messages( $error_message );
// Write error to log file.
Helpers::append_to_file(
$error_message,
$log_file_path,
esc_html__( 'Importing widgets', 'pt-ocdi' )
);
}
else {
ob_start();
self::format_results_for_log( $results );
$message = ob_get_clean();
// Add this message to log file.
$log_added = Helpers::append_to_file(
$message,
$log_file_path,
esc_html__( 'Importing widgets' , 'pt-ocdi' )
);
}
}
/**
* Imports widgets from a json file.
*
* @param string $data_file path to json file with WordPress widget export data.
*/
private static function import_widgets( $data_file ) {
// Get widgets data from file.
$data = self::process_import_file( $data_file );
// Return from this function if there was an error.
if ( is_wp_error( $data ) ) {
return $data;
}
// Import the widget data and save the results.
return self::import_data( $data );
}
/**
* Process import file - this parses the widget data and returns it.
*
* @param string $file path to json file.
* @return object $data decoded JSON string
*/
private static function process_import_file( $file ) {
// File exists?
if ( ! file_exists( $file ) ) {
return new \WP_Error(
'widget_import_file_not_found',
__( 'Error: Widget import file could not be found.', 'pt-ocdi' )
);
}
// Get file contents and decode.
$data = Helpers::data_from_file( $file );
// Return from this function if there was an error.
if ( is_wp_error( $data ) ) {
return $data;
}
return json_decode( $data );
}
/**
* Import widget JSON data
*
* @global array $wp_registered_sidebars
* @param object $data JSON widget data.
* @return array $results
*/
private static function import_data( $data ) {
global $wp_registered_sidebars;
// Have valid data? If no data or could not decode.
if ( empty( $data ) || ! is_object( $data ) ) {
return new \WP_Error(
'corrupted_widget_import_data',
__( 'Error: Widget import data could not be read. Please try a different file.', 'pt-ocdi' )
);
}
// Hook before import.
do_action( 'pt-ocdi/widget_importer_before_widgets_import' );
$data = apply_filters( 'pt-ocdi/before_widgets_import_data', $data );
// Get all available widgets site supports.
$available_widgets = self::available_widgets();
// Get all existing widget instances.
$widget_instances = array();
foreach ( $available_widgets as $widget_data ) {
$widget_instances[ $widget_data['id_base'] ] = get_option( 'widget_' . $widget_data['id_base'] );
}
// Begin results.
$results = array();
// Loop import data's sidebars.
foreach ( $data as $sidebar_id => $widgets ) {
// Skip inactive widgets (should not be in export file).
if ( 'wp_inactive_widgets' == $sidebar_id ) {
continue;
}
// Check if sidebar is available on this site. Otherwise add widgets to inactive, and say so.
if ( isset( $wp_registered_sidebars[ $sidebar_id ] ) ) {
$sidebar_available = true;
$use_sidebar_id = $sidebar_id;
$sidebar_message_type = 'success';
$sidebar_message = '';
}
else {
$sidebar_available = false;
$use_sidebar_id = 'wp_inactive_widgets'; // Add to inactive if sidebar does not exist in theme.
$sidebar_message_type = 'error';
$sidebar_message = __( 'Sidebar does not exist in theme (moving widget to Inactive)', 'pt-ocdi' );
}
// Result for sidebar.
$results[ $sidebar_id ]['name'] = ! empty( $wp_registered_sidebars[ $sidebar_id ]['name'] ) ? $wp_registered_sidebars[ $sidebar_id ]['name'] : $sidebar_id; // Sidebar name if theme supports it; otherwise ID.
$results[ $sidebar_id ]['message_type'] = $sidebar_message_type;
$results[ $sidebar_id ]['message'] = $sidebar_message;
$results[ $sidebar_id ]['widgets'] = array();
// Loop widgets.
foreach ( $widgets as $widget_instance_id => $widget ) {
$fail = false;
// Get id_base (remove -# from end) and instance ID number.
$id_base = preg_replace( '/-[0-9]+$/', '', $widget_instance_id );
$instance_id_number = str_replace( $id_base . '-', '', $widget_instance_id );
// Does site support this widget?
if ( ! $fail && ! isset( $available_widgets[ $id_base ] ) ) {
$fail = true;
$widget_message_type = 'error';
$widget_message = __( 'Site does not support widget', 'pt-ocdi' ); // Explain why widget not imported.
}
// Filter to modify settings object before conversion to array and import.
// Leave this filter here for backwards compatibility with manipulating objects (before conversion to array below).
// Ideally the newer wie_widget_settings_array below will be used instead of this.
$widget = apply_filters( 'pt-ocdi/widget_settings', $widget ); // Object.
// Convert multidimensional objects to multidimensional arrays.
// Some plugins like Jetpack Widget Visibility store settings as multidimensional arrays.
// Without this, they are imported as objects and cause fatal error on Widgets page.
// If this creates problems for plugins that do actually intend settings in objects then may need to consider other approach: https://wordpress.org/support/topic/problem-with-array-of-arrays.
// It is probably much more likely that arrays are used than objects, however.
$widget = json_decode( json_encode( $widget ), true );
// Filter to modify settings array.
// This is preferred over the older wie_widget_settings filter above.
// Do before identical check because changes may make it identical to end result (such as URL replacements).
$widget = apply_filters( 'pt-ocdi/widget_settings_array', $widget );
// Does widget with identical settings already exist in same sidebar?
if ( ! $fail && isset( $widget_instances[ $id_base ] ) ) {
// Get existing widgets in this sidebar.
$sidebars_widgets = get_option( 'sidebars_widgets' );
$sidebar_widgets = isset( $sidebars_widgets[ $use_sidebar_id ] ) ? $sidebars_widgets[ $use_sidebar_id ] : array(); // Check Inactive if that's where will go.
// Loop widgets with ID base.
$single_widget_instances = ! empty( $widget_instances[ $id_base ] ) ? $widget_instances[ $id_base ] : array();
foreach ( $single_widget_instances as $check_id => $check_widget ) {
// Is widget in same sidebar and has identical settings?
if ( in_array( "$id_base-$check_id", $sidebar_widgets ) && (array) $widget == $check_widget ) {
$fail = true;
$widget_message_type = 'warning';
$widget_message = __( 'Widget already exists', 'pt-ocdi' ); // Explain why widget not imported.
break;
}
}
}
// No failure.
if ( ! $fail ) {
// Add widget instance.
$single_widget_instances = get_option( 'widget_' . $id_base ); // All instances for that widget ID base, get fresh every time.
$single_widget_instances = ! empty( $single_widget_instances ) ? $single_widget_instances : array( '_multiwidget' => 1 ); // Start fresh if have to.
$single_widget_instances[] = $widget; // Add it.
// Get the key it was given.
end( $single_widget_instances );
$new_instance_id_number = key( $single_widget_instances );
// If key is 0, make it 1.
// When 0, an issue can occur where adding a widget causes data from other widget to load, and the widget doesn't stick (reload wipes it).
if ( '0' === strval( $new_instance_id_number ) ) {
$new_instance_id_number = 1;
$single_widget_instances[ $new_instance_id_number ] = $single_widget_instances[0];
unset( $single_widget_instances[0] );
}
// Move _multiwidget to end of array for uniformity.
if ( isset( $single_widget_instances['_multiwidget'] ) ) {
$multiwidget = $single_widget_instances['_multiwidget'];
unset( $single_widget_instances['_multiwidget'] );
$single_widget_instances['_multiwidget'] = $multiwidget;
}
// Update option with new widget.
update_option( 'widget_' . $id_base, $single_widget_instances );
// Assign widget instance to sidebar.
$sidebars_widgets = get_option( 'sidebars_widgets' ); // Which sidebars have which widgets, get fresh every time.
$new_instance_id = $id_base . '-' . $new_instance_id_number; // Use ID number from new widget instance.
$sidebars_widgets[ $use_sidebar_id ][] = $new_instance_id; // Add new instance to sidebar.
update_option( 'sidebars_widgets', $sidebars_widgets ); // Save the amended data.
// After widget import action.
$after_widget_import = array(
'sidebar' => $use_sidebar_id,
'sidebar_old' => $sidebar_id,
'widget' => $widget,
'widget_type' => $id_base,
'widget_id' => $new_instance_id,
'widget_id_old' => $widget_instance_id,
'widget_id_num' => $new_instance_id_number,
'widget_id_num_old' => $instance_id_number,
);
do_action( 'pt-ocdi/widget_importer_after_single_widget_import', $after_widget_import );
// Success message.
if ( $sidebar_available ) {
$widget_message_type = 'success';
$widget_message = __( 'Imported', 'pt-ocdi' );
}
else {
$widget_message_type = 'warning';
$widget_message = __( 'Imported to Inactive', 'pt-ocdi' );
}
}
// Result for widget instance.
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['name'] = isset( $available_widgets[ $id_base ]['name'] ) ? $available_widgets[ $id_base ]['name'] : $id_base; // Widget name or ID if name not available (not supported by site).
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['title'] = ! empty( $widget['title'] ) ? $widget['title'] : __( 'No Title', 'pt-ocdi' ); // Show "No Title" if widget instance is untitled.
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['message_type'] = $widget_message_type;
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['message'] = $widget_message;
}
}
// Hook after import.
do_action( 'pt-ocdi/widget_importer_after_widgets_import' );
// Return results.
return apply_filters( 'pt-ocdi/widget_import_results', $results );
}
/**
* Available widgets.
*
* Gather site's widgets into array with ID base, name, etc.
*
* @global array $wp_registered_widget_controls
* @return array $available_widgets, Widget information
*/
private static function available_widgets() {
global $wp_registered_widget_controls;
$widget_controls = $wp_registered_widget_controls;
$available_widgets = array();
foreach ( $widget_controls as $widget ) {
if ( ! empty( $widget['id_base'] ) && ! isset( $available_widgets[ $widget['id_base'] ] ) ) {
$available_widgets[ $widget['id_base'] ]['id_base'] = $widget['id_base'];
$available_widgets[ $widget['id_base'] ]['name'] = $widget['name'];
}
}
return apply_filters( 'pt-ocdi/available_widgets', $available_widgets );
}
/**
* Format results for log file
*
* @param array $results widget import results.
*/
private static function format_results_for_log( $results ) {
if ( empty( $results ) ) {
esc_html_e( 'No results for widget import!', 'pt-ocdi' );
}
// Loop sidebars.
foreach ( $results as $sidebar ) {
echo esc_html( $sidebar['name'] ) . ' : ' . esc_html( $sidebar['message'] ) . PHP_EOL . PHP_EOL;
// Loop widgets.
foreach ( $sidebar['widgets'] as $widget ) {
echo esc_html( $widget['name'] ) . ' - ' . esc_html( $widget['title'] ) . ' - ' . esc_html( $widget['message'] ) . PHP_EOL;
}
echo PHP_EOL;
}
}
}

View File

@@ -0,0 +1,409 @@
# Copyright (C) 2017 ProteusThemes
# This file is distributed under the GPL 2.0.
msgid ""
msgstr ""
"Project-Id-Version: One Click Demo Import 2.4.0\n"
"Report-Msgid-Bugs-To: http://support.proteusthemes.com/\n"
"POT-Creation-Date: 2016-05-14 09:53:17+00:00\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2017-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"X-Generator: grunt-wp-i18n 0.5.4\n"
"X-Poedit-KeywordsList: "
"__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
"attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
"Language: en\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-Country: United States\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-Basepath: ../\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-Bookmarks: \n"
"X-Textdomain-Support: yes\n"
#: inc/CustomizerImporter.php:37 inc/CustomizerImporter.php:45
msgid "Importing customizer settings"
msgstr ""
#: inc/CustomizerImporter.php:43
msgid "Customizer settings import finished!"
msgstr ""
#: inc/CustomizerImporter.php:73
msgid "Error: The customizer import file is missing! File path: %s"
msgstr ""
#: inc/CustomizerImporter.php:93
msgid ""
"Error: The customizer import file is not in a correct format. Please make "
"sure to use the correct customizer import file."
msgstr ""
#: inc/CustomizerImporter.php:99
msgid ""
"Error: The customizer import file is not suitable for current theme. You "
"can only import customizer settings for the same theme or a child theme."
msgstr ""
#: inc/Downloader.php:58
msgid "Missing URL for downloading a file!"
msgstr ""
#: inc/Downloader.php:76
msgid ""
"An error occurred while fetching file from: %1$s%2$s%3$s!%4$sReason: %5$s - "
"%6$s."
msgstr ""
#: inc/Helpers.php:197 inc/Helpers.php:240
msgid ""
"An error occurred while writing file to your server! Tried to write a file "
"to: %s%s."
msgstr ""
#: inc/Helpers.php:274
msgid ""
"An error occurred while reading a file from your server! Tried reading file "
"from path: %s%s."
msgstr ""
#: inc/Helpers.php:297
msgid ""
"This WordPress page does not have %sdirect%s write file access. This plugin "
"needs it in order to save the demo import xml file to the upload directory "
"of your site. You can change this setting with these instructions: %s."
msgstr ""
#. Plugin Name of the plugin/theme
msgid "One Click Demo Import"
msgstr ""
#: inc/Helpers.php:309 inc/OneClickDemoImport.php:132
msgid "Import Demo Data"
msgstr ""
#: inc/Helpers.php:321
msgid ""
"An error occurred while retrieving reading/writing permissions to your "
"server (could not retrieve WP filesystem credentials)!"
msgstr ""
#: inc/Helpers.php:329
msgid "Your WordPress login credentials don't allow to use WP_Filesystem!"
msgstr ""
#: inc/Helpers.php:369
msgid "One Click Demo Import - "
msgstr ""
#: inc/Helpers.php:403
msgid ""
"%sYour user role isn't high enough. You don't have permission to import "
"demo data.%s"
msgstr ""
#: inc/Helpers.php:449
msgid "Content file was not uploaded. Error: %s"
msgstr ""
#: inc/Helpers.php:453 inc/Helpers.php:470 inc/Helpers.php:487
#: inc/Helpers.php:498 inc/Helpers.php:518 inc/Helpers.php:526
msgid "Upload files"
msgstr ""
#: inc/Helpers.php:466
msgid "Widget file was not uploaded. Error: %s"
msgstr ""
#: inc/Helpers.php:483
msgid "Customizer file was not uploaded. Error: %s"
msgstr ""
#: inc/Helpers.php:496
msgid "Missing Redux option name! Please also enter the Redux option name!"
msgstr ""
#: inc/Helpers.php:514
msgid "Redux file was not uploaded. Error: %s"
msgstr ""
#: inc/Helpers.php:524
msgid "The import files were successfully uploaded!"
msgstr ""
#: inc/Helpers.php:550
msgid "Initial max execution time = %s"
msgstr ""
#: inc/Helpers.php:554
msgid ""
"Files info:%1$sSite URL = %2$s%1$sData file = %3$s%1$sWidget file = "
"%4$s%1$sCustomizer file = %5$s%1$sRedux files:%1$s%6$s"
msgstr ""
#: inc/Helpers.php:557 inc/Helpers.php:558 inc/Helpers.php:559
#: inc/Helpers.php:560
msgid "not defined!"
msgstr ""
#: inc/Importer.php:172
msgid "New AJAX call!"
msgstr ""
#: inc/OneClickDemoImport.php:183
msgid "No preview image defined for this import."
msgstr ""
#: inc/OneClickDemoImport.php:184
msgid "Are you sure?"
msgstr ""
#: inc/OneClickDemoImport.php:185
msgid "Cancel"
msgstr ""
#: inc/OneClickDemoImport.php:186
msgid "Yes, import!"
msgstr ""
#: inc/OneClickDemoImport.php:187
msgid "Selected demo import:"
msgstr ""
#: inc/OneClickDemoImport.php:234
msgid "Manually uploaded files"
msgstr ""
#: inc/OneClickDemoImport.php:247 inc/OneClickDemoImport.php:258
msgid "Downloaded files"
msgstr ""
#: inc/OneClickDemoImport.php:254
msgid "The import files for: %s were successfully downloaded!"
msgstr ""
#: inc/OneClickDemoImport.php:263
msgid "No import files specified!"
msgstr ""
#: inc/OneClickDemoImport.php:384
msgid ""
"Just used One Click Demo Import plugin and it was awesome! Thanks "
"@ProteusThemes! #OCDI https://www.proteusthemes.com/"
msgstr ""
#: inc/OneClickDemoImport.php:387
msgid ""
"%1$s%6$sWasn't this a great One Click Demo Import experience?%7$s Created "
"and maintained by %3$sProteusThemes%4$s. %2$s%5$sClick to Tweet!%4$s%8$s"
msgstr ""
#: inc/OneClickDemoImport.php:400
msgid ""
"%1$s%3$sThat's it, all done!%4$s%2$sThe demo import has finished. Please "
"check your page and make sure that everything has imported correctly. If it "
"did, you can deactivate the %3$sOne Click Demo Import%4$s plugin, because "
"it has done its job.%5$s"
msgstr ""
#: inc/OneClickDemoImport.php:411
msgid ""
"%1$sThe demo import has finished, but there were some import "
"errors.%2$sMore details about the errors can be found in this %3$s%5$slog "
"file%6$s%4$s%7$s"
msgstr ""
#: inc/ReduxImporter.php:23
msgid "The Redux plugin is not activated, so the Redux import was skipped!"
msgstr ""
#: inc/ReduxImporter.php:32 inc/ReduxImporter.php:53 inc/ReduxImporter.php:66
msgid "Importing Redux settings"
msgstr ""
#: inc/ReduxImporter.php:51
msgid "Redux settings import for: %s finished successfully!"
msgstr ""
#: inc/ReduxImporter.php:57
msgid ""
"The Redux option name: %s, was not found in this WP site, so it was not "
"imported!"
msgstr ""
#: inc/WPCLICommands.php:34
msgid "There are no predefined demo imports for currently active theme!"
msgstr ""
#: inc/WPCLICommands.php:37
msgid "Here are the predefined demo imports:"
msgstr ""
#: inc/WPCLICommands.php:71
msgid "At least one of the possible options should be set! Check them with --help"
msgstr ""
#: inc/WPCLICommands.php:122
msgid ""
"The \"predefined\" parameter should be a number (an index of the OCDI "
"predefined demo import)!"
msgstr ""
#: inc/WPCLICommands.php:128
msgid ""
"The supplied predefined index does not exist! Please take a look at the "
"available predefined demo imports:"
msgstr ""
#: inc/WPCLICommands.php:135
msgid "Predefined demo import started! All other parameters will be ignored!"
msgstr ""
#: inc/WPCLICommands.php:140
msgid "Selected predefined demo import: %s"
msgstr ""
#: inc/WPCLICommands.php:143
msgid "Preparing the demo import files..."
msgstr ""
#: inc/WPCLICommands.php:148
msgid "Demo import files could not be retrieved!"
msgstr ""
#: inc/WPCLICommands.php:151
msgid "Demo import files retrieved successfully!"
msgstr ""
#: inc/WPCLICommands.php:153
msgid "Importing..."
msgstr ""
#: inc/WPCLICommands.php:173
msgid "Predefined import finished!"
msgstr ""
#: inc/WPCLICommands.php:185
msgid "Content import file provided does not exist! Skipping this import!"
msgstr ""
#: inc/WPCLICommands.php:194
msgid "Importing content (this might take a while)..."
msgstr ""
#: inc/WPCLICommands.php:196
msgid "Importing content"
msgstr ""
#: inc/WPCLICommands.php:201
msgid "Content import finished!"
msgstr ""
#: inc/WPCLICommands.php:204
msgid "There were some issues while importing the content!"
msgstr ""
#: inc/WPCLICommands.php:223
msgid "Widgets import file provided does not exist! Skipping this import!"
msgstr ""
#: inc/WPCLICommands.php:227
msgid "Importing widgets..."
msgstr ""
#: inc/WPCLICommands.php:232
msgid "Widgets imported successfully!"
msgstr ""
#: inc/WPCLICommands.php:235
msgid "There were some issues while importing widgets!"
msgstr ""
#: inc/WPCLICommands.php:254
msgid "Customizer import file provided does not exist! Skipping this import!"
msgstr ""
#: inc/WPCLICommands.php:258
msgid "Importing customizer settings..."
msgstr ""
#: inc/WPCLICommands.php:263
msgid "Customizer settings imported successfully!"
msgstr ""
#: inc/WPCLICommands.php:266
msgid "There were some issues while importing customizer settings!"
msgstr ""
#: inc/WPCLICommands.php:286
msgid "Executing action: %s ..."
msgstr ""
#: inc/WidgetImporter.php:40 inc/WidgetImporter.php:52
msgid "Importing widgets"
msgstr ""
#: inc/WidgetImporter.php:88
msgid "Error: Widget import file could not be found."
msgstr ""
#: inc/WidgetImporter.php:118
msgid "Error: Widget import data could not be read. Please try a different file."
msgstr ""
#: inc/WidgetImporter.php:157
msgid "Sidebar does not exist in theme (moving widget to Inactive)"
msgstr ""
#: inc/WidgetImporter.php:178
msgid "Site does not support widget"
msgstr ""
#: inc/WidgetImporter.php:211
msgid "Widget already exists"
msgstr ""
#: inc/WidgetImporter.php:269
msgid "Imported"
msgstr ""
#: inc/WidgetImporter.php:273
msgid "Imported to Inactive"
msgstr ""
#: inc/WidgetImporter.php:279
msgid "No Title"
msgstr ""
#: inc/WidgetImporter.php:326
msgid "No results for widget import!"
msgstr ""
#: one-click-demo-import.php:57
msgid ""
"The %2$sOne Click Demo Import%3$s plugin requires %2$sPHP 5.3.2+%3$s to run "
"properly. Please contact your hosting company and ask them to update the "
"PHP version of your site to at least PHP 5.3.2.%4$s Your current version of "
"PHP: %2$s%1$s%3$s"
msgstr ""
#. Plugin URI of the plugin/theme
msgid "https://wordpress.org/plugins/one-click-demo-import/"
msgstr ""
#. Description of the plugin/theme
msgid ""
"Import your content, widgets and theme settings with one click. Theme "
"authors! Enable simple demo import for your theme demo data."
msgstr ""
#. Author of the plugin/theme
msgid "ProteusThemes"
msgstr ""
#. Author URI of the plugin/theme
msgid "http://www.proteusthemes.com"
msgstr ""

View File

@@ -0,0 +1,94 @@
<?php
/*
Plugin Name: One Click Demo Import
Plugin URI: https://wordpress.org/plugins/one-click-demo-import/
Description: Import your content, widgets and theme settings with one click. Theme authors! Enable simple demo import for your theme demo data.
Version: 2.4.0
Author: ProteusThemes
Author URI: http://www.proteusthemes.com
License: GPL3
License URI: http://www.gnu.org/licenses/gpl.html
Text Domain: pt-ocdi
*/
// Block direct access to the main plugin file.
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
* Main plugin class with initialization tasks.
*/
class OCDI_Plugin {
/**
* Constructor for this class.
*/
public function __construct() {
/**
* Display admin error message if PHP version is older than 5.3.2.
* Otherwise execute the main plugin class.
*/
if ( version_compare( phpversion(), '5.3.2', '<' ) ) {
add_action( 'admin_notices', array( $this, 'old_php_admin_error_notice' ) );
}
else {
// Set plugin constants.
$this->set_plugin_constants();
// Composer autoloader.
require_once PT_OCDI_PATH . 'vendor/autoload.php';
// Instantiate the main plugin class *Singleton*.
$pt_one_click_demo_import = OCDI\OneClickDemoImport::get_instance();
// Register WP CLI commands
if ( defined( 'WP_CLI' ) && WP_CLI ) {
WP_CLI::add_command( 'ocdi list', array( 'OCDI\WPCLICommands', 'list_predefined' ) );
WP_CLI::add_command( 'ocdi import', array( 'OCDI\WPCLICommands', 'import' ) );
}
}
}
/**
* Display an admin error notice when PHP is older the version 5.3.2.
* Hook it to the 'admin_notices' action.
*/
public function old_php_admin_error_notice() {
$message = sprintf( esc_html__( 'The %2$sOne Click Demo Import%3$s plugin requires %2$sPHP 5.3.2+%3$s to run properly. Please contact your hosting company and ask them to update the PHP version of your site to at least PHP 5.3.2.%4$s Your current version of PHP: %2$s%1$s%3$s', 'pt-ocdi' ), phpversion(), '<strong>', '</strong>', '<br>' );
printf( '<div class="notice notice-error"><p>%1$s</p></div>', wp_kses_post( $message ) );
}
/**
* Set plugin constants.
*
* Path/URL to root of this plugin, with trailing slash and plugin version.
*/
private function set_plugin_constants() {
// Path/URL to root of this plugin, with trailing slash.
if ( ! defined( 'PT_OCDI_PATH' ) ) {
define( 'PT_OCDI_PATH', plugin_dir_path( __FILE__ ) );
}
if ( ! defined( 'PT_OCDI_URL' ) ) {
define( 'PT_OCDI_URL', plugin_dir_url( __FILE__ ) );
}
// Action hook to set the plugin version constant.
add_action( 'admin_init', array( $this, 'set_plugin_version_constant' ) );
}
/**
* Set plugin version constant -> PT_OCDI_VERSION.
*/
public function set_plugin_version_constant() {
if ( ! defined( 'PT_OCDI_VERSION' ) ) {
$plugin_data = get_plugin_data( __FILE__ );
define( 'PT_OCDI_VERSION', $plugin_data['Version'] );
}
}
}
// Instantiate the plugin class.
$ocdi_plugin = new OCDI_Plugin();

View File

@@ -0,0 +1,7 @@
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInite70ea380d43073ce103daddb33b73ed6::getLoader();

View File

@@ -0,0 +1,445 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
// PSR-4
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
// PSR-0
private $prefixesPsr0 = array();
private $fallbackDirsPsr0 = array();
private $useIncludePath = false;
private $classMap = array();
private $classMapAuthoritative = false;
private $missingClasses = array();
private $apcuPrefix;
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0);
}
return array();
}
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
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') && ini_get('apc.enabled') ? $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.
*
* @param bool $prepend Whether to prepend the autoloader or not
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
/**
* Unregisters this instance as an autoloader.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath.'\\';
if (isset($this->prefixDirsPsr4[$search])) {
foreach ($this->prefixDirsPsr4[$search] as $dir) {
$length = $this->prefixLengthsPsr4[$first][$search];
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}

View File

@@ -0,0 +1,21 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,9 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

View File

@@ -0,0 +1,9 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

View File

@@ -0,0 +1,11 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'ProteusThemes\\WPContentImporter2\\' => array($vendorDir . '/proteusthemes/wp-content-importer-v2/src'),
'OCDI\\' => array($baseDir . '/inc'),
);

View File

@@ -0,0 +1,52 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInite70ea380d43073ce103daddb33b73ed6
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInite70ea380d43073ce103daddb33b73ed6', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInite70ea380d43073ce103daddb33b73ed6', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInite70ea380d43073ce103daddb33b73ed6::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->register(true);
return $loader;
}
}

View File

@@ -0,0 +1,39 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInite70ea380d43073ce103daddb33b73ed6
{
public static $prefixLengthsPsr4 = array (
'P' =>
array (
'ProteusThemes\\WPContentImporter2\\' => 33,
),
'O' =>
array (
'OCDI\\' => 5,
),
);
public static $prefixDirsPsr4 = array (
'ProteusThemes\\WPContentImporter2\\' =>
array (
0 => __DIR__ . '/..' . '/proteusthemes/wp-content-importer-v2/src',
),
'OCDI\\' =>
array (
0 => __DIR__ . '/../..' . '/inc',
),
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInite70ea380d43073ce103daddb33b73ed6::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInite70ea380d43073ce103daddb33b73ed6::$prefixDirsPsr4;
}, null, ClassLoader::class);
}
}

View File

@@ -0,0 +1,47 @@
[
{
"name": "proteusthemes/wp-content-importer-v2",
"version": "v0.4.7",
"version_normalized": "0.4.7.0",
"source": {
"type": "git",
"url": "https://github.com/proteusthemes/WordPress-Importer.git",
"reference": "ec052cc8fdcde29b47b69599b2b430e7fb423c22"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/proteusthemes/WordPress-Importer/zipball/ec052cc8fdcde29b47b69599b2b430e7fb423c22",
"reference": "ec052cc8fdcde29b47b69599b2b430e7fb423c22",
"shasum": ""
},
"time": "2017-05-02T11:07:20+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"psr-4": {
"ProteusThemes\\WPContentImporter2\\": "src/"
}
},
"license": [
"GPL-2.0+"
],
"authors": [
{
"name": "Contributors",
"homepage": "https://github.com/humanmade/WordPress-Importer/graphs/contributors"
}
],
"description": "WP content importer v2 forked from humanmade/wordpress-importer.",
"keywords": [
"content",
"import",
"proteusthemes",
"theme",
"wordpress",
"wp"
],
"support": {
"source": "https://github.com/proteusthemes/WordPress-Importer/tree/v0.4.7"
}
}
]

View File

@@ -0,0 +1,25 @@
# WP content importer used in OCDI
List of files used in OCDI plugin (from the original repo):
- class-logger-cli.php,
- class-logger.php,
- class-wxr-importer.php
One click demo import plugin page: https://wordpress.org/plugins/one-click-demo-import/
One click demo import github page: https://github.com/proteusthemes/one-click-demo-import
## Changelog
*October 29th 2016*
- Cleaned up this forked repo, to only include the thing we need in the OCDI plugin.
- Changed the class names and use psr-4 autoloading in composer.json
*October 26th 2016*
- made a fork form the original repo
- merged a pull request for "term meta data" from the original repo: https://github.com/humanmade/WordPress-Importer/pull/18

View File

@@ -0,0 +1,17 @@
{
"name": "proteusthemes/wp-content-importer-v2",
"description": "WP content importer v2 forked from humanmade/wordpress-importer.",
"keywords": ["wp", "wordpress", "proteusthemes", "theme", "import", "content"],
"license": "GPL-2.0+",
"authors": [
{
"name" : "Contributors",
"homepage" : "https://github.com/humanmade/WordPress-Importer/graphs/contributors"
}
],
"autoload": {
"psr-4": {
"ProteusThemes\\WPContentImporter2\\": "src/"
}
}
}

View File

@@ -0,0 +1,137 @@
<?php
namespace ProteusThemes\WPContentImporter2;
/**
* Describes a logger instance
*
* Based on PSR-3: http://www.php-fig.org/psr/psr-3/
*
* The message MUST be a string or object implementing __toString().
*
* The message MAY contain placeholders in the form: {foo} where foo
* will be replaced by the context data in key "foo".
*
* The context array can contain arbitrary data, the only assumption that
* can be made by implementors is that if an Exception instance is given
* to produce a stack trace, it MUST be in a key named "exception".
*
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
* for the full interface specification.
*/
class WPImporterLogger {
/**
* System is unusable.
*
* @param string $message
* @param array $context
* @return null
*/
public function emergency( $message, array $context = array() ) {
return $this->log( 'emergency', $message, $context );
}
/**
* Action must be taken immediately.
*
* Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up.
*
* @param string $message
* @param array $context
* @return null
*/
public function alert( $message, array $context = array() ) {
return $this->log( 'alert', $message, $context );
}
/**
* Critical conditions.
*
* Example: Application component unavailable, unexpected exception.
*
* @param string $message
* @param array $context
* @return null
*/
public function critical( $message, array $context = array() ) {
return $this->log( 'critical', $message, $context );
}
/**
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*
* @param string $message
* @param array $context
* @return null
*/
public function error( $message, array $context = array()) {
return $this->log( 'error', $message, $context );
}
/**
* Exceptional occurrences that are not errors.
*
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*
* @param string $message
* @param array $context
* @return null
*/
public function warning( $message, array $context = array() ) {
return $this->log( 'warning', $message, $context );
}
/**
* Normal but significant events.
*
* @param string $message
* @param array $context
* @return null
*/
public function notice( $message, array $context = array() ) {
return $this->log( 'notice', $message, $context );
}
/**
* Interesting events.
*
* Example: User logs in, SQL logs.
*
* @param string $message
* @param array $context
* @return null
*/
public function info( $message, array $context = array() ) {
return $this->log( 'info', $message, $context );
}
/**
* Detailed debug information.
*
* @param string $message
* @param array $context
* @return null
*/
public function debug( $message, array $context = array() ) {
return $this->log( 'debug', $message, $context );
}
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
* @return null
*/
public function log( $level, $message, array $context = array() ) {
$this->messages[] = array(
'timestamp' => time(),
'level' => $level,
'message' => $message,
'context' => $context,
);
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace ProteusThemes\WPContentImporter2;
class WPImporterLoggerCLI extends WPImporterLogger {
public $min_level = 'notice';
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
* @return null
*/
public function log( $level, $message, array $context = array() ) {
if ( $this->level_to_numeric( $level ) < $this->level_to_numeric( $this->min_level ) ) {
return;
}
printf(
'[%s] %s' . PHP_EOL,
strtoupper( $level ),
$message
);
}
public static function level_to_numeric( $level ) {
$levels = array(
'emergency' => 8,
'alert' => 7,
'critical' => 6,
'error' => 5,
'warning' => 4,
'notice' => 3,
'info' => 2,
'debug' => 1,
);
if ( ! isset( $levels[ $level ] ) ) {
return 0;
}
return $levels[ $level ];
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace ProteusThemes\WPContentImporter2;
class WXRImportInfo {
public $home;
public $siteurl;
public $title;
public $users = array();
public $post_count = 0;
public $media_count = 0;
public $comment_count = 0;
public $term_count = 0;
public $generator = '';
public $version;
}

View File

@@ -0,0 +1,148 @@
<?php
/**
* The plugin page view - the "settings" page of the plugin.
*
* @package ocdi
*/
namespace OCDI;
?>
<div class="kdadmin-dashboard kdadmin-import wrap">
<div class="kdadmin-welcome-box postbox">
<?php ob_start(); ?>
<h1><?php esc_html_e( 'Import demos', 'pt-ocdi' ); ?></h1>
<?php
$plugin_title = ob_get_clean();
// Display the plugin title (can be replaced with custom title text through the filter below).
echo wp_kses_post( apply_filters( 'pt-ocdi/plugin_page_title', $plugin_title ) );
// Display warrning if PHP safe mode is enabled, since we wont be able to change the max_execution_time.
if ( ini_get( 'safe_mode' ) ) {
printf(
esc_html__( '%sWarning: your server is using %sPHP safe mode%s. This means that you might experience server timeout errors.%s', 'pt-ocdi' ),
'<div class="notice notice-warning is-dismissible"><p>',
'<strong>',
'</strong>',
'</p></div>'
);
}
// Start output buffer for displaying the plugin intro text.
ob_start();
?>
<div class="notice notice-warning is-dismissible">
<p><?php esc_html_e( 'Before you begin, make sure all the required plugins are activated.', 'pt-ocdi' ); ?></p>
</div>
<?php if (get_option( 'keydesign-verify' ) == 'no' ) { ?>
<div class="kdadmin-activate-column kdadmin-activate-column-import">
<h3>Ekko theme is not activated! Please activate your copy from <a href="<?php echo admin_url( 'admin.php?page=Ekko-dashboard'); ?>">dashboard</a> and take full advantage of Ekko.</h3>
</div>
<?php } ?>
<?php if (get_option( 'keydesign-verify' ) == 'yes' ) { ?>
<div class="kdadmin-intro-text">
<p class="about-description">
<?php esc_html_e( 'Importing demo data (posts, pages, images, theme settings) is the easiest way to setup your theme.', 'pt-ocdi' ); ?>
<?php esc_html_e( 'It will allow you to quickly edit everything instead of creating content from scratch.', 'pt-ocdi' ); ?>
</p>
<p><?php esc_html_e( 'When you import the data, the following things might happen:', 'pt-ocdi' ); ?></p>
<ul>
<li><?php esc_html_e( 'No existing posts, pages, categories, images, custom post types or any other data will be deleted or modified.', 'pt-ocdi' ); ?></li>
<li><?php esc_html_e( 'Posts, pages, images, widgets, menus and other theme settings will get imported.', 'pt-ocdi' ); ?></li>
<li><?php esc_html_e( 'Please click on the Import button only once and wait, it can take a couple of minutes.', 'pt-ocdi' ); ?></li>
</ul>
</div>
<?php } ?>
</div>
<?php if (get_option( 'keydesign-verify' ) == 'yes' ) { ?>
<?php if ( 1 === count( $this->import_files ) ) : ?>
<div class="ocdi__demo-import-notice js-ocdi-demo-import-notice"><?php
if ( is_array( $this->import_files ) && ! empty( $this->import_files[0]['import_notice'] ) ) {
echo wp_kses_post( $this->import_files[0]['import_notice'] );
}
?></div>
<p class="ocdi__button-container">
<button class="ocdi__button button button-hero button-primary js-ocdi-import-data"><?php esc_html_e( 'Import Demo Data', 'pt-ocdi' ); ?></button>
</p>
<?php else : ?>
<!-- OCDI grid layout -->
<div class="ocdi__gl js-ocdi-gl">
<?php
// Prepare navigation data.
$categories = Helpers::get_all_demo_import_categories( $this->import_files );
?>
<?php if ( ! empty( $categories ) ) : ?>
<div class="ocdi__gl-header js-ocdi-gl-header">
<nav class="ocdi__gl-navigation">
<ul>
<li class="active"><a href="#all" class="ocdi__gl-navigation-link js-ocdi-nav-link"><?php esc_html_e( 'All', 'pt-ocdi' ); ?></a></li>
<?php foreach ( $categories as $key => $name ) : ?>
<li><a href="#<?php echo esc_attr( $key ); ?>" class="ocdi__gl-navigation-link js-ocdi-nav-link"><?php echo esc_html( $name ); ?></a></li>
<?php endforeach; ?>
</ul>
</nav>
<div clas="ocdi__gl-search">
<input type="search" class="ocdi__gl-search-input js-ocdi-gl-search" name="ocdi-gl-search" value="" placeholder="<?php esc_html_e( 'Search demos...', 'pt-ocdi' ); ?>">
</div>
</div>
<?php endif; ?>
<div class="ocdi__gl-item-container wp-clearfix js-ocdi-gl-item-container">
<?php foreach ( $this->import_files as $index => $import_file ) : ?>
<?php
// Prepare import item display data.
$img_src = isset( $import_file['import_preview_image_url'] ) ? $import_file['import_preview_image_url'] : '';
// Default to the theme screenshot, if a custom preview image is not defined.
if ( empty( $img_src ) ) {
$theme = wp_get_theme();
$img_src = $theme->get_screenshot();
}
?>
<div class="ocdi__gl-item js-ocdi-gl-item" data-categories="<?php echo esc_attr( Helpers::get_demo_import_item_categories( $import_file ) ); ?>" data-name="<?php echo esc_attr( strtolower( $import_file['import_file_name'] ) ); ?>">
<div class="ocdi__gl-item-image-container">
<?php if ( ! empty( $img_src ) ) : ?>
<img class="ocdi__gl-item-image" src="<?php echo esc_url( $img_src ) ?>">
<?php else : ?>
<div class="ocdi__gl-item-image ocdi__gl-item-image--no-image"><?php esc_html_e( 'No preview image.', 'pt-ocdi' ); ?></div>
<?php endif; ?>
</div>
<div class="ocdi__gl-item-footer<?php echo ! empty( $import_file['preview_url'] ) ? ' ocdi__gl-item-footer--with-preview' : ''; ?>">
<h4 class="ocdi__gl-item-title" title="<?php echo esc_attr( $import_file['import_file_name'] ); ?>"><?php echo esc_html( $import_file['import_file_name'] ); ?></h4>
<button class="ocdi__gl-item-button button button-primary js-ocdi-gl-import-data" value="<?php echo esc_attr( $index ); ?>"><?php esc_html_e( 'Import', 'pt-ocdi' ); ?></button>
<?php if ( ! empty( $import_file['preview_url'] ) ) : ?>
<a class="ocdi__gl-item-button button" href="<?php echo esc_url( $import_file['preview_url'] ); ?>" target="_blank"><?php esc_html_e( 'Preview', 'pt-ocdi' ); ?></a>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<div id="js-ocdi-modal-content"></div>
<?php endif; ?>
<p class="ocdi__ajax-loader js-ocdi-ajax-loader">
<span class="spinner"></span> <?php esc_html_e( 'Importing, please wait!', 'pt-ocdi' ); ?>
</p>
<div class="ocdi__response js-ocdi-ajax-response"></div>
<?php } ?>
</div>

View File

@@ -0,0 +1,151 @@
<?php
/**
* The plugin page view - the "settings" page of the plugin.
*
* @package ocdi
*/
namespace OCDI;
?>
<div class="kdadmin-dashboard kdadmin-import wrap">
<div class="kdadmin-welcome-box postbox">
<?php ob_start(); ?>
<h1><?php esc_html_e( 'Import demos', 'pt-ocdi' ); ?></h1>
<?php
$plugin_title = ob_get_clean();
// Display the plugin title (can be replaced with custom title text through the filter below).
echo wp_kses_post( apply_filters( 'pt-ocdi/plugin_page_title', $plugin_title ) );
// Display warrning if PHP safe mode is enabled, since we wont be able to change the max_execution_time.
if ( ini_get( 'safe_mode' ) ) {
printf(
esc_html__( '%sWarning: your server is using %sPHP safe mode%s. This means that you might experience server timeout errors.%s', 'pt-ocdi' ),
'<div class="notice notice-warning is-dismissible"><p>',
'<strong>',
'</strong>',
'</p></div>'
);
}
// Start output buffer for displaying the plugin intro text.
ob_start();
?>
<div class="notice notice-warning is-dismissible">
<p><?php esc_html_e( 'Before you begin, make sure all the required plugins are activated.', 'pt-ocdi' ); ?></p>
</div>
<?php if (get_option( 'keydesign-verify' ) == 'no' ) { ?>
<div class="kdadmin-activate-column kdadmin-activate-column-import">
<h3>Ekko theme is not activated! Please activate your copy from <a href="<?php echo admin_url( 'admin.php?page=ekko-dashboard'); ?>">dashboard</a> and take full advantage of Ekko.</h3>
</div>
<?php } ?>
<?php if (get_option( 'keydesign-verify' ) == 'yes' ) { ?>
<div class="kdadmin-intro-text">
<p class="about-description">
<?php esc_html_e( 'Importing demo data (posts, pages, images, theme settings) is the easiest way to setup your theme.', 'pt-ocdi' ); ?>
<?php esc_html_e( 'It will allow you to quickly edit everything instead of creating content from scratch.', 'pt-ocdi' ); ?>
</p>
<p><?php esc_html_e( 'When you import the data, the following things might happen:', 'pt-ocdi' ); ?></p>
<ul>
<li><?php esc_html_e( 'No existing posts, pages, categories, images, custom post types or any other data will be deleted or modified.', 'pt-ocdi' ); ?></li>
<li><?php esc_html_e( 'Posts, pages, images, widgets, menus and other theme settings will get imported.', 'pt-ocdi' ); ?></li>
<li><?php esc_html_e( 'Please click on the Import button only once and wait, it can take a couple of minutes.', 'pt-ocdi' ); ?></li>
</ul>
</div>
<?php } ?>
</div>
<?php if (get_option( 'keydesign-verify' ) == 'yes' ) { ?>
<?php if ( 1 === count( $this->import_files ) ) : ?>
<div class="ocdi__demo-import-notice js-ocdi-demo-import-notice"><?php
if ( is_array( $this->import_files ) && ! empty( $this->import_files[0]['import_notice'] ) ) {
echo wp_kses_post( $this->import_files[0]['import_notice'] );
}
?></div>
<p class="ocdi__button-container">
<button class="ocdi__button button button-hero button-primary js-ocdi-import-data"><?php esc_html_e( 'Import Demo Data', 'pt-ocdi' ); ?></button>
</p>
<?php else : ?>
<!-- OCDI grid layout -->
<div class="ocdi__gl js-ocdi-gl">
<?php
// Prepare navigation data.
$categories = Helpers::get_all_demo_import_categories( $this->import_files );
?>
<?php if ( ! empty( $categories ) ) : ?>
<div class="ocdi__gl-header js-ocdi-gl-header">
<nav class="ocdi__gl-navigation">
<ul>
<li class="active"><a href="#all" class="ocdi__gl-navigation-link js-ocdi-nav-link"><?php esc_html_e( 'All', 'pt-ocdi' ); ?></a></li>
<?php foreach ( $categories as $key => $name ) : ?>
<li><a href="#<?php echo esc_attr( $key ); ?>" class="ocdi__gl-navigation-link js-ocdi-nav-link"><?php echo esc_html( $name ); ?></a></li>
<?php endforeach; ?>
</ul>
</nav>
<div clas="ocdi__gl-search">
<input type="search" class="ocdi__gl-search-input js-ocdi-gl-search" name="ocdi-gl-search" value="" placeholder="<?php esc_html_e( 'Search demos...', 'pt-ocdi' ); ?>">
</div>
</div>
<?php endif; ?>
<div class="ocdi__gl-item-container wp-clearfix js-ocdi-gl-item-container">
<?php foreach ( $this->import_files as $index => $import_file ) : ?>
<?php
// Prepare import item display data.
$img_src = isset( $import_file['import_preview_image_url'] ) ? $import_file['import_preview_image_url'] : '';
// Default to the theme screenshot, if a custom preview image is not defined.
if ( empty( $img_src ) ) {
$theme = wp_get_theme();
$img_src = $theme->get_screenshot();
}
?>
<div class="ocdi__gl-item js-ocdi-gl-item" data-categories="<?php echo esc_attr( Helpers::get_demo_import_item_categories( $import_file ) ); ?>" data-name="<?php echo esc_attr( strtolower( $import_file['import_file_name'] ) ); ?>">
<div class="ocdi__gl-item-image-container">
<?php if ( ! empty( $img_src ) ) : ?>
<img class="ocdi__gl-item-image" src="<?php echo esc_url( $img_src ) ?>">
<?php else : ?>
<div class="ocdi__gl-item-image ocdi__gl-item-image--no-image"><?php esc_html_e( 'No preview image.', 'pt-ocdi' ); ?></div>
<?php endif; ?>
</div>
<div class="ocdi__gl-item-footer<?php echo ! empty( $import_file['preview_url'] ) ? ' ocdi__gl-item-footer--with-preview' : ''; ?>">
<h4 class="ocdi__gl-item-title" title="<?php echo esc_attr( $import_file['import_file_name'] ); ?>"><?php echo esc_html( $import_file['import_file_name'] ); ?></h4>
<button class="ocdi__gl-item-button button button-primary js-ocdi-gl-import-data" value="<?php echo esc_attr( $index ); ?>"><?php esc_html_e( 'Import', 'pt-ocdi' ); ?></button>
<?php if ( ! empty( $import_file['preview_url'] ) ) : ?>
<a class="ocdi__gl-item-button button" href="<?php echo esc_url( $import_file['preview_url'] ); ?>" target="_blank"><?php esc_html_e( 'Preview', 'pt-ocdi' ); ?></a>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<div id="js-ocdi-modal-content"></div>
<?php endif; ?>
<p class="ocdi__ajax-loader js-ocdi-ajax-loader">
<span class="spinner"></span> <?php esc_html_e( 'Importing, please wait!', 'pt-ocdi' ); ?>
</p>
<div class="ocdi__response js-ocdi-ajax-response"></div>
<?php } ?>
</div>