Initial commit: Atomaste website

This commit is contained in:
2025-12-10 12:17:30 -05:00
commit 0b9e5d1605
19260 changed files with 5206382 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="ast-block-templates" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe900;" glyph-name="maximize" d="M341.333 853.334h-128c-35.328 0-67.413-14.379-90.496-37.504s-37.504-55.168-37.504-90.496v-128c0-23.552 19.115-42.667 42.667-42.667s42.667 19.115 42.667 42.667v128c0 11.776 4.736 22.4 12.501 30.165s18.389 12.501 30.165 12.501h128c23.552 0 42.667 19.115 42.667 42.667s-19.115 42.667-42.667 42.667zM938.667 597.334v128c0 35.328-14.379 67.413-37.504 90.496s-55.168 37.504-90.496 37.504h-128c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667h128c11.776 0 22.4-4.736 30.165-12.501s12.501-18.389 12.501-30.165v-128c0-23.552 19.115-42.667 42.667-42.667s42.667 19.115 42.667 42.667zM682.667-0h128c35.328 0 67.413 14.379 90.496 37.504s37.504 55.168 37.504 90.496v128c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667v-128c0-11.776-4.736-22.4-12.501-30.165s-18.389-12.501-30.165-12.501h-128c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667zM85.333 256v-128c0-35.328 14.379-67.413 37.504-90.496s55.168-37.504 90.496-37.504h128c23.552 0 42.667 19.115 42.667 42.667s-19.115 42.667-42.667 42.667h-128c-11.776 0-22.4 4.736-30.165 12.501s-12.501 18.389-12.501 30.165v128c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667z" />
<glyph unicode="&#xe901;" glyph-name="rotate-cw" d="M834.005 312.875c-31.403-88.875-95.787-156.587-174.677-194.261s-171.989-45.269-260.864-13.867-156.587 95.787-194.261 174.677-45.269 171.989-13.867 260.864 95.787 156.587 174.677 194.261 171.989 45.269 260.864 13.867c50.688-17.92 94.251-46.421 127.445-80.299l120.491-113.451h-148.48c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667h255.872c0.171 0 0.384 0 0.555 0 5.845 0.043 11.392 1.28 16.469 3.499 5.077 2.176 9.771 5.376 13.824 9.6 0.512 0.512 0.981 1.067 1.451 1.621 3.243 3.712 5.717 7.851 7.467 12.245 1.749 4.352 2.773 9.088 2.944 13.995 0.085 0.555 0.085 1.109 0.085 1.707v256c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667v-157.227l-124.416 117.12c-42.368 43.179-97.024 78.763-159.915 100.949-111.104 39.296-227.669 29.781-326.144-17.28s-179.072-131.755-218.325-242.859-29.696-227.627 17.323-326.101 131.755-179.072 242.859-218.325 227.627-29.739 326.101 17.323 179.072 131.755 218.325 242.859c7.851 22.229-3.797 46.592-26.027 54.443s-46.592-3.797-54.443-26.027z" />
<glyph unicode="&#xe902;" glyph-name="file" d="M554.667 896h-298.667c-35.328 0-67.413-14.379-90.496-37.504s-37.504-55.168-37.504-90.496v-682.667c0-35.328 14.379-67.413 37.504-90.496s55.168-37.504 90.496-37.504h512c35.328 0 67.413 14.379 90.496 37.504s37.504 55.168 37.504 90.496v469.333c0 11.776-4.779 22.443-12.501 30.165l-298.667 298.667c-4.096 4.096-8.789 7.168-13.824 9.259-5.205 2.176-10.795 3.243-16.341 3.243zM750.336 597.334h-153.003v153.003zM512 810.667v-256c0-23.552 19.115-42.667 42.667-42.667h256v-426.667c0-11.776-4.736-22.4-12.501-30.165s-18.389-12.501-30.165-12.501h-512c-11.776 0-22.4 4.736-30.165 12.501s-12.501 18.389-12.501 30.165v682.667c0 11.776 4.736 22.4 12.501 30.165s18.389 12.501 30.165 12.501z" />
<glyph unicode="&#xe903;" glyph-name="layers" d="M512 805.632l331.264-165.632-331.264-165.632-331.264 165.632zM492.928 891.478l-426.667-213.333c-21.077-10.539-29.611-36.139-19.072-57.216 4.309-8.661 11.136-15.189 19.072-19.072l426.667-213.333c12.459-6.229 26.453-5.803 38.144 0l426.667 213.333c21.077 10.539 29.611 36.181 19.072 57.259-4.309 8.619-11.179 15.147-19.072 19.072l-426.667 213.333c-12.459 6.229-26.453 5.803-38.144 0zM66.261 175.19l426.667-213.333c12.459-6.229 26.453-5.803 38.144 0l426.667 213.333c21.077 10.539 29.611 36.181 19.072 57.259s-36.181 29.611-57.259 19.072l-407.552-203.819-407.595 203.776c-21.077 10.539-46.72 2.005-57.259-19.072s-2.005-46.72 19.072-57.259zM66.261 388.523l426.667-213.333c12.459-6.229 26.453-5.803 38.144 0l426.667 213.333c21.077 10.539 29.611 36.181 19.072 57.259s-36.181 29.611-57.259 19.072l-407.552-203.819-407.595 203.776c-21.077 10.539-46.72 2.005-57.259-19.072s-2.005-46.72 19.072-57.259z" />
<glyph unicode="&#xe904;" glyph-name="chevron-left" d="M670.165 200.832l-225.835 225.835 225.835 225.835c16.683 16.683 16.683 43.691 0 60.331s-43.691 16.683-60.331 0l-256-256c-16.683-16.683-16.683-43.691 0-60.331l256-256c16.683-16.683 43.691-16.683 60.331 0s16.683 43.691 0 60.331z" />
</font></defs></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Plus sm">
<path id="Icon" fill-rule="evenodd" clip-rule="evenodd" d="M10 5C10.5523 5 11 5.44772 11 6V9L14 9C14.5523 9 15 9.44772 15 10C15 10.5523 14.5523 11 14 11H11V14C11 14.5523 10.5523 15 10 15C9.44771 15 9 14.5523 9 14V11H6C5.44772 11 5 10.5523 5 10C5 9.44771 5.44772 9 6 9L9 9V6C9 5.44772 9.44771 5 10 5Z" fill="white"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 441 B

View File

@@ -0,0 +1,209 @@
/**
* AJAX Request Queue
*
* - add()
* - remove()
* - run()
* - stop()
*
* @since 2.0.0
*/
const AstBlockTemplatesAjaxQueue = ( function () {
let requests = [];
return {
/**
* Add AJAX request
*
* @param {string} opt selected opt.
* @since 2.0.0
*/
add( opt ) {
requests.push( opt );
},
/**
* Remove AJAX request
*
* @param {string} opt selected opt.
* @since 2.0.0
*/
remove( opt ) {
if ( jQuery.inArray( opt, requests ) > -1 ) {
requests.splice( jQuery.inArray( opt, requests ), 1 );
}
},
/**
* Run / Process AJAX request
*
* @since 2.0.0
*/
run() {
const self = this;
let oriSuc;
if ( requests.length ) {
oriSuc = requests[ 0 ].complete;
requests[ 0 ].complete = function () {
if ( typeof oriSuc === 'function' ) {
oriSuc();
}
requests.shift();
self.run.apply( self, [] );
};
jQuery.ajax( requests[ 0 ] );
} else {
self.tid = setTimeout( function () {
self.run.apply( self, [] );
}, 1000 );
}
},
/**
* Stop AJAX request
*
* @since 2.0.0
*/
stop() {
requests = [];
clearTimeout( this.tid );
},
};
}() );
( function ( $ ) {
const AstBlockTemplates = {
remaining_install_plugins: 0,
remaining_active_plugins: 0,
init() {
this._bind();
},
/**
* Bind
*/
_bind() {
//Page builder installation & save option
$( document )
// .on(
// 'click',
// '.install-required-plugins',
// AstBlockTemplates._install_required_plugins
// )
.on( 'wp-plugin-installing', AstBlockTemplates._pluginInstalling )
.on( 'wp-plugin-install-error', AstBlockTemplates._installError )
.on(
'wp-plugin-install-success',
AstBlockTemplates._installSuccess
);
},
_installPlugin( plugin_slug ) {
if (
wp.updates.shouldRequestFilesystemCredentials &&
! wp.updates.ajaxLocked
) {
wp.updates.requestFilesystemCredentials( event );
$document.on( 'credential-modal-cancel', function () {
const $message = $( '.install-now.updating-message' );
$message
.removeClass( 'updating-message' )
.text( wp.updates.l10n.installNow );
wp.a11y.speak( wp.updates.l10n.updateCancel, 'polite' );
} );
}
wp.updates.queue.push( {
action: 'install-plugin', // Required action.
data: {
slug: plugin_slug,
},
} );
// Required to set queue.
wp.updates.queueChecker();
},
_activatePlugin( plugin_init, plugin_slug ) {
$.ajax( {
url: ajaxurl,
method: 'POST',
data: {
action: '',
plugin_slug,
plugin_init,
security: '',
},
} )
.done( function ( response ) {
if ( response.success ) {
console.log( plugin_slug + ' activated' );
// trigger_event();
} else {
console.log(
'Error: ' + response.data && response.data.message
? response.data.message
: 'Plugin not activated'
);
}
} )
.fail( function () {
console.log( 'activation error' );
} );
},
/**
* Installing Plugin
*
* @param {Object} event event data.
*/
_pluginInstalling( event ) {
event.preventDefault();
console.log( 'Installing..' );
},
/**
* Install Error
*
* @param {Object} event event data.
*/
_installError( event ) {
event.preventDefault();
console.log( 'Install Error!' );
},
/**
* Install Success
*
* @param {Object} event event data.
* @param {Array} args args data.
*/
_installSuccess( event, args ) {
event.preventDefault();
const plugin_init = args.slug + '/' + args.slug + '.php';
const plugin_slug = args.slug;
// WordPress adds "Activate" button after waiting for 1000ms. So we will run our activation after that.
setTimeout( function () {
AstBlockTemplates._activatePlugin( plugin_init, plugin_slug );
}, 1500 );
},
};
function trigger_event() {
const custom_event = new Event( 'ast-plugins-install-success' );
document.dispatchEvent( custom_event );
}
$( function () {
AstBlockTemplates.init();
} );
}( jQuery ) );

View File

@@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<title>aspect_ratio</title>
<path d="M21 19.031v-14.063h-18v14.063h18zM21 3q0.797 0 1.406 0.609t0.609 1.406v13.969q0 0.797-0.609 1.406t-1.406 0.609h-18q-0.797 0-1.406-0.609t-0.609-1.406v-13.969q0-0.797 0.609-1.406t1.406-0.609h18zM6.984 9v3h-1.969v-5.016h4.969v2.016h-3zM18.984 12v5.016h-4.969v-2.016h3v-3h1.969z"></path>
</svg>

After

Width:  |  Height:  |  Size: 459 B

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="ast-block-templates" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe900;" glyph-name="maximize" d="M341.333 853.334h-128c-35.328 0-67.413-14.379-90.496-37.504s-37.504-55.168-37.504-90.496v-128c0-23.552 19.115-42.667 42.667-42.667s42.667 19.115 42.667 42.667v128c0 11.776 4.736 22.4 12.501 30.165s18.389 12.501 30.165 12.501h128c23.552 0 42.667 19.115 42.667 42.667s-19.115 42.667-42.667 42.667zM938.667 597.334v128c0 35.328-14.379 67.413-37.504 90.496s-55.168 37.504-90.496 37.504h-128c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667h128c11.776 0 22.4-4.736 30.165-12.501s12.501-18.389 12.501-30.165v-128c0-23.552 19.115-42.667 42.667-42.667s42.667 19.115 42.667 42.667zM682.667-0h128c35.328 0 67.413 14.379 90.496 37.504s37.504 55.168 37.504 90.496v128c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667v-128c0-11.776-4.736-22.4-12.501-30.165s-18.389-12.501-30.165-12.501h-128c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667zM85.333 256v-128c0-35.328 14.379-67.413 37.504-90.496s55.168-37.504 90.496-37.504h128c23.552 0 42.667 19.115 42.667 42.667s-19.115 42.667-42.667 42.667h-128c-11.776 0-22.4 4.736-30.165 12.501s-12.501 18.389-12.501 30.165v128c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667z" />
<glyph unicode="&#xe901;" glyph-name="rotate-cw" d="M834.005 312.875c-31.403-88.875-95.787-156.587-174.677-194.261s-171.989-45.269-260.864-13.867-156.587 95.787-194.261 174.677-45.269 171.989-13.867 260.864 95.787 156.587 174.677 194.261 171.989 45.269 260.864 13.867c50.688-17.92 94.251-46.421 127.445-80.299l120.491-113.451h-148.48c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667h255.872c0.171 0 0.384 0 0.555 0 5.845 0.043 11.392 1.28 16.469 3.499 5.077 2.176 9.771 5.376 13.824 9.6 0.512 0.512 0.981 1.067 1.451 1.621 3.243 3.712 5.717 7.851 7.467 12.245 1.749 4.352 2.773 9.088 2.944 13.995 0.085 0.555 0.085 1.109 0.085 1.707v256c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667v-157.227l-124.416 117.12c-42.368 43.179-97.024 78.763-159.915 100.949-111.104 39.296-227.669 29.781-326.144-17.28s-179.072-131.755-218.325-242.859-29.696-227.627 17.323-326.101 131.755-179.072 242.859-218.325 227.627-29.739 326.101 17.323 179.072 131.755 218.325 242.859c7.851 22.229-3.797 46.592-26.027 54.443s-46.592-3.797-54.443-26.027z" />
<glyph unicode="&#xe902;" glyph-name="file" d="M554.667 896h-298.667c-35.328 0-67.413-14.379-90.496-37.504s-37.504-55.168-37.504-90.496v-682.667c0-35.328 14.379-67.413 37.504-90.496s55.168-37.504 90.496-37.504h512c35.328 0 67.413 14.379 90.496 37.504s37.504 55.168 37.504 90.496v469.333c0 11.776-4.779 22.443-12.501 30.165l-298.667 298.667c-4.096 4.096-8.789 7.168-13.824 9.259-5.205 2.176-10.795 3.243-16.341 3.243zM750.336 597.334h-153.003v153.003zM512 810.667v-256c0-23.552 19.115-42.667 42.667-42.667h256v-426.667c0-11.776-4.736-22.4-12.501-30.165s-18.389-12.501-30.165-12.501h-512c-11.776 0-22.4 4.736-30.165 12.501s-12.501 18.389-12.501 30.165v682.667c0 11.776 4.736 22.4 12.501 30.165s18.389 12.501 30.165 12.501z" />
<glyph unicode="&#xe903;" glyph-name="layers" d="M512 805.632l331.264-165.632-331.264-165.632-331.264 165.632zM492.928 891.478l-426.667-213.333c-21.077-10.539-29.611-36.139-19.072-57.216 4.309-8.661 11.136-15.189 19.072-19.072l426.667-213.333c12.459-6.229 26.453-5.803 38.144 0l426.667 213.333c21.077 10.539 29.611 36.181 19.072 57.259-4.309 8.619-11.179 15.147-19.072 19.072l-426.667 213.333c-12.459 6.229-26.453 5.803-38.144 0zM66.261 175.19l426.667-213.333c12.459-6.229 26.453-5.803 38.144 0l426.667 213.333c21.077 10.539 29.611 36.181 19.072 57.259s-36.181 29.611-57.259 19.072l-407.552-203.819-407.595 203.776c-21.077 10.539-46.72 2.005-57.259-19.072s-2.005-46.72 19.072-57.259zM66.261 388.523l426.667-213.333c12.459-6.229 26.453-5.803 38.144 0l426.667 213.333c21.077 10.539 29.611 36.181 19.072 57.259s-36.181 29.611-57.259 19.072l-407.552-203.819-407.595 203.776c-21.077 10.539-46.72 2.005-57.259-19.072s-2.005-46.72 19.072-57.259z" />
<glyph unicode="&#xe904;" glyph-name="chevron-left" d="M670.165 200.832l-225.835 225.835 225.835 225.835c16.683 16.683 16.683 43.691 0 60.331s-43.691 16.683-60.331 0l-256-256c-16.683-16.683-16.683-43.691 0-60.331l256-256c16.683-16.683 43.691-16.683 60.331 0s16.683 43.691 0 60.331z" />
</font></defs></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In SVG - Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.83;enable-background:new ;}
.st1{fill:#95F9EF;}
.st2{opacity:0.53;enable-background:new ;}
.st3{fill:url(#SVGID_1_);}
.st4{opacity:0.7;enable-background:new ;}
.st5{fill:url(#SVGID_2_);}
.st6{fill:#FFFFFF;}
</style>
<g>
<g class="st0">
<path class="st1" d="M26.8,88L9,33.5C8,30.7,9.6,27.8,12.2,27L66.8,9.2c2.7-0.9,5.7,0.6,6.4,3.2l17.9,54.6
c0.9,2.7-0.6,5.7-3.2,6.4l-54.6,18C30.5,92.2,27.6,90.8,26.8,88z"/>
</g>
<g class="st2">
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="4.238" y1="739.9995" x2="95.762" y2="739.9995" gradientTransform="matrix(1 0 0 1 0 -690)">
<stop offset="0" style="stop-color:#00E97B"/>
<stop offset="1" style="stop-color:#00F9D7"/>
</linearGradient>
<path class="st3" d="M44.7,94.3L5.6,52c-1.9-2.1-1.8-5.3,0.3-7.3L48.1,5.4c2.1-1.9,5.3-1.8,7.2,0.3L94.4,48
c1.9,2.1,1.8,5.3-0.3,7.3L51.9,94.6C50,96.6,46.6,96.4,44.7,94.3z"/>
</g>
<g class="st4">
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="296.5753" y1="-720.5554" x2="368.5928" y2="-720.5554" gradientTransform="matrix(0.9591 0.2829 0.2829 -0.9591 -65.1611 -734.9626)">
<stop offset="0" style="stop-color:#00DBDE"/>
<stop offset="1" style="stop-color:#FC00FF"/>
</linearGradient>
<path class="st5" d="M69.2,93.3L10.6,76.1c-2.9-0.8-4.5-3.9-3.7-6.8l17.2-58.6c0.8-2.9,3.9-4.5,6.8-3.7l58.6,17.2
c2.9,0.8,4.5,3.9,3.7,6.8L75.9,89.6C75.1,92.5,72,94.1,69.2,93.3z"/>
</g>
<g>
<path class="st6" d="M51.9,39.1L51.9,39.1h14.4V28.4H45.9c-1.9,0-3.7,0.3-5.3,1.1c-1.6,0.6-3.1,1.8-4.4,2.9
c-1.3,1.3-2.2,2.7-2.9,4.4c-0.4,0.7-0.6,1.6-0.8,2.4L51.9,39.1L51.9,39.1z"/>
<path class="st6" d="M66.9,53.3c-0.6-1.6-1.8-3.2-2.9-4.4c-1.3-1.3-2.7-2.2-4.4-2.9c-1.6-0.6-3.5-1.1-5.3-1.1h-2.4h-6H32.5
c0.2,0.9,0.5,1.7,0.8,2.6c0.6,1.6,1.8,3.2,2.9,4.4c1.3,1.3,2.7,2.2,4.4,2.9c1.6,0.8,3.5,1.1,5.3,1.1h8.4c0.5,0,0.8,0,1.1,0.2
c0.3,0.2,0.6,0.3,0.9,0.6c0.3,0.3,0.5,0.6,0.6,0.9c0.2,0.3,0.2,0.8,0.2,1.1c0,0.5,0,0.8-0.2,1.1c-0.2,0.3-0.3,0.6-0.6,0.9
c-0.3,0.3-0.6,0.5-0.9,0.6c-0.3,0.2-0.8,0.2-1.1,0.2h-20v10.8h19.8c1.9,0,3.7-0.3,5.5-1.1c1.6-0.6,3.2-1.8,4.4-2.9
c1.3-1.3,2.2-2.7,2.9-4.4c0.6-1.6,1.1-3.5,1.1-5.3C68,56.6,67.7,54.9,66.9,53.3z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@@ -0,0 +1,9 @@
<svg width="60" height="60" viewBox="0 0 84 85" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M41.7849 0C33.5206 0 25.4419 2.49258 18.5705 7.16254C11.699 11.8325 6.34331 18.4701 3.18071 26.236C0.0181112 34.0018 -0.809377 42.5471 0.802901 50.7913C2.41518 59.0355 6.3948 66.6083 12.2385 72.552C18.0822 78.4958 25.5276 82.5435 33.633 84.1834C41.7385 85.8232 50.1401 84.9816 57.7753 81.7649C65.4105 78.5482 71.9363 73.1008 76.5277 66.1117C81.1191 59.1226 83.5697 50.9057 83.5697 42.5C83.565 31.2298 79.1612 20.4225 71.326 12.4533C63.4908 4.48402 52.8655 0.0048112 41.7849 0ZM57.5278 49.0175C57.5278 49.1264 57.5278 49.2354 57.5278 49.3443V49.6529V49.8526C57.3161 51.0856 56.8673 52.2639 56.207 53.3201L55.8143 53.8829L55.2431 54.5546C55.0482 54.8082 54.8268 55.0396 54.5827 55.2445V55.3353L54.4578 55.4261L54.2079 55.6258C54.1249 55.7007 54.0353 55.7675 53.9402 55.8255L53.6724 56.0071L34.3061 69.0602C34.1479 69.1683 33.9612 69.2253 33.7706 69.2236H33.5743C33.447 69.1967 33.3262 69.1443 33.2189 69.0695C33.1117 68.9947 33.0201 68.899 32.9495 68.7879C32.9495 68.7879 32.5033 67.9891 32.4676 67.9347V67.7531V67.6623V67.5534V67.4263V67.2811C31.7014 65.262 31.6378 63.0371 32.2872 60.9761C32.9366 58.9152 34.2601 57.1424 36.0375 55.9526L45.0691 49.8708C45.2101 49.7754 45.3201 49.6398 45.3853 49.4809C45.4505 49.322 45.4679 49.147 45.4355 48.9781C45.403 48.8091 45.3221 48.6537 45.2029 48.5315C45.0837 48.4093 44.9316 48.3257 44.7657 48.2913L34.1633 46.1128H33.8599H33.7706H33.485H33.1816H33.0567H32.896H32.8068L32.5212 46.0038H32.4319H32.2534L31.9679 45.8586L31.6823 45.7134L31.4145 45.55L31.1468 45.3866C30.3041 44.8521 29.5509 44.1841 28.9156 43.4077L28.6836 43.0809L28.4159 42.6634C27.73 41.6278 27.255 40.4629 27.0189 39.2375C26.7828 38.012 26.7905 36.751 27.0415 35.5286C27.228 34.6884 27.5221 33.8766 27.9161 33.1141C28.0232 32.9144 28.1124 32.7328 28.2195 32.5694L28.3802 32.3153C28.4948 32.1207 28.6199 31.9329 28.755 31.7525L28.9156 31.5528L29.112 31.3167L29.3083 31.0989L29.4333 30.9718L29.6475 30.754L29.8259 30.5906L30.0223 30.4272L30.2365 30.2456H30.3257L30.4685 30.1185H30.5578L30.7898 29.9551L50.049 16.9746C50.1725 16.8912 50.3113 16.8338 50.457 16.806C50.6027 16.7782 50.7524 16.7804 50.8973 16.8126C51.0421 16.8448 51.1791 16.9062 51.3002 16.9933C51.4212 17.0804 51.5238 17.1913 51.6019 17.3195L51.7626 17.5918L51.8875 17.846C51.8875 17.9368 51.9768 18.0094 52.0125 18.082C52.0125 18.082 52.0125 18.082 52.0125 18.191C52.0239 18.2325 52.0239 18.2765 52.0125 18.318L52.1195 18.5904C52.1292 18.6383 52.1292 18.6877 52.1195 18.7356C52.1195 18.7356 52.1195 18.7356 52.1195 18.8445C52.8288 20.8305 52.8625 23.0011 52.2153 25.0089C51.5681 27.0166 50.2774 28.7455 48.5497 29.9188L39.6251 35.9462C39.4842 36.0415 39.3742 36.1772 39.309 36.3361C39.2438 36.495 39.2263 36.6699 39.2588 36.8389C39.2912 37.0078 39.3722 37.1632 39.4914 37.2854C39.6106 37.4077 39.7627 37.4912 39.9286 37.5256L50.4417 39.686C52.5458 40.1281 54.4361 41.2935 55.7948 42.9862C57.1536 44.679 57.8979 46.796 57.9027 48.9812C57.5635 48.4003 57.5278 48.9812 57.5278 48.9812V49.0175Z" fill="url(#paint0_linear_619_170)"/>
<defs>
<linearGradient id="paint0_linear_619_170" x1="1.17098e-05" y1="1.49716e-06" x2="84.02" y2="71.3596" gradientUnits="userSpaceOnUse">
<stop stop-color="#4E01D1"/>
<stop offset="1" stop-color="#6104FF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,3 @@
<svg width="71" height="71" viewBox="0 0 71 71" fill="#000000" xmlns="http://www.w3.org/2000/svg">
<path d="M35.292 0C28.3119 0 21.4885 2.08204 15.6848 5.98283C9.88107 9.88362 5.35762 15.428 2.68645 21.9147C0.0152817 28.4015 -0.683625 35.5394 0.678124 42.4257C2.03987 49.312 5.40111 55.6375 10.3368 60.6023C15.2725 65.5671 21.5609 68.9481 28.4068 70.3179C35.2528 71.6876 42.3489 70.9846 48.7976 68.2977C55.2464 65.6108 60.7583 61.0607 64.6362 55.2227C68.5141 49.3848 70.584 42.5212 70.584 35.5C70.58 26.0861 66.8604 17.0588 60.2428 10.4021C53.6251 3.74548 44.6508 0.00401876 35.292 0V0ZM48.5887 40.944C48.5887 41.035 48.5887 41.126 48.5887 41.217V41.4748V41.6416C48.4098 42.6715 48.0307 43.6558 47.4731 44.538L47.1414 45.0081L46.659 45.5692C46.4943 45.781 46.3073 45.9742 46.1012 46.1454V46.2213L45.9957 46.2971L45.7846 46.4639C45.7145 46.5265 45.6388 46.5823 45.5585 46.6307L45.3323 46.7824L28.9753 57.6856C28.8417 57.7759 28.684 57.8235 28.523 57.8221H28.3572C28.2497 57.7996 28.1477 57.7558 28.0571 57.6933C27.9665 57.6309 27.8892 57.5509 27.8296 57.4582C27.8296 57.4582 27.4527 56.7909 27.4225 56.7454V56.5938V56.5179V56.4269V56.3208V56.1995C26.7754 54.513 26.7216 52.6545 27.2701 50.933C27.8187 49.2115 28.9365 47.7307 30.4376 46.7369L38.0659 41.6568C38.1849 41.5771 38.2779 41.4638 38.3329 41.3311C38.388 41.1984 38.4027 41.0522 38.3753 40.9111C38.3479 40.77 38.2796 40.6402 38.1789 40.5381C38.0782 40.436 37.9497 40.3662 37.8096 40.3375L28.8547 38.5177H28.5984H28.523H28.2818H28.0255H27.92H27.7843H27.709L27.4678 38.4267H27.3924H27.2416L27.0004 38.3054L26.7592 38.1841L26.533 38.0476L26.3069 37.9111C25.5952 37.4647 24.959 36.9067 24.4225 36.2582L24.2265 35.9853L24.0004 35.6365C23.421 34.7714 23.0198 33.7984 22.8205 32.7748C22.6211 31.7512 22.6276 30.6979 22.8395 29.6769C22.9971 28.975 23.2455 28.2969 23.5782 27.66C23.6687 27.4932 23.7441 27.3415 23.8345 27.205L23.9702 26.9927C24.067 26.8303 24.1727 26.6733 24.2868 26.5226L24.4225 26.3558L24.5883 26.1587L24.7541 25.9767L24.8597 25.8706L25.0406 25.6886L25.1913 25.5521L25.3572 25.4156L25.5381 25.264H25.6134L25.734 25.1578H25.8094L26.0054 25.0214L42.272 14.1788C42.3763 14.1091 42.4935 14.0612 42.6166 14.038C42.7396 14.0147 42.8661 14.0166 42.9884 14.0435C43.1108 14.0704 43.2265 14.1217 43.3287 14.1944C43.431 14.2672 43.5176 14.3598 43.5836 14.4669L43.7192 14.6944L43.8248 14.9067C43.8248 14.9825 43.9002 15.0432 43.9303 15.1038C43.9303 15.1038 43.9303 15.1038 43.9303 15.1948C43.94 15.2295 43.94 15.2662 43.9303 15.3009V15.3009L44.0208 15.5284C44.0289 15.5684 44.0289 15.6097 44.0208 15.6497C44.0208 15.6497 44.0208 15.6497 44.0208 15.7407C44.6198 17.3996 44.6483 19.2127 44.1017 20.8897C43.555 22.5668 42.4648 24.011 41.0056 24.991L33.4678 30.0256C33.3488 30.1053 33.2559 30.2186 33.2008 30.3513C33.1457 30.484 33.131 30.6302 33.1584 30.7713C33.1858 30.9124 33.2542 31.0422 33.3549 31.1443C33.4555 31.2464 33.584 31.3162 33.7241 31.3449L42.6036 33.1495C44.3808 33.5188 45.9773 34.4922 47.1249 35.9061C48.2726 37.3201 48.9012 39.0884 48.9053 40.9137C48.6188 40.4285 48.5887 40.9137 48.5887 40.9137V40.944Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,4 @@
<svg width="90" height="90" viewBox="0 0 90 90" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M71.2429 7.34463H18.3616C12.2771 7.34463 7.34463 12.2771 7.34463 18.3616V71.2429C7.34463 77.3274 12.2771 82.2598 18.3616 82.2598H71.2429C77.3274 82.2598 82.2598 77.3274 82.2598 71.2429V18.3616C82.2598 12.2771 77.3274 7.34463 71.2429 7.34463ZM18.3616 0C8.22076 0 0 8.22075 0 18.3616V71.2429C0 81.3837 8.22075 89.6045 18.3616 89.6045H71.2429C81.3837 89.6045 89.6045 81.3837 89.6045 71.2429V18.3616C89.6045 8.22076 81.3837 0 71.2429 0H18.3616Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M54.1449 28.1896C53.9728 28.0356 53.7911 27.8882 53.5998 27.7474C51.9414 26.5264 49.6907 25.9159 46.8478 25.9159C44.916 25.9159 43.285 26.1892 41.9546 26.7359C40.6243 27.2644 39.6037 28.0025 38.893 28.9502C38.1294 29.995 36.829 30.8418 35.7046 30.2012C34.8223 29.6985 34.0076 29.0784 33.2839 28.3548C31.9339 27.0047 30.944 25.3377 30.405 23.5061C30.1674 22.6988 30.3776 21.8165 31.0133 21.265C32.434 20.0323 34.0947 18.9948 35.9954 18.1524C39.2028 16.7309 42.8476 16.0202 46.9298 16.0202C51.0849 16.0202 54.7115 16.7309 57.8095 18.1524C60.9259 19.5739 63.3496 21.5512 65.0809 24.0843C65.7142 25.011 66.2354 25.9913 66.6443 27.0252C67.8571 30.0913 65.0579 32.8866 61.7607 32.8866C59.1869 32.8866 57.1265 30.9615 55.18 29.1429L55.1799 29.1428C54.8321 28.8178 54.4878 28.4962 54.1449 28.1896ZM37.1987 34.2544C37.6871 34.0635 38.21 34.3524 38.4829 34.8001C38.9568 35.5473 39.6037 36.1942 40.4238 36.7409C41.2439 37.2694 42.1915 37.7342 43.2667 38.1351C44.342 38.5178 45.4901 38.8458 46.7111 39.1192L51.7409 40.322C54.183 40.8687 56.4245 41.5977 58.4656 42.5089C60.5067 43.4201 62.2744 44.5408 63.7688 45.8712C65.2632 47.2015 66.4204 48.7688 67.2405 50.573C68.0788 52.3772 68.5071 54.4456 68.5253 56.7783C68.5071 60.2044 67.6323 63.1749 65.901 65.6898C64.188 68.1865 61.7095 70.1274 58.4656 71.5124C55.2399 72.8792 51.3491 73.5626 46.7931 73.5626C42.2735 73.5626 38.3371 72.8701 34.9839 71.4851C31.6489 70.1001 29.0429 68.0499 27.1658 65.3345C26.2995 64.0605 25.6252 62.646 25.1428 61.091C24.1699 57.9547 26.943 55.1928 30.2268 55.1928H30.6526C33.4909 55.1928 35.5992 57.6279 37.3075 59.8946C38.2734 61.1338 39.5582 62.0724 41.1619 62.7102C42.7838 63.3298 44.6153 63.6396 46.6564 63.6396C48.6611 63.6396 50.4015 63.3481 51.8776 62.7649C53.372 62.1817 54.5292 61.3707 55.3493 60.332C56.1694 59.2932 56.5794 58.0995 56.5794 56.7509C56.5794 55.4935 56.2058 54.4365 55.4586 53.58C54.7297 52.7234 53.6545 51.9945 52.233 51.3931C50.8297 50.7917 49.1076 50.245 47.0665 49.7529L40.9705 48.2221C36.9718 47.2494 33.6859 45.8124 31.1129 43.9111C30.4174 43.3972 30.1608 42.4925 30.405 41.6629C30.9439 39.8315 31.9336 38.1645 33.2834 36.8145C34.4003 35.6975 35.7342 34.827 37.1987 34.2544ZM29.9545 26.532L29.4188 24.7118C29.3957 24.6328 29.3476 24.5633 29.2818 24.5139C29.2159 24.4645 29.1358 24.4378 29.0535 24.4378C28.9712 24.4378 28.8911 24.4645 28.8252 24.5139C28.7593 24.5633 28.7113 24.6328 28.6882 24.7118L28.1532 26.532C27.7938 27.7529 27.1338 28.8641 26.2338 29.764C25.3338 30.6639 24.2224 31.3236 23.0014 31.6829L21.1811 32.2186C20.8166 32.3267 20.8166 32.8426 21.1811 32.9491L23.0014 33.4849C24.2222 33.8442 25.3335 34.5041 26.2334 35.4039C27.1333 36.3038 27.7931 37.415 28.1525 38.6358L28.6882 40.4568C28.7955 40.8205 29.3115 40.8205 29.4188 40.4568L29.9545 38.6365C30.3138 37.4156 30.9736 36.3043 31.8735 35.4042C32.7734 34.5042 33.8847 33.8443 35.1056 33.4849L36.9266 32.9491C37.2904 32.8419 37.2904 32.3259 36.9266 32.2194L35.1064 31.6837C33.8853 31.3243 32.7738 30.6645 31.8738 29.7644C30.9738 28.8644 30.3138 27.753 29.9545 26.532ZM23.461 37.2817L23.6218 37.8277C23.7296 38.194 23.9275 38.5275 24.1975 38.7975C24.4676 39.0675 24.801 39.2654 25.1673 39.3732L25.7134 39.5339C25.8225 39.5659 25.8225 39.7207 25.7134 39.7529L25.1671 39.9136C24.8008 40.0214 24.4674 40.2194 24.1975 40.4894C23.9275 40.7594 23.7295 41.0928 23.6218 41.4591L23.461 42.0051C23.4288 42.1143 23.2741 42.1143 23.2419 42.0051L23.0812 41.4589C22.9733 41.0926 22.7754 40.7593 22.5054 40.4893C22.2354 40.2193 21.9021 40.0214 21.5358 39.9136L20.9897 39.7529C20.8804 39.7209 20.8804 39.5661 20.9897 39.5337L21.5358 39.373C21.9021 39.2652 22.2355 39.0673 22.5055 38.7973C22.7756 38.5274 22.9735 38.194 23.0814 37.8277L23.2419 37.2817C23.2488 37.2579 23.2632 37.2371 23.283 37.2223C23.3027 37.2075 23.3268 37.1995 23.3515 37.1995C23.3762 37.1995 23.4002 37.2075 23.4199 37.2223C23.4397 37.2371 23.4541 37.2579 23.461 37.2817ZM22.4142 22.428L22.1642 21.5786C22.1535 21.5417 22.131 21.5093 22.1003 21.4863C22.0696 21.4632 22.0322 21.4508 21.9938 21.4508C21.9554 21.4508 21.918 21.4632 21.8872 21.4863C21.8565 21.5093 21.8341 21.5417 21.8233 21.5786L21.5737 22.428C21.4059 22.9978 21.0979 23.5164 20.6779 23.9363C20.2579 24.3562 19.7392 24.6641 19.1695 24.8318L18.32 25.0818C18.1499 25.1322 18.1499 25.373 18.32 25.4227L19.1695 25.6727C19.7392 25.8404 20.2578 26.1483 20.6777 26.5683C21.0977 26.9882 21.4056 27.5068 21.5733 28.0765L21.8233 28.9263C21.8734 29.096 22.1142 29.096 22.1642 28.9263L22.4142 28.0768C22.5819 27.507 22.8898 26.9884 23.3098 26.5684C23.7297 26.1484 24.2483 25.8404 24.8181 25.6727L25.6679 25.4227C25.8377 25.3726 25.8377 25.1319 25.6679 25.0821L24.8184 24.8321C24.2486 24.6645 23.7299 24.3565 23.3099 23.9365C22.8899 23.5165 22.5819 22.9978 22.4142 22.428Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.5;}
.st1{fill:#FFFFFF;}
.st2{opacity:0.8;}
</style>
<g>
<g class="st0">
<path class="st1" d="M68.02,6.1l-6.81,2.16l6.14,6.64l10.29,2.99l-2.82-8.47C73.99,6.76,71.01,5.1,68.02,6.1z"/>
<path class="st1" d="M5.94,32.16l2.32,6.81l6.64-6.14l2.99-10.46l-8.47,2.82C6.6,26.18,4.94,29.34,5.94,32.16z"/>
<path class="st1" d="M22.37,82.45l2.82,8.47c0.83,2.99,3.98,4.48,6.97,3.65l7.14-2.32l-5.98-6.47L22.37,82.45z"/>
<path class="st1" d="M94.08,68.18l-2.32-7.14l-6.31,5.98l-3.32,10.95l8.47-2.82C93.41,74.32,95.24,71.16,94.08,68.18z"/>
</g>
<g class="st2">
<path class="st1" d="M55.73,2.45c-2.16-2.32-5.48-2.49-7.8-0.33l-5.98,5.48l11.29,3.32l13.94,4.15l-6.14-6.64L55.73,2.45z"/>
<path class="st1" d="M2.62,44.27c-2.32,2.16-2.49,5.48-0.33,7.8l5.15,5.64l3.15-10.95l4.15-13.94L8.1,38.96L2.62,44.27z"/>
<path class="st1" d="M97.73,47.93l-5.15-5.48l-3.32,11.12l-3.98,13.28l6.31-5.98l5.64-5.31C99.72,53.73,99.89,50.25,97.73,47.93z"
/>
<path class="st1" d="M33.16,85.6l5.98,6.47l5.15,5.48c2.16,2.32,5.64,2.49,7.8,0.33l5.64-5.15l-10.79-3.15L33.16,85.6z"/>
</g>
<path class="st1" d="M92.42,22.36l-14.77-4.32l-10.29-2.99l-13.94-4.15L42.12,7.59L29.51,3.94c-3.15-0.83-6.47,0.83-7.3,3.98
L17.89,22.7L14.9,33.15L10.75,47.1L7.6,58.05L3.78,71.16c-0.83,3.15,0.83,6.47,3.98,7.3l14.77,4.32l10.79,3.15l13.61,3.98
l10.79,3.15l12.95,3.82c3.15,0.83,6.47-0.83,7.3-3.98l4.32-14.61l3.32-10.95l3.98-13.28l3.32-11.12l3.82-12.78
C97.23,26.51,95.57,23.19,92.42,22.36z M67.69,26.68V38.3H52.25l0,0H31.5c0.17-0.83,0.5-1.83,0.83-2.66
c0.66-1.66,1.66-3.32,3.15-4.65c1.33-1.16,2.99-2.49,4.65-3.15c1.66-0.83,3.65-1.16,5.64-1.16H67.69z M33.33,74.15V62.53h21.41
c0.33,0,0.83,0,1.16-0.17c0.33-0.17,0.66-0.33,1-0.66c0.33-0.33,0.5-0.66,0.66-1c0.17-0.33,0.17-0.66,0.17-1.16
c0-0.33,0-0.83-0.17-1.16c-0.17-0.33-0.33-0.66-0.66-1c-0.33-0.33-0.66-0.5-1-0.66c-0.33-0.17-0.66-0.17-1.16-0.17h-8.96
c-1.83,0-3.98-0.33-5.64-1.16c-1.66-0.66-3.32-1.66-4.65-3.15c-1.16-1.16-2.49-2.99-3.15-4.65c-0.5-1-0.66-1.83-0.83-2.82h14.44
h6.47h2.49c1.83,0,3.98,0.5,5.64,1.16c1.66,0.66,3.32,1.66,4.65,3.15c1.16,1.16,2.49,2.99,3.15,4.65c0.83,1.66,1.16,3.65,1.16,5.81
c0,1.83-0.5,3.98-1.16,5.64c-0.66,1.66-1.66,3.32-3.15,4.65c-1.16,1.16-2.99,2.49-4.65,3.15c-1.83,0.83-3.82,1.16-5.81,1.16
L33.33,74.15L33.33,74.15z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,49 @@
@font-face {
font-family: ast-block-templates;
src: url( "fonts/ast-block-templates.eot?p3u0q1" );
src:
url( "fonts/ast-block-templates.eot?p3u0q1#iefix" ) format( "embedded-opentype" ),
url( "fonts/ast-block-templates.ttf?p3u0q1" ) format( "truetype" ),
url( "fonts/ast-block-templates.woff?p3u0q1" ) format( "woff" ),
url( "fonts/ast-block-templates.svg?p3u0q1#ast-block-templates" ) format( "svg" );
font-weight: 400;
font-style: normal;
font-display: block;
}
[class^="ast-block-templates-icon-"],
[class*=" ast-block-templates-icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: ast-block-templates, sans-serif !important;
speak: never;
font-style: normal;
font-weight: 400;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.ast-block-templates-icon-chevron-left::before {
content: "\e904";
}
.ast-block-templates-icon-pages::before {
content: "\e902";
}
.ast-block-templates-icon-patterns::before {
content: "\e903";
}
.ast-block-templates-icon-wireframe::before {
content: "\e900";
}
.ast-block-templates-icon-refresh::before {
content: "\e901";
}

View File

@@ -0,0 +1,185 @@
<?php
/**
* Plugin Loader.
*
* @package {{package}}
* @since 2.0.0
*/
namespace Gutenberg_Templates;
use Gutenberg_Templates\Inc\Api\Api_Init;
use Gutenberg_Templates\Inc\Importer\Sync_Library;
use Gutenberg_Templates\Inc\Importer\Sync_Library_WP_CLI;
use Gutenberg_Templates\Inc\Importer\Plugin;
use Gutenberg_Templates\Inc\Importer\Image_Importer;
use Gutenberg_Templates\Inc\Importer\Updater;
use Gutenberg_Templates\Inc\Content\Ai_Content;
use Gutenberg_Templates\Inc\Traits\Upgrade;
use Gutenberg_Templates\Inc\Importer\Template_Kit_Importer;
use Gutenberg_Templates\Inc\Block\Spectra_AI_Block;
use Gutenberg_Templates\Inc\Classes\Ast_Block_Templates_Zipwp_Api;
use Gutenberg_Templates\Inc\Classes\Ast_Block_Templates_Notices;
/**
* Ast_Block_Plugin_Loader
*
* @since 2.0.0
*/
class Ast_Block_Plugin_Loader {
/**
* Instance
*
* @access private
* @var object Class Instance.
* @since 2.0.0
*/
private static $instance = null;
/**
* Initiator
*
* @since 2.0.0
* @return object initialized object of class.
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Autoload classes.
*
* @param string $class class name.
*
* @return void
*/
public function autoload( $class ) {
if ( 0 !== strpos( $class, __NAMESPACE__ ) ) {
return;
}
$class_to_load = $class;
$filename = strtolower(
(string) preg_replace(
array( '/^' . __NAMESPACE__ . '\\\/', '/([a-z])([A-Z])/', '/_/', '/\\\/' ),
array( '', '$1-$2', '-', DIRECTORY_SEPARATOR ),
$class_to_load
)
);
$file = AST_BLOCK_TEMPLATES_DIR . $filename . '.php';
// if the file redable, include it.
if ( is_readable( $file ) ) {
require_once $file;
}
}
/**
* Constructor
*
* @since 2.0.0
*/
public function __construct() {
spl_autoload_register( array( $this, 'autoload' ) );
add_action( 'wp_loaded', array( $this, 'load_textdomain' ) );
add_action( 'wp_loaded', array( $this, 'load_classes' ), 999 );
}
/**
* Loads plugin classes as per requirement.
*
* @return void
* @since 2.0.0
*/
public function load_classes() {
require_once AST_BLOCK_TEMPLATES_DIR . 'inc/classes/ast-block-templates-notices.php';
if ( ! Ast_Block_Templates_Notices::instance()->has_file_read_write() ) {
return;
}
Ast_Block_Templates_Zipwp_Api::instance();
Api_Init::instance();
Template_Kit_Importer::instance();
Plugin::instance();
Image_Importer::instance();
Sync_Library::instance();
Sync_Library_WP_CLI::instance();
Ai_Content::instance();
Upgrade::instance();
Updater::instance();
//phpcs:disable Squiz
// Spectra_AI_Block::get_instance();
//phpcs:enable Squiz
}
/**
* Load Plugin Text Domain.
* This will load the translation textdomain depending on the file priorities.
* 1. Global Languages /wp-content/languages/gutenberg-templates/ folder
* 2. Local dorectory /wp-content/plugins/gutenberg-templates/languages/ folder
*
* @since 2.0.0
* @return void
*/
public function load_textdomain() {
// Default languages directory.
$lang_dir = AST_BLOCK_TEMPLATES_DIR . 'languages/';
/**
* Filters the languages directory path to use for plugin.
*
* @param string $lang_dir The languages directory path.
*/
$lang_dir = apply_filters( 'wpb_languages_directory', $lang_dir );
// Traditional WordPress plugin locale filter.
global $wp_version;
$get_locale = get_locale();
if ( $wp_version >= 4.7 ) {
$get_locale = get_user_locale();
}
/**
* Language Locale for plugin
*
* @var string $get_locale The locale to use.
* Uses get_user_locale()` in WordPress 4.7 or greater,
* otherwise uses `get_locale()`.
*/
$locale = apply_filters( 'plugin_locale', $get_locale, 'ast-block-templates' );
$mofile = sprintf( '%1$s-%2$s.mo', 'ast-block-templates', $locale );
// Setup paths to current locale file.
$mofile_global = WP_LANG_DIR . '/plugins/' . $mofile;
$mofile_local = $lang_dir . $mofile;
if ( file_exists( $mofile_global ) ) {
// Look in global /wp-content/languages/gutenberg-templates/ folder.
load_textdomain( 'ast-block-templates', $mofile_global );
} elseif ( file_exists( $mofile_local ) ) {
// Look in local /wp-content/plugins/gutenberg-templates/languages/ folder.
load_textdomain( 'ast-block-templates', $mofile_local );
} else {
// Load the default language files.
load_plugin_textdomain( 'ast-block-templates', false, $lang_dir );
}
}
}
/**
* Kicking this off by calling 'get_instance()' method
*/
Ast_Block_Plugin_Loader::get_instance();

View File

@@ -0,0 +1,41 @@
<?php
/**
* Plugin Name: Gutenberg Starter Templates
* Plugin URI: https://wpastra.com/
* Description: Gutenberg single page templates, and blocks library to imported your website easily.
* Version: 2.4.8
* Author: Brainstorm Force
* Author URI: https://www.brainstormforce.com
* Text Domain: ast-block-templates
*
* @package Ast Block Templates
*/
/**
* Set constants.
*/
if ( defined( 'Ast_Block_Templates' ) ) {
return;
}
if ( apply_filters( 'ast_block_templates_disable', false ) ) {
return;
}
// Set constants.
if ( ! defined( 'AST_BLOCK_TEMPLATES_LIBRARY_URL' ) ) {
define( 'AST_BLOCK_TEMPLATES_LIBRARY_URL', trailingslashit( apply_filters( 'ast_block_templates_library_url', 'https://websitedemos.net/' ) ) );
}
define( 'AST_BLOCK_TEMPLATES_VER', '2.4.8' );
define( 'AST_BLOCK_TEMPLATES_FILE', __FILE__ );
define( 'AST_BLOCK_TEMPLATES_BASE', plugin_basename( AST_BLOCK_TEMPLATES_FILE ) );
define( 'AST_BLOCK_TEMPLATES_DIR', plugin_dir_path( AST_BLOCK_TEMPLATES_FILE ) );
define( 'AST_BLOCK_TEMPLATES_URI', plugins_url( '/', AST_BLOCK_TEMPLATES_FILE ) );
if ( ! defined( 'AST_BLOCK_TEMPLATES_JSON_DIR' ) ) {
$upload_dir = wp_get_upload_dir();
define( 'AST_BLOCK_TEMPLATES_JSON_DIR', trailingslashit( $upload_dir['basedir'] ) . 'ast-block-templates-json/' );
}
require_once 'class-ast-block-templates.php';

View File

@@ -0,0 +1,353 @@
v.2.4.8 - 29-November-2024
Improvement: Improved business description screen for better user experience.
Improvement: UI enhancements for better usability.
Improvement: Improved code quality for enhanced performance and maintainability.
v.2.4.7 - 31-October-2024
Improvement: Generating business description based on the selected language.
Improvement: Optimized styles for better readability and usability on smaller screens.
v.2.4.6 - 14-October-2024
- New: Added source parameters to URLs redirecting to ZipWP for better tracking.
v.2.4.5 - 08-October-2024
Improvement: Removed outdated options data that were previously left undeleted.
Improvement: Optimized server API call execution for better performance.
v.2.4.4 - 30-September-2024
Improvement: Added loading skeleton when uploading the images on AI onboarding.
Improvement: Added images validation on AI onboarding.
Fix: Fixed PHP warning when generating content.
v.2.4.3 - 26-September-2024
Fix: Content was not getting generated in the selected language.
v.2.4.2 - 11-September-2024
New: Introduced filter `ast_block_templates_exclude_post_types` to exclude asset loading for specified post types.
Fix: Resolved CSS conflicts with the WordPress core list block.
v.2.4.1 - 29-August-2024
Improvement: Enhanced API performance by optimizing execution times and reducing delays.
Fix: Corrected styling issues for patterns/pages preview to ensure consistent display.
Fix: Addressed CSS conflicts with SureCart blocks to prevent styling discrepancies.
v.2.4.0 - 08-August-2024
New: Enhanced AI onboarding UI.
v.2.3.6 - 06-August-2024
Fix: Pattern CSS file was not loading correctly.
v.2.3.5 - 06-August-2024
Improvement: Hidden Update Image option until the user personalizes the library.
Improvement: Blocked block pages preview if import is in process.
v.2.3.4 - 02-August-2024
Improvement: Converted spectra common stylesheet to json file instead of option variable.
v.2.3.3 - 30-July-2024
Fix: Resolved issue where the Favorites functionality was not working in certain cases.
Fix: Addressed problem where related block pages were not displaying in some scenarios.
Fix: Content regeneration for a category was not working.
v.2.3.2 - 26-July-2024
Fix: Resolved visibility issue with the "Design Library" button in WordPress 6.6 with full site editor.
v.2.3.1 - 3-July-2024
Fix: Resolved an issue where adding social media URLs caused an error when proceeding to the next step.
v.2.3.0 - 2-July-2024
New: Added a page preview feature along with other page options.
Improvement: Introduced a new "Favorites" tab, separated from Patterns, Pages, and Kits.
Improvement: Added clickable navigation in the sidebar, allowing users to jump to previous steps.
Improvement: Disbaled live preview while inserting the kit into a page.
Improvement: Improved UI/UX for a better user experience.
Fix: Resolved an issue where the Design Library button was not displayed in the Spectra One theme editor when the Gutenberg Plugin was activated.
Fix: Fixed a console error that occurred on the screen of the image when AI data was prefilled.
Fix: Addressed a blank screen issue when accessing the "Design Library" on Bedrock-powered sites.
Fix: Fixed option 'ast-block-templates_data-' was not getting deleted after importing the site template.
v2.2.5 - 27-June-2024
- Fix: Fixed console error causing blank screen in GT AI onboarding if already prefilled.
v2.2.4 - 17-June-2024
- New: Added error boundaries for better error management.
- Improvement: Improved UI for better consistency.
- Improvement: Enhanced error handling during the import process.
- Improvement: Blocked all other actions while inserting the kit into a page.
- Improvement: Added an admin notice for missing file permissions.
- Improvement: Removed validation for the mobile field in AI onboarding.
- Improvement: Added loader while inserting the block.
- Fix: Prevented adding block to new page after Spectra installation.
- Fix: Shuffling of images if changes the orientation multiple times.
- Fix: AI generated business description response count was not working as expected.
- Fix: Fixed issue with authentication redirection.
v2.2.3 - 06-June-2024
- Fix: Resolved Console error for undefined images.
v2.2.2 - 20-May-2024
- Fix: Fixed design library was displaying empty on subfolder sites.
v2.2.1 - 02-May-2024
- Improvement: Better error message handling.
- Improvement: Blocked everything after clicking on the continue button.
- Fix: Removed the hotlinking of websitedemos link after import.
v2.2.0 - 26-April-2024
- Improvement: Revamped AI onboarding with language compatibility.
- Improvement: User Interface Enhancements & tweaks.
- Fix: JSON file names renamed correctly.
v2.1.28 - 12-April-2024
- Fix: Resolved line-height issue for blocks.
v2.1.27 - 9-April-2024
- Fix: Design library button not showing sometime.
v2.1.26 - 9-April-2024
- Fix: Fixed Media library not working.
v2.1.25 - 8-April-2024
- Fix: Custom permission fix for search category API.
- Fix: Fixed an issue where the Personalisation of the library was failing.
v2.1.24 - 5-April-2024
- Fix: Improved parsing mechanism for social media icons to ensure error-free processing.
v2.1.23 - 5-April-2024
- Fix: Pre-selected images were not displaying.
v2.1.22 - 4-April-2024
- Improvement: Updated image replacement mechanisms to enhance compatibility with the ZipWP.
v2.1.21 - 3 April-2024
- New: Added business type selection option in onboarding.
- Improvement: Using a ZipWP constant instead of a URL to facilitate easy overriding from the WordPress configuration.
- Improvement: Automatically prefill business details for sites created through ZipWP.
- Improvement: Moved JSON folder from plugin directory to WP upload folder to address memory issues.
v2.1.20 - 1-April-2024
- Improvement: Added Compatibility for Rank Match SEO plugin.
v2.1.19 - 29-March-2024
- Improvement: Updated the way to call REST API.
v2.1.18 - 14-March-2024
- Improvement: Added a filter to bypass the auth for non authenticated users to be able to import Templates
v2.1.17 - 11-March-2024
- Fix: Fixed broken patterns and pages caused by missing Spectra Plugin.
v2.1.16 - 07-March-2024
- Fix: Resolved an issue where the AI description won't get generated on WordPress.com sites.
v2.1.15 - 01-March-2024
- Improvement: Rename Template kits to Design Library and updated UI.
v2.1.14 - 20-February-2024
- Fix: Changed the button position and fixed console errors.
v2.1.13 - 12-February-2024
- Fix: Resolved an issue where the Template Kit button was not visible due to console error.
v2.1.12 - 07-February-2024
- Fix: Resolved an issue where the Template Kit button was not visible.
v2.1.11 - 30-January-2024
- Improvement: Moved the Template Kits button to the left of the post header center element.
v2.1.10 - 29-January-2024
- Fix: Resolved premium pages import issue in the kits section.
v2.1.9 - 08-January-2024
- Fix: Reverted capabilities check from manage_options to edit_post.
v2.1.8 - 08-January-2024
- Improvement: Show three dots loading indicator when regenerating content for a specific category.
- Improvement: Prevent unnecessary re-render to improve performance and UX.
- Improvement: Improved access control by transitioning from 'edit_post' to 'manage_options' for enhanced user capabilities.
- Fix: Google map location/address not getting updated.
- Fix: Not showing loading skeleton while regenerating content.
- Fix: 503 Error by removing kits data from the localize variable.
v2.1.7 - 04-January-2024
- Fix: Extra check added for checking wpforms-lite plugin.
v2.1.6 - 03-January-2024
- Fix: Spelling "organization" changed to "organisation".
v2.1.5 - 03-January-2024
- Fix: Tightened the plugin security while importing.
v2.1.4 - 02-January-2024
- Fix: Suggested items were not showing on the empty search results screen.
v2.1.3 - 02-January-2024
- Fix: Showing invalid message on the toaster while generating content.
v2.1.2 - 02-January-2024
- Improvement: Enhanced user experience and streamlined workflow.
v2.1.1 - 30-December-2023
- Fix: Resolved conflict with Gravity Forms plugin by transitioning from localization to using API for patterns and pages data.
v2.1.0 - 27-December-2023
- New: Added site templates kits.
- Fix: Customizer color palette was getting applied in non-adaptive mode.
- Fix: Templates looks broken if Spectra activated while importing template.
v2.0.19 - 22-December-2023
- New: Added "Revoke Access" button for seamless ZipAI authentication revocation.
- Fix: Resolved issue of patterns/pages importing at last index instead of selected insertion point.
- Fix: Resolved the need for two refreshes to reflect changes in Manage AI feature options.
v2.0.18 - 20-December-2023
- Fix: ZipAI authentication screen is visible even ZipAI Copilot module is disabled.
v2.0.17 - 19-December-2023
- Improvement: Downloading the selected images in onboarding to media.
- Improvement: Added compatibility for the ZipAI Manage AI feature option.
- Improvement: User Interface Enhancements & tweaks.
- Improvement: Updating Disable AI option value based on Non-Adaptive mode option.
- Fix: Updating Non-Adaptive mode option was not getting enabled after reloading the page.
v2.0.16 - 15-December-2023
- Improvement: Added RTL compatibility to the new Template Kits library.
- Fix: Generate Content with AI button was not showing if already authorised.
v2.0.15 - 13-December-2023
- Improvement: Added conditional logo for onboarding screen.
v2.0.14 - 13-December-2023
- New: Introduced Non-Adaptive mode option.
- Improvement: Improved pattern and page preview UI.
v2.0.13 - 07-December-2023
- Improvement: Showing Server Traffic Surge toaster.
- Improvement: Updated the flat rates for Pages and Patterns library from 3000 to 5000.
v2.0.12 - 05-December-2023
- Improvement: Added no credit notice in AI onoarding.
- Improvement: Removed Generate Content button if showing welcome scrren.
- Fix: Removed unwanted parameters from URL while passing the success_url for checkout process fir credits purchase.
v2.0.11 - 04-December-2023
- New: Introduced 'ast_block_templates_authorization_url_param' filter for authorization url parameters.
v2.0.10 - 04-December-2023
- Fix: Removed URL parameter after redirection.
v2.0.9 - 04-December-2023
- Synchronised the pattern/page library.
v2.0.8 - 04-December-2023
Improvement: Compatibility with ZipAI authorization.
- Fix: Removed Header and Footer from the preview.
- Fix: Redirction URL not working after authorization.
v2.0.4 - 27-November-2023
- Fix: Success url parameter was missing for some credit purchase url.
v2.0.3 - 27-November-2023
- Fix: Fixed conditional logo for the library.
- Fix: Displaying the default content and toaster error after updating content.
v2.0.2 - 24-November-2023
- Fix: Fixed an issue where the library won't load when integrated with Premium Starter Templates.
v2.0.0 - 24-November-2023
- New: AI based templates
v1.3.3 - 07-Sept-2023
- Fix: Temporary remove Template Kit support to Full Site Editor.
v1.3.2 - 11-July-2023
- Improvement: Added Template Kit support to Full Site Editor.
v1.3.1 - 14-June-2023
- Fix: WP Forms won't get imported due to regression in v1.3.0
v1.3.0 - 13-June-2023
- Improvement: Now we refresh the page and save the content if the required plugins for the template kit are missing.
- Improvement: Tightened the security of the plugin.
v1.2.1 - 19-May-2023
- Fix: Discarded the incorrect null.js generated for the library, instead added main.js.
v1.2.0 - 18-May-2023
- Improvement: Added Premium Block Editor Templates.
v1.1.11 - 20-February-2023
- Improvement: Sync library.
v1.1.10 - 30-January-2023
- Improvement: Capability updated for active plugin.
v1.1.9 - 25-January-2023
- Improvement: Hardened the security.
v1.1.8 - 19-January-2023
- Improvement: Added extra checks while block templates import.
v1.1.7 - 01-September-2022
- Fix: Install and Activate Spectra for light category patterns only.
v1.1.6 - 22-Auguest-2022
- Improvement: Install Spectra while importing Block Patterns and Wireframe Pattern.
v1.1.3 - 19-May-2022
- Improvement: Renamed button text and logo to template kits and spectra logo.
v1.1.2 - 08-March-2022
- Improvement: CSS tweaks for spectra button.
v1.1.1 - 14-February-2022
- Fix: Undefined error for WP_CLI
v1.1.0 - 4-October-2021
- New: Wireframe blocks for Gutenberg - [Doc](https://wpastra.com/docs/starter-templates-wireframe-blocks/)
v1.0.11 - 17-September-2021
- Improvement: Added site URL while importing the demo for analytics.
v1.0.10 - 12-August-2021
- Improvement: Rectified the condition to load the scripts in other screens.
- Fix: Starter template button not visible when gutenberg plugin is activated.
v1.0.9 - 2-August-2021
- Improvement: Rectified the condition to load the scripts in customizer screen.
v1.0.8 - 22-June-2021
- Improvement: Avoided to load the scripts in customizer screen.
v1.0.7 - 13-June-2021
- Improvement: Compatibility to WordPress 5.8.
- Improvement: Added support for dark and light support for block patterns with improved sidebar UI.
- Improvement: Added a filter `ast_block_templates_disable_auto_sync` to disable auto sync feature.
- Fix: Handle the white label support.
v1.0.6 - 24-May-2021
- Improvement: Added auto sync feature.
- Fix: Starter Templates popup opens by default on every page load on Gutenberg pages.
v1.0.5 - 21-May-2021
- Improvement: Added the dark and light filter support for blocks.
v1.0.4 - 14-May-2021
- Fix: Added the dynamic category support for multisites.
v1.0.3 - 10-May-2021
- Improvement: Added the dynamic category support.
v1.0.2 - 09-March-2021
- Improvement: Added a helper function to set the default assets
v1.0.1 - 09-March-2021
- Improvement: Used `version.json` instead of `package.json` to manage the dependency.
- Improvement: Added the suggestion link.
- Improvement: Added filter to disable the Gutenberg Templates.
- Fix: Block pattern category filter keep showing all category.
- Fix: Avoided dynamic json file names for importing.
v1.0.0 - 17-February-2021
- Initial Commit

View File

@@ -0,0 +1,59 @@
<?php
/**
* Init
*
* @since 2.0.0
* @package Ast Block Templates
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'Ast_Block_Templates' ) ) :
/**
* Admin
*/
class Ast_Block_Templates {
/**
* Instance
*
* @since 2.0.0
* @var (Object) Ast_Block_Templates
*/
private static $instance = null;
/**
* Get Instance
*
* @since 2.0.0
*
* @return object Class object.
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor.
*
* @since 2.0.0
*/
private function __construct() {
require_once AST_BLOCK_TEMPLATES_DIR . 'ast-block-plugin-loader.php';
}
}
/**
* Kicking this off by calling 'get_instance()' method
*/
Ast_Block_Templates::get_instance();
endif;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<title>aspect_ratio</title>
<path d="M21 19.031v-14.063h-18v14.063h18zM21 3q0.797 0 1.406 0.609t0.609 1.406v13.969q0 0.797-0.609 1.406t-1.406 0.609h-18q-0.797 0-1.406-0.609t-0.609-1.406v-13.969q0-0.797 0.609-1.406t1.406-0.609h18zM6.984 9v3h-1.969v-5.016h4.969v2.016h-3zM18.984 12v5.016h-4.969v-2.016h3v-3h1.969z"></path>
</svg>

After

Width:  |  Height:  |  Size: 459 B

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="ast-block-templates" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe900;" glyph-name="maximize" d="M341.333 853.334h-128c-35.328 0-67.413-14.379-90.496-37.504s-37.504-55.168-37.504-90.496v-128c0-23.552 19.115-42.667 42.667-42.667s42.667 19.115 42.667 42.667v128c0 11.776 4.736 22.4 12.501 30.165s18.389 12.501 30.165 12.501h128c23.552 0 42.667 19.115 42.667 42.667s-19.115 42.667-42.667 42.667zM938.667 597.334v128c0 35.328-14.379 67.413-37.504 90.496s-55.168 37.504-90.496 37.504h-128c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667h128c11.776 0 22.4-4.736 30.165-12.501s12.501-18.389 12.501-30.165v-128c0-23.552 19.115-42.667 42.667-42.667s42.667 19.115 42.667 42.667zM682.667-0h128c35.328 0 67.413 14.379 90.496 37.504s37.504 55.168 37.504 90.496v128c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667v-128c0-11.776-4.736-22.4-12.501-30.165s-18.389-12.501-30.165-12.501h-128c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667zM85.333 256v-128c0-35.328 14.379-67.413 37.504-90.496s55.168-37.504 90.496-37.504h128c23.552 0 42.667 19.115 42.667 42.667s-19.115 42.667-42.667 42.667h-128c-11.776 0-22.4 4.736-30.165 12.501s-12.501 18.389-12.501 30.165v128c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667z" />
<glyph unicode="&#xe901;" glyph-name="rotate-cw" d="M834.005 312.875c-31.403-88.875-95.787-156.587-174.677-194.261s-171.989-45.269-260.864-13.867-156.587 95.787-194.261 174.677-45.269 171.989-13.867 260.864 95.787 156.587 174.677 194.261 171.989 45.269 260.864 13.867c50.688-17.92 94.251-46.421 127.445-80.299l120.491-113.451h-148.48c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667h255.872c0.171 0 0.384 0 0.555 0 5.845 0.043 11.392 1.28 16.469 3.499 5.077 2.176 9.771 5.376 13.824 9.6 0.512 0.512 0.981 1.067 1.451 1.621 3.243 3.712 5.717 7.851 7.467 12.245 1.749 4.352 2.773 9.088 2.944 13.995 0.085 0.555 0.085 1.109 0.085 1.707v256c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667v-157.227l-124.416 117.12c-42.368 43.179-97.024 78.763-159.915 100.949-111.104 39.296-227.669 29.781-326.144-17.28s-179.072-131.755-218.325-242.859-29.696-227.627 17.323-326.101 131.755-179.072 242.859-218.325 227.627-29.739 326.101 17.323 179.072 131.755 218.325 242.859c7.851 22.229-3.797 46.592-26.027 54.443s-46.592-3.797-54.443-26.027z" />
<glyph unicode="&#xe902;" glyph-name="file" d="M554.667 896h-298.667c-35.328 0-67.413-14.379-90.496-37.504s-37.504-55.168-37.504-90.496v-682.667c0-35.328 14.379-67.413 37.504-90.496s55.168-37.504 90.496-37.504h512c35.328 0 67.413 14.379 90.496 37.504s37.504 55.168 37.504 90.496v469.333c0 11.776-4.779 22.443-12.501 30.165l-298.667 298.667c-4.096 4.096-8.789 7.168-13.824 9.259-5.205 2.176-10.795 3.243-16.341 3.243zM750.336 597.334h-153.003v153.003zM512 810.667v-256c0-23.552 19.115-42.667 42.667-42.667h256v-426.667c0-11.776-4.736-22.4-12.501-30.165s-18.389-12.501-30.165-12.501h-512c-11.776 0-22.4 4.736-30.165 12.501s-12.501 18.389-12.501 30.165v682.667c0 11.776 4.736 22.4 12.501 30.165s18.389 12.501 30.165 12.501z" />
<glyph unicode="&#xe903;" glyph-name="layers" d="M512 805.632l331.264-165.632-331.264-165.632-331.264 165.632zM492.928 891.478l-426.667-213.333c-21.077-10.539-29.611-36.139-19.072-57.216 4.309-8.661 11.136-15.189 19.072-19.072l426.667-213.333c12.459-6.229 26.453-5.803 38.144 0l426.667 213.333c21.077 10.539 29.611 36.181 19.072 57.259-4.309 8.619-11.179 15.147-19.072 19.072l-426.667 213.333c-12.459 6.229-26.453 5.803-38.144 0zM66.261 175.19l426.667-213.333c12.459-6.229 26.453-5.803 38.144 0l426.667 213.333c21.077 10.539 29.611 36.181 19.072 57.259s-36.181 29.611-57.259 19.072l-407.552-203.819-407.595 203.776c-21.077 10.539-46.72 2.005-57.259-19.072s-2.005-46.72 19.072-57.259zM66.261 388.523l426.667-213.333c12.459-6.229 26.453-5.803 38.144 0l426.667 213.333c21.077 10.539 29.611 36.181 19.072 57.259s-36.181 29.611-57.259 19.072l-407.552-203.819-407.595 203.776c-21.077 10.539-46.72 2.005-57.259-19.072s-2.005-46.72 19.072-57.259z" />
<glyph unicode="&#xe904;" glyph-name="chevron-left" d="M670.165 200.832l-225.835 225.835 225.835 225.835c16.683 16.683 16.683 43.691 0 60.331s-43.691 16.683-60.331 0l-256-256c-16.683-16.683-16.683-43.691 0-60.331l256-256c16.683-16.683 43.691-16.683 60.331 0s16.683 43.691 0 60.331z" />
</font></defs></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In SVG - Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.83;enable-background:new ;}
.st1{fill:#95F9EF;}
.st2{opacity:0.53;enable-background:new ;}
.st3{fill:url(#SVGID_1_);}
.st4{opacity:0.7;enable-background:new ;}
.st5{fill:url(#SVGID_2_);}
.st6{fill:#FFFFFF;}
</style>
<g>
<g class="st0">
<path class="st1" d="M26.8,88L9,33.5C8,30.7,9.6,27.8,12.2,27L66.8,9.2c2.7-0.9,5.7,0.6,6.4,3.2l17.9,54.6
c0.9,2.7-0.6,5.7-3.2,6.4l-54.6,18C30.5,92.2,27.6,90.8,26.8,88z"/>
</g>
<g class="st2">
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="4.238" y1="739.9995" x2="95.762" y2="739.9995" gradientTransform="matrix(1 0 0 1 0 -690)">
<stop offset="0" style="stop-color:#00E97B"/>
<stop offset="1" style="stop-color:#00F9D7"/>
</linearGradient>
<path class="st3" d="M44.7,94.3L5.6,52c-1.9-2.1-1.8-5.3,0.3-7.3L48.1,5.4c2.1-1.9,5.3-1.8,7.2,0.3L94.4,48
c1.9,2.1,1.8,5.3-0.3,7.3L51.9,94.6C50,96.6,46.6,96.4,44.7,94.3z"/>
</g>
<g class="st4">
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="296.5753" y1="-720.5554" x2="368.5928" y2="-720.5554" gradientTransform="matrix(0.9591 0.2829 0.2829 -0.9591 -65.1611 -734.9626)">
<stop offset="0" style="stop-color:#00DBDE"/>
<stop offset="1" style="stop-color:#FC00FF"/>
</linearGradient>
<path class="st5" d="M69.2,93.3L10.6,76.1c-2.9-0.8-4.5-3.9-3.7-6.8l17.2-58.6c0.8-2.9,3.9-4.5,6.8-3.7l58.6,17.2
c2.9,0.8,4.5,3.9,3.7,6.8L75.9,89.6C75.1,92.5,72,94.1,69.2,93.3z"/>
</g>
<g>
<path class="st6" d="M51.9,39.1L51.9,39.1h14.4V28.4H45.9c-1.9,0-3.7,0.3-5.3,1.1c-1.6,0.6-3.1,1.8-4.4,2.9
c-1.3,1.3-2.2,2.7-2.9,4.4c-0.4,0.7-0.6,1.6-0.8,2.4L51.9,39.1L51.9,39.1z"/>
<path class="st6" d="M66.9,53.3c-0.6-1.6-1.8-3.2-2.9-4.4c-1.3-1.3-2.7-2.2-4.4-2.9c-1.6-0.6-3.5-1.1-5.3-1.1h-2.4h-6H32.5
c0.2,0.9,0.5,1.7,0.8,2.6c0.6,1.6,1.8,3.2,2.9,4.4c1.3,1.3,2.7,2.2,4.4,2.9c1.6,0.8,3.5,1.1,5.3,1.1h8.4c0.5,0,0.8,0,1.1,0.2
c0.3,0.2,0.6,0.3,0.9,0.6c0.3,0.3,0.5,0.6,0.6,0.9c0.2,0.3,0.2,0.8,0.2,1.1c0,0.5,0,0.8-0.2,1.1c-0.2,0.3-0.3,0.6-0.6,0.9
c-0.3,0.3-0.6,0.5-0.9,0.6c-0.3,0.2-0.8,0.2-1.1,0.2h-20v10.8h19.8c1.9,0,3.7-0.3,5.5-1.1c1.6-0.6,3.2-1.8,4.4-2.9
c1.3-1.3,2.2-2.7,2.9-4.4c0.6-1.6,1.1-3.5,1.1-5.3C68,56.6,67.7,54.9,66.9,53.3z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,25 @@
/*!
* is-plain-object <https://github.com/jonschlinkert/is-plain-object>
*
* Copyright (c) 2014-2017, Jon Schlinkert.
* Released under the MIT License.
*/
/**
* @license
* Lodash <https://lodash.com/>
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/**
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,9 @@
<svg width="60" height="60" viewBox="0 0 84 85" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M41.7849 0C33.5206 0 25.4419 2.49258 18.5705 7.16254C11.699 11.8325 6.34331 18.4701 3.18071 26.236C0.0181112 34.0018 -0.809377 42.5471 0.802901 50.7913C2.41518 59.0355 6.3948 66.6083 12.2385 72.552C18.0822 78.4958 25.5276 82.5435 33.633 84.1834C41.7385 85.8232 50.1401 84.9816 57.7753 81.7649C65.4105 78.5482 71.9363 73.1008 76.5277 66.1117C81.1191 59.1226 83.5697 50.9057 83.5697 42.5C83.565 31.2298 79.1612 20.4225 71.326 12.4533C63.4908 4.48402 52.8655 0.0048112 41.7849 0ZM57.5278 49.0175C57.5278 49.1264 57.5278 49.2354 57.5278 49.3443V49.6529V49.8526C57.3161 51.0856 56.8673 52.2639 56.207 53.3201L55.8143 53.8829L55.2431 54.5546C55.0482 54.8082 54.8268 55.0396 54.5827 55.2445V55.3353L54.4578 55.4261L54.2079 55.6258C54.1249 55.7007 54.0353 55.7675 53.9402 55.8255L53.6724 56.0071L34.3061 69.0602C34.1479 69.1683 33.9612 69.2253 33.7706 69.2236H33.5743C33.447 69.1967 33.3262 69.1443 33.2189 69.0695C33.1117 68.9947 33.0201 68.899 32.9495 68.7879C32.9495 68.7879 32.5033 67.9891 32.4676 67.9347V67.7531V67.6623V67.5534V67.4263V67.2811C31.7014 65.262 31.6378 63.0371 32.2872 60.9761C32.9366 58.9152 34.2601 57.1424 36.0375 55.9526L45.0691 49.8708C45.2101 49.7754 45.3201 49.6398 45.3853 49.4809C45.4505 49.322 45.4679 49.147 45.4355 48.9781C45.403 48.8091 45.3221 48.6537 45.2029 48.5315C45.0837 48.4093 44.9316 48.3257 44.7657 48.2913L34.1633 46.1128H33.8599H33.7706H33.485H33.1816H33.0567H32.896H32.8068L32.5212 46.0038H32.4319H32.2534L31.9679 45.8586L31.6823 45.7134L31.4145 45.55L31.1468 45.3866C30.3041 44.8521 29.5509 44.1841 28.9156 43.4077L28.6836 43.0809L28.4159 42.6634C27.73 41.6278 27.255 40.4629 27.0189 39.2375C26.7828 38.012 26.7905 36.751 27.0415 35.5286C27.228 34.6884 27.5221 33.8766 27.9161 33.1141C28.0232 32.9144 28.1124 32.7328 28.2195 32.5694L28.3802 32.3153C28.4948 32.1207 28.6199 31.9329 28.755 31.7525L28.9156 31.5528L29.112 31.3167L29.3083 31.0989L29.4333 30.9718L29.6475 30.754L29.8259 30.5906L30.0223 30.4272L30.2365 30.2456H30.3257L30.4685 30.1185H30.5578L30.7898 29.9551L50.049 16.9746C50.1725 16.8912 50.3113 16.8338 50.457 16.806C50.6027 16.7782 50.7524 16.7804 50.8973 16.8126C51.0421 16.8448 51.1791 16.9062 51.3002 16.9933C51.4212 17.0804 51.5238 17.1913 51.6019 17.3195L51.7626 17.5918L51.8875 17.846C51.8875 17.9368 51.9768 18.0094 52.0125 18.082C52.0125 18.082 52.0125 18.082 52.0125 18.191C52.0239 18.2325 52.0239 18.2765 52.0125 18.318L52.1195 18.5904C52.1292 18.6383 52.1292 18.6877 52.1195 18.7356C52.1195 18.7356 52.1195 18.7356 52.1195 18.8445C52.8288 20.8305 52.8625 23.0011 52.2153 25.0089C51.5681 27.0166 50.2774 28.7455 48.5497 29.9188L39.6251 35.9462C39.4842 36.0415 39.3742 36.1772 39.309 36.3361C39.2438 36.495 39.2263 36.6699 39.2588 36.8389C39.2912 37.0078 39.3722 37.1632 39.4914 37.2854C39.6106 37.4077 39.7627 37.4912 39.9286 37.5256L50.4417 39.686C52.5458 40.1281 54.4361 41.2935 55.7948 42.9862C57.1536 44.679 57.8979 46.796 57.9027 48.9812C57.5635 48.4003 57.5278 48.9812 57.5278 48.9812V49.0175Z" fill="url(#paint0_linear_619_170)"/>
<defs>
<linearGradient id="paint0_linear_619_170" x1="1.17098e-05" y1="1.49716e-06" x2="84.02" y2="71.3596" gradientUnits="userSpaceOnUse">
<stop stop-color="#4E01D1"/>
<stop offset="1" stop-color="#6104FF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,3 @@
<svg width="71" height="71" viewBox="0 0 71 71" fill="#000000" xmlns="http://www.w3.org/2000/svg">
<path d="M35.292 0C28.3119 0 21.4885 2.08204 15.6848 5.98283C9.88107 9.88362 5.35762 15.428 2.68645 21.9147C0.0152817 28.4015 -0.683625 35.5394 0.678124 42.4257C2.03987 49.312 5.40111 55.6375 10.3368 60.6023C15.2725 65.5671 21.5609 68.9481 28.4068 70.3179C35.2528 71.6876 42.3489 70.9846 48.7976 68.2977C55.2464 65.6108 60.7583 61.0607 64.6362 55.2227C68.5141 49.3848 70.584 42.5212 70.584 35.5C70.58 26.0861 66.8604 17.0588 60.2428 10.4021C53.6251 3.74548 44.6508 0.00401876 35.292 0V0ZM48.5887 40.944C48.5887 41.035 48.5887 41.126 48.5887 41.217V41.4748V41.6416C48.4098 42.6715 48.0307 43.6558 47.4731 44.538L47.1414 45.0081L46.659 45.5692C46.4943 45.781 46.3073 45.9742 46.1012 46.1454V46.2213L45.9957 46.2971L45.7846 46.4639C45.7145 46.5265 45.6388 46.5823 45.5585 46.6307L45.3323 46.7824L28.9753 57.6856C28.8417 57.7759 28.684 57.8235 28.523 57.8221H28.3572C28.2497 57.7996 28.1477 57.7558 28.0571 57.6933C27.9665 57.6309 27.8892 57.5509 27.8296 57.4582C27.8296 57.4582 27.4527 56.7909 27.4225 56.7454V56.5938V56.5179V56.4269V56.3208V56.1995C26.7754 54.513 26.7216 52.6545 27.2701 50.933C27.8187 49.2115 28.9365 47.7307 30.4376 46.7369L38.0659 41.6568C38.1849 41.5771 38.2779 41.4638 38.3329 41.3311C38.388 41.1984 38.4027 41.0522 38.3753 40.9111C38.3479 40.77 38.2796 40.6402 38.1789 40.5381C38.0782 40.436 37.9497 40.3662 37.8096 40.3375L28.8547 38.5177H28.5984H28.523H28.2818H28.0255H27.92H27.7843H27.709L27.4678 38.4267H27.3924H27.2416L27.0004 38.3054L26.7592 38.1841L26.533 38.0476L26.3069 37.9111C25.5952 37.4647 24.959 36.9067 24.4225 36.2582L24.2265 35.9853L24.0004 35.6365C23.421 34.7714 23.0198 33.7984 22.8205 32.7748C22.6211 31.7512 22.6276 30.6979 22.8395 29.6769C22.9971 28.975 23.2455 28.2969 23.5782 27.66C23.6687 27.4932 23.7441 27.3415 23.8345 27.205L23.9702 26.9927C24.067 26.8303 24.1727 26.6733 24.2868 26.5226L24.4225 26.3558L24.5883 26.1587L24.7541 25.9767L24.8597 25.8706L25.0406 25.6886L25.1913 25.5521L25.3572 25.4156L25.5381 25.264H25.6134L25.734 25.1578H25.8094L26.0054 25.0214L42.272 14.1788C42.3763 14.1091 42.4935 14.0612 42.6166 14.038C42.7396 14.0147 42.8661 14.0166 42.9884 14.0435C43.1108 14.0704 43.2265 14.1217 43.3287 14.1944C43.431 14.2672 43.5176 14.3598 43.5836 14.4669L43.7192 14.6944L43.8248 14.9067C43.8248 14.9825 43.9002 15.0432 43.9303 15.1038C43.9303 15.1038 43.9303 15.1038 43.9303 15.1948C43.94 15.2295 43.94 15.2662 43.9303 15.3009V15.3009L44.0208 15.5284C44.0289 15.5684 44.0289 15.6097 44.0208 15.6497C44.0208 15.6497 44.0208 15.6497 44.0208 15.7407C44.6198 17.3996 44.6483 19.2127 44.1017 20.8897C43.555 22.5668 42.4648 24.011 41.0056 24.991L33.4678 30.0256C33.3488 30.1053 33.2559 30.2186 33.2008 30.3513C33.1457 30.484 33.131 30.6302 33.1584 30.7713C33.1858 30.9124 33.2542 31.0422 33.3549 31.1443C33.4555 31.2464 33.584 31.3162 33.7241 31.3449L42.6036 33.1495C44.3808 33.5188 45.9773 34.4922 47.1249 35.9061C48.2726 37.3201 48.9012 39.0884 48.9053 40.9137C48.6188 40.4285 48.5887 40.9137 48.5887 40.9137V40.944Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,4 @@
<svg width="90" height="90" viewBox="0 0 90 90" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M71.2429 7.34463H18.3616C12.2771 7.34463 7.34463 12.2771 7.34463 18.3616V71.2429C7.34463 77.3274 12.2771 82.2598 18.3616 82.2598H71.2429C77.3274 82.2598 82.2598 77.3274 82.2598 71.2429V18.3616C82.2598 12.2771 77.3274 7.34463 71.2429 7.34463ZM18.3616 0C8.22076 0 0 8.22075 0 18.3616V71.2429C0 81.3837 8.22075 89.6045 18.3616 89.6045H71.2429C81.3837 89.6045 89.6045 81.3837 89.6045 71.2429V18.3616C89.6045 8.22076 81.3837 0 71.2429 0H18.3616Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M54.1449 28.1896C53.9728 28.0356 53.7911 27.8882 53.5998 27.7474C51.9414 26.5264 49.6907 25.9159 46.8478 25.9159C44.916 25.9159 43.285 26.1892 41.9546 26.7359C40.6243 27.2644 39.6037 28.0025 38.893 28.9502C38.1294 29.995 36.829 30.8418 35.7046 30.2012C34.8223 29.6985 34.0076 29.0784 33.2839 28.3548C31.9339 27.0047 30.944 25.3377 30.405 23.5061C30.1674 22.6988 30.3776 21.8165 31.0133 21.265C32.434 20.0323 34.0947 18.9948 35.9954 18.1524C39.2028 16.7309 42.8476 16.0202 46.9298 16.0202C51.0849 16.0202 54.7115 16.7309 57.8095 18.1524C60.9259 19.5739 63.3496 21.5512 65.0809 24.0843C65.7142 25.011 66.2354 25.9913 66.6443 27.0252C67.8571 30.0913 65.0579 32.8866 61.7607 32.8866C59.1869 32.8866 57.1265 30.9615 55.18 29.1429L55.1799 29.1428C54.8321 28.8178 54.4878 28.4962 54.1449 28.1896ZM37.1987 34.2544C37.6871 34.0635 38.21 34.3524 38.4829 34.8001C38.9568 35.5473 39.6037 36.1942 40.4238 36.7409C41.2439 37.2694 42.1915 37.7342 43.2667 38.1351C44.342 38.5178 45.4901 38.8458 46.7111 39.1192L51.7409 40.322C54.183 40.8687 56.4245 41.5977 58.4656 42.5089C60.5067 43.4201 62.2744 44.5408 63.7688 45.8712C65.2632 47.2015 66.4204 48.7688 67.2405 50.573C68.0788 52.3772 68.5071 54.4456 68.5253 56.7783C68.5071 60.2044 67.6323 63.1749 65.901 65.6898C64.188 68.1865 61.7095 70.1274 58.4656 71.5124C55.2399 72.8792 51.3491 73.5626 46.7931 73.5626C42.2735 73.5626 38.3371 72.8701 34.9839 71.4851C31.6489 70.1001 29.0429 68.0499 27.1658 65.3345C26.2995 64.0605 25.6252 62.646 25.1428 61.091C24.1699 57.9547 26.943 55.1928 30.2268 55.1928H30.6526C33.4909 55.1928 35.5992 57.6279 37.3075 59.8946C38.2734 61.1338 39.5582 62.0724 41.1619 62.7102C42.7838 63.3298 44.6153 63.6396 46.6564 63.6396C48.6611 63.6396 50.4015 63.3481 51.8776 62.7649C53.372 62.1817 54.5292 61.3707 55.3493 60.332C56.1694 59.2932 56.5794 58.0995 56.5794 56.7509C56.5794 55.4935 56.2058 54.4365 55.4586 53.58C54.7297 52.7234 53.6545 51.9945 52.233 51.3931C50.8297 50.7917 49.1076 50.245 47.0665 49.7529L40.9705 48.2221C36.9718 47.2494 33.6859 45.8124 31.1129 43.9111C30.4174 43.3972 30.1608 42.4925 30.405 41.6629C30.9439 39.8315 31.9336 38.1645 33.2834 36.8145C34.4003 35.6975 35.7342 34.827 37.1987 34.2544ZM29.9545 26.532L29.4188 24.7118C29.3957 24.6328 29.3476 24.5633 29.2818 24.5139C29.2159 24.4645 29.1358 24.4378 29.0535 24.4378C28.9712 24.4378 28.8911 24.4645 28.8252 24.5139C28.7593 24.5633 28.7113 24.6328 28.6882 24.7118L28.1532 26.532C27.7938 27.7529 27.1338 28.8641 26.2338 29.764C25.3338 30.6639 24.2224 31.3236 23.0014 31.6829L21.1811 32.2186C20.8166 32.3267 20.8166 32.8426 21.1811 32.9491L23.0014 33.4849C24.2222 33.8442 25.3335 34.5041 26.2334 35.4039C27.1333 36.3038 27.7931 37.415 28.1525 38.6358L28.6882 40.4568C28.7955 40.8205 29.3115 40.8205 29.4188 40.4568L29.9545 38.6365C30.3138 37.4156 30.9736 36.3043 31.8735 35.4042C32.7734 34.5042 33.8847 33.8443 35.1056 33.4849L36.9266 32.9491C37.2904 32.8419 37.2904 32.3259 36.9266 32.2194L35.1064 31.6837C33.8853 31.3243 32.7738 30.6645 31.8738 29.7644C30.9738 28.8644 30.3138 27.753 29.9545 26.532ZM23.461 37.2817L23.6218 37.8277C23.7296 38.194 23.9275 38.5275 24.1975 38.7975C24.4676 39.0675 24.801 39.2654 25.1673 39.3732L25.7134 39.5339C25.8225 39.5659 25.8225 39.7207 25.7134 39.7529L25.1671 39.9136C24.8008 40.0214 24.4674 40.2194 24.1975 40.4894C23.9275 40.7594 23.7295 41.0928 23.6218 41.4591L23.461 42.0051C23.4288 42.1143 23.2741 42.1143 23.2419 42.0051L23.0812 41.4589C22.9733 41.0926 22.7754 40.7593 22.5054 40.4893C22.2354 40.2193 21.9021 40.0214 21.5358 39.9136L20.9897 39.7529C20.8804 39.7209 20.8804 39.5661 20.9897 39.5337L21.5358 39.373C21.9021 39.2652 22.2355 39.0673 22.5055 38.7973C22.7756 38.5274 22.9735 38.194 23.0814 37.8277L23.2419 37.2817C23.2488 37.2579 23.2632 37.2371 23.283 37.2223C23.3027 37.2075 23.3268 37.1995 23.3515 37.1995C23.3762 37.1995 23.4002 37.2075 23.4199 37.2223C23.4397 37.2371 23.4541 37.2579 23.461 37.2817ZM22.4142 22.428L22.1642 21.5786C22.1535 21.5417 22.131 21.5093 22.1003 21.4863C22.0696 21.4632 22.0322 21.4508 21.9938 21.4508C21.9554 21.4508 21.918 21.4632 21.8872 21.4863C21.8565 21.5093 21.8341 21.5417 21.8233 21.5786L21.5737 22.428C21.4059 22.9978 21.0979 23.5164 20.6779 23.9363C20.2579 24.3562 19.7392 24.6641 19.1695 24.8318L18.32 25.0818C18.1499 25.1322 18.1499 25.373 18.32 25.4227L19.1695 25.6727C19.7392 25.8404 20.2578 26.1483 20.6777 26.5683C21.0977 26.9882 21.4056 27.5068 21.5733 28.0765L21.8233 28.9263C21.8734 29.096 22.1142 29.096 22.1642 28.9263L22.4142 28.0768C22.5819 27.507 22.8898 26.9884 23.3098 26.5684C23.7297 26.1484 24.2483 25.8404 24.8181 25.6727L25.6679 25.4227C25.8377 25.3726 25.8377 25.1319 25.6679 25.0821L24.8184 24.8321C24.2486 24.6645 23.7299 24.3565 23.3099 23.9365C22.8899 23.5165 22.5819 22.9978 22.4142 22.428Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.5;}
.st1{fill:#FFFFFF;}
.st2{opacity:0.8;}
</style>
<g>
<g class="st0">
<path class="st1" d="M68.02,6.1l-6.81,2.16l6.14,6.64l10.29,2.99l-2.82-8.47C73.99,6.76,71.01,5.1,68.02,6.1z"/>
<path class="st1" d="M5.94,32.16l2.32,6.81l6.64-6.14l2.99-10.46l-8.47,2.82C6.6,26.18,4.94,29.34,5.94,32.16z"/>
<path class="st1" d="M22.37,82.45l2.82,8.47c0.83,2.99,3.98,4.48,6.97,3.65l7.14-2.32l-5.98-6.47L22.37,82.45z"/>
<path class="st1" d="M94.08,68.18l-2.32-7.14l-6.31,5.98l-3.32,10.95l8.47-2.82C93.41,74.32,95.24,71.16,94.08,68.18z"/>
</g>
<g class="st2">
<path class="st1" d="M55.73,2.45c-2.16-2.32-5.48-2.49-7.8-0.33l-5.98,5.48l11.29,3.32l13.94,4.15l-6.14-6.64L55.73,2.45z"/>
<path class="st1" d="M2.62,44.27c-2.32,2.16-2.49,5.48-0.33,7.8l5.15,5.64l3.15-10.95l4.15-13.94L8.1,38.96L2.62,44.27z"/>
<path class="st1" d="M97.73,47.93l-5.15-5.48l-3.32,11.12l-3.98,13.28l6.31-5.98l5.64-5.31C99.72,53.73,99.89,50.25,97.73,47.93z"
/>
<path class="st1" d="M33.16,85.6l5.98,6.47l5.15,5.48c2.16,2.32,5.64,2.49,7.8,0.33l5.64-5.15l-10.79-3.15L33.16,85.6z"/>
</g>
<path class="st1" d="M92.42,22.36l-14.77-4.32l-10.29-2.99l-13.94-4.15L42.12,7.59L29.51,3.94c-3.15-0.83-6.47,0.83-7.3,3.98
L17.89,22.7L14.9,33.15L10.75,47.1L7.6,58.05L3.78,71.16c-0.83,3.15,0.83,6.47,3.98,7.3l14.77,4.32l10.79,3.15l13.61,3.98
l10.79,3.15l12.95,3.82c3.15,0.83,6.47-0.83,7.3-3.98l4.32-14.61l3.32-10.95l3.98-13.28l3.32-11.12l3.82-12.78
C97.23,26.51,95.57,23.19,92.42,22.36z M67.69,26.68V38.3H52.25l0,0H31.5c0.17-0.83,0.5-1.83,0.83-2.66
c0.66-1.66,1.66-3.32,3.15-4.65c1.33-1.16,2.99-2.49,4.65-3.15c1.66-0.83,3.65-1.16,5.64-1.16H67.69z M33.33,74.15V62.53h21.41
c0.33,0,0.83,0,1.16-0.17c0.33-0.17,0.66-0.33,1-0.66c0.33-0.33,0.5-0.66,0.66-1c0.17-0.33,0.17-0.66,0.17-1.16
c0-0.33,0-0.83-0.17-1.16c-0.17-0.33-0.33-0.66-0.66-1c-0.33-0.33-0.66-0.5-1-0.66c-0.33-0.17-0.66-0.17-1.16-0.17h-8.96
c-1.83,0-3.98-0.33-5.64-1.16c-1.66-0.66-3.32-1.66-4.65-3.15c-1.16-1.16-2.49-2.99-3.15-4.65c-0.5-1-0.66-1.83-0.83-2.82h14.44
h6.47h2.49c1.83,0,3.98,0.5,5.64,1.16c1.66,0.66,3.32,1.66,4.65,3.15c1.16,1.16,2.49,2.99,3.15,4.65c0.83,1.66,1.16,3.65,1.16,5.81
c0,1.83-0.5,3.98-1.16,5.64c-0.66,1.66-1.66,3.32-3.15,4.65c-1.16,1.16-2.99,2.49-4.65,3.15c-1.83,0.83-3.82,1.16-5.81,1.16
L33.33,74.15L33.33,74.15z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,49 @@
@font-face {
font-family: ast-block-templates;
src: url( "fonts/ast-block-templates.eot?p3u0q1" );
src:
url( "fonts/ast-block-templates.eot?p3u0q1#iefix" ) format( "embedded-opentype" ),
url( "fonts/ast-block-templates.ttf?p3u0q1" ) format( "truetype" ),
url( "fonts/ast-block-templates.woff?p3u0q1" ) format( "woff" ),
url( "fonts/ast-block-templates.svg?p3u0q1#ast-block-templates" ) format( "svg" );
font-weight: 400;
font-style: normal;
font-display: block;
}
[class^="ast-block-templates-icon-"],
[class*=" ast-block-templates-icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: ast-block-templates, sans-serif !important;
speak: never;
font-style: normal;
font-weight: 400;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.ast-block-templates-icon-chevron-left::before {
content: "\e904";
}
.ast-block-templates-icon-pages::before {
content: "\e902";
}
.ast-block-templates-icon-patterns::before {
content: "\e903";
}
.ast-block-templates-icon-wireframe::before {
content: "\e900";
}
.ast-block-templates-icon-refresh::before {
content: "\e901";
}

View File

@@ -0,0 +1,43 @@
<?php
/**
* API base.
*
* @package {{package}}
* @since 0.0.1
*/
namespace Gutenberg_Templates\Inc\Api;
/**
* Api_Base
*
* @since 0.0.1
*/
abstract class Api_Base extends \WP_REST_Controller {
/**
* Endpoint namespace.
*
* @var string
*/
protected $namespace = 'gutenberg-templates/v1';
/**
* Constructor
*
* @since 0.0.1
*/
public function __construct() {
}
/**
* Get API namespace.
*
* @since 0.0.1
* @return string
*/
public function get_api_namespace() {
return $this->namespace;
}
}

View File

@@ -0,0 +1,71 @@
<?php
/**
* INitialize API.
*
* @package {{package}}
* @since 0.0.1
*/
namespace Gutenberg_Templates\Inc\Api;
use Gutenberg_Templates\Inc\Traits\Instance;
/**
* Api_Base
*
* @since 0.0.1
*/
class Api_Init {
use Instance;
/**
* Controller object.
*
* @var object class.
*/
public $controller = null;
/**
* Constructor
*
* @since 0.0.1
*/
public function __construct() {
// REST API extensions init.
add_action( 'rest_api_init', array( $this, 'register_routes' ) );
}
/**
* Register API routes.
*
* @since 0.0.1
* @return void
*/
public function register_routes() {
$controllers = array(
'\Gutenberg_Templates\Inc\Api\Category',
'\Gutenberg_Templates\Inc\Api\Description',
'\Gutenberg_Templates\Inc\Api\PageDescription',
'\Gutenberg_Templates\Inc\Api\Keywords',
'\Gutenberg_Templates\Inc\Api\Images',
'\Gutenberg_Templates\Inc\Api\Settings',
'\Gutenberg_Templates\Inc\Api\Favorite',
'Gutenberg_Templates\Inc\Api\Do_It_Later',
'\Gutenberg_Templates\Inc\Api\Pages',
'\Gutenberg_Templates\Inc\Api\RevokeAccess',
'\Gutenberg_Templates\Inc\Api\Blocks',
'\Gutenberg_Templates\Inc\Api\Initialize_Setup',
'\Gutenberg_Templates\Inc\Api\Sites',
);
foreach ( $controllers as $controller ) {
$this->controller = $controller::instance();
$this->controller->register_routes();
}
}
}

View File

@@ -0,0 +1,115 @@
<?php
/**
* Progress API.
*
* @package {{package}}
* @since 0.0.1
*/
namespace Gutenberg_Templates\Inc\Api;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Api\Api_Base;
use Gutenberg_Templates\Inc\Importer\Plugin;
/**
* Progress
*
* @since 0.0.1
*/
class Blocks extends Api_Base {
use Instance;
/**
* Route base.
*
* @var string
*/
protected $rest_base = '/blocks/';
/**
* Init Hooks.
*
* @since 0.0.1
* @return void
*/
public function register_routes() {
$namespace = $this->get_api_namespace();
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get_blocks' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
),
)
);
}
/**
* Check whether a given request has permission to read notes.
*
* @param object $request WP_REST_Request Full details about the request.
* @return object|boolean
*/
public function get_item_permissions_check( $request ) {
// To do: Check api token or JWT token for permission.
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
return new \WP_Error(
'gt_rest_cannot_access',
__( 'Sorry, you are not allowed to do that.', 'astra-sites' ),
array( 'status' => rest_authorization_required_code() )
);
}
return true;
}
/**
* Save Prompts.
*
* @param \WP_REST_Request $request Full details about the request.
* @return \WP_REST_Response
*/
public function get_blocks( $request ) {
$nonce = (string) $request->get_header( 'X-WP-Nonce' );
// Verify the nonce.
if ( ! wp_verify_nonce( sanitize_text_field( $nonce ), 'wp_rest' ) ) {
return new \WP_REST_Response(
array(
'success' => false,
'data' => __( 'Nonce verification failed.', 'astra-sites' ),
),
403
);
}
$start = isset( $request['start'] ) ? intval( $request['start'] ) : 1;
$end = isset( $request['end'] ) ? intval( $request['end'] ) : 1;
$blocks = Plugin::instance()->get_all_blocks( $start, $end );
$response = new \WP_REST_Response(
array(
'success' => true,
'allBlocks' => $blocks['blocks'],
'allBlocksPages' => $blocks['blocks_pages'],
)
);
$response->set_status( 200 );
return $response;
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* Progress API.
*
* @package {{package}}
* @since 0.0.1
*/
namespace Gutenberg_Templates\Inc\Api;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Traits\Helper;
use Gutenberg_Templates\Inc\Api\Api_Base;
/**
* Progress
*
* @since 0.0.1
*/
class Category extends Api_Base {
use Instance;
/**
* Route base.
*
* @var string
*/
protected $rest_base = '/categories/';
/**
* Init Hooks.
*
* @since 0.0.1
* @return void
*/
public function register_routes() {
$namespace = $this->get_api_namespace();
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
),
)
);
}
/**
* Check whether a given request has permission to read notes.
*
* @param object $request WP_REST_Request Full details about the request.
* @return object|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
return new \WP_Error(
'gt_rest_cannot_access',
__( 'Sorry, you are not allowed to do that.', 'astra-sites' ),
array( 'status' => rest_authorization_required_code() )
);
}
return true;
}
/**
* Save Prompts.
*
* @param \WP_REST_Request $request Full details about the request.
* @return \WP_REST_Response
*/
public function get( $request ) {
$nonce = (string) $request->get_header( 'X-WP-Nonce' );
// Verify the nonce.
if ( ! wp_verify_nonce( sanitize_text_field( $nonce ), 'wp_rest' ) ) {
return new \WP_REST_Response(
array(
'success' => false,
'data' => __( 'Nonce verification failed.', 'astra-sites' ),
),
403
);
}
$categories = Helper::instance()->get_block_template_category();
$total_requests = (int) Helper::instance()->get_block_templates_requests();
$response = new \WP_REST_Response(
array(
'success' => true,
'categories' => $categories,
'total_requests' => $total_requests,
)
);
$response->set_status( 200 );
return $response;
}
}

View File

@@ -0,0 +1,191 @@
<?php
/**
* Description API.
*
* @package {{package}}
* @since 2.0.0
*/
namespace Gutenberg_Templates\Inc\Api;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Api\Api_Base;
use Gutenberg_Templates\Inc\Importer\Importer_Helper;
/**
* Progress
*
* @since 2.0.0
*/
class Description extends Api_Base {
use Instance;
/**
* Route base.
*
* @var string
*/
protected $rest_base = '/description/';
/**
* Init Hooks.
*
* @since 2.0.0
* @return void
*/
public function register_routes() {
$namespace = $this->get_api_namespace();
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array( $this, 'get' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'business_name' => array(
'type' => 'string',
'required' => true,
'sanitize_callback' => 'sanitize_text_field',
),
'business_description' => array(
'type' => 'string',
'required' => false,
'sanitize_callback' => 'sanitize_text_field',
),
'category' => array(
'type' => 'string',
'required' => false,
'sanitize_callback' => 'sanitize_text_field',
),
'language_name' => array(
'type' => 'string',
'required' => false,
'sanitize_callback' => 'sanitize_text_field',
),
),
),
)
);
}
/**
* Check whether a given request has permission to read notes.
*
* @param object $request WP_REST_Request Full details about the request.
* @return object|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
return new \WP_Error(
'gt_rest_cannot_access',
__( 'Sorry, you are not allowed to do that.', 'astra-sites' ),
array( 'status' => rest_authorization_required_code() )
);
}
return true;
}
/**
* Save Prompts.
*
* @param \WP_REST_Request $request Full details about the request.
* @return mixed
*/
public function get( $request ) {
$nonce = (string) $request->get_header( 'X-WP-Nonce' );
// Verify the nonce.
if ( ! wp_verify_nonce( sanitize_text_field( $nonce ), 'wp_rest' ) ) {
wp_send_json_error(
array(
'data' => __( 'Nonce verification failed.', 'astra-sites' ),
'status' => false,
)
);
}
$api_endpoint = AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/ai/v1/description';
$token = Importer_Helper::get_business_details( 'token' );
$post_data = array(
'business_name' =>
isset( $request['business_name'] ) ?
sanitize_text_field( $request['business_name'] ) :
'',
'business_description' =>
isset( $request['business_description'] ) ? sanitize_text_field( $request['business_description'] ) : '',
'category' =>
isset( $request['category'] ) ? sanitize_text_field( $request['category'] ) : '',
'language_name' =>
isset( $request['language_name'] ) ? sanitize_text_field( $request['language_name'] ) : '',
'token' =>
$token,
);
$body = wp_json_encode( $post_data );
$request_args = array(
'body' => is_string( $body ) ? $body : '',
'headers' => array(
'Content-Type' => 'application/json',
),
'timeout' => 100,
);
$response = wp_safe_remote_post( $api_endpoint, $request_args );
if ( is_wp_error( $response ) ) {
// There was an error in the request.
wp_send_json_error(
array(
'data' => 'Failed ' . $response->get_error_message(),
'status' => false,
)
);
} else {
$response_code = wp_remote_retrieve_response_code( $response );
$response_body = wp_remote_retrieve_body( $response );
if ( 200 === $response_code ) {
$response_data = json_decode( $response_body, true );
if ( $response_data['status'] ) {
wp_send_json_success(
array(
'data' => $response_data['data'],
'status' => true,
)
);
} else {
wp_send_json_error(
array(
'data' => 'Failed ' . $response_data['data'],
'status' => false,
)
);
}
} else {
wp_send_json_error(
array(
'data' => 'Failed',
'status' => false,
)
);
}
}
}
}

View File

@@ -0,0 +1,91 @@
<?php
/**
* Do It Later API.
*
* @package {{package}}
* @since 2.0.0
*/
namespace Gutenberg_Templates\Inc\Api;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Api\Api_Base;
/**
* Do It Later
*
* @since 2.0.0
*/
class Do_It_Later extends Api_Base {
use Instance;
/**
* Route base.
*
* @var string
*/
protected $rest_base = '/do-it-later/';
/**
* Init Hooks.
*
* @since 2.0.0
* @return void
*/
public function register_routes() {
$namespace = $this->get_api_namespace();
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
),
)
);
}
/**
* Check whether a given request has permission to read notes.
*
* @param object $request WP_REST_Request Full details about the request.
* @return object|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
return new \WP_Error(
'gt_rest_cannot_access',
__( 'Sorry, you are not allowed to do that.', 'astra-sites' ),
array( 'status' => rest_authorization_required_code() )
);
}
return true;
}
/**
* Save Prompts.
*
* @return \WP_REST_Response
*/
public function get() {
update_option( 'ast-block-templates-show-onboarding', 'no' );
$response = new \WP_REST_Response(
array(
'success' => true,
)
);
$response->set_status( 200 );
return $response;
}
}

View File

@@ -0,0 +1,187 @@
<?php
/**
* Favorite API.
*
* @package {{package}}
* @since 2.0.0
*/
namespace Gutenberg_Templates\Inc\Api;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Api\Api_Base;
/**
* Favorite
*
* @since 2.0.0
*/
class Favorite extends Api_Base {
use Instance;
/**
* Route base.
*
* @var string
*/
protected $rest_base = '/favorite/';
/**
* Init Hooks.
*
* @since 2.0.0
* @return void
*/
public function register_routes() {
$namespace = $this->get_api_namespace();
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
),
)
);
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array( $this, 'save' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'type' => array(
'type' => 'string',
'required' => true,
'sanitize_callback' => 'sanitize_text_field',
),
'block_id' => array(
'type' => 'integer',
'required' => true,
),
'status' => array(
'type' => 'boolean',
'required' => true,
),
),
),
)
);
}
/**
* Check whether a given request has permission to read notes.
*
* @param object $request WP_REST_Request Full details about the request.
* @return object|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
return new \WP_Error(
'gt_rest_cannot_access',
__( 'Sorry, you are not allowed to do that.', 'astra-sites' ),
array( 'status' => rest_authorization_required_code() )
);
}
return true;
}
/**
* Get Favorite.
*
* @param \WP_REST_Request $request Full details about the request.
* @return mixed
*/
public function get( $request ) {
$favorites = get_option( 'ast_block_templates_favorites', array() );
$response = new \WP_REST_Response(
array(
'success' => true,
'data' => $favorites,
)
);
$response->set_status( 200 );
return $response;
}
/**
* Save Favorite.
*
* @param \WP_REST_Request $request Full details about the request.
* @return mixed
*/
public function save( $request ) {
$nonce = (string) $request->get_header( 'X-WP-Nonce' );
// Verify the nonce.
if ( ! wp_verify_nonce( sanitize_text_field( $nonce ), 'wp_rest' ) ) {
wp_send_json_error(
array(
'data' => __( 'Nonce verification failed.', 'astra-sites' ),
'status' => false,
)
);
}
$favorites = get_option( 'ast_block_templates_favorites', array() );
$block_type = $request->get_param( 'type' );
$id = $request->get_param( 'block_id' );
$status = $request->get_param( 'status' );
// Empty favorite then add favorite in respective array tye and early return.
if ( ! isset( $favorites[ $block_type ] ) || ! is_array( $favorites[ $block_type ] ) ) {
$favorites[ $block_type ] = array();
}
if ( empty( $favorites ) && $status ) {
$favorites[ $block_type ][] = $id;
}
// Empty patterns OR blocks array then add favorite and return early.
if ( empty( $favorites[ $block_type ] ) && $status ) {
$favorites[ $block_type ][] = $id;
}
if ( $status ) {
// Insert the block-id/page-id if it doesn't already exist.
if ( ! in_array( $id, $favorites[ $block_type ] ) ) {
$favorites[ $block_type ][] = $id;
}
} else {
// Remove the block-id/page-id if it exists.
if ( isset( $favorites[ $block_type ] ) && is_array( $favorites[ $block_type ] ) ) {
$key = array_search( $id, $favorites[ $block_type ] );
if ( false !== $key ) {
unset( $favorites[ $block_type ][ $key ] );
$favorites[ $block_type ] = array_values( $favorites[ $block_type ] );
}
}
}
$update_status = update_option( 'ast_block_templates_favorites', $favorites );
$data = array(
'success' => $update_status,
'message' => $update_status ? __( 'Action Completed', 'astra-sites' ) : __( 'Action failed', 'astra-sites' ),
'data' => $favorites,
);
return rest_ensure_response( $data );
}
}

View File

@@ -0,0 +1,174 @@
<?php
/**
* Images API.
*
* @package {{package}}
* @since 2.0.0
*/
namespace Gutenberg_Templates\Inc\Api;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Api\Api_Base;
/**
* Progress
*
* @since 2.0.0
*/
class Images extends Api_Base {
use Instance;
/**
* Route base.
*
* @var string
*/
protected $rest_base = '/images/';
/**
* Init Hooks.
*
* @since 2.0.0
* @return void
*/
public function register_routes() {
$namespace = $this->get_api_namespace();
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array( $this, 'get' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'keywords' => array(
'type' => 'string',
'required' => true,
),
'per_page' => array(
'type' => 'integer',
'required' => false,
),
'page' => array(
'type' => 'integer',
'required' => false,
),
'orientation' => array(
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
'required' => false,
),
'engine' => array(
'type' => 'string',
'required' => false,
'sanitize_callback' => 'sanitize_text_field',
),
),
),
)
);
}
/**
* Check whether a given request has permission to read notes.
*
* @param object $request WP_REST_Request Full details about the request.
* @return object|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
return new \WP_Error(
'gt_rest_cannot_access',
__( 'Sorry, you are not allowed to do that.', 'astra-sites' ),
array( 'status' => rest_authorization_required_code() )
);
}
return true;
}
/**
* Save Prompts.
*
* @param \WP_REST_Request $request Full details about the request.
* @return mixed
*/
public function get( $request ) {
$nonce = (string) $request->get_header( 'X-WP-Nonce' );
// Verify the nonce.
if ( ! wp_verify_nonce( sanitize_text_field( $nonce ), 'wp_rest' ) ) {
wp_send_json_error(
array(
'data' => __( 'Nonce verification failed.', 'astra-sites' ),
'status' => false,
)
);
}
$api_endpoint = AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/image/v1/images';
$post_data = array(
'keywords' => isset( $request['keywords'] ) ? $request['keywords'] : '',
'per_page' => isset( $request['per_page'] ) ? $request['per_page'] : 20,
'page' => isset( $request['page'] ) ? $request['page'] : 1,
'orientation' => isset( $request['orientation'] ) ? sanitize_text_field( $request['orientation'] ) : '',
'engine' => isset( $request['engine'] ) ? sanitize_text_field( $request['engine'] ) : '',
);
$body = wp_json_encode( $post_data );
$request_args = array(
'body' => is_string( $body ) ? $body : '',
'headers' => array(
'Content-Type' => 'application/json',
),
'timeout' => 100,
);
$response = wp_safe_remote_post( $api_endpoint, $request_args );
if ( is_wp_error( $response ) ) {
// There was an error in the request.
wp_send_json_error(
array(
'data' => 'Failed ' . $response->get_error_message(),
'status' => false,
)
);
} else {
$response_code = wp_remote_retrieve_response_code( $response );
$response_body = wp_remote_retrieve_body( $response );
if ( 200 === $response_code ) {
$response_data = json_decode( $response_body, true );
wp_send_json_success(
array(
'data' => $response_data,
'status' => true,
)
);
} else {
wp_send_json_error(
array(
'data' => 'Failed',
'status' => false,
)
);
}
}
}
}

View File

@@ -0,0 +1,104 @@
<?php
/**
* Initialize Setup.
*
* @package {{package}}
* @since 0.0.1
*/
namespace Gutenberg_Templates\Inc\Api;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Api\Api_Base;
use Gutenberg_Templates\Inc\Importer\Plugin;
use Gutenberg_Templates\Inc\Importer\Sync_Library;
/**
* Progress
*
* @since 0.0.1
*/
class Initialize_Setup extends Api_Base {
use Instance;
/**
* Route base.
*
* @var string
*/
protected $rest_base = '/setup/';
/**
* Init Hooks.
*
* @since 0.0.1
* @return void
*/
public function register_routes() {
$namespace = $this->get_api_namespace();
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'setup_templates' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
),
)
);
}
/**
* Check whether a given request has permission to read notes.
*
* @param object $request WP_REST_Request Full details about the request.
* @return object|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
return new \WP_Error(
'gt_rest_cannot_access',
__( 'Sorry, you are not allowed to do that.', 'astra-sites' ),
array( 'status' => rest_authorization_required_code() )
);
}
return true;
}
/**
* Save Prompts.
*
* @param \WP_REST_Request $request Full details about the request.
* @return \WP_REST_Response
*/
public function setup_templates( $request ) {
$is_fresh_site = get_option( 'ast_block_templates_fresh_site', 'yes' );
if ( 'yes' === $is_fresh_site ) {
Sync_Library::instance()->set_default_assets();
update_option( 'ast_block_templates_fresh_site', 'no' );
}
Sync_Library::instance()->process_sync();
$response = new \WP_REST_Response(
array(
'success' => true,
'syncing' => $is_fresh_site,
)
);
$response->set_status( 200 );
return $response;
}
}

View File

@@ -0,0 +1,176 @@
<?php
/**
* Keywords API.
*
* @package {{package}}
* @since 2.0.0
*/
namespace Gutenberg_Templates\Inc\Api;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Api\Api_Base;
use Gutenberg_Templates\Inc\Importer\Importer_Helper;
/**
* Progress
*
* @since 2.0.0
*/
class Keywords extends Api_Base {
use Instance;
/**
* Route base.
*
* @var string
*/
protected $rest_base = '/keywords/';
/**
* Init Hooks.
*
* @since 2.0.0
* @return void
*/
public function register_routes() {
$namespace = $this->get_api_namespace();
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array( $this, 'get' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'business_name' => array(
'type' => 'string',
'required' => true,
'sanitize_callback' => 'sanitize_text_field',
),
'business_description' => array(
'type' => 'string',
'required' => false,
'sanitize_callback' => 'sanitize_text_field',
),
'category' => array(
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
'required' => false,
),
),
),
)
);
}
/**
* Check whether a given request has permission to read notes.
*
* @param object $request WP_REST_Request Full details about the request.
* @return object|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
return new \WP_Error(
'gt_rest_cannot_access',
__( 'Sorry, you are not allowed to do that.', 'astra-sites' ),
array( 'status' => rest_authorization_required_code() )
);
}
return true;
}
/**
* Save Prompts.
*
* @param \WP_REST_Request $request Full details about the request.
* @return mixed
*/
public function get( $request ) {
$nonce = (string) $request->get_header( 'X-WP-Nonce' );
// Verify the nonce.
if ( ! wp_verify_nonce( sanitize_text_field( $nonce ), 'wp_rest' ) ) {
wp_send_json_error(
array(
'data' => __( 'Nonce verification failed.', 'astra-sites' ),
'status' => false,
)
);
}
$api_endpoint = AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/ai/v1/keywords';
$token = Importer_Helper::get_business_details( 'token' );
$post_data = array(
'business_name' => isset( $request['business_name'] ) ? sanitize_text_field( $request['business_name'] ) : '',
'business_description' => isset( $request['business_description'] ) ? sanitize_text_field( $request['business_description'] ) : '',
'category' => isset( $request['category'] ) ? sanitize_text_field( $request['category'] ) : '',
'token' => $token,
);
$body = wp_json_encode( $post_data );
$request_args = array(
'body' => is_string( $body ) ? $body : '',
'headers' => array(
'Content-Type' => 'application/json',
),
'timeout' => 100,
);
$response = wp_safe_remote_post( $api_endpoint, $request_args );
if ( is_wp_error( $response ) ) {
// There was an error in the request.
wp_send_json_error(
array(
'data' => 'Failed ' . $response->get_error_message(),
'status' => false,
)
);
} else {
$response_code = wp_remote_retrieve_response_code( $response );
$response_body = wp_remote_retrieve_body( $response );
if ( 200 === $response_code ) {
$response_data = json_decode( $response_body, true );
if ( $response_data['status'] ) {
wp_send_json_success(
array(
'data' => $response_data['data'],
'status' => true,
)
);
} else {
wp_send_json_error(
array(
'data' => 'Failed ' . $response_data['data'],
'status' => false,
)
);
}
} else {
wp_send_json_error(
array(
'data' => 'Failed',
'status' => false,
)
);
}
}
}
}

View File

@@ -0,0 +1,190 @@
<?php
/**
* PageDescription API.
*
* @package {{package}}
* @since 2.0.16
*/
namespace Gutenberg_Templates\Inc\Api;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Api\Api_Base;
use Gutenberg_Templates\Inc\Importer\Importer_Helper;
/**
* Progress
*
* @since 2.0.16
*/
class PageDescription extends Api_Base {
use Instance;
/**
* Route base.
*
* @var string
*/
protected $rest_base = '/page-description/';
/**
* Init Hooks.
*
* @since 2.0.16
* @return void
*/
public function register_routes() {
$namespace = $this->get_api_namespace();
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array( $this, 'get' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'business_name' => array(
'type' => 'string',
'required' => true,
'sanitize_callback' => 'sanitize_text_field',
),
'business_description' => array(
'type' => 'string',
'required' => false,
'sanitize_callback' => 'sanitize_text_field',
),
'page_name' => array(
'type' => 'string',
'required' => true,
'sanitize_callback' => 'sanitize_text_field',
),
'page_description' => array(
'type' => 'string',
'required' => false,
'sanitize_callback' => 'sanitize_text_field',
),
'category' => array(
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
'required' => false,
),
),
),
)
);
}
/**
* Check whether a given request has permission to read notes.
*
* @param object $request WP_REST_Request Full details about the request.
* @return object|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
return new \WP_Error(
'gt_rest_cannot_access',
__( 'Sorry, you are not allowed to do that.', 'astra-sites' ),
array( 'status' => rest_authorization_required_code() )
);
}
return true;
}
/**
* Save Prompts.
*
* @param \WP_REST_Request $request Full details about the request.
* @return mixed
*/
public function get( $request ) {
$nonce = (string) $request->get_header( 'X-WP-Nonce' );
// Verify the nonce.
if ( ! wp_verify_nonce( sanitize_text_field( $nonce ), 'wp_rest' ) ) {
wp_send_json_error(
array(
'data' => __( 'Nonce verification failed.', 'astra-sites' ),
'status' => false,
)
);
}
$api_endpoint = AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/ai/v1/page-description';
$token = Importer_Helper::get_business_details( 'token' );
$post_data = array(
'business_name' => isset( $request['business_name'] ) ? sanitize_text_field( $request['business_name'] ) : '',
'business_description' => isset( $request['business_description'] ) ? sanitize_text_field( $request['business_description'] ) : '',
'page_name' => isset( $request['page_name'] ) ? sanitize_text_field( $request['page_name'] ) : '',
'page_description' => isset( $request['page_description'] ) ? sanitize_text_field( $request['page_description'] ) : '',
'category' => isset( $request['category'] ) ? sanitize_text_field( $request['category'] ) : '',
'token' => $token,
);
$body = wp_json_encode( $post_data );
$request_args = array(
'body' => is_string( $body ) ? $body : '',
'headers' => array(
'Content-Type' => 'application/json',
),
'timeout' => 100,
);
$response = wp_safe_remote_post( $api_endpoint, $request_args );
if ( is_wp_error( $response ) ) {
// There was an error in the request.
wp_send_json_error(
array(
'data' => 'Failed ' . $response->get_error_message(),
'status' => false,
)
);
} else {
$response_code = wp_remote_retrieve_response_code( $response );
$response_body = wp_remote_retrieve_body( $response );
if ( 200 === $response_code ) {
$response_data = json_decode( $response_body, true );
if ( $response_data['status'] ) {
wp_send_json_success(
array(
'data' => $response_data['data'],
'status' => true,
)
);
} else {
wp_send_json_error(
array(
'data' => 'Failed ' . $response_data['data'],
'status' => false,
)
);
}
} else {
wp_send_json_error(
array(
'data' => 'Failed',
'status' => false,
)
);
}
}
}
}

View File

@@ -0,0 +1,97 @@
<?php
/**
* Pages generate content confirmation API.
*
* @package {{package}}
* @since 0.0.1
*/
namespace Gutenberg_Templates\Inc\Api;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Api\Api_Base;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;
/**
* Pages generate content confirmation.
*
* @since 0.0.1
*/
class Pages extends Api_Base {
use Instance;
/**
* Route base.
*
* @var string
*/
protected $rest_base = '/pages-onboarding/';
/**
* Init Hooks.
*
* @since 0.0.1
* @return void
*/
public function register_routes() {
$namespace = $this->get_api_namespace();
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array( $this, 'set' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
),
)
);
}
/**
* Check whether a given request has permission to read notes.
*
* @param object $request WP_REST_Request Full details about the request.
* @return object|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
return new WP_Error(
'gt_rest_cannot_access',
__( 'Sorry, you are not allowed to do that.', 'astra-sites' ),
array( 'status' => rest_authorization_required_code() )
);
}
return true;
}
/**
* Save the pages onboarding flag status.
*
* @return WP_REST_Response
*/
public function set(): WP_REST_Response {
$saved = update_option( 'ast-show-pages-onboarding', 'no' );
$response = new WP_REST_Response(
array(
'success' => $saved,
)
);
$response->set_status( 200 );
return $response;
}
}

View File

@@ -0,0 +1,113 @@
<?php
/**
* Revoke Access API.
*
* @package {{package}}
* @since 0.0.1
*/
namespace Gutenberg_Templates\Inc\Api;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Api\Api_Base;
use Gutenberg_Templates\Inc\Traits\Helper;
use WP_Error;
use WP_REST_Response;
use WP_REST_Server;
/**
* Pages generate content confirmation.
*
* @since 0.0.1
*/
class RevokeAccess extends Api_Base {
use Instance;
/**
* Route base.
*
* @var string
*/
protected $rest_base = '/revoke-access/';
/**
* Init Hooks.
*
* @since 0.0.1
* @return void
*/
public function register_routes() {
$namespace = $this->get_api_namespace();
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array( $this, 'set' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
),
)
);
}
/**
* Check whether a given request has permission to read notes.
*
* @param object $request WP_REST_Request Full details about the request.
* @return object|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
return new WP_Error(
'gt_rest_cannot_access',
__( 'Sorry, you are not allowed to do that.', 'astra-sites' ),
array( 'status' => rest_authorization_required_code() )
);
}
return true;
}
/**
* Revoke access.
*
* @param \WP_REST_Request $request Full details about the request.
* @return WP_REST_Response
*/
public function set( $request ): WP_REST_Response {
$nonce = $request->get_header( 'X-WP-Nonce' );
$nonce = isset( $nonce ) ? sanitize_text_field( $nonce ) : '';
// Verify the nonce.
if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
wp_send_json_error(
array(
'data' => __( 'Nonce verification failed.', 'astra-sites' ),
'status' => false,
)
);
}
delete_option( 'ast-block-templates-show-onboarding' );
Helper::delete_admin_settings_option( 'zip_ai_settings' );
$response = new WP_REST_Response(
array(
'success' => true,
)
);
$response->set_status( 200 );
return $response;
}
}

View File

@@ -0,0 +1,186 @@
<?php
/**
* Settings API.
*
* @package {{package}}
* @since 2.0.0
*/
namespace Gutenberg_Templates\Inc\Api;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Api\Api_Base;
use Gutenberg_Templates\Inc\Importer\Plugin;
/**
* Settings
*
* @since 2.0.0
*/
class Settings extends Api_Base {
use Instance;
/**
* Route base.
*
* @var string
*/
protected $rest_base = '/settings/';
/**
* Init Hooks.
*
* @since 2.0.0
* @return void
*/
public function register_routes() {
$namespace = $this->get_api_namespace();
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
),
)
);
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array( $this, 'save' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'key' => array(
'type' => 'string',
'required' => true,
),
'value' => array(
'type' => 'boolean',
'required' => true,
),
),
),
)
);
}
/**
* Check whether a given request has permission to read notes.
*
* @param object $request WP_REST_Request Full details about the request.
* @return object|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
return new \WP_Error(
'gt_rest_cannot_access',
__( 'Sorry, you are not allowed to do that.', 'astra-sites' ),
array( 'status' => rest_authorization_required_code() )
);
}
return true;
}
/**
* Get Settings.
*
* @param \WP_REST_Request $request Full details about the request.
* @return mixed
*/
public function get( $request ) {
$ai_settings = get_option( 'ast_block_templates_ai_settings', array() );
$response = new \WP_REST_Response(
array(
'success' => true,
'data' => $ai_settings,
)
);
$response->set_status( 200 );
return $response;
}
/**
* Save Settings.
*
* @param \WP_REST_Request $request Full details about the request.
* @return mixed
*/
public function save( $request ) {
$nonce = (string) $request->get_header( 'X-WP-Nonce' );
// Verify the nonce.
if ( ! wp_verify_nonce( sanitize_text_field( $nonce ), 'wp_rest' ) ) {
wp_send_json_error(
array(
'data' => __( 'Nonce verification failed.', 'astra-sites' ),
'status' => false,
)
);
}
$setting_key = $request->get_param( 'key' );
$setting_value = $request->get_param( 'value' );
if ( ! empty( $setting_key ) ) {
$settings = get_option( 'ast_block_templates_ai_settings', array() );
$settings[ $setting_key ] = $setting_value;
if ( 'disable_ai' === $setting_key ) {
$ai_settings = get_option( 'zip_ai_modules', array() );
$ai_copilot_value = $setting_value ? 'disabled' : 'enabled';
$ai_settings['ai_design_copilot']['status'] = $ai_copilot_value;
update_option( 'zip_ai_modules', $ai_settings );
$settings['disable_ai'] = $setting_value;
}
if ( 'adaptive_mode' === $setting_key ) {
$ai_settings = get_option( 'zip_ai_modules', array() );
$ai_copilot_value = $setting_value ? 'enabled' : 'disabled';
$ai_settings['ai_design_copilot']['status'] = $ai_copilot_value;
update_option( 'zip_ai_modules', $ai_settings );
$settings['disable_ai'] = ! $setting_value;
}
$status = update_option( 'ast_block_templates_ai_settings', $settings );
$blocks = Plugin::instance()->get_all_blocks();
$response = new \WP_REST_Response(
array(
'success' => $status,
'blocks' => $blocks,
)
);
$response->set_status( 200 );
return $response;
}
return new \WP_Error(
'failed',
__( 'Sorry, settings are not saved.', 'astra-sites' ),
array( 'status' => 'fail' )
);
}
}

View File

@@ -0,0 +1,109 @@
<?php
/**
* Progress API.
*
* @package {{package}}
* @since 0.0.1
*/
namespace Gutenberg_Templates\Inc\Api;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Importer\Plugin;
use Gutenberg_Templates\Inc\Api\Api_Base;
/**
* Progress
*
* @since 0.0.1
*/
class Sites extends Api_Base {
use Instance;
/**
* Route base.
*
* @var string
*/
protected $rest_base = '/sites/';
/**
* Init Hooks.
*
* @since 0.0.1
* @return void
*/
public function register_routes() {
$namespace = $this->get_api_namespace();
register_rest_route(
$namespace,
$this->rest_base,
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get_sites' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
),
)
);
}
/**
* Check whether a given request has permission to read notes.
*
* @param object $request WP_REST_Request Full details about the request.
* @return object|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
return new \WP_Error(
'gt_rest_cannot_access',
__( 'Sorry, you are not allowed to do that.', 'astra-sites' ),
array( 'status' => rest_authorization_required_code() )
);
}
return true;
}
/**
* Save Prompts.
*
* @param \WP_REST_Request $request Full details about the request.
* @return \WP_REST_Response
*/
public function get_sites( $request ) {
$nonce = (string) $request->get_header( 'X-WP-Nonce' );
// Verify the nonce.
if ( ! wp_verify_nonce( sanitize_text_field( $nonce ), 'wp_rest' ) ) {
return new \WP_REST_Response(
array(
'success' => false,
'data' => __( 'Nonce verification failed.', 'astra-sites' ),
),
403
);
}
$all_sites = Plugin::instance()->get_all_sites();
$response = new \WP_REST_Response(
array(
'success' => true,
'sites' => $all_sites,
)
);
$response->set_status( 200 );
return $response;
}
}

View File

@@ -0,0 +1,8 @@
{
"apiVersion": 3,
"title": "Spectra AI",
"name": "gutenberg-templates/spectra-ai",
"category": "layout",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css"
}

View File

@@ -0,0 +1 @@
<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-i18n'), 'version' => 'f9a7230af2d27cbc398e');

View File

@@ -0,0 +1 @@
:root{--ast-spectra-ai-primary: #0073aa;--ast-spectra-ai-primary-hover: #007cba;--ast-spectra-ai-primary-text: #fff;--ast-spectra-ai-heading-text: #030712;--ast-spectra-ai-text: #374151;--ast-spectra-ai-icon-active: #111827;--ast-spectra-ai-icon-inactive: #374151}.spectra-ai-block-layout{font-family:Inter,sans-serif}.spectra-ai-block-layout.block-wrapper{width:100%;max-width:544px !important;padding:32px;border-radius:5px;display:flex;flex-direction:column;gap:32px}.spectra-ai-block-layout.block-wrapper:hover{box-shadow:none}.spectra-ai-block-layout .block-heading-wrapper{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:12px}.spectra-ai-block-layout .block-title{font-size:24px;font-weight:600;line-height:33.6px;text-align:center;margin:0 !important;padding:0 !important;color:var(--ast-spectra-ai-heading-text)}.spectra-ai-block-layout .block-description{font-size:16px;font-weight:400;line-height:24px;text-align:center;margin:0 !important;padding:0 !important;color:var(--ast-spectra-ai-text)}.spectra-ai-block-layout .block-button{font-size:16px;font-weight:500;line-height:24px;padding:8px 20px;border-radius:4px;display:flex;align-items:center;justify-content:center;gap:8px;transition:color .15s ease-in-out}.spectra-ai-block-layout .block-button.prefix-icon{padding-left:12px}.spectra-ai-block-layout .button-icon{width:24px;height:24px}.spectra-ai-block-layout .button-primary{background-color:var(--ast-spectra-ai-primary);border-color:var(--ast-spectra-ai-primary);color:var(--ast-spectra-ai-primary-text)}.spectra-ai-block-layout .button-primary:hover{background-color:var(--ast-spectra-ai-primary-hover);border:1px solid var(--ast-spectra-ai-primary-hover);color:var(--ast-spectra-ai-primary-text)}.spectra-ai-block-layout .button-secondary{background-color:#fff;color:var(--ast-spectra-ai-primary);border:1px solid var(--ast-spectra-ai-primary)}.spectra-ai-block-layout .button-secondary:hover{background-color:#fff;color:var(--ast-spectra-ai-primary-hover);border:1px solid var(--ast-spectra-ai-primary-hover)}.spectra-ai-block-layout .block-buttons{display:flex;align-items:center;justify-content:center;gap:16px}.spectra-ai-block-layout .close-button{position:absolute;top:16px;right:16px;width:24px;height:24px;cursor:pointer;border:none;outline:none;background:none;color:var(--ast-spectra-ai-icon-inactive);transition:color .15s ease-in-out}.spectra-ai-block-layout .close-button:hover{color:var(--ast-spectra-ai-icon-active)}.spectra-ai-block-layout .close-button .close-button-icon{width:24px;height:24px}.spectra-ai-block-layout+.block-list-appender .block-editor-default-block-appender{display:none !important}

View File

@@ -0,0 +1 @@
(()=>{"use strict";const e=window.wp.blocks,t=window.wp.blockEditor,a=window.wp.i18n,l=window.React;function n({title:e,titleId:t,...a},n){return l.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor","aria-hidden":"true","data-slot":"icon",ref:n,"aria-labelledby":t},a),e?l.createElement("title",{id:t},e):null,l.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9.813 15.904 9 18.75l-.813-2.846a4.5 4.5 0 0 0-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 0 0 3.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 0 0 3.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 0 0-3.09 3.09ZM18.259 8.715 18 9.75l-.259-1.035a3.375 3.375 0 0 0-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 0 0 2.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 0 0 2.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 0 0-2.456 2.456ZM16.894 20.567 16.5 21.75l-.394-1.183a2.25 2.25 0 0 0-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 0 0 1.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 0 0 1.423 1.423l1.183.394-1.183.394a2.25 2.25 0 0 0-1.423 1.423Z"}))}const o=l.forwardRef(n);function c({title:e,titleId:t,...a},n){return l.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor","aria-hidden":"true","data-slot":"icon",ref:n,"aria-labelledby":t},a),e?l.createElement("title",{id:t},e):null,l.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18 18 6M6 6l12 12"}))}const r=l.forwardRef(c),s=(()=>{const e={};return Object.seal({on:(t,a)=>{e[t]||(e[t]=[]),e[t].push(a)},emit:(t,...a)=>{const l=e[t];l&&l.forEach((e=>e(...a)))},removeListener:(t,a)=>{const l=e[t];if(l){const e=l.findIndex((e=>e===a));-1!==e&&l.splice(e,1)}},removeAllListeners:t=>{e[t]&&delete e[t]}})})();function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var a=arguments[t];for(var l in a)({}).hasOwnProperty.call(a,l)&&(e[l]=a[l])}return e},i.apply(null,arguments)}const u=JSON.parse('{"UU":"gutenberg-templates/spectra-ai"}');(0,e.registerBlockType)(u.UU,{icon:React.createElement("svg",{width:"32",height:"32",viewBox:"0 0 32 32",fill:"none",xmlns:"http://www.w3.org/2000/svg"},React.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M16 32C24.8366 32 32 24.8366 32 16C32 7.16343 24.8366 0 16 0C7.16343 0 0 7.16343 0 16C0 24.8366 7.16343 32 16 32ZM20.9202 20.688C21.8453 20.1032 22.4 19.1247 22.4 18.0775C22.4 16.6224 21.3376 15.357 19.8308 15.0174L15.3161 13.8968C14.8905 13.8009 14.7885 13.2761 15.1506 13.0452L18.6679 10.8017C20.3051 9.75739 20.7308 7.66455 19.6187 6.12718C19.4797 5.93499 19.2011 5.88503 18.9964 6.01559L11.0507 11.3753C10.1433 11.9541 9.6 12.9173 9.6 13.9473C9.6 15.3851 10.6496 16.6352 12.1385 16.9708L16.7267 18.108C17.1533 18.2042 17.2544 18.7307 16.8905 18.9607L13.3473 21.2006C11.7055 22.2385 11.2706 24.3297 12.3759 25.8714C12.5141 26.0641 12.7925 26.1152 12.9977 25.9854L20.9202 20.688Z",fill:"var(--colors-accent-spectra)"})),attributes:{isOpen:{type:"boolean",default:!0}},useOnce:!0,supports:{customClassName:!1,className:!1,html:!1},edit:({onReplace:e})=>{const{blockProps:l}=(0,t.useBlockProps)();return React.createElement("div",i({className:"spectra-ai-block-layout block-wrapper border border-solid border-border-primary relative"},l),React.createElement("div",{className:"block-heading-wrapper"},React.createElement("h5",{className:"block-title"},(0,a.__)("Spectra AI Block","astra-sites")),React.createElement("p",{className:"block-description"},(0,a.__)("Eu lectus mauris vulputate et sem consequat ornare. Et consectetur sagittis faucibus eget.","astra-sites"))),React.createElement("div",{className:"block-buttons"},React.createElement("button",{className:"block-button button-primary prefix-icon",onClick:()=>{s.emit("toggle-onboarding-page-ai"),e([])}},React.createElement(o,{className:"button-icon"}),React.createElement("span",null,(0,a.__)("Build using AI","astra-sites"))),React.createElement("button",{className:"block-button button-secondary",onClick:()=>{const t=document.querySelector("#ast-block-templates-button");e([]),t&&t.click()}},React.createElement("span",null,(0,a.__)("Template Kits","astra-sites")))),React.createElement("button",{className:"close-button",onClick:()=>{e([])}},React.createElement(r,{className:"close-button-icon"})))},save:()=>!1})})();

View File

@@ -0,0 +1,157 @@
<?php
/**
* Spectra AI Block.
*
* @package Gutenberg_Templates
*/
namespace Gutenberg_Templates\Inc\Block;
/**
* Spectra_AI_Block
*
* @since 2.0.16
*/
class Spectra_AI_Block {
/**
* Instance
*
* @access private
* @var object Class Instance.
* @since 2.0.16
*/
private static $instance = null;
/**
* Constructor
*
* @since 2.0.16
*/
public function __construct() {
global $wp_version;
$hook = version_compare( $wp_version, '5.8-alpha', '<' ) ? 'block_editor_preload_paths' : 'block_editor_rest_api_preload_paths';
add_action( 'init', array( $this, 'register_block_type' ) );
add_filter( $hook, array( $this, 'update_new_post' ), 10, 2 );
}
/**
* Get Instance
*
* @since 2.0.16
*
* @return object Class object.
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Register Block Type
*
* @since 2.0.16
*
* @return void
*/
public function register_block_type() {
register_block_type( AST_BLOCK_TEMPLATES_DIR . '/block/dist' );
}
/**
* Add the block on new page creation.
*
* @since 2.0.16
*
* @param array<string, string> $paths Array of preload paths.
* @param mixed $context Context of the request.
*
* @return array<string, string>
*/
public static function update_new_post( $paths, $context ) {
if ( ! is_object( $context ) || ! property_exists( $context, 'post' ) ) {
return $paths;
}
$post = $context->post;
if ( ! is_object( $post ) || ! property_exists( $post, 'ID' ) || ! property_exists( $post, 'post_content' ) ) {
return $paths;
}
if ( ! is_string( $post->post_content ) ) {
return $paths;
}
$blocks = preg_match( '/<!-- wp:(.*) \/?-->/', $post->post_content );
if ( ! $blocks ) {
$block = '<!-- wp:gutenberg-templates/spectra-ai -->';
$block .= self::remove_broken_p_tags( $post->post_content );
$block .= '<!-- /wp:gutenberg-templates/spectra-ai -->';
$post->post_content = $block;
wp_update_post(
array(
'ID' => $post->ID,
'post_content' => $block,
)
);
}
return $paths;
}
/**
* Remove broken p tags.
*
* @since 2.0.16
*
* @param string $content Post content.
*
* @return string
*/
public static function remove_broken_p_tags( $content ) {
if ( ! is_string( $content ) ) {
return '';
}
// Convert microsoft special characters.
$replace = array(
'' => "'",
'' => "'",
'”' => '"',
'“' => '"',
'' => '-',
'—' => '-',
'…' => '&#8230;',
);
// Remove empty tags.
$content = preg_replace( '@<([^>]+)\s*>\s*<\/\1\s*>@m', '', $content );
// Remove all <p> tags.
$content = preg_replace( '/<\/?p[^>]*\>/i', '', $content ?? '' );
// Replace special characters.
foreach ( $replace as $k => $v ) {
$content = str_replace( $k, $v, $content ?? '' );
}
// Balance tags.
$content = force_balance_tags( $content );
return $content;
}
}
/**
* Kicking this off by calling 'get_instance()' method.
*/
Spectra_AI_Block::get_instance();

View File

@@ -0,0 +1,118 @@
<?php
/**
* Ast BlockTemplates
*
* @since 2.2.4
* @package Astra Sites
*/
namespace Gutenberg_Templates\Inc\Classes;
use Gutenberg_Templates\Inc\Traits\Instance;
if ( ! class_exists( 'Ast_Block_Templates_Notices' ) ) :
/**
* Ast BlockTemplates
*/
class Ast_Block_Templates_Notices {
use Instance;
/**
* Check file read/write permissions and process.
*
* @since 2.2.4
* @return bool
*/
public function has_file_read_write() {
if ( defined( 'WP_CLI' ) && WP_CLI ) {
return true;
}
$upload_dir = self::log_dir();
$file_created = self::get_filesystem()->put_contents( $upload_dir['path'] . 'index.html', '' );
if ( ! $file_created ) {
add_action( 'admin_notices', array( $this, 'file_permission_notice' ) );
return false;
}
return true;
}
/**
* File Permission Notice
*
* @since 2.0.0
* @return void
*/
public function file_permission_notice() {
$notice = __( 'File Permissions Needed - Importing patterns, pages, and templates from Design Library requires proper file permissions. For guidance on resolving this issue and ensuring smooth importing processes, please refer to the accompanying documentation.', 'astra-sites' );
?>
<div class="notice notice-error ast-block-templates-must-notices ast-block-templates-file-permission-issue">
<p><?php echo esc_html( $notice ); ?></p>
<p><?php echo esc_html( __( 'Doc: ', 'astra-sites' ) ); ?><a href="https://wpastra.com/docs/could-not-store-files-in-wp-content-folder/" target="__blank"><?php echo esc_html( __( 'Resolve file permission issue', 'astra-sites' ) ); ?></a></p>
</div>
<?php
}
/**
* Get an instance of WP_Filesystem_Direct.
*
* @since 2.0.0
* @return mixed A WP_Filesystem_Direct instance.
*/
public static function get_filesystem() {
global $wp_filesystem;
require_once ABSPATH . '/wp-admin/includes/file.php';
WP_Filesystem();
return $wp_filesystem;
}
/**
* Log file directory
*
* @since 2.2.4
* @param string $dir_name Directory Name.
* @return array<string, string> Uploads directory array.
*/
public static function log_dir( $dir_name = 'ast-block-templates-json' ) {
$upload_dir = wp_upload_dir();
// Build the paths.
$dir_info = array(
'path' => $upload_dir['basedir'] . '/' . $dir_name . '/',
'url' => $upload_dir['baseurl'] . '/' . $dir_name . '/',
);
// Create the upload dir if it doesn't exist.
if ( ! file_exists( $dir_info['path'] ) ) {
// Create the directory.
wp_mkdir_p( $dir_info['path'] );
// Add an index file for security.
self::get_filesystem()->put_contents( $dir_info['path'] . 'index.html', '' );
// Add an .htaccess for security.
self::get_filesystem()->put_contents( $dir_info['path'] . '.htaccess', 'deny from all' );
}
return $dir_info;
}
}
/**
* Kicking this off by calling 'get_instance()' method
*/
Ast_Block_Templates_Notices::instance();
endif;

View File

@@ -0,0 +1,249 @@
<?php
/**
* Handle ZipWP API calls.
*
* @package {{package}}
* @since {{since}}
*/
namespace Gutenberg_Templates\Inc\Classes;
use Gutenberg_Templates\Inc\Traits\Helper;
use Gutenberg_Templates\Inc\Traits\Instance;
/**
* AST Block Templates ZipWP API
*
* @since {{since}}
*/
class Ast_Block_Templates_Zipwp_Api {
use Instance;
/**
* Constructor
*
* @since 2.1.13
*/
public function __construct() {
add_action( 'rest_api_init', array( $this, 'register_route' ) );
}
/**
* Get api domain
*
* @since 2.1.13
* @return string
*/
public function get_api_domain() {
return ( defined( 'ZIPWP_API' ) ? ZIPWP_API : 'https://api.zipwp.com/api/' );
}
/**
* Get API headers
*
* @since 2.1.13
* @return array<string, string>
*/
public function get_api_headers() {
return array(
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . Helper::decrypt( Helper::get_setting( 'zip_token' ) ),
);
}
/**
* Get api namespace
*
* @since 2.1.13
* @return string
*/
public function get_api_namespace() {
return 'zipwp/v1';
}
/**
* Check whether a given request has permission to read notes.
*
* @param object $request WP_REST_Request Full details about the request.
* @return object|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
return new \WP_Error(
'gt_rest_cannot_access',
__( 'Sorry, you are not allowed to do that.', 'astra-sites' ),
array( 'status' => rest_authorization_required_code() )
);
}
return true;
}
/**
* Register route
*
* @since 2.1.13
* @return void
*/
public function register_route() {
$namespace = $this->get_api_namespace();
register_rest_route(
$namespace,
'/search-category/',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array( $this, 'search_business_category' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'keyword' => array(
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
'required' => true,
),
),
),
)
);
register_rest_route(
$namespace,
'/site-languages/',
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get_site_languages' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
),
)
);
}
/**
* Search business category.
*
* @param \WP_REST_Request $request Full details about the request.
* @return mixed
*/
public function search_business_category( $request ) {
$nonce = (string) $request->get_header( 'X-WP-Nonce' );
// Verify the nonce.
if ( ! wp_verify_nonce( sanitize_text_field( $nonce ), 'wp_rest' ) ) {
wp_send_json_error(
array(
'data' => __( 'Nonce verification failed.', 'astra-sites' ),
'status' => false,
)
);
}
$keyword = $request['keyword'];
$api_endpoint = $this->get_api_domain() . 'sites/business/search?q=' . $keyword;
$request_args = array(
'headers' => $this->get_api_headers(),
'timeout' => 100,
);
$response = wp_safe_remote_get( $api_endpoint, $request_args );
if ( is_wp_error( $response ) ) {
// There was an error in the request.
wp_send_json_error(
array(
'data' => 'Failed ' . $response->get_error_message(),
'status' => false,
)
);
}
$response_code = wp_remote_retrieve_response_code( $response );
$response_body = wp_remote_retrieve_body( $response );
if ( 200 === $response_code ) {
$response_data = json_decode( $response_body, true );
wp_send_json_success(
array(
'data' => $response_data['results'],
'status' => true,
)
);
} else {
wp_send_json_error(
array(
'data' => 'Failed - ' . $response_body,
'status' => false,
)
);
}
}
/**
* Get ZipWP Languages list.
*
* @param \WP_REST_Request $request Full details about the request.
* @return mixed
*/
public function get_site_languages( $request ) {
$nonce = (string) $request->get_header( 'X-WP-Nonce' );
// Verify the nonce.
if ( ! wp_verify_nonce( sanitize_text_field( $nonce ), 'wp_rest' ) ) {
wp_send_json_error(
array(
'data' => __( 'Nonce verification failed.', 'astra-sites' ),
'status' => false,
)
);
}
$api_endpoint = $this->get_api_domain() . 'sites/languages/';
$request_args = array(
'headers' => $this->get_api_headers(),
'timeout' => 100,
);
$response = wp_safe_remote_get( $api_endpoint, $request_args );
if ( is_wp_error( $response ) ) {
// There was an error in the request.
wp_send_json_error(
array(
'data' => 'Failed ' . $response->get_error_message(),
'status' => false,
)
);
}
$response_code = wp_remote_retrieve_response_code( $response );
$response_body = wp_remote_retrieve_body( $response );
if ( 200 === $response_code ) {
$response_data = json_decode( $response_body, true );
if ( $response_data ) {
wp_send_json_success(
array(
'data' => $response_data['data'],
'status' => true,
)
);
}
wp_send_json_error(
array(
'data' => $response_data,
'status' => false,
)
);
}
wp_send_json_error(
array(
'data' => 'Failed ' . $response_body,
'status' => false,
)
);
}
}

View File

@@ -0,0 +1,408 @@
<?php
/**
* Sync Library
*
* @package Ast Block Templates
* @since 1.0.0
*/
namespace Gutenberg_Templates\Inc\Content;
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Importer\Importer_Helper;
use Gutenberg_Templates\Inc\Importer\Plugin;
use Gutenberg_Templates\Inc\Traits\Helper;
use Gutenberg_Templates\Inc\Importer\Images;
/**
* Sync Library
*
* @since 1.0.0
*/
class Ai_Content {
use Instance;
/**
* Constructor
*
* @since 1.0.0
*/
public function __construct() {
$this->define_required_constants();
add_action( 'wp_ajax_ast-block-templates-ai-content', array( $this, 'save_user_details' ) );
add_action( 'wp_ajax_ast-block-templates-regenerate', array( $this, 'generate_ai_content' ) );
add_action( 'wp_ajax_ast-block-templates-reset-business-details', array( $this, 'reset_business_details' ) );
add_action( 'wp_footer', array( $this, 'footer' ) );
add_action( 'ast_templates_download_selected_images', array( $this, 'download_selected_images' ) );
}
/**
* Debug mode for testing.
*
* @return void
*/
public function footer() {
if ( isset( $_GET['debug'] ) && Helper::instance()->is_debug_mode() ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
echo '<xmp>';
print_r( get_option( 'ast_block_ai_content_log', array() ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
print_r( get_option( 'zipwp_user_business_details' ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
echo '</xmp>';
}
}
/**
* Define Required Constants
*
* @since 2.0.0
* @return void
*/
public function define_required_constants() {
define( 'AST_BLOCK_TEMPLATES_IMAGE_COUNT', 20 );
}
/**
* Reset Business details
*
* @since 2.0.0
* @return void
*/
public function reset_business_details() {
// Verify Nonce.
check_ajax_referer( 'ast-block-templates-reset-business-details', 'security' );
delete_option( 'ast-block-templates-show-onboarding' );
delete_option( 'zipwp_user_business_details' );
delete_option( 'ast_block_ai_content_log' );
delete_option( 'ast-templates-ai-content' );
wp_send_json_success(
array(
'status' => true,
)
);
}
/**
* Generate AI based blocks.
*
* @since 2.0.0
* @return void
*/
public function generate_ai_content() {
// Verify Nonce.
check_ajax_referer( 'ast-block-templates-ai-content', 'security' );
$details = Importer_Helper::get_business_details();
$language = 'en';
if ( isset( $details['language'] ) ) {
$language = is_array( $details['language'] ) ? $details['language']['code'] : $details['language'];
}
$post_data = array(
'business_name' => isset( $details['business_name'] ) ? sanitize_text_field( $details['business_name'] ) : '',
'business_description' => isset( $details['business_description'] ) ? sanitize_text_field( $details['business_description'] ) : '',
'business_category' => isset( $details['business_category'] ) ? sanitize_text_field( $details['business_category'] ) : '',
'category' => isset( $_POST['category'] ) ? intval( $_POST['category'] ) : '',
'token' => isset( $details['token'] ) ? $details['token'] : '',
'regenerate' => isset( $_POST['regenerate'] ) ? filter_var( $_POST['regenerate'], FILTER_VALIDATE_BOOLEAN ) : false,
'block_type' => isset( $_POST['block_type'] ) ? sanitize_text_field( $_POST['block_type'] ) : 'block',
'is_last_category' => isset( $_POST['is_last_category'] ) ? filter_var( $_POST['is_last_category'], FILTER_VALIDATE_BOOLEAN ) : false,
'language_slug' => $language,
'language_name' => isset( $details['language']['name'] ) ? sanitize_text_field( $details['language']['name'] ) : '',
);
$category_content = get_option( 'ast-templates-ai-content', array() );
if ( ! $post_data['regenerate'] ) {
if ( isset( $category_content[ $post_data['category'] ] ) ) {
wp_send_json_success(
array(
'data' => $category_content,
'status' => true,
'extra' => 'from club saved already',
'single' => $category_content[ $post_data['category'] ],
'spec_credit_details' => Plugin::instance()->get_spec_credit_details(),
)
);
}
}
$this->get_ai_content( $post_data, $category_content );
}
/**
* Get Club of Category
*
* @since 2.0.0
* @param array<int, array<string, mixed>> $categories Categories.
* @param array<string, mixed> $post_data Post Data.
*
* @return string
*/
public function get_club_of_category( $categories, $post_data ) {
$club_categories = null;
foreach ( $categories as $single_category ) {
if ( $single_category['id'] === $post_data['category'] ) {
$club_categories = $single_category['club'] ?? null;
break;
}
}
return $club_categories;
}
/**
* Get Matching Categories
*
* @since 2.0.0
* @param array<int, array<string, mixed>> $categories Categories.
* @param string $club_categories Club Categories.
*
* @return array<int, array<string, mixed>>
*/
public function get_matching_categories( $categories, $club_categories ) {
$matching_categories = array();
if ( null !== $club_categories ) {
// Find all other categories with the same club.
foreach ( $categories as $single_category ) {
if ( isset( $single_category['club'] ) && $single_category['club'] === $club_categories ) {
$matching_categories[] = $single_category;
}
}
}
return $matching_categories;
}
/**
* Get AI Content
*
* @since 2.0.0
* @param array<string, mixed> $post_data Post Data.
* @param string $category_content Categories content.
*
* @return void
*/
public function get_ai_content( $post_data, $category_content ) {
$api_endpoint = Helper::instance()->is_debug_mode() ? AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/ai/v1/content?debug=yes' : AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/ai/v1/content';
$body = wp_json_encode( $post_data );
$request_args = array(
'body' => is_string( $body ) ? $body : '',
'headers' => array(
'Content-Type' => 'application/json',
),
'timeout' => 50,
);
$response = wp_safe_remote_post( $api_endpoint, $request_args );
$log = get_option( 'ast_block_ai_content_log', array() );
$log[ $post_data['category'] ] = array();
if ( is_wp_error( $response ) ) {
$log[ $post_data['category'] ] = 'Error: ' . $response->get_error_message();
update_option( 'ast_block_ai_content_log', $log );
wp_send_json_error(
array(
'data' => 'Error: ' . $response->get_error_message(),
'status' => false,
)
);
} else {
$response_code = wp_remote_retrieve_response_code( $response );
$response_body = wp_remote_retrieve_body( $response );
$response_data = json_decode( $response_body, true );
if ( 200 === $response_code ) {
if ( $response_data['status'] ) {
if ( ! $post_data['regenerate'] ) {
$categories = Helper::instance()->get_block_template_category();
// Find the club of the current category.
$club = $this->get_club_of_category( $categories, $post_data );
// Find all other categories with the same club.
$matching_categories = $this->get_matching_categories( $categories, $club );
// Save same content for all categories with same club.
foreach ( $matching_categories as $m_category ) {
$category_content[ $m_category['id'] ] = $response_data['content'];
}
$category_content[ $post_data['category'] ] = $response_data['content'];
update_option( 'ast-templates-ai-content', $category_content );
} else {
$category_content[ $post_data['category'] ] = $response_data['content'];
update_option( 'ast-templates-ai-content', $category_content );
}
$log[ $post_data['category'] ] = $response_data['debug'];
update_option( 'ast_block_ai_content_log', $log );
// Set the new user flag to 'no'.
if ( get_option( 'ast-block-templates-new-user', 'yes' ) === 'yes' ) {
update_option( 'ast-block-templates-new-user', 'no' );
}
if ( Helper::instance()->is_debug_mode() ) {
wp_send_json_success(
array(
'data' => $category_content,
'status' => true,
'extra' => $response_data['debug'],
'single' => $category_content[ $post_data['category'] ],
'spec_credit_details' => Plugin::instance()->get_spec_credit_details(),
)
);
} else {
wp_send_json_success(
array(
'data' => $category_content,
'status' => true,
'spec_credit_details' => Plugin::instance()->get_spec_credit_details(),
)
);
}
} else {
$log[ $post_data['category'] ] = $response_data['data'];
update_option( 'ast_block_ai_content_log', $log );
wp_send_json_error(
array(
'data' => 'Failed ' . $response_data['data'],
'status' => false,
)
);
}
} else {
$log[ $post_data['category'] ] = $response_code . ' - Failed';
update_option( 'ast_block_ai_content_log', $log );
wp_send_json_error(
array(
'data' => 'Failed',
'status' => false,
'code' => $response_data['code'],
'error' => $response_data['message'],
)
);
}
}
}
/**
* Save user details
*
* @since 2.0.0
* @return void
*/
public function save_user_details() {
// Verify Nonce.
check_ajax_referer( 'ast-block-templates-ai-content', 'security' );
$keywords = isset( $_POST['image_keyword'] ) ? json_decode( wp_unslash( $_POST['image_keyword'] ), true ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$images = isset( $_POST['images'] ) ? json_decode( wp_unslash( $_POST['images'] ), true ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$social_profiles = isset( $_POST['social_profiles'] ) ? json_decode( wp_unslash( $_POST['social_profiles'] ), true ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$save_only = isset( $_POST['save_only'] ) ? filter_var( $_POST['save_only'], FILTER_VALIDATE_BOOLEAN ) : false;
foreach ( $keywords as $key => $keyword ) {
$keywords[ $key ] = sanitize_text_field( wp_unslash( $keyword ) );
}
if ( ! empty( $images ) ) {
foreach ( $images as $key => $image ) {
foreach ( $image as $j => $image_attr ) {
switch ( $image_attr ) {
case 'author_name':
case 'orientation':
case 'author_url':
case 'description':
case 'engine':
case 'id':
$images[ $key ][ $image_attr ] = sanitize_text_field( wp_unslash( $image_attr ) );
break;
case 'engine_url':
case 'author_url':
case 'optimized_url':
case 'url':
$images[ $key ][ $image_attr ] = esc_url_raw( wp_unslash( $image_attr ) );
break;
}
}
}
}
$language = isset( $_POST['language'] ) ? json_decode( wp_unslash( $_POST['language'] ), true ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$business_details = get_option( 'zipwp_user_business_details', array() );
$business_details['business_name'] = isset( $_POST['business_name'] ) ? sanitize_text_field( wp_unslash( $_POST['business_name'] ) ) : '';
$business_details['business_description'] = isset( $_POST['business_desc'] ) ? sanitize_text_field( wp_unslash( $_POST['business_desc'] ) ) : '';
$business_details['business_category'] = isset( $_POST['business_category'] ) ? sanitize_text_field( wp_unslash( $_POST['business_category'] ) ) : '';
$business_details['images'] = $images;
$business_details['image_keyword'] = $keywords;
$business_details['business_address'] = ( isset( $_POST['business_address'] ) ) ? sanitize_text_field( wp_unslash( $_POST['business_address'] ) ) : '';
$business_details['business_phone'] = ( isset( $_POST['business_phone'] ) ) ? sanitize_text_field( wp_unslash( $_POST['business_phone'] ) ) : '';
$business_details['business_email'] = ( isset( $_POST['business_email'] ) ) ? sanitize_email( wp_unslash( $_POST['business_email'] ) ) : '';
$business_details['social_profiles'] = $social_profiles;
$business_details['language'] = $language;
update_option( 'ast-block-templates-show-onboarding', 'no' );
update_option( 'zipwp_user_business_details', $business_details );
if ( ! $save_only ) {
delete_option( 'ast-templates-ai-content' );
}
// Schedule event to download images in background.
wp_schedule_single_event( time() + 1, 'ast_templates_download_selected_images' );
wp_send_json_success(
array(
'status' => true,
'images' => $images,
)
);
}
/**
* Download Selected Images
*
* @since 2.0.17
*
* @return void
*/
public function download_selected_images() {
$image = get_option( 'zipwp_user_business_details', array() );
$all_images = isset( $image['images'] ) ? $image['images'] : array();
if ( empty( $all_images ) ) {
return;
}
$images = $all_images;
$downloaded_ids = array();
foreach ( $images as $image ) {
$image = array(
'url' => $image['url'],
'id' => $image['id'],
'description' => $image['description'],
'engine' => $image['engine'],
);
$image_id = Images::instance()->download_image( $image );
$downloaded_ids[ $image['id'] ] = $image_id;
}
update_option( 'ast_block_downloaded_images', $downloaded_ids );
}
}

View File

@@ -0,0 +1,466 @@
<?php
/**
* AI content generator and replacer file.
*
* @package {{package}}
* @since {{since}}
*/
namespace Gutenberg_Templates\Inc\Importer;
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Traits\Helper;
use Gutenberg_Templates\Inc\Importer\Importer_Helper;
use Gutenberg_Templates\Inc\Importer\Images;
/**
* Block Editor Blocks Replacer
*
* @since {{since}}
*/
class BlockEditor {
use Instance;
/**
* Constructor
*
* @since {{since}}
*/
public function __construct() {}
/**
* Old Images
*
* @var array<int> $old_images Old images.
*/
public static $old_images = array();
/**
* Parses images and other content in the Spectra Container block.
*
* @since {{since}}
* @param array<mixed> $block Block.
* @return array<mixed> $block Block.
*/
public function parse_spectra_container( $block ) {
if (
! isset( $block['attrs']['backgroundImageDesktop'] ) ||
empty( $block['attrs']['backgroundImageDesktop'] ) ||
Importer_Helper::is_skipable( $block['attrs']['backgroundImageDesktop']['url'] )
) {
return $block;
}
$image = Images::instance()->get_image( Images::$image_index );
if ( empty( $image ) || ! is_array( $image ) ) {
return $block;
}
$image = Images::instance()->download_image( $image );
if ( is_wp_error( $image ) ) {
Helper::instance()->ast_block_templates_log( 'Replacing Image problem : ' . $block['attrs']['backgroundImageDesktop']['url'] . ' Warning: ' . wp_json_encode( $image ) );
return $block;
}
$attachment = wp_prepare_attachment_for_js( absint( $image ) );
if ( ! is_array( $attachment ) ) {
return $block;
}
self::$old_images[] = $block['attrs']['backgroundImageDesktop']['id'];
Helper::instance()->ast_block_templates_log( 'Replacing Image from ' . $block['attrs']['backgroundImageDesktop']['url'] . 'to "' . $attachment['url'] . '" for ' . $block['blockName'] . '" with index "' . Images::$image_index . '"' );
$block['attrs']['backgroundImageDesktop'] = $attachment;
Images::$image_index++;
return $block;
}
/**
* Parses images and other content in the Spectra Info Box block.
*
* @since {{since}}
* @param array<mixed> $block Block.
* @return array<mixed> $block Block.
*/
public function parse_spectra_infobox( $block ) {
if (
! isset( $block['attrs']['iconImage'] ) ||
empty( $block['attrs']['iconImage'] ) ||
Importer_Helper::is_skipable( $block['attrs']['iconImage']['url'] )
) {
return $block;
}
$image = Images::instance()->get_image( Images::$image_index );
if ( empty( $image ) || ! is_array( $image ) ) {
return $block;
}
$image = Images::instance()->download_image( $image );
if ( is_wp_error( $image ) ) {
Helper::instance()->ast_block_templates_log( 'Replacing Image problem : ' . $block['attrs']['iconImage']['url'] . ' Warning: ' . wp_json_encode( $image ) );
return $block;
}
$attachment = wp_prepare_attachment_for_js( absint( $image ) );
if ( ! is_array( $attachment ) ) {
return $block;
}
self::$old_images[] = $block['attrs']['iconImage']['id'];
if ( ! empty( $block['attrs']['iconImage']['url'] ) ) {
Helper::instance()->ast_block_templates_log( 'Replacing Image from ' . $block['attrs']['iconImage']['url'] . ' to "' . $attachment['url'] . '" for ' . $block['blockName'] . '" with index "' . Images::$image_index . '"' );
$block['innerHTML'] = str_replace( $block['attrs']['iconImage']['url'], $attachment['url'], $block['innerHTML'] );
}
foreach ( $block['innerContent'] as $key => &$inner_content ) {
if ( is_string( $block['innerContent'][ $key ] ) && '' === trim( $block['innerContent'][ $key ] ) ) {
continue;
}
$block['innerContent'][ $key ] = str_replace( $block['attrs']['iconImage']['url'], $attachment['url'], $block['innerContent'][ $key ] );
}
$block['attrs']['iconImage'] = $attachment;
Images::$image_index++;
return $block;
}
/**
* Parses images and other content in the Spectra Image block.
*
* @since {{since}}
* @param array<mixed> $block Block.
* @return array<mixed> $block Block.
*/
public function parse_spectra_image( $block ) {
if (
! isset( $block['attrs']['url'] ) ||
Importer_Helper::is_skipable( $block['attrs']['url'] )
) {
return $block;
}
$image = Images::instance()->get_image( Images::$image_index );
if ( empty( $image ) || ! is_array( $image ) ) {
return $block;
}
$image = Images::instance()->download_image( $image );
if ( is_wp_error( $image ) ) {
Helper::instance()->ast_block_templates_log( 'Replacing Image problem : ' . $block['attrs']['url'] . ' Warning: ' . wp_json_encode( $image ) );
return $block;
}
$attachment = wp_prepare_attachment_for_js( absint( $image ) );
if ( ! is_array( $attachment ) ) {
return $block;
}
self::$old_images[] = $block['attrs']['id'];
Helper::instance()->ast_block_templates_log( 'Replacing Image from ' . $block['attrs']['url'] . ' to "' . $attachment['url'] . '" for ' . $block['blockName'] . '" with index "' . Images::$image_index . '"' );
$block['innerHTML'] = str_replace( $block['attrs']['url'], $attachment['url'], $block['innerHTML'] );
$block['innerHTML'] = str_replace( $block['attrs']['id'], (string) $attachment['id'], $block['innerHTML'] );
$tablet_size_slug = ! empty( $block['attrs']['sizeSlugTablet'] ) ? $block['attrs']['sizeSlugTablet'] : '';
$mobile_size_slug = ! empty( $block['attrs']['sizeSlugMobile'] ) ? $block['attrs']['sizeSlugMobile'] : '';
$is_attachemnts = is_array( $attachment['sizes'] ) && ! empty( $attachment['sizes'] );
if ( ! empty( $block['attrs']['urlTablet'] ) && ! empty( $tablet_size_slug ) && ! empty( $attachment['sizes'][ $tablet_size_slug ]['url'] ) ) {
$block['innerHTML'] = str_replace( $block['attrs']['urlTablet'], $attachment['sizes'][ $tablet_size_slug ]['url'], $block['innerHTML'] );
}
if ( ! empty( $block['attrs']['urlMobile'] && ! empty( $mobile_size_slug ) ) && ! empty( $attachment['sizes'][ $mobile_size_slug ]['url'] ) ) {
$block['innerHTML'] = str_replace( $block['attrs']['urlMobile'], $attachment['sizes'][ $mobile_size_slug ]['url'], $block['innerHTML'] );
}
foreach ( $block['innerContent'] as $key => &$inner_content ) {
if ( is_string( $block['innerContent'][ $key ] ) && '' === trim( $block['innerContent'][ $key ] ) ) {
continue;
}
$block['innerContent'][ $key ] = str_replace( $block['attrs']['url'], $attachment['url'], $block['innerContent'][ $key ] );
$block['innerContent'][ $key ] = str_replace( $block['attrs']['id'], (string) $attachment['id'], $block['innerContent'][ $key ] );
if ( $is_attachemnts ) {
if ( ! empty( $block['attrs']['urlTablet'] ) ) {
$block['innerContent'][ $key ] = str_replace( $block['attrs']['urlTablet'], $attachment['url'], $block['innerContent'][ $key ] );
}
if ( ! empty( $block['attrs']['urlMobile'] ) ) {
$block['innerContent'][ $key ] = str_replace( $block['attrs']['urlMobile'], $attachment['url'], $block['innerContent'][ $key ] );
}
}
}
if ( $is_attachemnts ) {
if ( ! empty( $block['attrs']['urlTablet'] ) ) {
$block['attrs']['urlTablet'] = $attachment['url'];
}
if ( ! empty( $block['attrs']['urlMobile'] ) ) {
$block['attrs']['urlMobile'] = $attachment['url'];
}
}
$block['attrs']['url'] = $attachment['url'];
$block['attrs']['id'] = $attachment['id'];
Images::$image_index++;
return $block;
}
/**
* Parses images and other content in the Spectra Info Box block.
*
* @since {{since}}
* @param array<mixed> $block Block.
* @return array<mixed> $block Block.
*/
public function parse_spectra_gallery( $block ) {
$images = $block['attrs']['mediaGallery'];
$gallery_ids = array();
foreach ( $images as $key => &$image ) {
if (
! isset( $image ) ||
empty( $image ) ||
Importer_Helper::is_skipable( $image['url'] )
) {
continue;
}
$new_image = Images::instance()->get_image( Images::$image_index );
if ( empty( $new_image ) || ! is_array( $new_image ) ) {
continue;
}
$new_image = Images::instance()->download_image( $new_image );
if ( is_wp_error( $new_image ) ) {
Helper::instance()->ast_block_templates_log( 'Replacing Image problem : ' . $image['url'] . ' Warning: ' . wp_json_encode( $new_image ) );
continue;
}
$attachment = wp_prepare_attachment_for_js( absint( $new_image ) );
if ( ! is_array( $attachment ) ) {
continue;
}
$gallery_ids[] = $attachment['id'];
self::$old_images[] = $image['id'];
Helper::instance()->ast_block_templates_log( 'Replacing Image from ' . $image['url'] . ' to "' . $attachment['url'] . '" for ' . $block['blockName'] . '" with index "' . Images::$image_index . '"' );
$image['url'] = ! empty( $attachment['url'] ) ? $attachment['url'] : $image['url'];
$image['sizes'] = ! empty( $attachment['sizes'] ) ? $attachment['sizes'] : $image['sizes'];
$image['mime'] = ! empty( $attachment['mime'] ) ? $attachment['mime'] : $image['mime'];
$image['type'] = ! empty( $attachment['type'] ) ? $attachment['type'] : $image['type'];
$image['subtype'] = ! empty( $attachment['subtype'] ) ? $attachment['subtype'] : $image['subtype'];
$image['id'] = ! empty( $attachment['id'] ) ? $attachment['id'] : $image['id'];
$image['alt'] = ! empty( $attachment['alt'] ) ? $attachment['alt'] : $image['alt'];
$image['link'] = ! empty( $attachment['link'] ) ? $attachment['link'] : $image['link'];
Images::$image_index++;
}
$block['attrs']['mediaGallery'] = $images;
$block['attrs']['mediaIDs'] = $gallery_ids;
return $block;
}
/**
* Parses Google Map for the Spectra Google Map block.
*
* @since {{since}}
* @param array<mixed> $block Block.
* @return array<mixed> $block Block.
*/
public function parse_spectra_google_map( $block ) {
$address = Importer_Helper::get_business_details( 'business_address' );
if ( empty( $address ) ) {
return $block;
}
Helper::instance()->ast_block_templates_log( 'Replacing Google Map from ' . $block['attrs']['address'] . ' to "' . wp_json_encode( $address ) );
$block['attrs']['address'] = $address;
return $block;
}
/**
* Parses images and other content in the Spectra Info Box block.
*
* @since {{since}}
* @param \WP_Post $post Post.
* @return void
*/
public function parse_featured_image( $post ) {
$thumb_id = get_post_thumbnail_id( $post );
if ( false === $thumb_id ) {
return;
}
$thumb = wp_prepare_attachment_for_js( $thumb_id );
if (
! isset( $thumb['url'] ) ||
Importer_Helper::is_skipable( $thumb['url'] )
) {
return;
}
$image = Images::instance()->get_image( Images::$image_index );
if ( empty( $image ) || ! is_array( $image ) ) {
return;
}
$image = Images::instance()->download_image( $image );
if ( is_wp_error( $image ) ) {
Helper::instance()->ast_block_templates_log( 'Replacing Image problem : ' . $thumb['url'] . ' Warning: ' . wp_json_encode( $image ) );
return;
}
$attachment = wp_prepare_attachment_for_js( absint( $image ) );
if ( ! is_array( $attachment ) ) {
return;
}
self::$old_images[] = $thumb['id'];
Helper::instance()->ast_block_templates_log( 'Replacing Image from ' . $thumb['url'] . ' to "' . $attachment['url'] . '" with index "' . Images::$image_index . '"' );
set_post_thumbnail( $post, $attachment['id'] );
Images::$image_index++;
}
/**
* Parses address and contct in the block.
*
* @since {{since}}
* @param string $key key to replace.
* @param string $ai_content ai content string.
*
* @return string
*/
public function replace_contact_details( $key, $ai_content ) {
$business_details = Importer_Helper::get_business_details();
$social_profiles = $business_details['social_profiles'];
if ( ! is_array( $social_profiles ) ) {
return $ai_content;
}
$social_icons = array_combine( array_column( $social_profiles, 'type' ), array_column( $social_profiles, 'url' ) );
switch ( $key ) {
case '2360 Hood Avenue, San Diego, CA, 92123':
$ai_content = $business_details['business_address'];
break;
case '202-555-0188':
$ai_content = $business_details['business_phone'];
break;
case 'contact@example.com':
$ai_content = $business_details['business_email'];
break;
case '#facebook':
case '#twitter':
case '#linkenin':
case '#instagram':
case '#youtube':
$ai_content = $social_icons[ str_replace( '#', '', $key ) ];
break;
}
return $ai_content;
}
/**
* Parses Spectra form block.
*
* @since {{since}}
* @param array<mixed> $block Block.
* @return array<mixed> $block Block.
*/
public function parse_spectra_form( $block ) {
$business_email = Importer_Helper::get_business_details( 'business_email' );
if ( ! empty( $business_email ) ) {
$block['attrs']['afterSubmitToEmail'] = $business_email;
}
return $block;
}
/**
* Parse social icon list.
*
* @since {{since}}
* @param array<mixed> $block Block.
* @return array<mixed> $block Block.
*/
public function parse_spectra_social_icons( $block ) {
$social_profile = Importer_Helper::get_business_details( 'social_profiles' );
if ( empty( $social_profile ) ) {
return $block;
}
$social_icons = array_combine( array_column( $social_profile, 'id' ), array_column( $social_profile, 'url' ) );
$inner_blocks = $block['innerBlocks'];
if ( is_array( $inner_blocks ) ) {
$social_icons_list = array_map(
function( $item ) {
return $item['attrs']['icon'];
},
$inner_blocks
);
// Check if icon-list contains social icons by checking facebook icon in list.
if ( ! in_array( 'facebook', $social_icons_list, true ) ) {
return $block;
}
foreach ( $inner_blocks as $index => &$inner_block ) {
if ( 'uagb/icon-list-child' !== $inner_block['blockName'] ) {
continue;
}
$icon = $inner_block['attrs']['icon'];
if ( empty( $icon ) ) {
continue;
}
if ( in_array( $icon, array_keys( $social_icons ), true ) ) {
$block['innerBlocks'][ $index ]['attrs']['link'] = $social_icons[ $icon ];
}
if ( ! in_array( $icon, array_keys( $social_icons ), true ) ) {
unset( $block['innerBlocks'][ $index ] );
}
}
$block['innerBlocks'] = array_values( $block['innerBlocks'] );
}
return $block;
}
}

View File

@@ -0,0 +1,253 @@
<?php
/**
* Image Importer
*
* => How to use?
*
* $image = array(
* 'url' => '<image-url>',
* 'id' => '<image-id>',
* );
*
* $downloaded_image = Image_Importer::get_instance()->import( $image );
*
* @package Ast Block Templates
* @since 1.0.0
*/
namespace Gutenberg_Templates\Inc\Importer;
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Traits\Helper;
/**
* Ast_Block Templates Image Importer
*
* @since 1.0.0
*/
class Image_Importer {
use Instance;
/**
* Images IDs
*
* @var array<int, int> The Array of already image IDs.
* @since 1.0.0
*/
private $already_imported_ids = array();
/**
* Constructor
*
* @since 1.0.0
*/
public function __construct() {
if ( ! function_exists( 'WP_Filesystem' ) ) {
require_once ABSPATH . 'wp-admin/includes/file.php';
}
WP_Filesystem();
}
/**
* Process Image Download
*
* @since 1.0.0
* @param array<int, mixed> $attachments Attachment array.
* @return array<int, mixed> Attachment array.
*/
public function process( $attachments ) {
$downloaded_images = array();
foreach ( $attachments as $key => $attachment ) {
$downloaded_images[] = $this->import( $attachment );
}
return $downloaded_images;
}
/**
* Get Hash Image.
*
* @since 1.0.0
* @param string $attachment_url Attachment URL.
* @return string Hash string.
*/
public function get_hash_image( $attachment_url ) {
return sha1( $attachment_url );
}
/**
* Get Already Imported IDs
*
* @return array<int>
* This function to is to suppress phpstan warnings
* since this parameter is not being used
*/
public function get_already_imported_ids() {
return $this->already_imported_ids;
}
/**
* Get Saved Image.
*
* @since 1.0.0
* @param array<string, mixed> $attachment Attachment Data.
* @return array<string, mixed> Hash string.
*/
private function get_saved_image( $attachment ) {
if ( apply_filters( 'ast_block_templates_image_importer_skip_image', false, $attachment ) ) {
Helper::instance()->ast_block_templates_log( 'BATCH - SKIP Image - {from filter} - ' . $attachment['url'] . ' - Filter name `ast_block_templates_image_importer_skip_image`.' );
return array(
'status' => true,
'attachment' => $attachment,
);
}
global $wpdb;
// 1. Is already imported in Batch Import Process?
$post_id = $wpdb->get_var( $wpdb->prepare( 'SELECT `post_id` FROM `' . $wpdb->postmeta . '` WHERE `meta_key` = \'_ast_block_templates_image_hash\' AND `meta_value` = %s;', $this->get_hash_image( $attachment['url'] ) ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
// 2. Is image already imported though XML?
if ( empty( $post_id ) ) {
// Get file name without extension.
// To check it exist in attachment.
$filename = basename( $attachment['url'] );
$post_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_wp_attached_file' AND meta_value LIKE %s", '%/' . $filename . '%' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
Helper::instance()->ast_block_templates_log( 'BATCH - SKIP Image {already imported from xml} - ' . $attachment['url'] );
}
if ( $post_id ) {
$new_attachment = array(
'id' => $post_id,
'url' => wp_get_attachment_url( $post_id ),
);
$this->already_imported_ids[] = $post_id;
return array(
'status' => true,
'attachment' => $new_attachment,
);
}
return array(
'status' => false,
'attachment' => $attachment,
);
}
/**
* Import Image
*
* @since 1.0.0
* @param array<string, mixed> $attachment Attachment array.
* @return array<string, mixed> Attachment array.,
*/
public function import( $attachment ) {
Helper::instance()->ast_block_templates_log( 'Source - ' . $attachment['url'] );
$saved_image = $this->get_saved_image( $attachment );
Helper::instance()->ast_block_templates_log( 'Log - ' . wp_json_encode( $saved_image['attachment'] ) );
if ( $saved_image['status'] ) {
return $saved_image['attachment'];
}
// Extract the file name and extension from the URL.
$filename = basename( $attachment['url'] );
if ( isset( $attachment['engine'] ) && 'unsplash' === $attachment['engine'] ) {
$filename = 'unsplash-photo-' . $attachment['id'] . '.jpg';
}
$file_content = wp_remote_retrieve_body(
wp_safe_remote_get(
$attachment['url'],
array(
'timeout' => 60,
)
)
);
// Empty file content?
if ( empty( $file_content ) ) {
Helper::instance()->ast_block_templates_log( 'BATCH - FAIL Image {Error: Failed wp_remote_retrieve_body} - ' . $attachment['url'] );
return $attachment;
}
$upload = wp_upload_bits( $filename, null, $file_content );
$upload_json = wp_json_encode( $upload );
if ( is_string( $upload_json ) ) {
Helper::instance()->ast_block_templates_log( $upload_json );
} else {
Helper::instance()->ast_block_templates_log( "Failed to log: {$filename}" );
}
$post = array(
'post_title' => $filename,
'guid' => $upload['url'],
);
$post_json = wp_json_encode( $post );
if ( is_string( $post_json ) ) {
Helper::instance()->ast_block_templates_log( $post_json );
} else {
Helper::instance()->ast_block_templates_log( "Failed to log post data: {$filename}" );
}
$info = wp_check_filetype( $upload['file'] );
if ( is_array( $info ) ) {
$post['post_mime_type'] = $info['type'];
}
if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
include ABSPATH . 'wp-admin/includes/image.php';
}
$post_id = wp_insert_attachment( $post, $upload['file'] );
wp_update_attachment_metadata(
$post_id,
wp_generate_attachment_metadata( $post_id, $upload['file'] )
);
update_post_meta( $post_id, '_ast_block_templates_image_hash', $this->get_hash_image( $attachment['url'] ) );
$new_attachment = array(
'id' => $post_id,
'url' => $upload['url'],
);
Helper::instance()->ast_block_templates_log( 'BATCH - SUCCESS Image {Imported} - ' . $new_attachment['url'] );
$this->already_imported_ids[] = $post_id;
return $new_attachment;
}
/**
* Is Image URL
*
* @since 1.0.0
*
* @param string $url URL.
* @return boolean
*/
public function is_image_url( $url = '' ) {
if ( empty( $url ) ) {
return false;
}
if ( Helper::instance()->ast_block_templates_is_valid_image( $url ) ) {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,144 @@
<?php
/**
* AI content generator and Images file.
*
* @package {{package}}
* @since {{since}}
*/
namespace Gutenberg_Templates\Inc\Importer;
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Traits\Helper;
use Gutenberg_Templates\Inc\Importer\Importer_Helper;
/**
* Images
*
* @since {{since}}
*/
class Images {
use Instance;
/**
* Images
*
* @since {{since}}
* @var array<string, array<mixed>> $images
*/
public static $images = array(
'landscape' => array(),
'portrait' => array(),
'square' => array(),
);
/**
* Image index
*
* @since {{since}}
* @var (int) image_index
*/
public static $image_index = 0;
/**
* Get Images
*
* @return array<string|int, mixed> Array of images.
* @since {{since}}
*/
public function get_images() {
return Importer_Helper::get_business_details( 'images' );
}
/**
* Get Image for the specified index and orientation
*
* @param int $index Index of the image.
* @return array<int, mixed>|boolean Array of images or false.
* @since {{since}}
*/
public function get_image( $index = 0 ) {
$images = $this->get_images();
Helper::instance()->ast_block_templates_log( 'Fetching image with index ' . $index );
return ( isset( $images[ $index ] ) ) ? $images[ $index ] : false;
}
/**
* Download image from URL.
*
* @param array<int|string, mixed> $image Image data.
* @return int|\WP_Error Image ID or WP_Error.
* @since {{since}}
*/
public function download_image( $image ) {
$id = isset( $image['id'] ) ? $image['id'] : 0;
$downloaded_ids = get_option( 'ast_block_downloaded_images', array() );
$downloaded_ids = ( is_array( $downloaded_ids ) ) ? $downloaded_ids : array();
if ( array_key_exists( $id, $downloaded_ids ) ) {
// Return already downloaded image.
return $downloaded_ids[ $id ];
}
/* This is a Pixabay code $name = $image['tags']; Pixabay. */
$name = 'zipwp-image-' . sanitize_title( $id );
/* This is a Pixabay code $url = $image['largeImageURL']; Pixabay. */
$url = $image['url']; // Unsplash.
$description = isset( $image['description'] ) ? $image['description'] : '';
$name = preg_replace( '/\.[^.]+$/', '', $name ) . '.jpg';
Helper::instance()->ast_block_templates_log( 'Downloading Image as "' . $name . '" : ' . $url );
$wp_id = $this->create_image_from_url( $url, $name, $id, $description );
$downloaded_ids[ $id ] = $wp_id;
update_option( 'ast_block_downloaded_images', $downloaded_ids );
return $wp_id;
}
/**
* Create the image and return the new media upload id.
*
* @param String $url URL to the image.
* @param String $name Name to the image.
* @param String $photo_id Photo ID to the image.
* @param String $description Description to the image.
* @return mixed
* @see http://codex.wordpress.org/Function_Reference/wp_insert_attachment#Example
*/
public function create_image_from_url( $url, $name, $photo_id, $description ) {
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/image.php';
$file_array = array();
$file_array['name'] = wp_basename( $name );
// Download file to temp location.
$file_array['tmp_name'] = download_url( $url );
// If error storing temporarily, return the error.
if ( is_wp_error( $file_array['tmp_name'] ) ) {
return $file_array;
}
// Do the validation and storage stuff.
$id = media_handle_sideload( $file_array, 0, null );
// If error storing permanently, unlink.
if ( is_wp_error( $id ) ) {
@unlink( $file_array['tmp_name'] ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_unlink -- Deleting the file from temp location.
return $id;
}
$alt = ( '' === $description ) ? $name : $description;
// Store the original attachment source in meta.
add_post_meta( $id, '_source_url', $url );
update_post_meta( $id, '_wp_attachment_image_alt', $alt );
return $id;
}
}

View File

@@ -0,0 +1,151 @@
<?php
/**
* Import Helper.
*
* @package {{package}}
* @since {{since}}
*/
namespace Gutenberg_Templates\Inc\Importer;
use Gutenberg_Templates\Inc\Traits\Helper;
use WP_Query;
/**
* Importer Helper
*
* @since {{since}}
*/
class Importer_Helper {
/**
* Get pages.
*
* @return array<int|\WP_Post> Array for pages.
* @param string $type Post type.
* @since {{since}}
*/
public static function get_pages( $type = 'page' ) {
$query_args = array(
'post_type' => array( $type ),
// Query performance optimization.
'fields' => array( 'ids', 'post_content', 'post_title' ),
'posts_per_page' => '10',
'post_status' => 'publish',
'ignore_sticky_posts' => true,
'no_found_rows' => true,
);
$query = new WP_Query( $query_args );
$desired_first_page_id = intval( get_option( 'page_on_front', 0 ) );
$pages = $query->posts ? $query->posts : array();
$desired_page_index = false;
if ( is_array( $pages ) && ! empty( $pages ) && ! empty( $desired_first_page_id ) ) {
foreach ( $pages as $key => $page ) {
if ( isset( $page->ID ) && $page->ID === $desired_first_page_id ) {
$desired_page_index = $key;
break;
}
}
if ( false !== $desired_page_index ) {
$desired_page = $pages[ $desired_page_index ];
unset( $pages[ $desired_page_index ] );
array_unshift( $pages, $desired_page );
}
}
return $pages;
}
/**
* Get Business details.
*
* @since {{since}}
* @param string $key options name.
* @return array<string, mixed> Array for business details or single detail in a string.
*/
public static function get_business_details( $key = '' ) {
$details = get_option(
'zipwp_user_business_details',
array(
'business_name' => '',
'business_address' => '',
'business_phone' => '',
'business_category' => '',
'business_email' => '',
'social_profiles' => array(),
'business_description' => '',
'token' => '',
'images' => array(),
'image_keyword' => array(),
'templates' => array(),
'language' => 'en',
)
);
$details = array(
'business_name' => ( ! empty( $details['business_name'] ) ) ? $details['business_name'] : '',
'business_address' => ( ! empty( $details['business_address'] ) ) ? $details['business_address'] : '2360 Hood Avenue, San Diego, CA, 92123',
'business_phone' => ( ! empty( $details['business_phone'] ) ) ? $details['business_phone'] : '202-555-0188',
'business_category' => ( ! empty( $details['business_category'] ) ) ? $details['business_category'] : '',
'business_email' => ( ! empty( $details['business_email'] ) ) ? $details['business_email'] : 'contact@example.com',
'social_profiles' => ( ! empty( $details['social_profiles'] ) ) ? $details['social_profiles'] : array(),
'business_description' => ( ! empty( $details['business_description'] ) ) ? $details['business_description'] : '',
'token' => Helper::get_decrypted_auth_token(),
'images' => ( ! empty( $details['images'] ) ) ? $details['images'] : array(),
'image_keyword' => ( ! empty( $details['image_keyword'] ) ) ? $details['image_keyword'] : array(),
'templates' => ( ! empty( $details['templates'] ) ) ? $details['templates'] : array(),
'language' => ( ! empty( $details['language'] ) ) ? $details['language'] : '',
);
if ( ! empty( $key ) ) {
return isset( $details[ $key ] ) ? $details[ $key ] : array();
}
return $details;
}
/**
* Check if we need to skip the URL.
*
* @param string $url URL to check.
* @return boolean
* @since {{since}}
*/
public static function is_skipable( $url ) {
if ( strpos( $url, 'skip' ) !== false ) {
return true;
}
return false;
}
/**
* Get image orientation of the specified image.
*
* @param string $url Image URL.
* @return string Image orientation.
* @since {{since}}
*/
public static function get_image_orientation( $url ): string {
// Use `@` to suppress warnings from `getimagesize` if the file is not valid or accessible.
$size = getimagesize( $url );
if ( $size && is_array( $size ) ) {
list( $width, $height ) = $size;
// Determine orientation based on width and height.
if ( $width > $height ) {
return 'landscape';
} else {
return 'portrait';
}
} else {
return 'landscape';
}
}
}

View File

@@ -0,0 +1,68 @@
<?php
/**
* WP CLI
*
* 1. Run `wp ast-block-templates sync` Info.
*
* @since 1.0.0
*
* @package ast-block-templates
*/
namespace Gutenberg_Templates\Inc\Importer;
use Gutenberg_Templates\Inc\Importer\Sync_Library;
use Gutenberg_Templates\Inc\Traits\Helper;
use Gutenberg_Templates\Inc\Traits\Instance;
use WP_CLI;
use WP_CLI_Command;
/**
* Ast_Block Templates WP CLI
*/
class Sync_Library_WP_CLI {
use Instance;
/**
* Sync
*
* Example: wp ast-block-templates sync
*
* @since 1.0.0
* @param array<string, string|int> $args Arguments with specific value types.
* @param array<string, mixed> $assoc_args Associated Arguments.
* @return void
*/
public function sync( $args = array(), $assoc_args = array() ) {
// Start Sync.
if ( Helper::instance()->ast_block_templates_doing_wp_cli() ) {
WP_CLI::line( 'Sync Started' );
}
$force = isset( $assoc_args['force'] ) ? true : false;
$result_data = Sync_Library::instance()->check_checksum_and_get_blocks_data();
if ( empty( $result_data ) && Helper::instance()->ast_block_templates_doing_wp_cli() && ! $force ) {
WP_CLI::line( 'Blocks are up to date.' );
return;
}
Sync_Library::instance()->process_data_sync( $result_data );
Sync_Library::instance()->update_latest_checksums( $result_data['checksum'] );
Sync_Library::instance()->get_server_astra_customizer_css();
// Start Sync.
if ( Helper::instance()->ast_block_templates_doing_wp_cli() ) {
WP_CLI::line( 'Sync Completed' );
}
}
}
/**
* Add Command
*/
if ( Helper::instance()->ast_block_templates_doing_wp_cli() ) {
WP_CLI::add_command( 'ast-block-templates', 'Gutenberg_Templates\Inc\Importer\Sync_Library_WP_CLI' );
}

View File

@@ -0,0 +1,878 @@
<?php
/**
* Sync Library
*
* @package Ast Block Templates
* @since 1.0.0
*/
namespace Gutenberg_Templates\Inc\Importer;
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Traits\Helper;
use Gutenberg_Templates\Inc\Importer\Plugin;
/**
* Sync Library
*
* @since 1.0.0
*/
class Sync_Library {
use Instance;
/**
* Catch the latest checksums
*
* @since 1.1.0
* @access public
* @var string Last checksums.
*/
public $last_export_checksums;
/**
* Constructor
*
* @since 1.0.0
*/
public function __construct() {
add_action( 'wp_ajax_ast-block-templates-check-sync-library-status', array( $this, 'sync_via_ajax' ) );
add_action( 'wp_ajax_ast-block-templates-import-blocks', array( $this, 'ajax_import_blocks' ) );
add_action( 'sync_blocks', array( $this, 'sync_blocks' ) );
add_action( 'wp_ajax_ast-block-templates-get-sites-request-count', array( $this, 'ajax_sites_requests_count' ) );
add_action( 'wp_ajax_ast-block-templates-import-sites', array( $this, 'ajax_import_sites' ) );
}
/**
* Get Custimizer CSS.
*
* @return void
*/
public function get_server_astra_customizer_css() {
Helper::instance()->ast_block_templates_log( 'BLOCK: Getting Server Custimizer CSS' );
$api_args = array(
'timeout' => 50,
);
$query_args = array();
$api_url = add_query_arg( $query_args, AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/astra-blocks/v2/get-customizer-css' );
Helper::instance()->ast_block_templates_log( 'BLOCK: ' . $api_url );
$response = wp_safe_remote_get( $api_url, $api_args );
if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
$res_data = json_decode( wp_remote_retrieve_body( $response ), true );
if ( isset( $res_data['data']['customizer_css'] ) ) {
Helper::instance()->update_json_file( 'ast-block-templates-customizer-css', $res_data['data']['customizer_css'] );
do_action( 'ast_block_templates_customizer_css', $res_data['data']['customizer_css'] );
}
}
}
/**
* Get Spectra Common CSS.
*
* @return string
*/
public function get_server_spectra_common_css() {
Helper::instance()->ast_block_templates_log( 'BLOCK: Getting Spectra Common CSS' );
$common_css_content = trim( Helper::instance()->get_json_file_content( 'ast-block-templates-spectra-common-styles.json', false ), '"' );
$common_css_content = str_replace( '\n', '', $common_css_content );
if ( ! empty( $common_css_content ) ) {
return $common_css_content;
}
$api_args = array(
'timeout' => 50,
);
$query_args = array();
$api_url = add_query_arg( $query_args, AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/astra-blocks/v2/spectra-common-styles' );
Helper::instance()->ast_block_templates_log( 'BLOCK: ' . $api_url );
$response = wp_safe_remote_get( $api_url, $api_args );
if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
$res_data = json_decode( wp_remote_retrieve_body( $response ), true );
if ( isset( $res_data['data']['spectra-common-styles'] ) ) {
Helper::instance()->update_json_file( 'ast-block-templates-spectra-common-styles', $res_data['data']['spectra-common-styles'] );
return $res_data['data']['spectra-common-styles'];
}
}
return '';
}
/**
* Start Importer
*
* @since 1.0.0
* @return void
*/
public function setup_templates() {
$is_fresh_site = get_option( 'ast_block_templates_fresh_site', 'yes' );
if ( 'yes' === $is_fresh_site ) {
$this->set_default_assets();
update_option( 'ast_block_templates_fresh_site', 'no' );
}
$this->process_sync();
}
/**
* Set default assets
*
* @since 1.0.2
* @return void
*/
public function set_default_assets() {
$list_files = $this->get_default_assets();
$files = array();
foreach ( $list_files as $key => $file_name ) {
$content = '';
$file_data = array(
'file_name' => $file_name . '.json',
'file_content' => $content,
'file_base' => AST_BLOCK_TEMPLATES_JSON_DIR,
);
array_push( $files, $file_data );
}
Helper::instance()->create_files( $files );
}
/**
* Process Import
*
* @since 1.0.6
*
* @return void
*/
public function process_sync() {
if ( apply_filters( 'ast_block_templates_disable_auto_sync', false ) ) {
return;
}
// Check if last sync and this sync has a gap of 24 hours.
$last_check_time = (int) get_option( 'ast-block-templates-last-export-checksums-time', 0 );
if ( ( time() - $last_check_time ) < 86400 ) {
return;
}
update_option( 'ast_blocks_sync_in_progress', 'yes', false );
$this->sync_blocks();
}
/**
* Sync Blocks
* Sync blocks from library.
*
* @since 2.0.0
* @return void
*/
public function sync_blocks() {
// Check checksum difference, if found get blocks categories, count and blocks.
$result_data = $this->check_checksum_and_get_blocks_data();
if ( empty( $result_data ) ) {
Helper::instance()->ast_block_templates_log( 'Blocks are up to date.' );
update_option( 'ast-block-templates-last-export-checksums-time', time() );
update_option( 'ast_blocks_sync_in_progress', 'no', false );
return;
}
$this->process_data_sync( $result_data );
$this->update_latest_checksums( $result_data['checksum'] );
$this->get_server_astra_customizer_css();
}
/**
* Handle Sync API Response
*
* @since 2.0.0
* @return array<string, mixed>
*/
public function check_checksum_and_get_blocks_data() {
$old_last_export_checksums = Helper::instance()->get_last_exported_checksum();
$api_args = array(
'timeout' => 100,
);
$query_args = array(
'blocks_category' => array(
'per_page' => 100,
'_fields' => 'id,count,name,slug,parent',
'hide_empty' => true,
),
'blocks_pages' => array(
'page_builder' => 'gutenberg',
'wireframe' => 'yes',
'per_page' => 30,
),
'last_export_checksums' => urlencode( $old_last_export_checksums ),
);
$api_url = add_query_arg( $query_args, AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/astra-sites/v2/checksum/' );
$response = wp_safe_remote_get( $api_url, $api_args );
if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
$result = json_decode( wp_remote_retrieve_body( $response ), true );
$result_data = isset( $result['data'] ) ? $result['data'] : '';
return $result_data;
}
return array();
}
/**
* Process Data Sync
*
* @since 2.0.0
* @param array<string, mixed> $data Data to process.
* @return void
*/
public function process_data_sync( $data ) {
Helper::instance()->ast_block_templates_log( 'Sync process for Gutenberg Blocks has started.' );
if ( isset( $data['categories'] ) && ! empty( $data['categories'] ) ) {
Helper::instance()->ast_block_templates_log( 'CATEGORY: Storing in ast-block-templates-categories.json' );
Helper::instance()->update_json_file( 'ast-block-templates-categories', $data['categories'] );
do_action( 'ast_block_templates_sync_categories', $data['categories'] );
}
if ( isset( $data['count']['pages'] ) && ! empty( $data['count']['pages'] ) ) {
Helper::instance()->ast_block_templates_log( 'BLOCK: Requests count ' . $data['count']['pages'] );
Helper::instance()->update_json_file( 'ast-block-templates-block-requests', $data['count']['pages'] );
do_action( 'ast_block_templates_sync_blocks_requests', $data['count']['pages'] );
}
for ( $i = 1; $i <= $data['count']['pages']; $i++ ) {
$this->import_blocks( $i );
}
$sites = $this->get_total_sites_count();
for ( $i = 1; $i <= $sites; $i++ ) {
$this->import_sites( $i );
}
Helper::instance()->ast_block_templates_log( 'Sync process for Gutenberg Blocks is done.' );
}
/**
* Json Files Names.
*
* @since 1.0.1
* @return array<string>
*/
public function get_default_assets() {
return array(
'ast-block-templates-categories',
'ast-block-templates-blocks-1',
'ast-block-templates-blocks-2',
'ast-block-templates-blocks-3',
'ast-block-templates-blocks-4',
'ast-block-templates-blocks-5',
'ast-block-templates-blocks-6',
'ast-block-templates-blocks-7',
'ast-block-templates-block-requests',
'ast-block-templates-sites-1',
'ast-block-templates-sites-2',
'ast-block-templates-sites-3',
'ast-block-templates-sites-4',
'ast-block-templates-sites-5',
'ast-block-templates-sites-6',
'ast-block-templates-sites-7',
'ast-block-templates-site-requests',
'ast-block-templates-last-export-checksums',
'ast-block-templates-customizer-css',
);
}
/**
* Update Library
*
* @since 1.0.0
* @return void
*/
public function sync_via_ajax() {
if ( ! Helper::instance()->ast_block_templates_doing_wp_cli() ) {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
// Verify Nonce.
check_ajax_referer( 'ast-block-templates-ajax-nonce', '_ajax_nonce' );
}
$result_data = $this->check_checksum_and_get_blocks_data();
if ( empty( $result_data ) ) {
Helper::instance()->ast_block_templates_log( 'Blocks are up to date.' );
wp_send_json_success(
array(
'message' => 'Complete',
'status' => true,
'data' => 'updated',
)
);
}
$this->get_server_astra_customizer_css();
if ( isset( $result_data['categories'] ) && ! empty( $result_data['categories'] ) ) {
Helper::instance()->ast_block_templates_log( 'CATEGORY: Storing in option ast-block-templates-categories.json' );
Helper::instance()->update_json_file( 'ast-block-templates-categories', $result_data['categories'] );
do_action( 'ast_block_templates_sync_categories', $result_data['categories'] );
}
if ( isset( $result_data['count']['pages'] ) && ! empty( $result_data['count']['pages'] ) ) {
Helper::instance()->ast_block_templates_log( 'BLOCK: Requests count ' . $result_data['count']['pages'] );
Helper::instance()->update_json_file( 'ast-block-templates-block-requests', $result_data['count']['pages'] );
do_action( 'ast_block_templates_sync_blocks_requests', $result_data['count']['pages'] );
}
$this->update_latest_checksums( $result_data['checksum'] );
wp_send_json_success(
array(
'message' => 'in-progress',
'status' => true,
'data' => $result_data['count'],
)
);
}
/**
* Get Last Exported Checksum Status
*
* @since 1.0.0
* @return string Checksums Status.
*/
public function get_last_export_checksums() {
$old_last_export_checksums = Helper::instance()->get_last_exported_checksum();
$new_last_export_checksums = $this->set_last_export_checksums();
$checksums_status = 'no';
if ( empty( $old_last_export_checksums ) ) {
$checksums_status = 'yes';
}
if ( $new_last_export_checksums !== $old_last_export_checksums ) {
$checksums_status = 'yes';
}
return apply_filters( 'ast_block_templates_checksums_status', $checksums_status );
}
/**
* Set Last Exported Checksum
*
* @since 1.0.0
* @return string Checksums Status.
*/
public function set_last_export_checksums() {
if ( ! empty( $this->last_export_checksums ) ) {
return $this->last_export_checksums;
}
$api_args = array(
'timeout' => 60,
);
$query_args = array();
$api_url = add_query_arg( $query_args, AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/astra-sites/v1/get-last-export-checksums/' );
$response = wp_safe_remote_get( $api_url, $api_args );
if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
$result = json_decode( wp_remote_retrieve_body( $response ), true );
// Set last export checksums.
if ( ! empty( $result['last_export_checksums'] ) ) {
update_option( 'ast-block-templates-last-export-checksums-latest', $result['last_export_checksums'], false );
$this->last_export_checksums = $result['last_export_checksums'];
}
}
return $this->last_export_checksums;
}
/**
* Update Latest Checksums
*
* Store latest checksum after batch complete.
*
* @param string $new_checksum New Checksum.
*
* @since 1.0.0
* @return void
*/
public function update_latest_checksums( $new_checksum ) {
Helper::instance()->update_json_file( 'ast-block-templates-last-export-checksums', $new_checksum );
update_option( 'ast-block-templates-last-export-checksums-time', time(), false );
update_option( 'ast_blocks_sync_in_progress', 'no', false );
do_action( 'ast_block_templates_sync_export_checksum', $new_checksum );
}
/**
* Import Categories
*
* @since 1.0.3
* @return void
*/
public function ajax_import_categories() {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
// Verify Nonce.
check_ajax_referer( 'ast-block-templates-ajax-nonce', '_ajax_nonce' );
// Import categories doesn't return any values.
$this->import_categories();
wp_send_json_success(
array(
'message' => 'Success imported categories',
'status' => true,
)
);
}
/**
* Import Blocks
*
* @since 1.0.0
* @return void
*/
public function ajax_import_blocks() {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
// Verify Nonce.
check_ajax_referer( 'ast-block-templates-ajax-nonce', '_ajax_nonce' );
$page_no = isset( $_POST['page_no'] ) ? absint( $_POST['page_no'] ) : '';
if ( $page_no ) {
$this->import_blocks( $page_no );
$data = array(
'message' => 'Success imported sites for page ' . $page_no,
'status' => true,
'data' => array(),
);
if ( isset( $_POST['total'] ) && $_POST['total'] === $_POST['page_no'] ) {
$data['data']['allBlocks'] = Plugin::instance()->get_all_blocks();
$data['data']['categories'] = Helper::instance()->get_block_template_category();
}
wp_send_json_success(
$data
);
}
wp_send_json_error(
array(
'message' => 'Failed imported blocks for page ' . $page_no,
'status' => false,
'data' => '',
)
);
}
/**
* Blocks Requests Count
*
* @since 1.0.0
* @return void
*/
public function ajax_blocks_requests_count() {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
// Verify Nonce.
check_ajax_referer( 'ast-block-templates-ajax-nonce', '_ajax_nonce' );
// Get count.
$total_requests = $this->get_total_blocks_requests();
$this->get_server_astra_customizer_css();
if ( $total_requests ) {
wp_send_json_success(
array(
'message' => 'Success',
'status' => true,
'data' => $total_requests,
)
);
}
wp_send_json_success(
array(
'message' => 'Failed',
'status' => false,
'data' => $total_requests,
)
);
}
/**
* Get Blocks Total Requests
*
* @return integer
*/
public function get_total_blocks_requests() {
Helper::instance()->ast_block_templates_log( 'BLOCK: Getting Total Blocks' );
$api_args = array(
'timeout' => 60,
);
$query_args = apply_filters(
'ast_block_templates_get_blocks_count_args',
array(
'page_builder' => 'gutenberg',
'wireframe' => 'yes',
'per_page' => 30,
)
);
$api_url = add_query_arg( $query_args, AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/astra-blocks/v2/get-blocks-count/' );
Helper::instance()->ast_block_templates_log( 'BLOCK: ' . $api_url );
$response = wp_safe_remote_get( $api_url, $api_args );
if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
$total_requests = json_decode( wp_remote_retrieve_body( $response ), true );
if ( isset( $total_requests['pages'] ) ) {
Helper::instance()->ast_block_templates_log( 'BLOCK: Requests count ' . $total_requests['pages'] );
Helper::instance()->update_json_file( 'ast-block-templates-block-requests', $total_requests['pages'] );
do_action( 'ast_block_templates_sync_blocks_requests', $total_requests['pages'] );
return $total_requests['pages'];
}
}
// returning 0 pages as no return statement exist.
return 0;
}
/**
* Import Categories
*
* @since 1.0.3
* @return void
*/
public function import_categories() {
Helper::instance()->ast_block_templates_log( 'CATEGORY:Importing categories..' );
$api_args = array(
'timeout' => 30,
);
$query_args = apply_filters(
'ast_block_templates_get_category_args',
array(
'per_page' => 100,
'_fields' => 'id,count,name,slug,parent',
'hide_empty' => true,
)
);
$api_url = add_query_arg( $query_args, AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/wp/v2/blocks-category/' );
$response = wp_safe_remote_get( $api_url, $api_args );
if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
$all_categories = json_decode( wp_remote_retrieve_body( $response ), true );
if ( isset( $all_categories['code'] ) ) {
$message = isset( $all_categories['message'] ) ? $all_categories['message'] : '';
if ( ! empty( $message ) ) {
Helper::instance()->ast_block_templates_log( 'CATEGORY:HTTP Request Error: ' . $message );
} else {
Helper::instance()->ast_block_templates_log( 'CATEGORY:HTTP Request Error!' );
}
} else {
Helper::instance()->ast_block_templates_log( 'CATEGORY:Storing in file ast-block-templates-categories' );
Helper::instance()->update_json_file( 'ast-block-templates-categories', $all_categories );
do_action( 'ast_block_templates_sync_categories', $all_categories );
if ( Helper::instance()->ast_block_templates_doing_wp_cli() ) {
Helper::instance()->ast_block_templates_log( 'CATEGORY:Generating ast-block-templates-categories.json file' );
}
}
} else {
Helper::instance()->ast_block_templates_log( 'CATEGORY:API Error: ' . $response->get_error_message() );
}
Helper::instance()->ast_block_templates_log( 'CATEGORY:Completed category import.' );
}
/**
* Import Blocks
*
* @since 1.0.0
* @param integer $page Page number.
* @return void
*/
public function import_blocks( $page = 1 ) {
Helper::instance()->ast_block_templates_log( 'BLOCK: Importing request ' . $page . ' ..' );
$api_args = array(
'timeout' => 30,
);
$all_blocks = array();
$query_args = apply_filters(
'ast_block_templates_blocks_args',
array(
'page_builder' => 'gutenberg',
'per_page' => 30,
'page' => $page,
'wireframe' => 'yes',
)
);
$api_url = add_query_arg( $query_args, AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/astra-blocks/v2/blocks/' );
Helper::instance()->ast_block_templates_log( 'BLOCK: ' . $api_url );
$response = wp_safe_remote_get( $api_url, $api_args );
if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
$all_blocks = json_decode( wp_remote_retrieve_body( $response ), true );
if ( isset( $all_blocks['code'] ) ) {
$message = isset( $all_blocks['message'] ) ? $all_blocks['message'] : '';
if ( ! empty( $message ) ) {
Helper::instance()->ast_block_templates_log( 'BLOCK: HTTP Request Error: ' . $message );
} else {
Helper::instance()->ast_block_templates_log( 'BLOCK: HTTP Request Error!' );
}
} else {
$file_name = 'ast-block-templates-blocks-' . $page;
Helper::instance()->ast_block_templates_log( 'BLOCK: Storing in file ' . $file_name );
Helper::instance()->update_json_file( $file_name, $all_blocks );
if ( Helper::instance()->ast_block_templates_doing_wp_cli() ) {
do_action( 'ast_block_templates_sync_blocks', $page, $all_blocks );
Helper::instance()->ast_block_templates_log( 'BLOCK: Genearting ' . $file_name . '.json file' );
}
}
} else {
Helper::instance()->ast_block_templates_log( 'BLOCK: API Error: ' . $response->get_error_message() );
}
Helper::instance()->ast_block_templates_log( 'BLOCK: Completed request ' . $page );
}
/**
* Get Sites Total Requests
*
* @return integer
*/
public function get_total_sites_count() {
Helper::instance()->ast_block_templates_log( 'SITE: Getting Total Sites' );
$api_args = array(
'timeout' => 60,
);
$query_args = apply_filters(
'ast_block_templates_get_total_pages_args',
array(
'page_builder' => 'gutenberg',
'per_page' => 30,
)
);
$api_url = esc_url_raw( add_query_arg( $query_args, AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/astra-sites/v1/get-total-pages/' ) );
Helper::instance()->ast_block_templates_log( 'SITE: ' . $api_url );
$response = wp_safe_remote_get( $api_url, $api_args );
if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
$total_requests = json_decode( wp_remote_retrieve_body( $response ), true );
if ( isset( $total_requests['pages'] ) ) {
Helper::instance()->ast_block_templates_log( 'SITE: Request count ' . $total_requests['pages'] );
Helper::instance()->update_json_file( 'ast-block-templates-site-requests', $total_requests['pages'] );
do_action( 'ast_block_templates_sync_get_total_pages', $total_requests['pages'] );
return $total_requests['pages'];
}
}
// Return a default value if conditions are not met.
return 0;
}
/**
* Import Sites
*
* @since 1.0.0
* @param integer $page Page number.
* @return void
*/
public function import_sites( $page = 1 ) {
Helper::instance()->ast_block_templates_log( 'SITE: Importing request ' . $page . ' ..' );
$api_args = array(
'timeout' => 30,
);
$all_blocks = array();
$query_args = apply_filters(
'ast_block_templates_get_sites_and_pages_args',
array(
'per_page' => 30,
'page' => $page,
'page-builder' => 'gutenberg',
)
);
$api_url = esc_url_raw( add_query_arg( $query_args, AST_BLOCK_TEMPLATES_LIBRARY_URL . 'wp-json/astra-sites/v1/sites-and-pages/' ) );
Helper::instance()->ast_block_templates_log( 'SITE: ' . $api_url );
$response = wp_safe_remote_get( $api_url, $api_args );
if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
$all_blocks = json_decode( wp_remote_retrieve_body( $response ), true );
if ( isset( $all_blocks['code'] ) ) {
$message = isset( $all_blocks['message'] ) ? $all_blocks['message'] : '';
if ( ! empty( $message ) ) {
Helper::instance()->ast_block_templates_log( 'SITE: HTTP Request Error: ' . $message );
} else {
Helper::instance()->ast_block_templates_log( 'SITE: HTTP Request Error!' );
}
} else {
$file_name = 'ast-block-templates-sites-' . $page;
Helper::instance()->ast_block_templates_log( 'SITE: Storing in file ' . $file_name );
Helper::instance()->update_json_file( $file_name, $all_blocks );
do_action( 'ast_block_templates_sync_sites', $page, $all_blocks );
if ( Helper::instance()->ast_block_templates_doing_wp_cli() ) {
Helper::instance()->ast_block_templates_log( 'SITE: Generating ' . $file_name . '.json file' );
}
}
} else {
Helper::instance()->ast_block_templates_log( 'SITE: API Error: ' . $response->get_error_message() );
}
Helper::instance()->ast_block_templates_log( 'SITE: Completed request ' . $page );
}
/**
* Blocks Requests Count
*
* @since 2.1.0
* @return void
*/
public function ajax_sites_requests_count() {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
// Verify Nonce.
check_ajax_referer( 'ast-block-templates-ajax-nonce', '_ajax_nonce' );
// Get count.
$total_requests = $this->get_total_sites_count();
if ( $total_requests ) {
wp_send_json_success(
array(
'message' => 'Success',
'status' => true,
'data' => $total_requests,
)
);
}
wp_send_json_success(
array(
'message' => 'Failed',
'status' => false,
'data' => $total_requests,
)
);
}
/**
* Import Sites
*
* @since 2.1.0
* @return void
*/
public function ajax_import_sites() {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
// Verify Nonce.
check_ajax_referer( 'ast-block-templates-ajax-nonce', '_ajax_nonce' );
$page_no = isset( $_POST['page_no'] ) ? absint( $_POST['page_no'] ) : '';
if ( $page_no ) {
$this->import_sites( $page_no );
$data = array(
'message' => 'Success imported sites for page ' . $page_no,
'status' => true,
'data' => array(),
);
if ( isset( $_POST['total'] ) && $_POST['total'] === $_POST['page_no'] ) {
$data['data']['allBlocks'] = Plugin::instance()->get_all_blocks();
$data['data']['categories'] = Helper::instance()->get_block_template_category();
$data['data']['allSites'] = Plugin::instance()->get_all_sites();
}
wp_send_json_success(
$data
);
}
wp_send_json_error(
array(
'message' => 'Failed imported sites for page ' . $page_no,
'status' => false,
'data' => '',
)
);
}
}

View File

@@ -0,0 +1,244 @@
<?php
/**
* Template Lit Importer
*
* @package Ast Block Templates
* @since 2.1.0
*/
namespace Gutenberg_Templates\Inc\Importer;
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Traits\Helper;
use Gutenberg_Templates\Inc\Importer\Image_Importer;
/**
* Ast_Block Templates Kit Importer
*
* @since 2.1.0
*/
class Template_Kit_Importer {
use Instance;
/**
* Constructor
*
* @since 2.1.0
*/
public function __construct() {
add_action( 'wp_ajax_ast_block_templates_kit_importer', array( $this, 'template_importer' ) );
add_action( 'wp_ajax_ast_block_templates_import_template_kit', array( $this, 'import_template_kit' ) );
}
/**
* Template kit Importer
*
* @return void
* @since 1.0.0
*/
public function template_importer() {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
// Verify Nonce.
check_ajax_referer( 'ast-block-templates-ajax-nonce', '_ajax_nonce' );
$api_uri = ( isset( $_REQUEST['api_uri'] ) ) ? esc_url_raw( $_REQUEST['api_uri'] ) : '';
$block_id = isset( $_REQUEST['id'] ) ? absint( $_REQUEST['id'] ) : 0;
if ( ! Plugin::instance()->is_valid_url( $api_uri ) ) {
wp_send_json_error(
array(
/* Translators: %s is API URL. */
'message' => sprintf( __( 'Invalid Request URL - %s', 'astra-sites' ), $api_uri ),
'code' => 'Error',
)
);
}
$api_args = apply_filters(
'ast_block_templates_api_args',
array(
'timeout' => 15,
)
);
$request_params = apply_filters(
'ast_block_templates_api_params',
array(
'_fields' => 'original_content',
)
);
$demo_api_uri = esc_url_raw( add_query_arg( $request_params, $api_uri ) );
// API Call.
$response = wp_safe_remote_get( $demo_api_uri, $api_args );
if ( is_wp_error( $response ) ) {
if ( isset( $response->status ) ) {
wp_send_json_error( json_decode( $response->status, true ) );
} else {
wp_send_json_error( $response->get_error_message() );
}
}
if ( wp_remote_retrieve_response_code( $response ) !== 200 ) {
wp_send_json_error( wp_remote_retrieve_body( $response ) );
}
$data = json_decode( wp_remote_retrieve_body( $response ), true );
// Flush the object when import is successful.
delete_option( 'ast-block-templates_data-' . $block_id );
wp_send_json_success( $data['original_content'] );
}
/**
* Import Block
*
* @return void
*/
public function import_template_kit() {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
// Verify Nonce.
check_ajax_referer( 'ast-block-templates-ajax-nonce', '_ajax_nonce' );
// Allow the SVG tags in batch update process.
add_filter( 'wp_kses_allowed_html', array( $this, 'allowed_tags_and_attributes' ), 10, 2 );
$ids_mapping = get_option( 'ast_block_templates_wpforms_ids_mapping', array() );
// Post content.
$content = isset( $_REQUEST['content'] ) ? stripslashes( $_REQUEST['content'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
// Empty mapping? Then return.
if ( ! empty( $ids_mapping ) ) {
// Replace ID's.
foreach ( $ids_mapping as $old_id => $new_id ) {
$content = str_replace( '[wpforms id="' . $old_id, '[wpforms id="' . $new_id, $content );
$content = str_replace( '{"formId":"' . $old_id . '"}', '{"formId":"' . $new_id . '"}', $content );
}
}
// # Tweak
// Gutenberg break block markup from render. Because the '&' is updated in database with '&amp;' and it
// expects as 'u0026amp;'. So, Converted '&amp;' with 'u0026amp;'.
//
// @todo This affect for normal page content too. Detect only Gutenberg pages and process only on it.
// $content = str_replace( '&amp;', "\u0026amp;", $content );
$content = $this->get_content( $content );
// Update content.
wp_send_json_success( $content );
}
/**
* Allowed tags for the batch update process.
*
* @param array<string, array<string, boolean>> $allowedposttags Array of default allowable HTML tags.
* @param string $context The context for which to retrieve tags. Allowed values are 'post',
* 'strip', 'data', 'entities', or the name of a field filter such as
* 'pre_user_description'.
* @return array<string, array<string, boolean>> Array of allowed HTML tags and their allowed attributes.
*/
public function allowed_tags_and_attributes( $allowedposttags, $context ) {
// Keep only for 'post' contenxt.
if ( 'post' === $context ) {
// <svg> tag and attributes.
$allowedposttags['svg'] = array(
'xmlns' => true,
'viewbox' => true,
);
// <path> tag and attributes.
$allowedposttags['path'] = array(
'd' => true,
);
}
return $allowedposttags;
}
/**
* Download and Replace hotlink images
*
* @since 1.0.0
*
* @param string $content Mixed post content.
* @return string
*/
public function get_content( $content = '' ) {
// Extract all links.
preg_match_all( '#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#', $content, $match );
$all_links = array_unique( $match[0] );
// Not have any link.
if ( empty( $all_links ) ) {
return $content;
}
$link_mapping = array();
$image_links = array();
$other_links = array();
// Extract normal and image links.
foreach ( $all_links as $key => $link ) {
if ( Helper::instance()->ast_block_templates_is_valid_image( $link ) ) {
// Get all image links.
// Avoid *-150x, *-300x and *-1024x images.
if (
false === strpos( $link, '-150x' ) &&
false === strpos( $link, '-300x' ) &&
false === strpos( $link, '-1024x' )
) {
$image_links[] = $link;
}
} else {
// Collect other links.
$other_links[] = $link;
}
}
// Step 1: Download images.
if ( ! empty( $image_links ) ) {
foreach ( $image_links as $key => $image_url ) {
// Download remote image.
$image = array(
'url' => $image_url,
'id' => 0,
);
$downloaded_image = Image_Importer::instance()->import( $image );
// Old and New image mapping links.
$link_mapping[ $image_url ] = $downloaded_image['url'];
}
}
// Step 3: Replace mapping links.
foreach ( $link_mapping as $old_url => $new_url ) {
$content = str_replace( strval( $old_url ), $new_url, $content );
// Replace the slashed URLs if any exist.
$old_url = str_replace( '/', '/\\', strval( $old_url ) );
$new_url = str_replace( '/', '/\\', $new_url );
$content = str_replace( $old_url, $new_url, $content );
}
return $content;
}
}

View File

@@ -0,0 +1,185 @@
<?php
/**
* Update Compatibility
*
* @package ast-block-templates
*/
namespace Gutenberg_Templates\Inc\Importer;
use Gutenberg_Templates\Inc\Traits\Instance;
use Gutenberg_Templates\Inc\Traits\Helper;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Updater class
*
* @since 2.0.0
*/
class Updater {
use Instance;
/**
* Constructor
*/
public function __construct() {
add_action( 'admin_init', array( $this, 'init' ) );
add_action( 'ast_block_templates_updated', array( $this, 'updated' ), 10, 2 );
}
/**
* Init
*
* @since 2.0.0
* @return void
*/
public function init() {
// Get auto saved version number.
$saved_version = get_option( 'ast-block-templates-version', false );
// Update auto saved version number.
if ( ! $saved_version ) {
// Fresh install updation.
$this->fresh_v2_install();
// Update current version.
update_option( 'ast-block-templates-version', AST_BLOCK_TEMPLATES_VER );
return;
}
do_action( 'ast_block_templates_update_before' );
// If equals then return.
if ( version_compare( $saved_version, AST_BLOCK_TEMPLATES_VER, '=' ) ) {
return;
}
do_action( 'ast_block_templates_updated', $saved_version, AST_BLOCK_TEMPLATES_VER );
// Update auto saved version number.
update_option( 'ast-block-templates-version', AST_BLOCK_TEMPLATES_VER );
do_action( 'ast_block_templates_update_after' );
}
/**
* Update onboarding variables
*
* @since 2.1.12
* @return void
*/
public function remove_deprecated_option() {
$deprecated_option = get_option( 'ast-templates-business-details', false );
if ( ! empty( $deprecated_option['business_name'] ) ) {
// Update social media key meta.
$social_profiles = isset( $deprecated_option['social_profiles'] ) ? $deprecated_option['social_profiles'] : array();
if ( is_array( $social_profiles ) ) {
foreach ( $social_profiles as $index => $profile ) {
if ( isset( $profile['id'] ) ) {
$social_profiles[ $index ]['type'] = $profile['id'];
}
}
}
$business_details = array(
'business_name' => isset( $deprecated_option['business_name'] ) ? $deprecated_option['business_name'] : '',
'business_description' => isset( $deprecated_option['business_description'] ) ? $deprecated_option['business_description'] : '',
'business_category' => '',
'images' => isset( $deprecated_option['images'] ) ? $deprecated_option['images'] : array(),
'image_keyword' => isset( $deprecated_option['image_keywords'] ) ? $deprecated_option['image_keywords'] : array(),
'business_address' => isset( $deprecated_option['business_address'] ) ? $deprecated_option['business_address'] : '',
'business_phone' => isset( $deprecated_option['business_phone'] ) ? $deprecated_option['business_phone'] : '',
'business_email' => isset( $deprecated_option['business_email'] ) ? $deprecated_option['business_email'] : '',
'social_profiles' => $social_profiles,
);
// Merge with existing business details if available.
$zip_user_details = get_option( 'zipwp_user_business_details', array() );
$business_details = array_merge( $zip_user_details, $business_details );
update_option( 'zipwp_user_business_details', $business_details );
delete_option( 'ast-templates-business-details' );
}
}
/**
* Fresh v2 install
*
* @since 2.0.0
* @return void
*/
public function fresh_v2_install() {
delete_option( 'ast-block-templates-last-export-checksums-time' );
delete_option( 'ast_block_templates_fresh_site' );
}
/**
* Updated
*
* @since 2.0.0
* @param string $old_version Old version number.
* @param string $new_version New version number.
* @return void
*/
public function updated( $old_version, $new_version ) {
switch ( $new_version ) {
case '2.0.0':
// Do something for that version.
break;
}
if ( version_compare( $old_version, '2.1.24', '<' ) ) {
// Create new files.
Sync_Library::instance()->set_default_assets();
// Update new files.
wp_schedule_single_event( time() + 1, 'sync_blocks' );
// Delete older options data.
$options = Sync_Library::instance()->get_default_assets();
foreach ( $options as $option_name ) {
delete_option( $option_name );
}
$this->remove_deprecated_option();
}
if ( version_compare( $old_version, '2.3.4', '<' ) ) {
$common_css_content = get_option( 'ast-block-templates-spectra-common-styles', '' );
if ( ! empty( $common_css_content ) ) {
Helper::instance()->update_json_file( 'ast-block-templates-spectra-common-styles', $common_css_content );
delete_option( 'ast-block-templates-spectra-common-styles' );
}
}
if ( version_compare( $old_version, '2.4.5', '<' ) ) {
global $wpdb;
// Query to get all options that start with 'ast-block-templates_data-'.
$options = $wpdb->get_col( //phpcs:ignore
$wpdb->prepare(
"SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s",
'ast-block-templates_data-%'
)
);
// Loop through each option and delete it.
if ( $options ) {
foreach ( $options as $option ) {
delete_option( $option );
}
}
}
}
}

View File

@@ -0,0 +1,475 @@
<?php
/**
* Trait.
*
* @package {{package}}
* @since 0.0.1
*/
namespace Gutenberg_Templates\Inc\Traits;
use Gutenberg_Templates\Inc\Traits\Instance;
/**
* Trait Instance.
*/
class Helper {
use Instance;
/**
* Log
*
* @param string $message Log message.
* @return void
*/
public function ast_block_templates_log( $message = '' ) {
if ( self::$instance->ast_block_templates_doing_wp_cli() ) {
\WP_CLI::line( $message );
} else {
if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG && function_exists( 'error_log' ) && apply_filters( 'ast_block_templates_debug_logs', false ) ) {
error_log( $message ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
}
}
}
/**
* Doing WP CLI
*
* @return bool
*/
public function ast_block_templates_doing_wp_cli() {
if ( defined( 'WP_CLI' ) && WP_CLI ) {
return true;
}
return false;
}
/**
* Get an instance of WP_Filesystem_Direct.
*
* @since 1.0.0
* @return object A WP_Filesystem_Direct instance.
*/
public function ast_block_templates_get_filesystem() {
global $wp_filesystem;
require_once ABSPATH . '/wp-admin/includes/file.php';
WP_Filesystem();
return $wp_filesystem;
}
/**
* Check for the valid image
*
* @param string $link The Image link.
*
* @since 1.0.0
* @return bool
*/
public function ast_block_templates_is_valid_image( $link = '' ) {
return boolVal( preg_match( '/^((https?:\/\/)|(www\.))([a-z0-9-].?)+(:[0-9]+)?\/[\w\-]+\.(jpg|png|gif|jpeg)\/?$/i', $link ) );
}
/**
* Encrypt data using base64.
*
* @param string $input The input string which needs to be encrypted.
* @since 1.0.0
* @return string The encrypted string.
*/
public static function encrypt( $input ) {
// If the input is empty or not a string, then abandon ship.
if ( empty( $input ) || ! is_string( $input ) ) {
return '';
}
// Encrypt the input and return it.
$base_64 = base64_encode( $input ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
$encode = rtrim( $base_64, '=' );
return $encode;
}
/**
* Decrypt data using base64.
*
* @param string $input The input string which needs to be decrypted.
* @since 1.0.0
* @return string The decrypted string.
*/
public static function decrypt( $input ) {
// If the input is empty or not a string, then abandon ship.
if ( empty( $input ) || ! is_string( $input ) ) {
return '';
}
// Decrypt the input and return it.
$base_64 = $input . str_repeat( '=', strlen( $input ) % 4 );
$decode = base64_decode( $base_64 ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
return $decode;
}
/**
* Get an option from the database.
*
* @param string $key The option key.
* @param mixed $default The option default value if option is not available.
* @param boolean $network_override Whether to allow the network admin setting to be overridden on subsites.
* @since 1.0.0
* @return mixed The option value.
*/
public static function get_admin_settings_option( $key, $default = false, $network_override = false ) {
// Get the site-wide option if we're in the network admin.
return $network_override && is_multisite() ? get_site_option( $key, $default ) : get_option( $key, $default );
}
/**
* Get the Zip AI Settings.
*
* If used with a key, it will return that specific setting.
* If used without a key, it will return the entire settings array.
*
* @param string $key The setting key.
* @param mixed $default The default value to return if the setting is not found.
* @since 1.0.0
* @return mixed|array The setting value, or the default.
*/
public static function get_setting( $key = '', $default = array() ) {
// Get the Zip AI settings.
$existing_settings = self::get_admin_settings_option( 'zip_ai_settings' );
// If the Zip AI settings are empty, return the fallback.
if ( empty( $existing_settings ) || ! is_array( $existing_settings ) ) {
return $default;
}
// If the key is empty, return the entire settings array - otherwise return the specific setting or the fallback.
if ( empty( $key ) ) {
return $existing_settings;
} else {
return isset( $existing_settings[ $key ] ) ? $existing_settings[ $key ] : $default;
}
}
/**
* Delete an option from the database for.
*
* @param string $key The option key.
* @param boolean $network_override Whether to allow the network admin setting to be overridden on subsites.
* @since 1.0.0
* @return void
*/
public static function delete_admin_settings_option( $key, $network_override = false ) {
// Delete the site-wide option if we're in the network admin.
if ( $network_override && is_multisite() ) {
delete_site_option( $key );
} else {
delete_option( $key );
}
}
/**
* This helper function returns credit details.
*
* @since 1.0.0
* @return array<string, integer>
*/
public static function get_credit_details() {
// Set the default credit details.
$credit_details = array(
'used' => 0,
'total' => 0,
'threshold' => array(
'medium' => defined( 'ZIP_AI_CREDIT_THRESHOLD_MEDIUM' ) ? ZIP_AI_CREDIT_THRESHOLD_MEDIUM : 65,
'high' => defined( 'ZIP_AI_CREDIT_THRESHOLD_HIGH' ) ? ZIP_AI_CREDIT_THRESHOLD_HIGH : 85,
),
'percentage' => 0,
'status' => 'success',
'free_user' => true,
);
// Get the response from the endpoint.
$response = self::get_credit_server_response( 'usage' );
// If the response is not an error, then update the credit details.
if (
empty( $response['error'] )
&& ! empty( $response['total_credits'] )
) {
$credit_details['used'] = ! empty( $response['total_used_credits'] ) ? $response['total_used_credits'] : 0;
$credit_details['total'] = $response['total_credits'];
$credit_details['percentage'] = intval( ( $credit_details['used'] / $credit_details['total'] ) * 100 );
$credit_details['free_user'] = $response['free_user'];
} else {
$credit_details['status'] = 'error';
}
return $credit_details;
}
/**
* Get the Zip AI Response from the Zip Credit Server.
*
* @param string $endpoint The endpoint to get the response from.
* @since 1.0.0
* @return mixed The Zip AI Response.
*/
public static function get_credit_server_response( $endpoint ) {
// If the endpoint is not a string, then abandon ship.
if ( ! is_string( $endpoint ) ) {
return array(
'error' => __( 'The Zip AI Endpoint was not declared', 'astra-sites' ),
);
}
// Get the Auth Token from the Zip AI Settings.
$auth_token = self::get_decrypted_auth_token();
// If the Zip Auth Token is not set, then abandon ship.
if ( empty( $auth_token ) || ! is_string( $auth_token ) ) {
return array(
'error' => __( 'The Zip AI Auth Token is not set.', 'astra-sites' ),
);
}
$server_url = defined( 'ZIP_AI_CREDIT_SERVER_API' ) ? ZIP_AI_CREDIT_SERVER_API : 'https://credits.startertemplates.com/api/';
// Set the API URL.
$api_url = $server_url . $endpoint;
// Get the response from the endpoint.
$response = wp_safe_remote_post(
$api_url,
array(
'headers' => array(
'Authorization' => 'Bearer ' . $auth_token,
),
'timeout' => 30, // phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout -- 30 seconds is required sometime for open ai responses
)
);
// If the response was an error, or not a 200 status code, then abandon ship.
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
return array(
'error' => __( 'The Zip AI Middleware is not responding.', 'astra-sites' ),
);
}
// Get the response body.
$response_body = wp_remote_retrieve_body( $response );
// If the response body is not a JSON, then abandon ship.
if ( empty( $response_body ) || ! json_decode( $response_body ) ) {
return array(
'error' => __( 'The Zip AI Middleware encountered an error.', 'astra-sites' ),
);
}
// Return the response body.
return json_decode( $response_body, true );
}
/**
* Get the decrypted auth token.
*
* @since 1.0.0
* @return string The decrypted auth token.
*/
public static function get_decrypted_auth_token() {
// Get the Zip AI Settings.
$auth_token = self::get_setting( 'auth_token' );
// Return early if the auth token is not set.
if ( empty( $auth_token ) || ! is_string( $auth_token ) ) {
return '';
}
// Return the decrypted auth token.
return ! empty( trim( $auth_token ) ) ? self::decrypt( $auth_token ) : '';
}
/**
* Get default AI categories.
*
* @since 2.0.0
*
* @return array<string, string>
*/
public function get_default_ai_categories() {
return array(
'business' => 'Business',
'person' => 'Person',
'organisation' => 'Organisation',
'restaurant' => 'Restaurant',
'product' => 'Product',
'event' => 'Event',
'landing-page' => 'Landing Page',
'medical' => 'Medical',
);
}
/**
* Is debug mode enabled
*
* @since 2.0.0
* @return boolean
*/
public function is_debug_mode() {
return defined( 'GT_DEBUG' ) && GT_DEBUG;
}
/**
* Create files/directories.
*
* @param array<int, array<string, string>> $files The files array.
*
* @return void
*/
public function create_files( $files = array() ) {
// Install files and folders for uploading files and prevent hotlinking.
foreach ( $files as $file ) {
$this->create_single_file( $file );
}
}
/**
* Create file/directories.
*
* @param array<string, string> $file The file array.
*
* @return void
*/
public function create_single_file( $file ) {
if ( wp_mkdir_p( $file['file_base'] ) && ! file_exists( trailingslashit( $file['file_base'] ) . $file['file_name'] ) ) {
$file_handle = @fopen( trailingslashit( $file['file_base'] ) . $file['file_name'], 'w' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fopen
if ( $file_handle ) {
fwrite( $file_handle, $file['file_content'] ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fwrite, WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_fwrite
fclose( $file_handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose
self::ast_block_templates_log( 'File: ' . $file['file_name'] . ' Created Successfully!' );
}
}
}
/**
* Update files/directories.
*
* @param string $file_name The file path.
* @param string|int $file_content The file content.
*
* @return void
*/
public function update_json_file( $file_name, $file_content ) {
$file_name = $file_name . '.json';
if ( ! file_exists( AST_BLOCK_TEMPLATES_JSON_DIR . $file_name ) ) {
$file_data = array(
'file_name' => $file_name,
'file_content' => '',
'file_base' => AST_BLOCK_TEMPLATES_JSON_DIR,
);
$this->create_single_file( $file_data );
}
if ( file_exists( AST_BLOCK_TEMPLATES_JSON_DIR . $file_name ) && file_put_contents( AST_BLOCK_TEMPLATES_JSON_DIR . $file_name, wp_json_encode( $file_content ) ) !== false ) { //phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_file_put_contents
self::ast_block_templates_log( 'File: ' . $file_name . ' Updated Successfully!' );
} else {
self::ast_block_templates_log( 'File: ' . $file_name . ' Not Updated!' );
}
}
/**
* Get files/directories.
*
* @param string $file_name The file name.
* @param bool $get_array Is The file content array.
*
* @return mixed
*/
public function get_json_file_content( $file_name, $get_array = true ) {
if ( file_exists( AST_BLOCK_TEMPLATES_JSON_DIR . $file_name ) ) {
// Ignoring the rule as it is not a remote file.
$file_content = file_get_contents( AST_BLOCK_TEMPLATES_JSON_DIR . $file_name ); //phpcs:ignore WordPressVIPMinimum.Performance.FetchingRemoteData.FileGetContentsUnknown
if ( $get_array ) {
return json_decode( (string) $file_content, true );
} else {
return $file_content;
}
}
return '';
}
/**
* Get block categories.
*
* @return array<int, array<string, string>>
*/
public function get_block_template_category() {
return self::get_json_file_content( 'ast-block-templates-categories.json', true );
}
/**
* Get customiser CSS.
*
* @return string
*/
public function get_block_template_customiser_css() {
return trim( self::get_json_file_content( 'ast-block-templates-customizer-css.json', false ), '"' );
}
/**
* Get last exported checksum.
*
* @return string
*/
public function get_last_exported_checksum() {
return trim( self::get_json_file_content( 'ast-block-templates-last-export-checksums.json', false ), '"' );
}
/**
* Get site request count.
*
* @return int
*/
public function get_site_request() {
return self::get_json_file_content( 'ast-block-templates-site-requests.json', false );
}
/**
* Get block request count.
*
* @return int
*/
public function get_block_templates_requests() {
return self::get_json_file_content( 'ast-block-templates-block-requests.json', false );
}
/**
* Get blocks page wise.
*
* @param int $page The page number.
* @return array<int, mixed>
*/
public function get_blocks_templates( $page = 0 ) {
return self::get_json_file_content( 'ast-block-templates-blocks-' . $page . '.json', true );
}
/**
* Get sites page wise.
*
* @param int $page The page number.
* @return array<int, mixed>
*/
public function get_sites_templates( $page = 0 ) {
return self::get_json_file_content( 'ast-block-templates-sites-' . $page . '.json', true );
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* Trait.
*
* @package {{package}}
* @since 0.0.1
*/
namespace Gutenberg_Templates\Inc\Traits;
/**
* Trait Instance.
*/
trait Instance {
/**
* Instance object.
*
* @var self Class Instance.
*/
private static $instance = null;
/**
* Initiator
*
* @since 0.0.1
* @return self Initialized object of class.
*/
public static function instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* Trait.
*
* @package {{package}}
* @since 0.0.1
*/
namespace Gutenberg_Templates\Inc\Traits;
use Gutenberg_Templates\Inc\Traits\Instance;
/**
* Trait Instance.
*/
class Upgrade {
use Instance;
/**
* Constructor
*/
public function __construct() {
add_action( 'wp_ajax_ast_skip_zip_ai_onboarding', array( $this, 'skip_spectra_pro_onboarding' ) );
}
/**
* Activate Plugin
*
* @return void
*/
public function skip_spectra_pro_onboarding() {
if ( ! current_user_can( 'manage_ast_block_templates' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
// Verify Nonce.
check_ajax_referer( 'skip-spectra-pro-onboarding-nonce', 'security' );
update_option( 'ast_skip_zip_ai_onboarding', 'yes' );
wp_send_json_success(
array(
'success' => 'true',
)
);
}
}

View File

@@ -0,0 +1,3 @@
{
"ast-block-templates": "2.4.8"
}

View File

@@ -0,0 +1,3 @@
const defaults = require( '@wordpress/scripts/config/webpack.config' );
module.exports = defaults