| Current Path : /home/x/b/o/xbodynamge/namtation/wp-content/ |
| Current File : /home/x/b/o/xbodynamge/namtation/wp-content/plugin-card.tar |
index.js 0000666 00000016073 15113760456 0006234 0 ustar 00 /**
* WordPress dependencies...
*/
const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;
const {
Placeholder,
Dashicon,
TextControl,
Spinner,
Button,
Toolbar,
Tooltip
} = wp.components;
const {
compose,
withState
} = wp.compose;
const { BlockControls } = wp.editor;
const { withSelect } = wp.data;
const { ENTER } = wp.keycodes;
const starRating = stars => {
const rating = Math.floor( stars / 10 ) / 2;
const fullStars = Math.floor( rating );
const halfStars = Math.ceil( rating - fullStars );
const emptyStars = 5 - fullStars - halfStars;
const ratings = '<span class="star-full"></span>'.repeat( fullStars ) + '<span class="star-half"></span>'.repeat( halfStars ) + '<span class="star-empty"></span>'.repeat( emptyStars );
return ratings;
};
const unescapeHTML = value => {
const htmlNode = document.createElement( 'div' );
htmlNode.innerHTML = value;
if ( htmlNode.innerText !== undefined ) {
return htmlNode.innerText;
}
return htmlNode.textContent;
};
/**
* Internal dependencies
*/
import './editor.scss';
import './style.scss';
registerBlockType( 'themeisle-blocks/plugin-cards', {
title: __( 'Plugin Card' ),
description: __( 'Plugin Card block lets you display plugins data in your blog posts.' ),
icon: 'admin-plugins',
category: 'themeisle-blocks',
keywords: [
'plugin',
'card',
'orbitfox'
],
attributes: {
slug: {
type: 'string'
},
pluginIcon: {
type: 'string'
},
pluginName: {
type: 'string'
},
pluginAuthor: {
type: 'string'
},
pluginRating: {
type: 'number'
},
pluginDescription: {
type: 'string'
},
pluginInstalls: {
type: 'number'
},
pluginVersion: {
type: 'string'
},
pluginTested: {
type: 'string'
},
pluginLink: {
type: 'string'
}
},
supports: {
html: false,
align: [ 'left', 'center', 'right' ]
},
edit: compose([
withSelect( ( select, props ) => {
return {
props
};
}),
withState({
status: 0,
results: {}
})
])( ({ props, className, status, results, setState }) => {
const changeSlug = ( value ) => {
props.setAttributes({ slug: value });
};
const searchPlugins = ( search ) => {
setState({ status: 1 });
wp.apiFetch({ path: `themeisle-gutenberg-blocks/v1/get_plugins?search='${ encodeURIComponent( search ) }` }).then( payload => {
const data = payload.data.plugins;
setState({
status: 0,
results: data
});
});
};
const selectPlugin = ( data ) => {
let icon;
if ( data.icons.svg ) {
icon = data.icons.svg;
} if ( data.icons['2x']) {
icon = data.icons['2x'];
} if ( data.icons['1x']) {
icon = data.icons['1x'];
} if ( data.icons.default ) {
icon = data.icons.default;
}
props.setAttributes({
slug: data.slug,
pluginIcon: icon,
pluginName: data.name,
pluginAuthor: data.author,
pluginRating: data.rating,
pluginDescription: data.short_description,
pluginInstalls: data.active_installs,
pluginVersion: data.version,
pluginTested: data.tested,
pluginLink: data.download_link
});
setState({
results: {}
});
};
return [
( props.attributes.pluginName ) && (
<BlockControls key="toolbar-controls">
<Toolbar
className='components-toolbar'
>
<Tooltip text={ __( 'Edit Plugin Card' ) }>
<Button
className="components-icon-button components-toolbar__control edit-plugin-card"
onClick={ () => {
props.setAttributes({
pluginIcon: '',
pluginName: '',
pluginAuthor: '',
pluginRating: '',
pluginDescription: '',
pluginInstalls: '',
pluginVersion: '',
pluginTested: '',
pluginLink: ''
});
} }
>
<Dashicon icon="edit" />
</Button>
</Tooltip>
</Toolbar>
</BlockControls>
),
<div className={ `${ className }` }>
{ ( props.attributes.pluginName ) ?
<div class="themeisle-plugin-card">
<div class="card-header">
<div class="card-main">
<div class="card-logo">
<img src={ props.attributes.pluginIcon } alt={ unescapeHTML( props.attributes.pluginName ) } title={ unescapeHTML( props.attributes.pluginName ) }/>
</div>
<div class="card-info">
<h4>{ unescapeHTML( props.attributes.pluginName ) }</h4>
<h5 dangerouslySetInnerHTML={ { __html: _.unescape( props.attributes.pluginAuthor ) } }></h5>
</div>
<div class={ 'card-ratings' } dangerouslySetInnerHTML={ { __html: _.unescape( starRating( props.attributes.pluginRating ) ) } }></div>
</div>
</div>
<div class="card-details">
<div class="card-description">{ unescapeHTML( props.attributes.pluginDescription ) }</div>
<div class="card-stats">
<h5>{__( 'Plugin Stats' ) }</h5>
<div class="card-stats-list">
<div class="card-stat">
<span class="card-text-large">{ props.attributes.pluginInstalls.toLocaleString() }+</span>
{ __( 'active installs' ) }
</div>
<div class="card-stat">
<span class="card-text-large">{ props.attributes.pluginVersion }</span>
{ __( 'version' ) }
</div>
<div class="card-stat">
<span class="card-text-large">{ props.attributes.pluginTested }</span>
{ __( 'tested up to' ) }
</div>
</div>
</div>
</div>
<div class="card-download">
<a href={ props.attributes.pluginLink }>{ __( 'Download' ) }</a>
</div>
</div> :
<Placeholder
icon="admin-plugins"
label={ __( 'Plugin Card' ) }
>
<div className="search-plugin-field">
<Dashicon icon="search" />
{ 1 === status && (
<Spinner/>
) }
<TextControl
type="text"
placeholder={ __( 'Search for plugin…' ) }
value={ props.attributes.slug }
onChange={ changeSlug }
onKeyDown={ ( event ) => {
if ( event.keyCode === ENTER ) {
searchPlugins( event.target.value );
}
}}
/>
{ results && (
<div className="plugin-card-search-results">
<div>
{ Object.keys( results ).map( ( i, j ) => {
const pluginData = results[i];
let icon;
if ( pluginData.icons.svg ) {
icon = pluginData.icons.svg;
} if ( pluginData.icons['2x']) {
icon = pluginData.icons['2x'];
} if ( pluginData.icons['1x']) {
icon = pluginData.icons['1x'];
} if ( pluginData.icons.default ) {
icon = pluginData.icons.default;
}
return (
<div className="plugin-card-list-item" key={i} onClick={ ( e ) => {
e.preventDefault();
selectPlugin( pluginData );
} }>
<img src={ icon } />
<span dangerouslySetInnerHTML={ { __html: _.unescape( pluginData.name ) } }></span>
</div>
);
}) }
</div>
</div>
) }
</div>
</Placeholder>
}
</div>
];
}),
save: () => {
return null;
}
});
style.scss 0000666 00000003773 15113760456 0006627 0 ustar 00 .wp-block-themeisle-blocks-plugin-cards {
padding: 20px 0;
&.align-left {
float: left;
}
&.align-center {
text-align: center;
}
&.align-right {
float: right;
}
.themeisle-plugin-card {
border: 1px #EAEAEA solid;
display: inline-block;
width: 350px;
font-family: "PT Serif Caption";
a {
color: #000;
text-decoration: none;
}
.card-header {
background: #ffffff;
text-align: center;
padding: 25px;
.card-logo {
padding: 10px;
img {
width: 128px;
height: 128px;
}
}
.card-info {
padding: 10px;
h4 {
font-size: 24px;
margin: 0;
}
h5 {
font-size: 16px;
margin: 0;
}
}
.card-ratings {
font-family: "Font Awesome 5 Free";
.star-full:before {
content: "\f005";
font-weight: 900;
}
.star-half:before {
content: "\f5c0";
font-weight: 900;
}
.star-empty:before {
content: "\f005";
}
}
}
.card-details {
background: #FCFCFC;
border-top: 1px #EAEAEA solid;
padding: 20px;
font-size: 12px;
text-align: center;
.card-description {
color: #707070;
font-size: 12px;
text-align: center;
}
.card-stats {
padding: 25px 0 0 0;
text-align: justify;
h5 {
color: #707070;
border-bottom: 1px #d8d8d8 solid;
font-size: 14px;
margin: 0;
}
.card-stats-list {
display: flex;
.card-stat {
flex: auto;
padding-top: 10px;
text-align: center;
.card-text-large {
color: #4550ae;
font-size: 24px;
display: block;
}
}
}
}
}
.card-download {
background: #4551af;
text-align: center;
a {
color: #fff;
text-decoration: none;
display: block;
padding: 20px;
}
}
}
}
@media ( max-width:415px ) {
.wp-block-themeisle-blocks-plugin-cards {
.themeisle-plugin-card {
width: auto;
.card-details {
.card-stats {
.card-stats-list {
display: block;
}
}
}
}
}
} class-plugin-card-server.php 0000666 00000006602 15113760456 0012111 0 ustar 00 <?php
namespace ThemeIsle\GutenbergBlocks;
/**
* Class Plugin_Card_Server
*/
class Plugin_Card_Server extends \WP_Rest_Controller {
/**
* The main instance var.
*
* @var Plugin_Card_Server
*/
public static $instance = null;
/**
* Rest route namespace.
*
* @var Plugin_Card_Server
*/
public $namespace = 'themeisle-gutenberg-blocks/';
/**
* Rest route version.
*
* @var Plugin_Card_Server
*/
public $version = 'v1';
/**
* Initialize the class
*/
public function init() {
add_action( 'rest_api_init', array( $this, 'register_routes' ) );
}
/**
* Register REST API route
*/
public function register_routes() {
$namespace = $this->namespace . $this->version;
register_rest_route(
$namespace,
'/get_plugins',
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'search' ),
'args' => array(
'search' => array(
'type' => 'string',
'required' => true,
'description' => __( 'The form must have data', 'themeisle-companion' ),
),
),
),
)
);
}
/**
* Search WordPress Plugin
*
* Search WordPress plugin using WordPress.org API.
*
* @return mixed|\WP_REST_Response
*/
public function search( $request ) {
$return = array(
'success' => false,
'data' => esc_html__( 'Something went wrong', 'themeisle-companion' ),
);
$search = $request->get_param( 'search' );
require_once( ABSPATH . 'wp-admin' . '/includes/plugin-install.php' );
$request = array(
'per_page' => 12,
'search' => $search,
'fields' => array(
'active_installs' => true,
'added' => false,
'donate_link' => false,
'downloadlink' => true,
'homepage' => true,
'icons' => true,
'last_updated' => false,
'requires' => true,
'requires_php' => false,
'screenshots' => false,
'short_description' => true,
'slug' => false,
'sections' => false,
'requires' => false,
'rating' => true,
'ratings' => false,
),
);
$results = plugins_api( 'query_plugins', $request );
if ( is_wp_error( $request ) ) {
$return['data'] = 'error';
return $return;
}
$return['success'] = true;
// Get data from API
$return['data'] = $results;
return rest_ensure_response( $return );
}
/**
* The instance method for the static class.
* Defines and returns the instance of the static class.
*
* @static
* @since 1.0.0
* @access public
* @return Plugin_Card_Server
*/
public static function instance() {
if ( is_null( self::$instance ) ) {
self::$instance = new self();
self::$instance->init();
}
return self::$instance;
}
/**
* Throw error on object clone
*
* The whole idea of the singleton design pattern is that there is a single
* object therefore, we don't want the object to be cloned.
*
* @access public
* @since 1.0.0
* @return void
*/
public function __clone() {
// Cloning instances of the class is forbidden.
_doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'themeisle-companion' ), '1.0.0' );
}
/**
* Disable unserializing of the class
*
* @access public
* @since 1.0.0
* @return void
*/
public function __wakeup() {
// Unserializing instances of the class is forbidden.
_doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'themeisle-companion' ), '1.0.0' );
}
}
editor.scss 0000666 00000010170 15113760456 0006742 0 ustar 00 .wp-block-themeisle-blocks-plugin-cards {
padding: 0;
&.align-left {
float: left;
}
&.align-center {
text-align: center;
}
&.align-right {
float: right;
}
.components-placeholder {
padding: 60px 1em;
.components-placeholder__fieldset {
max-width: 100%;
padding: 0 50px;
.components-base-control__field {
margin-bottom: 0;
}
.search-plugin-field {
width: 100%;
background: #ffffff;
position: relative;
svg.dashicon {
position: absolute;
left: 0;
margin: 12px;
}
.components-spinner {
position: absolute;
margin: 12px;
right: 0;
}
input[type="text"] {
position: relative;
width: 100%;
margin: 0;
padding: 1em 3.5em 1em 3.5em;
border-radius: 0;
border-color: #e6eaee;
background: 0 0;
box-shadow: none;
z-index: 2;
&:focus {
color: #191e23;
border-color: #00a0d2;
box-shadow: 0 0 0 1px #00a0d2;
outline: 2px solid transparent;
outline-offset: -2px;
}
}
.plugin-card-search-results {
width: 100%;
list-style: none;
background: #fff;
margin: -1px 0 0;
border: 1px solid #e6eaee;
box-shadow: 0 1px 3px #e6eaee;
div {
max-height: 175px;
overflow-y: auto;
.plugin-card-list-item {
position: relative;
border-width: 0 0 1px 0;
border-style: solid;
border-color: #e6eaee;
transition: opacity .7s;
cursor: pointer;
color: #00a0d2;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
padding: .75em 1.25em;
&:hover {
background-color: #f7fcff;
}
img {
-o-object-fit: cover;
object-fit: cover;
-o-object-position: center;
object-position: center;
width: 2.5em;
height: 2.5em;
margin: 0 1em 0 0;
}
span {
text-align: left;
}
}
}
}
}
}
}
.themeisle-plugin-card {
border: 1px #EAEAEA solid;
display: inline-block;
width: 350px;
font-family: "PT Serif Caption";
a {
color: #000;
text-decoration: none;
}
.card-header {
text-align: center;
padding: 25px;
.card-logo {
padding: 10px;
img {
width: 128px;
height: 128px;
}
}
.card-info {
padding: 10px;
h4 {
font-size: 24px;
margin: 0;
}
h5 {
font-size: 16px;
margin: 0;
}
}
.card-ratings {
font-family: "Font Awesome 5 Free";
.star-full:before {
content: "\f005";
font-weight: 900;
}
.star-half:before {
content: "\f5c0";
font-weight: 900;
}
.star-empty:before {
content: "\f005";
}
}
}
.card-details {
background: #FCFCFC;
border-top: 1px #EAEAEA solid;
padding: 20px;
font-size: 12px;
text-align: center;
.card-description {
color: #707070;
font-size: 12px;
text-align: center;
}
.card-stats {
padding: 25px 0 0 0;
text-align: justify;
h5 {
color: #707070;
border-bottom: 1px #d8d8d8 solid;
font-size: 14px;
margin: 0;
}
.card-stats-list {
display: flex;
.card-stat {
flex: auto;
padding-top: 10px;
text-align: center;
.card-text-large {
color: #4550ae;
font-size: 24px;
display: block;
}
}
}
}
}
.card-download {
background: #4551af;
text-align: center;
a {
color: #fff;
text-decoration: none;
display: block;
padding: 20px;
}
}
}
}
[data-type="themeisle-blocks/plugin-cards"] {
.edit-plugin-card{
&:hover {
svg {
padding: 5px;
box-shadow: inset 0 0 0 1px #555d66,inset 0 0 0 2px #fff;
}
}
}
}
@media ( max-width:415px ) {
.wp-block-themeisle-blocks-plugin-cards {
.themeisle-plugin-card {
width: auto;
.card-details {
.card-stats {
.card-stats-list {
display: block;
}
}
}
}
}
} class-plugin-card-block.php 0000666 00000011142 15113760456 0011670 0 ustar 00 <?php
namespace ThemeIsle\GutenbergBlocks;
/**
* Class Plugin_Card_Block
*/
class Plugin_Card_Block extends Base_Block {
/**
* Constructor function for the module.
*
* @method __construct
*/
public function __construct() {
parent::__construct();
}
/**
* Every block needs a slug, so we need to define one and assign it to the `$this->block_slug` property
*
* @return mixed
*/
function set_block_slug() {
$this->block_slug = 'plugin-cards';
}
/**
* Set the attributes required on the server side.
*
* @return mixed
*/
function set_attributes() {
$this->attributes = array(
'slug' => array(
'type' => 'string',
),
);
}
/**
* Block render function for server-side.
*
* This method will pe passed to the render_callback parameter and it will output
* the server side output of the block.
*
* @return mixed|string
*/
function render( $attributes ) {
$results = $this->search( $attributes['slug'] );
if ( ! is_wp_error( $results['data'] ) ) {
$results = $results['data'];
$icon = '';
if ( isset( $results->icons['svg'] ) ) {
$icon = $results->icons['svg'];
} if ( isset( $results->icons['2x'] ) ) {
$icon = $results->icons['2x'];
} if ( isset( $results->icons['1x'] ) ) {
$icon = $results->icons['1x'];
} if ( isset( $results->icons['default'] ) ) {
$icon = $results->icons['default'];
}
$markup = '<div class="wp-block-themeisle-blocks-plugin-cards">
<div class="themeisle-plugin-card">
<div class="card-header">
<div class="card-main">
<div class="card-logo">
<img src="' . $icon . '" alt="' . $results->name . '" title="' . $results->name . '"/>
</div>
<div class="card-info">
<h4>' . $results->name . '</h4>
<h5>' . $results->author . '</h5>
</div>
<div class="card-ratings">
' . $this->get_ratings( $results->rating ) . '
</div>
</div>
</div>
<div class="card-details">
<div class="card-description">' . $results->short_description . '</div>
<div class="card-stats">
<h5>' . __( 'Plugin Stats', 'themeisle-companion' ) . '</h5>
<div class="card-stats-list">
<div class="card-stat">
<span class="card-text-large">' . number_format( $results->active_installs ) . '+</span>
' . __( 'active installs', 'themeisle-companion' ) . '
</div>
<div class="card-stat">
<span class="card-text-large">' . $results->version . '+</span>
' . __( 'version', 'themeisle-companion' ) . '
</div>
<div class="card-stat">
<span class="card-text-large">' . $results->tested . '+</span>
' . __( 'tested up to', 'themeisle-companion' ) . '
</div>
</div>
</div>
</div>
<div class="card-download">
<a href="' . $results->download_link . '">' . __( 'Download', 'themeisle-companion' ) . '</a>
</div>
</div>
</div>';
return $markup;
}
}
/**
* Search WordPress Plugin
*
* Search WordPress plugin using WordPress.org API.
*
* @return mixed
*/
function search( $request ) {
$return = array(
'success' => false,
'data' => esc_html__( 'Something went wrong', 'themeisle-companion' ),
);
$slug = $request;
require_once( ABSPATH . 'wp-admin' . '/includes/plugin-install.php' );
$request = array(
'per_page' => 12,
'slug' => $slug,
'fields' => array(
'active_installs' => true,
'added' => false,
'donate_link' => false,
'downloadlink' => true,
'homepage' => true,
'icons' => true,
'last_updated' => false,
'requires' => true,
'requires_php' => false,
'screenshots' => false,
'short_description' => true,
'slug' => false,
'sections' => false,
'requires' => false,
'rating' => true,
'ratings' => false,
),
);
$results = plugins_api( 'plugin_information', $request );
if ( is_wp_error( $request ) ) {
$return['data'] = 'error';
return $return;
}
$return['success'] = true;
// Get data from API
$return['data'] = $results;
return $return;
}
/**
* Get Rating Stars
*
* Get 0-5 star rating from rating score.
*
* @return mixed|string
*/
function get_ratings( $rating ) {
$rating = round( $rating / 10, 0 ) / 2;
$full_stars = floor( $rating );
$half_stars = ceil( $rating - $full_stars );
$empty_stars = 5 - $full_stars - $half_stars;
$output = str_repeat( '<span class="star-full"></span>', $full_stars );
$output .= str_repeat( '<span class="star-half"></span>', $half_stars );
$output .= str_repeat( '<span class="star-empty"></span>', $empty_stars );
return $output;
}
}
.htaccess 0000666 00000000424 15114242726 0006352 0 ustar 00 <IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
Deny from all
</FilesMatch>
</IfModule>