initial commit
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin.
|
||||
*/
|
||||
|
||||
namespace Extendify\Library;
|
||||
|
||||
use Extendify\Library\App;
|
||||
use Extendify\Library\User;
|
||||
use Extendify\Library\SiteSettings;
|
||||
|
||||
/**
|
||||
* This class handles any file loading for the admin area.
|
||||
*/
|
||||
class Admin
|
||||
{
|
||||
|
||||
/**
|
||||
* The instance
|
||||
*
|
||||
* @var $instance
|
||||
*/
|
||||
public static $instance = null;
|
||||
|
||||
/**
|
||||
* Adds various actions to set up the page
|
||||
*
|
||||
* @return self|void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (self::$instance) {
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
self::$instance = $this;
|
||||
$this->loadScripts();
|
||||
|
||||
\add_filter('plugin_action_links_' . EXTENDIFY_PLUGIN_BASENAME, [ $this, 'pluginActionLinks' ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds action links to the plugin list table
|
||||
*
|
||||
* @param array $links An array of plugin action links.
|
||||
* @return array An array of plugin action links.
|
||||
*/
|
||||
public function pluginActionLinks($links)
|
||||
{
|
||||
$theme = get_option('template');
|
||||
$label = esc_html__('Upgrade', 'extendify');
|
||||
|
||||
$links['upgrade'] = sprintf('<a href="%1$s" target="_blank"><b>%2$s</b></a>', "https://extendify.com/pricing?utm_source=extendify-plugin&utm_medium=wp-dash&utm_campaign=action-link&utm_content=$label&utm_term=$theme", $label);
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds scripts to the admin
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function loadScripts()
|
||||
{
|
||||
\add_action(
|
||||
'admin_enqueue_scripts',
|
||||
function ($hook) {
|
||||
if (!current_user_can(App::$requiredCapability)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->checkItsGutenbergPost($hook)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->isLibraryEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addScopedScriptsAndStyles();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure we are on the correct page
|
||||
*
|
||||
* @param string $hook - An optional hook provided by WP to identify the page.
|
||||
* @return boolean
|
||||
*/
|
||||
public function checkItsGutenbergPost($hook = '')
|
||||
{
|
||||
if (isset($GLOBALS['typenow']) && \use_block_editor_for_post_type($GLOBALS['typenow'])) {
|
||||
return $hook && in_array($hook, ['post.php', 'post-new.php'], true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds various JS scripts
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addScopedScriptsAndStyles()
|
||||
{
|
||||
$version = App::$environment === 'PRODUCTION' ? App::$version : uniqid();
|
||||
|
||||
\wp_register_script(
|
||||
App::$slug . '-scripts',
|
||||
EXTENDIFY_BASE_URL . 'public/build/extendify.js',
|
||||
[
|
||||
'wp-i18n',
|
||||
'wp-components',
|
||||
'wp-element',
|
||||
'wp-editor',
|
||||
],
|
||||
$version,
|
||||
true
|
||||
);
|
||||
\wp_localize_script(
|
||||
App::$slug . '-scripts',
|
||||
'extendifyData',
|
||||
[
|
||||
'root' => \esc_url_raw(rest_url(APP::$slug . '/' . APP::$apiVersion)),
|
||||
'nonce' => \wp_create_nonce('wp_rest'),
|
||||
'user' => json_decode(User::data('extendifysdk_user_data'), true),
|
||||
'sitesettings' => json_decode(SiteSettings::data()),
|
||||
'sdk_partner' => \esc_attr(APP::$sdkPartner),
|
||||
'asset_path' => \esc_url(EXTENDIFY_URL . 'public/assets'),
|
||||
'standalone' => \esc_attr(APP::$standalone),
|
||||
'devbuild' => \esc_attr(APP::$environment === 'DEVELOPMENT'),
|
||||
]
|
||||
);
|
||||
\wp_enqueue_script(App::$slug . '-scripts');
|
||||
|
||||
\wp_set_script_translations(App::$slug . '-scripts', 'extendify');
|
||||
|
||||
// Inline the library styles to keep them out of the iframe live preview.
|
||||
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
|
||||
$css = file_get_contents(EXTENDIFY_PATH . 'public/build/extendify.css');
|
||||
\wp_register_style(App::$slug, false, [], $version);
|
||||
\wp_enqueue_style(App::$slug);
|
||||
\wp_add_inline_style(App::$slug, $css);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current user is Admin
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
private function isAdmin()
|
||||
{
|
||||
if (\is_multisite()) {
|
||||
return \is_super_admin();
|
||||
}
|
||||
|
||||
return in_array('administrator', \wp_get_current_user()->roles, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if scripts should add
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isLibraryEnabled()
|
||||
{
|
||||
$settings = json_decode(SiteSettings::data());
|
||||
|
||||
// If it's disabled, only show it for admins.
|
||||
if (isset($settings->state) && (isset($settings->state->enabled)) && !$settings->state->enabled) {
|
||||
return $this->isAdmin();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* API router
|
||||
*/
|
||||
|
||||
namespace Extendify\Library;
|
||||
|
||||
use Extendify\Library\App;
|
||||
use Extendify\Library\Http;
|
||||
|
||||
/**
|
||||
* Simple router for the REST Endpoints
|
||||
*/
|
||||
class ApiRouter extends \WP_REST_Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* The class instance.
|
||||
*
|
||||
* @var $instance
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* The capablity required for access.
|
||||
*
|
||||
* @var $capability
|
||||
*/
|
||||
protected $capability;
|
||||
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->capability = App::$requiredCapability;
|
||||
add_filter(
|
||||
'rest_request_before_callbacks',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($response, $handler, $request) {
|
||||
// Add the request to our helper class.
|
||||
if ($request->get_header('x_extendify')) {
|
||||
Http::init($request);
|
||||
}
|
||||
|
||||
return $response;
|
||||
},
|
||||
10,
|
||||
3
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the authorization of the request
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function checkPermission()
|
||||
{
|
||||
// Check for the nonce on the server (used by WP REST).
|
||||
if (isset($_SERVER['HTTP_X_WP_NONCE']) && \wp_verify_nonce(sanitize_text_field(wp_unslash($_SERVER['HTTP_X_WP_NONCE'])), 'wp_rest')) {
|
||||
return \current_user_can($this->capability);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register dynamic routes
|
||||
*
|
||||
* @param string $namespace - The api name space.
|
||||
* @param string $endpoint - The endpoint.
|
||||
* @param function $callback - The callback to run.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getHandler($namespace, $endpoint, $callback)
|
||||
{
|
||||
\register_rest_route(
|
||||
$namespace,
|
||||
$endpoint,
|
||||
[
|
||||
'methods' => 'GET',
|
||||
'callback' => $callback,
|
||||
'permission_callback' => [
|
||||
$this,
|
||||
'checkPermission',
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The post handler
|
||||
*
|
||||
* @param string $namespace - The api name space.
|
||||
* @param string $endpoint - The endpoint.
|
||||
* @param string $callback - The callback to run.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function postHandler($namespace, $endpoint, $callback)
|
||||
{
|
||||
\register_rest_route(
|
||||
$namespace,
|
||||
$endpoint,
|
||||
[
|
||||
'methods' => 'POST',
|
||||
'callback' => $callback,
|
||||
'permission_callback' => [
|
||||
$this,
|
||||
'checkPermission',
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The caller
|
||||
*
|
||||
* @param string $name - The name of the method to call.
|
||||
* @param array $arguments - The arguments to pass in.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function __callStatic($name, array $arguments)
|
||||
{
|
||||
$name = "{$name}Handler";
|
||||
if (is_null(self::$instance)) {
|
||||
self::$instance = new static();
|
||||
}
|
||||
|
||||
$r = self::$instance;
|
||||
return $r->$name(APP::$slug . '/' . APP::$apiVersion, ...$arguments);
|
||||
}
|
||||
}
|
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* The App details file
|
||||
*/
|
||||
|
||||
namespace Extendify\Library;
|
||||
|
||||
use Extendify\Library\Plugin;
|
||||
|
||||
/**
|
||||
* Controller for handling various app data
|
||||
*/
|
||||
class App
|
||||
{
|
||||
|
||||
/**
|
||||
* Plugin name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $name = '';
|
||||
|
||||
/**
|
||||
* Plugin slug
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $slug = '';
|
||||
|
||||
/**
|
||||
* Plugin version
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $version = '';
|
||||
|
||||
/**
|
||||
* Plugin API REST version
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $apiVersion = 'v1';
|
||||
|
||||
/**
|
||||
* Whether this is the standalone plugin
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public static $standalone;
|
||||
|
||||
/**
|
||||
* Plugin environment
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $environment = '';
|
||||
|
||||
/**
|
||||
* The partner plugin/theme
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $sdkPartner = 'standalone';
|
||||
|
||||
/**
|
||||
* Host plugin
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $requiredCapability = 'upload_files';
|
||||
|
||||
/**
|
||||
* Plugin config
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $config = [];
|
||||
|
||||
/**
|
||||
* Process the readme file to get version and name
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (isset($GLOBALS['extendify_sdk_partner']) && $GLOBALS['extendify_sdk_partner']) {
|
||||
self::$sdkPartner = $GLOBALS['extendify_sdk_partner'];
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
|
||||
$readme = file_get_contents(dirname(__DIR__) . '/readme.txt');
|
||||
|
||||
preg_match('/=== (.+) ===/', $readme, $matches);
|
||||
self::$name = $matches[1];
|
||||
self::$slug = strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', self::$name), '-'));
|
||||
|
||||
preg_match('/Stable tag: ([0-9.:]+)/', $readme, $matches);
|
||||
self::$version = $matches[1];
|
||||
|
||||
// An easy way to check if we are in dev mode is to look for a dev specific file.
|
||||
$isDev = is_readable(EXTENDIFY_PATH . 'node_modules') || is_readable(EXTENDIFY_PATH . '.devbuild');
|
||||
self::$environment = $isDev ? 'DEVELOPMENT' : 'PRODUCTION';
|
||||
|
||||
self::$standalone = self::$sdkPartner === 'standalone';
|
||||
|
||||
// Add the config.
|
||||
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
|
||||
$config = file_get_contents(dirname(__DIR__) . '/config.json');
|
||||
self::$config = json_decode($config, true);
|
||||
}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* Controls Auth
|
||||
*/
|
||||
|
||||
namespace Extendify\Library\Controllers;
|
||||
|
||||
use Extendify\Library\Http;
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
die('No direct access.');
|
||||
}
|
||||
|
||||
/**
|
||||
* The controller for dealing registration and authentication
|
||||
*/
|
||||
class AuthController
|
||||
{
|
||||
|
||||
/**
|
||||
* Login a user to extendify - it will return the API key
|
||||
*
|
||||
* @param \WP_REST_Request $request - The request.
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
public static function login($request)
|
||||
{
|
||||
$response = Http::post('/login', $request->get_params());
|
||||
return new \WP_REST_Response($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle registration - It will return the API key.
|
||||
*
|
||||
* @param \WP_REST_Request $request - The request.
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
public static function register($request)
|
||||
{
|
||||
$response = Http::post('/register', $request->get_params());
|
||||
return new \WP_REST_Response($response);
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* Controls Http requests
|
||||
*/
|
||||
|
||||
namespace Extendify\Library\Controllers;
|
||||
|
||||
use Extendify\Library\Http;
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
die('No direct access.');
|
||||
}
|
||||
|
||||
/**
|
||||
* The controller for sending little bits of info
|
||||
*/
|
||||
class MetaController
|
||||
{
|
||||
/**
|
||||
* Send data about a specific topic
|
||||
*
|
||||
* @param \WP_REST_Request $request - The request.
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
public static function getAll($request)
|
||||
{
|
||||
$response = Http::get('/meta-data', $request->get_params());
|
||||
return new \WP_REST_Response($response);
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* Controls Http requests
|
||||
*/
|
||||
|
||||
namespace Extendify\Library\Controllers;
|
||||
|
||||
use Extendify\Library\Http;
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
die('No direct access.');
|
||||
}
|
||||
|
||||
/**
|
||||
* The controller for sending little bits of info
|
||||
*/
|
||||
class PingController
|
||||
{
|
||||
/**
|
||||
* Send data about a specific topic
|
||||
*
|
||||
* @param \WP_REST_Request $request - The request.
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
public static function ping($request)
|
||||
{
|
||||
$response = Http::post('/ping', $request->get_params());
|
||||
return new \WP_REST_Response($response);
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Controls Plugins
|
||||
*/
|
||||
|
||||
namespace Extendify\Library\Controllers;
|
||||
|
||||
use Extendify\Library\Plugin;
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
die('No direct access.');
|
||||
}
|
||||
|
||||
/**
|
||||
* The controller for plugin dependency checking, etc
|
||||
*/
|
||||
class PluginController
|
||||
{
|
||||
|
||||
/**
|
||||
* Return all plugins
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function index()
|
||||
{
|
||||
if (! function_exists('get_plugins')) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
return \get_plugins();
|
||||
}
|
||||
|
||||
/**
|
||||
* List active plugins
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function active()
|
||||
{
|
||||
return \get_option('active_plugins');
|
||||
}
|
||||
|
||||
/**
|
||||
* Install plugins
|
||||
*
|
||||
* @param \WP_REST_Request $request - The request.
|
||||
* @return bool|WP_Error
|
||||
*/
|
||||
public static function install($request)
|
||||
{
|
||||
if (!\current_user_can('activate_plugins')) {
|
||||
return new \WP_Error('not_allowed', \__('You are not allowed to activate plugins on this site.', 'extendify'));
|
||||
}
|
||||
|
||||
$requiredPlugins = json_decode($request->get_param('plugins'), true);
|
||||
foreach ($requiredPlugins as $plugin) {
|
||||
$status = Plugin::install_and_activate_plugin($plugin);
|
||||
if (\is_wp_error($status)) {
|
||||
// Return first error encountered.
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* Controls User info
|
||||
*/
|
||||
|
||||
namespace Extendify\Library\Controllers;
|
||||
|
||||
use Extendify\Library\SiteSettings;
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
die('No direct access.');
|
||||
}
|
||||
|
||||
/**
|
||||
* The controller for managing Extendify SiteSettings.
|
||||
*/
|
||||
class SiteSettingsController
|
||||
{
|
||||
|
||||
/**
|
||||
* Return Current SiteSettings meta data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function show()
|
||||
{
|
||||
return new \WP_REST_Response(SiteSettings::data());
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist the data
|
||||
*
|
||||
* @param \WP_REST_Request $request - The request.
|
||||
* @return array
|
||||
*/
|
||||
public static function store($request)
|
||||
{
|
||||
$settingsData = json_decode($request->get_param('data'), true);
|
||||
\update_option(SiteSettings::key(), $settingsData, true);
|
||||
return new \WP_REST_Response(SiteSettings::data());
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Controls Taxonomies
|
||||
*/
|
||||
|
||||
namespace Extendify\Library\Controllers;
|
||||
|
||||
use Extendify\Library\Http;
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
die('No direct access.');
|
||||
}
|
||||
|
||||
/**
|
||||
* The controller for dealing with taxonomies
|
||||
*/
|
||||
class TaxonomyController
|
||||
{
|
||||
/**
|
||||
* Return all taxonomies
|
||||
*
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
public static function index()
|
||||
{
|
||||
$response = Http::get('/taxonomies', []);
|
||||
return new \WP_REST_Response($response);
|
||||
}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* Controls Http requests
|
||||
*/
|
||||
|
||||
namespace Extendify\Library\Controllers;
|
||||
|
||||
use Extendify\Library\Http;
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
die('No direct access.');
|
||||
}
|
||||
|
||||
/**
|
||||
* The controller for dealing with templates
|
||||
*/
|
||||
class TemplateController
|
||||
{
|
||||
|
||||
/**
|
||||
* Return info about a template
|
||||
*
|
||||
* @param \WP_REST_Request $request - The request.
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
public static function index($request)
|
||||
{
|
||||
$response = Http::post('/templates', $request->get_params());
|
||||
return new \WP_REST_Response($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send data about a specific template
|
||||
*
|
||||
* @param \WP_REST_Request $request - The request.
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
public static function ping($request)
|
||||
{
|
||||
$response = Http::post('/templates', $request->get_params());
|
||||
return new \WP_REST_Response($response);
|
||||
}
|
||||
}
|
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* Controls User info
|
||||
*/
|
||||
|
||||
namespace Extendify\Library\Controllers;
|
||||
|
||||
use Extendify\Library\Http;
|
||||
use Extendify\Library\User;
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
die('No direct access.');
|
||||
}
|
||||
|
||||
/**
|
||||
* The controller for managing user data like API keys, etc
|
||||
*/
|
||||
class UserController
|
||||
{
|
||||
|
||||
/**
|
||||
* Return the current user state
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function show()
|
||||
{
|
||||
return new \WP_REST_Response(User::state());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return meta info about the current user
|
||||
*
|
||||
* @param \WP_REST_Request $request - The request.
|
||||
* @return array
|
||||
*/
|
||||
public static function meta($request)
|
||||
{
|
||||
$key = \sanitize_text_field(\wp_unslash($request->get_param('key')));
|
||||
return new \WP_REST_Response(User::data($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist the data
|
||||
*
|
||||
* @param \WP_REST_Request $request - The request.
|
||||
* @return array
|
||||
*/
|
||||
public static function store($request)
|
||||
{
|
||||
$userData = json_decode($request->get_param('data'), true);
|
||||
// Keep this key for historical reasons.
|
||||
\update_user_meta(\get_current_user_id(), 'extendifysdk_user_data', $userData);
|
||||
|
||||
return new \WP_REST_Response(User::state());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function delete()
|
||||
{
|
||||
\delete_user_meta(\get_current_user_id(), 'extendifysdk_user_data');
|
||||
return new \WP_REST_Response(User::state());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign up the user to the mailing list.
|
||||
*
|
||||
* @param \WP_REST_Request $request - The request.
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
public static function mailingList($request)
|
||||
{
|
||||
$response = Http::post('/register-mailing-list', $request->get_params());
|
||||
return new \WP_REST_Response($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the max imports
|
||||
*
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
public static function maxImports()
|
||||
{
|
||||
$response = Http::get('/max-free-imports');
|
||||
return new \WP_REST_Response($response);
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* Manage any frontend related tasks here.
|
||||
*/
|
||||
|
||||
namespace Extendify\Library;
|
||||
|
||||
use Extendify\Library\App;
|
||||
|
||||
/**
|
||||
* This class handles any file loading for the frontend of the site.
|
||||
*/
|
||||
class Frontend
|
||||
{
|
||||
|
||||
/**
|
||||
* The instance
|
||||
*
|
||||
* @var $instance
|
||||
*/
|
||||
public static $instance = null;
|
||||
|
||||
/**
|
||||
* Adds various actions to set up the page
|
||||
*
|
||||
* @return self|void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (self::$instance) {
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
self::$instance = $this;
|
||||
$this->loadScripts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds scripts and styles to every page is enabled
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function loadScripts()
|
||||
{
|
||||
\add_action(
|
||||
'wp_enqueue_scripts',
|
||||
function () {
|
||||
// TODO: Determine a way to conditionally load assets (https://github.com/extendify/company-product/issues/72).
|
||||
$this->addStylesheets();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds stylesheets as needed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addStylesheets()
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
/**
|
||||
* Helper class for making http requests
|
||||
*/
|
||||
|
||||
namespace Extendify\Library;
|
||||
|
||||
use Extendify\Library\App;
|
||||
use Extendify\Library\User;
|
||||
|
||||
/**
|
||||
* Controller for http communication
|
||||
*/
|
||||
class Http
|
||||
{
|
||||
|
||||
/**
|
||||
* The api endpoint
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $baseUrl = '';
|
||||
|
||||
/**
|
||||
* Request data sent to the server
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $data = [];
|
||||
|
||||
/**
|
||||
* Any headers required
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $headers = [];
|
||||
|
||||
/**
|
||||
* The class instance.
|
||||
*
|
||||
* @var $instance
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* Set up the base object to send with every request
|
||||
*
|
||||
* @param \WP_REST_Request $request - The request.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($request)
|
||||
{
|
||||
// Redundant, but extra prodection!
|
||||
if (!\wp_verify_nonce(sanitize_text_field(wp_unslash($request->get_header('x_wp_nonce'))), 'wp_rest')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Some special cases for development.
|
||||
$this->baseUrl = $request->get_header('x_extendify_dev_mode') !== 'false' ? App::$config['api']['dev'] : App::$config['api']['live'];
|
||||
$this->baseUrl = $request->get_header('x_extendify_local_mode') !== 'false' ? App::$config['api']['local'] : $this->baseUrl;
|
||||
|
||||
$this->data = [
|
||||
'wp_language' => \get_locale(),
|
||||
'wp_theme' => \get_option('template'),
|
||||
'mode' => App::$environment,
|
||||
'uuid' => User::data('uuid'),
|
||||
'library_version' => App::$version,
|
||||
'wp_active_plugins' => $request->get_method() === 'POST' ? \get_option('active_plugins') : [],
|
||||
'sdk_partner' => App::$sdkPartner,
|
||||
];
|
||||
|
||||
$this->headers = [
|
||||
'Accept' => 'application/json',
|
||||
'referer' => $request->get_header('referer'),
|
||||
'user_agent' => $request->get_header('user_agent'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Register dynamic routes
|
||||
*
|
||||
* @param string $endpoint - The endpoint.
|
||||
* @param array $data - The data to include.
|
||||
* @param array $headers - The headers to include.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHandler($endpoint, $data = [], $headers = [])
|
||||
{
|
||||
$url = \esc_url_raw(
|
||||
\add_query_arg(
|
||||
\urlencode_deep(\urldecode_deep(array_merge($this->data, $data))),
|
||||
$this->baseUrl . $endpoint
|
||||
)
|
||||
);
|
||||
|
||||
$response = \wp_remote_get(
|
||||
$url,
|
||||
[
|
||||
'headers' => array_merge($this->headers, $headers),
|
||||
]
|
||||
);
|
||||
|
||||
$responseBody = \wp_remote_retrieve_body($response);
|
||||
return json_decode($responseBody, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register dynamic routes
|
||||
*
|
||||
* @param string $endpoint - The endpoint.
|
||||
* @param array $data - The arguments to include.
|
||||
* @param array $headers - The headers to include.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function postHandler($endpoint, $data = [], $headers = [])
|
||||
{
|
||||
$response = \wp_remote_post(
|
||||
$this->baseUrl . $endpoint,
|
||||
[
|
||||
'headers' => array_merge($this->headers, $headers),
|
||||
'body' => array_merge($this->data, $data),
|
||||
]
|
||||
);
|
||||
|
||||
$responseBody = \wp_remote_retrieve_body($response);
|
||||
return json_decode($responseBody, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* The caller
|
||||
*
|
||||
* @param string $name - The name of the method to call.
|
||||
* @param array $arguments - The arguments to pass in.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function __callStatic($name, array $arguments)
|
||||
{
|
||||
if ($name === 'init') {
|
||||
self::$instance = new static($arguments[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
$name = "{$name}Handler";
|
||||
$r = self::$instance;
|
||||
|
||||
return $r->$name(...$arguments);
|
||||
}
|
||||
}
|
@@ -0,0 +1,318 @@
|
||||
<?php
|
||||
// phpcs:ignoreFile
|
||||
// This class was copied from JetPack (mostly)
|
||||
// so will be a bit of work to refactor
|
||||
/**
|
||||
* Manage plugin dependencies
|
||||
*/
|
||||
|
||||
namespace Extendify\Library;
|
||||
|
||||
class Plugin
|
||||
{
|
||||
/**
|
||||
* Install and activate a plugin.
|
||||
*
|
||||
* @since 5.8.0
|
||||
*
|
||||
* @param string $slug Plugin slug.
|
||||
*
|
||||
* @return bool|WP_Error True if installation succeeded, error object otherwise.
|
||||
*/
|
||||
public static function install_and_activate_plugin($slug)
|
||||
{
|
||||
$plugin_id = self::get_plugin_id_by_slug($slug);
|
||||
if (! $plugin_id) {
|
||||
$installed = self::install_plugin($slug);
|
||||
if (is_wp_error($installed)) {
|
||||
return $installed;
|
||||
}
|
||||
$plugin_id = self::get_plugin_id_by_slug($slug);
|
||||
} elseif (is_plugin_active($plugin_id)) {
|
||||
return true; // Already installed and active.
|
||||
}
|
||||
|
||||
if (! current_user_can('activate_plugins')) {
|
||||
return new \WP_Error('not_allowed', __('You are not allowed to activate plugins on this site.', 'jetpack'));
|
||||
}
|
||||
$activated = activate_plugin($plugin_id);
|
||||
if (is_wp_error($activated)) {
|
||||
return $activated;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a plugin.
|
||||
*
|
||||
* @since 5.8.0
|
||||
*
|
||||
* @param string $slug Plugin slug.
|
||||
*
|
||||
* @return bool|WP_Error True if installation succeeded, error object otherwise.
|
||||
*/
|
||||
public static function install_plugin($slug)
|
||||
{
|
||||
if (is_multisite() && ! current_user_can('manage_network')) {
|
||||
return new \WP_Error('not_allowed', __('You are not allowed to install plugins on this site.', 'jetpack'));
|
||||
}
|
||||
|
||||
$skin = new PluginUpgraderSkin();
|
||||
$upgrader = new \Plugin_Upgrader($skin);
|
||||
$zip_url = self::generate_wordpress_org_plugin_download_link($slug);
|
||||
|
||||
$result = $upgrader->install($zip_url);
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$plugin = self::get_plugin_id_by_slug($slug);
|
||||
$error_code = 'install_error';
|
||||
if (! $plugin) {
|
||||
$error = __('There was an error installing your plugin', 'jetpack');
|
||||
}
|
||||
|
||||
if (! $result) {
|
||||
$error_code = $upgrader->skin->get_main_error_code();
|
||||
$message = $upgrader->skin->get_main_error_message();
|
||||
$error = $message ? $message : __('An unknown error occurred during installation', 'jetpack');
|
||||
}
|
||||
|
||||
if (! empty($error)) {
|
||||
if ('download_failed' === $error_code) {
|
||||
// For backwards compatibility: versions prior to 3.9 would return no_package instead of download_failed.
|
||||
$error_code = 'no_package';
|
||||
}
|
||||
|
||||
return new \WP_Error($error_code, $error, 400);
|
||||
}
|
||||
|
||||
return (array) $upgrader->skin->get_upgrade_messages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get WordPress.org zip download link from a plugin slug
|
||||
*
|
||||
* @param string $plugin_slug Plugin slug.
|
||||
*/
|
||||
protected static function generate_wordpress_org_plugin_download_link($plugin_slug)
|
||||
{
|
||||
return "https://downloads.wordpress.org/plugin/$plugin_slug.latest-stable.zip";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin ID (composed of the plugin slug and the name of the main plugin file) from a plugin slug.
|
||||
*
|
||||
* @param string $slug Plugin slug.
|
||||
*/
|
||||
public static function get_plugin_id_by_slug($slug)
|
||||
{
|
||||
// Check if get_plugins() function exists. This is required on the front end of the
|
||||
// site, since it is in a file that is normally only loaded in the admin.
|
||||
if (! function_exists('get_plugins')) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
/** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */
|
||||
$plugins = apply_filters('all_plugins', get_plugins());
|
||||
if (! is_array($plugins)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($plugins as $plugin_file => $plugin_data) {
|
||||
if (self::get_slug_from_file_path($plugin_file) === $slug) {
|
||||
return $plugin_file;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin slug from the plugin ID (composed of the plugin slug and the name of the main plugin file)
|
||||
*
|
||||
* @param string $plugin_file Plugin file (ID -- e.g. hello-dolly/hello.php).
|
||||
*/
|
||||
protected static function get_slug_from_file_path($plugin_file)
|
||||
{
|
||||
// Similar to get_plugin_slug() method.
|
||||
$slug = dirname($plugin_file);
|
||||
if ('.' === $slug) {
|
||||
$slug = preg_replace('/(.+)\.php$/', '$1', $plugin_file);
|
||||
}
|
||||
|
||||
return $slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the activation status for a plugin.
|
||||
*
|
||||
* @since 8.9.0
|
||||
*
|
||||
* @param string $plugin_file The plugin file to check.
|
||||
* @return string Either 'network-active', 'active' or 'inactive'.
|
||||
*/
|
||||
public static function get_plugin_status($plugin_file)
|
||||
{
|
||||
if (is_plugin_active_for_network($plugin_file)) {
|
||||
return 'network-active';
|
||||
}
|
||||
|
||||
if (is_plugin_active($plugin_file)) {
|
||||
return 'active';
|
||||
}
|
||||
|
||||
return 'inactive';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all plugins in the site.
|
||||
*
|
||||
* @since 8.9.0
|
||||
* @uses get_plugins()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_plugins()
|
||||
{
|
||||
if (! function_exists('get_plugins')) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
/** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */
|
||||
$plugins = apply_filters('all_plugins', get_plugins());
|
||||
|
||||
if (is_array($plugins) && ! empty($plugins)) {
|
||||
foreach ($plugins as $plugin_slug => $plugin_data) {
|
||||
$plugins[ $plugin_slug ]['active'] = in_array(
|
||||
self::get_plugin_status($plugin_slug),
|
||||
array( 'active', 'network-active' ),
|
||||
true
|
||||
);
|
||||
}
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
|
||||
include_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
|
||||
/**
|
||||
* Allows us to capture that the site doesn't have proper file system access.
|
||||
* In order to update the plugin.
|
||||
*/
|
||||
class PluginUpgraderSkin extends \Automatic_Upgrader_Skin
|
||||
{
|
||||
/**
|
||||
* Stores the last error key;
|
||||
**/
|
||||
protected $main_error_code = 'install_error';
|
||||
|
||||
/**
|
||||
* Stores the last error message.
|
||||
**/
|
||||
protected $main_error_message = 'An unknown error occurred during installation';
|
||||
|
||||
/**
|
||||
* Overwrites the set_upgrader to be able to tell if we e ven have the ability to write to the files.
|
||||
*
|
||||
* @param WP_Upgrader $upgrader
|
||||
*
|
||||
*/
|
||||
public function set_upgrader(&$upgrader)
|
||||
{
|
||||
parent::set_upgrader($upgrader);
|
||||
|
||||
// Check if we even have permission to.
|
||||
$result = $upgrader->fs_connect(array( WP_CONTENT_DIR, WP_PLUGIN_DIR ));
|
||||
if (! $result) {
|
||||
// set the string here since they are not available just yet
|
||||
$upgrader->generic_strings();
|
||||
$this->feedback('fs_unavailable');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites the error function
|
||||
*/
|
||||
public function error($error)
|
||||
{
|
||||
if (is_wp_error($error)) {
|
||||
$this->feedback($error);
|
||||
}
|
||||
}
|
||||
|
||||
private function set_main_error_code($code)
|
||||
{
|
||||
// Don't set the process_failed as code since it is not that helpful unless we don't have one already set.
|
||||
$this->main_error_code = ($code === 'process_failed' && $this->main_error_code ? $this->main_error_code : $code);
|
||||
}
|
||||
|
||||
private function set_main_error_message($message, $code)
|
||||
{
|
||||
// Don't set the process_failed as message since it is not that helpful unless we don't have one already set.
|
||||
$this->main_error_message = ($code === 'process_failed' && $this->main_error_code ? $this->main_error_code : $message);
|
||||
}
|
||||
|
||||
public function get_main_error_code()
|
||||
{
|
||||
return $this->main_error_code;
|
||||
}
|
||||
|
||||
public function get_main_error_message()
|
||||
{
|
||||
return $this->main_error_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites the feedback function
|
||||
*
|
||||
* @param string|array|WP_Error $data Data.
|
||||
* @param mixed ...$args Optional text replacements.
|
||||
*/
|
||||
public function feedback($data, ...$args)
|
||||
{
|
||||
$current_error = null;
|
||||
if (is_wp_error($data)) {
|
||||
$this->set_main_error_code($data->get_error_code());
|
||||
$string = $data->get_error_message();
|
||||
} elseif (is_array($data)) {
|
||||
return;
|
||||
} else {
|
||||
$string = $data;
|
||||
}
|
||||
|
||||
if (! empty($this->upgrader->strings[$string])) {
|
||||
$this->set_main_error_code($string);
|
||||
|
||||
$current_error = $string;
|
||||
$string = $this->upgrader->strings[$string];
|
||||
}
|
||||
|
||||
if (strpos($string, '%') !== false) {
|
||||
if (! empty($args)) {
|
||||
$string = vsprintf($string, $args);
|
||||
}
|
||||
}
|
||||
|
||||
$string = trim($string);
|
||||
$string = wp_kses(
|
||||
$string,
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => true
|
||||
),
|
||||
'br' => true,
|
||||
'em' => true,
|
||||
'strong' => true,
|
||||
)
|
||||
);
|
||||
|
||||
$this->set_main_error_message($string, $current_error);
|
||||
$this->messages[] = $string;
|
||||
}
|
||||
}
|
@@ -0,0 +1,247 @@
|
||||
<?php
|
||||
/**
|
||||
* Manage any shared assets that load within the editor and the front-end.
|
||||
*/
|
||||
|
||||
namespace Extendify\Library;
|
||||
|
||||
use Extendify\Library\App;
|
||||
|
||||
/**
|
||||
* This class handles assets that load within the editor and the front-end.
|
||||
*/
|
||||
class Shared
|
||||
{
|
||||
|
||||
/**
|
||||
* Adds various actions to set up the page
|
||||
*
|
||||
* @return self|void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
\add_action(
|
||||
'wp_enqueue_scripts',
|
||||
function () {
|
||||
$this->themeCompatInlineStyles();
|
||||
}
|
||||
);
|
||||
|
||||
\add_action(
|
||||
'admin_init',
|
||||
function () {
|
||||
$this->themeCompatInlineStyles();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline styles to be applied for compatible themes
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
// phpcs:ignore
|
||||
public function themeCompatInlineStyles()
|
||||
{
|
||||
$css = '';
|
||||
$theme = get_option('template');
|
||||
|
||||
if ($theme === 'kadence') {
|
||||
$css = 'body, .editor-styles-wrapper {
|
||||
--wp--preset--color--background: var(--global-palette8);
|
||||
--wp--preset--color--foreground: var(--global-palette4);
|
||||
--wp--preset--color--primary: var(--global-palette1);
|
||||
--wp--preset--color--secondary: var(--global-palette2);
|
||||
--wp--preset--color--tertiary: var(--global-palette7);
|
||||
--wp--custom--spacing--large: clamp(var(--global-sm-spacing), 5vw, var(--global-xxl-spacing));
|
||||
--wp--preset--font-size--large: var(--h2FontSize);
|
||||
--wp--preset--font-size--huge: var(--h1FontSize);
|
||||
}';
|
||||
}
|
||||
|
||||
if ($theme === 'neve') {
|
||||
$css = 'body, .editor-styles-wrapper {
|
||||
--wp--preset--color--background: var(--nv-site-bg);
|
||||
--wp--preset--color--foreground: var(--nv-text-color);
|
||||
--wp--preset--color--primary: var(--nv-primary-accent);
|
||||
--wp--preset--color--secondary: var(--nv-secondary-accent);
|
||||
--wp--preset--color--tertiary: var(--nv-light-bg);
|
||||
--wp--custom--spacing--large: clamp(15px, 5vw, 80px);
|
||||
--wp--preset--font-size--large: var(--h2FontSize);
|
||||
--wp--preset--font-size--huge: var(--h1FontSize);
|
||||
}';
|
||||
}
|
||||
|
||||
if ($theme === 'blocksy') {
|
||||
$css = 'body, .editor-styles-wrapper {
|
||||
--wp--preset--color--background: var(--paletteColor7);
|
||||
--wp--preset--color--foreground: var(--color);
|
||||
--wp--preset--color--primary: var(--paletteColor1);
|
||||
--wp--preset--color--secondary: var(--paletteColor4);
|
||||
}';
|
||||
}
|
||||
|
||||
if ($theme === 'go') {
|
||||
$css = 'body, .editor-styles-wrapper {
|
||||
--wp--preset--color--background: var(--go--color--background);
|
||||
--wp--preset--color--foreground: var(--go--color--text);
|
||||
}';
|
||||
}
|
||||
|
||||
if ($theme === 'astra') {
|
||||
$css = 'body, .editor-styles-wrapper {
|
||||
--wp--preset--color--background: #ffffff;
|
||||
--wp--preset--color--foreground: var(--ast-global-color-2);
|
||||
--wp--preset--color--primary: var(--ast-global-color-0);
|
||||
--wp--preset--color--secondary: var(--ast-global-color-2);
|
||||
}';
|
||||
}
|
||||
|
||||
if ($theme === 'oceanwp') {
|
||||
$background = get_theme_mod('ocean_background_color', '#ffffff');
|
||||
$primary = get_theme_mod('ocean_primary_color', '#13aff0');
|
||||
$secondary = get_theme_mod('ocean_hover_primary_color', '#0b7cac');
|
||||
$gap = get_theme_mod('ocean_separate_content_padding', '30px');
|
||||
|
||||
$css = 'body, .editor-styles-wrapper {
|
||||
--wp--preset--color--background: ' . $background . ';
|
||||
--wp--preset--color--foreground: #1B1B1B;
|
||||
--wp--preset--color--primary: ' . $primary . ';
|
||||
--wp--preset--color--secondary: ' . $secondary . ';
|
||||
--wp--style--block-gap: ' . $gap . ';
|
||||
--wp--custom--spacing--large: clamp(2rem, 7vw, 8rem);
|
||||
}';
|
||||
}
|
||||
|
||||
if ($theme === 'generatepress') {
|
||||
$settings = (array) get_option('generate_settings', []);
|
||||
|
||||
if (! array_key_exists('background_color', $settings)) {
|
||||
$background = '#f7f8f9';
|
||||
} else {
|
||||
$background = $settings['background_color'];
|
||||
}
|
||||
|
||||
if (! array_key_exists('text_color', $settings)) {
|
||||
$foreground = '#222222';
|
||||
} else {
|
||||
$foreground = $settings['text_color'];
|
||||
}
|
||||
|
||||
if (! array_key_exists('link_color', $settings)) {
|
||||
$primary = '#1e73be';
|
||||
} else {
|
||||
$primary = $settings['link_color'];
|
||||
}
|
||||
|
||||
if (! array_key_exists('link_color', $settings)) {
|
||||
$primary = '#1e73be';
|
||||
} else {
|
||||
$primary = $settings['link_color'];
|
||||
}
|
||||
|
||||
$css = 'body, .editor-styles-wrapper {
|
||||
--wp--preset--color--background: ' . $background . ';
|
||||
--wp--preset--color--foreground: ' . $foreground . ';
|
||||
--wp--preset--color--primary: ' . $primary . ';
|
||||
--wp--preset--color--secondary: #636363;
|
||||
--wp--style--block-gap: 3rem;
|
||||
--wp--custom--spacing--large: clamp(2rem, 7vw, 8rem);
|
||||
--responsive--alignwide-width: 1120px;
|
||||
}';
|
||||
}//end if
|
||||
|
||||
if ($theme === 'twentytwentytwo') {
|
||||
$css = 'body, .editor-styles-wrapper {
|
||||
--extendify--spacing--large: clamp(2rem,8vw,8rem);
|
||||
}';
|
||||
}
|
||||
|
||||
if ($theme === 'twentytwentyone') {
|
||||
$css = 'body, .editor-styles-wrapper {
|
||||
--wp--preset--color--background: var(--global--color-background);
|
||||
--wp--preset--color--foreground: var(--global--color-primary);
|
||||
--wp--preset--color--primary: var(--global--color-gray);
|
||||
--wp--preset--color--secondary: #464b56;
|
||||
--wp--preset--color--tertiary: var(--global--color-light-gray);
|
||||
--wp--style--block-gap: var(--global--spacing-unit);
|
||||
--wp--preset--font-size--large: 2.5rem;
|
||||
--wp--preset--font-size--huge: var(--global--font-size-xxl);
|
||||
}
|
||||
.has-foreground-background-color,
|
||||
.has-primary-background-color,
|
||||
.has-secondary-background-color {
|
||||
--local--color-primary: var(--wp--preset--color--background);
|
||||
--local--color-background: var(--wp--preset--color--primary);
|
||||
}';
|
||||
}
|
||||
|
||||
if ($theme === 'twentytwenty') {
|
||||
$background = sanitize_hex_color_no_hash(get_theme_mod('background_color', 'f5efe0'));
|
||||
$primary = get_theme_mod(
|
||||
'accent_accessible_colors',
|
||||
[
|
||||
'content' => [ 'accent' => '#cd2653' ],
|
||||
]
|
||||
);
|
||||
$primary = $primary['content']['accent'];
|
||||
$css = 'body, .editor-styles-wrapper {
|
||||
--wp--preset--color--background: #' . $background . ';
|
||||
--wp--preset--color--foreground: #000;
|
||||
--wp--preset--color--primary: ' . $primary . ';
|
||||
--wp--preset--color--secondary: #69603e;
|
||||
--wp--style--block-gap: 3rem;
|
||||
--wp--custom--spacing--large: clamp(2rem, 7vw, 8rem);
|
||||
--responsive--alignwide-width: 120rem;
|
||||
}';
|
||||
}//end if
|
||||
|
||||
if ($theme === 'twentynineteen') {
|
||||
/**
|
||||
* Use the color from Twenty Nineteen's customizer value.
|
||||
*/
|
||||
$primary = 199;
|
||||
if (get_theme_mod('primary_color', 'default') !== 'default') {
|
||||
$primary = absint(get_theme_mod('primary_color_hue', 199));
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters Twenty Nineteen default saturation level.
|
||||
*
|
||||
* @since Twenty Nineteen 1.0
|
||||
*
|
||||
* @param int $saturation Color saturation level.
|
||||
*/
|
||||
// phpcs:ignore
|
||||
$saturation = apply_filters('twentynineteen_custom_colors_saturation', 100);
|
||||
$saturation = absint($saturation) . '%';
|
||||
|
||||
/**
|
||||
* Filters Twenty Nineteen default lightness level.
|
||||
*
|
||||
* @since Twenty Nineteen 1.0
|
||||
*
|
||||
* @param int $lightness Color lightness level.
|
||||
*/
|
||||
// phpcs:ignore
|
||||
$lightness = apply_filters('twentynineteen_custom_colors_lightness', 33);
|
||||
$lightness = absint($lightness) . '%';
|
||||
|
||||
$css = 'body, .editor-styles-wrapper {
|
||||
--wp--preset--color--foreground: #111;
|
||||
--wp--preset--color--primary: hsl( ' . $primary . ', ' . $saturation . ', ' . $lightness . ' );
|
||||
--wp--preset--color--secondary: #767676;
|
||||
--wp--preset--color--tertiary: #f7f7f7;
|
||||
}';
|
||||
}//end if
|
||||
|
||||
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
|
||||
$content = file_get_contents(EXTENDIFY_PATH . 'public/build/extendify-utilities.css');
|
||||
$version = App::$environment === 'PRODUCTION' ? App::$version : uniqid();
|
||||
\wp_register_style(App::$slug . '-utilities', false, [], $version);
|
||||
\wp_enqueue_style(App::$slug . '-utilities');
|
||||
\wp_add_inline_style(App::$slug . '-utilities', $content . $css);
|
||||
// Adds inline to the live preview.
|
||||
\wp_add_inline_style('wp-components', $content . $css);
|
||||
}
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* Helper class for interacting with the user
|
||||
*/
|
||||
|
||||
namespace Extendify\Library;
|
||||
|
||||
/**
|
||||
* Helper class for interacting with the user
|
||||
*/
|
||||
class SiteSettings
|
||||
{
|
||||
|
||||
/**
|
||||
* SiteSettings option_name - For historical reasons do not change.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $key = 'extendifysdk_sitesettings';
|
||||
|
||||
/**
|
||||
* SiteSettings default value
|
||||
*
|
||||
* @var Json
|
||||
*/
|
||||
protected $default = '{"state":{"enabled":true}}';
|
||||
|
||||
/**
|
||||
* The class instance.
|
||||
*
|
||||
* @var $instance
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* Returns Setting
|
||||
* Use it like Setting::data()
|
||||
*
|
||||
* @return mixed - Setting Data
|
||||
*/
|
||||
private function dataHandler()
|
||||
{
|
||||
return \get_option($this->key, $this->default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Setting Key
|
||||
* Use it like Setting::key()
|
||||
*
|
||||
* @return string - Setting key
|
||||
*/
|
||||
private function keyHandler()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use it like Setting::method() e.g. Setting::data()
|
||||
*
|
||||
* @param string $name - The name of the method to call.
|
||||
* @param array $arguments - The arguments to pass in.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function __callStatic($name, array $arguments)
|
||||
{
|
||||
$name = "{$name}Handler";
|
||||
self::$instance = new static();
|
||||
$r = self::$instance;
|
||||
return $r->$name(...$arguments);
|
||||
}
|
||||
}
|
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
/**
|
||||
* Helper class for interacting with the user
|
||||
*/
|
||||
|
||||
namespace Extendify\Library;
|
||||
|
||||
use Extendify\Library\App;
|
||||
|
||||
/**
|
||||
* Helper class for interacting with the user
|
||||
*/
|
||||
class User
|
||||
{
|
||||
|
||||
/**
|
||||
* User unique, anonymous identifier
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $uuid = '';
|
||||
|
||||
/**
|
||||
* A WP user
|
||||
*
|
||||
* @var \WP_User
|
||||
*/
|
||||
protected $user = null;
|
||||
|
||||
/**
|
||||
* The DB key for scoping. For historical reasons do not change
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $key = 'extendifysdk_';
|
||||
|
||||
/**
|
||||
* The class instance.
|
||||
*
|
||||
* @var $instance
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* Set up the user
|
||||
*
|
||||
* @param WP_User $user - A WP User object.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($user)
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user ID
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function setupUuid()
|
||||
{
|
||||
$uuid = \get_user_meta($this->user->ID, $this->key . 'uuid', true);
|
||||
if (!$uuid) {
|
||||
$id = \wp_hash(\wp_json_encode($this->user));
|
||||
\update_user_meta($this->user->ID, $this->key . 'uuid', $id);
|
||||
}
|
||||
|
||||
$this->uuid = $uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns data about the user
|
||||
* Use it like User::data('ID') to get the user id
|
||||
*
|
||||
* @param string $arguments - Right now a string of arguments, like ID.
|
||||
* @return mixed - Data about the user.
|
||||
*/
|
||||
private function dataHandler($arguments)
|
||||
{
|
||||
// Right now assume a single argument, but could expand to multiple.
|
||||
if (isset($this->user->$arguments)) {
|
||||
return $this->user->$arguments;
|
||||
}
|
||||
|
||||
return \get_user_meta($this->user->ID, $this->key . $arguments, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the application state for he current user
|
||||
* Use it like User::data('ID') to get the user id
|
||||
*
|
||||
* @return string - JSON representation of the current state
|
||||
*/
|
||||
private function stateHandler()
|
||||
{
|
||||
$state = \get_user_meta($this->user->ID, $this->key . 'user_data');
|
||||
|
||||
// Add some state boilerplate code for the first load.
|
||||
if (!isset($state[0])) {
|
||||
$state[0] = '{}';
|
||||
}
|
||||
|
||||
$userData = json_decode($state[0], true);
|
||||
if (!isset($userData['version'])) {
|
||||
$userData['version'] = 0;
|
||||
}
|
||||
|
||||
// This will reset the allowed max imports to 0 once a week which will force the library to re-check.
|
||||
if (!get_transient('extendify_import_max_check_' . $this->user->ID)) {
|
||||
set_transient('extendify_import_max_check_' . $this->user->ID, time(), strtotime('1 week', 0));
|
||||
$userData['state']['allowedImports'] = 0;
|
||||
}
|
||||
|
||||
// Similiar to above, this will give the user free imports once a month just for logging in.
|
||||
if (!get_transient('extendify_free_extra_imports_check_' . $this->user->ID)) {
|
||||
set_transient('extendify_free_extra_imports_check_' . $this->user->ID, time(), strtotime('first day of next month', 0));
|
||||
$userData['state']['runningImports'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($userData['state']['sdkPartner']) || !$userData['state']['sdkPartner']) {
|
||||
$userData['state']['sdkPartner'] = App::$sdkPartner;
|
||||
}
|
||||
|
||||
$userData['state']['uuid'] = self::data('uuid');
|
||||
$userData['state']['canInstallPlugins'] = \current_user_can('install_plugins');
|
||||
$userData['state']['canActivatePlugins'] = \current_user_can('activate_plugins');
|
||||
$userData['state']['isAdmin'] = \current_user_can('create_users');
|
||||
|
||||
return \wp_json_encode($userData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to dynamically setup the user with uuid
|
||||
* Use it like User::data('ID') to get the user id
|
||||
*
|
||||
* @param string $name - The name of the method to call.
|
||||
* @param array $arguments - The arguments to pass in.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function __callStatic($name, array $arguments)
|
||||
{
|
||||
$name = "{$name}Handler";
|
||||
if (is_null(self::$instance)) {
|
||||
require_once ABSPATH . 'wp-includes/pluggable.php';
|
||||
self::$instance = new static(\wp_get_current_user());
|
||||
$r = self::$instance;
|
||||
$r->setupUuid();
|
||||
}
|
||||
|
||||
$r = self::$instance;
|
||||
return $r->$name(...$arguments);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user