Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: GPHWPP-3655 Dashboard - NBA #76

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions packages/wp-plugin/essentials/inc/dashboard/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace ionos_wordpress\essentials\dashboard;

use function ionos_wordpress\essentials\dashboard\blocks\next_best_actions\getNBAData;
use function ionos_wordpress\essentials\dashboard\blocks\next_best_actions\model\getNBAElements;

use const ionos_wordpress\essentials\PLUGIN_DIR;

/*
Expand Down Expand Up @@ -41,6 +44,8 @@
\register_block_type(PLUGIN_DIR . '/build/dashboard/blocks/deep-links');
\register_block_type(PLUGIN_DIR . '/build/dashboard/blocks/quick-links');
\register_block_type(PLUGIN_DIR . '/build/dashboard/blocks/vulnerability');
\register_block_type(PLUGIN_DIR . '/build/dashboard/blocks/next-best-actions');

});

// remove our blocks from all other post types
Expand Down Expand Up @@ -165,3 +170,44 @@
EOF
);
});

\add_action('load-' . ADMIN_PAGE_HOOK, function () {

});
add_action('wp_ajax_execute-nba-callback', function() {
$process = isset($_GET['process']) ? sanitize_text_field($_GET['process']) : '';
$id = isset($_GET['id']) ? sanitize_text_field($_GET['id']) : '';

if (empty($process) || empty($id)) {
\wp_send_json_error(new \WP_Error('missing_parameters', 'Missing parameters'));
}

require_once PLUGIN_DIR . '/build/dashboard/blocks/next-best-actions/data.php';
$elements = getNBAData();
if (! is_array($elements)) {
\wp_send_json_error(new \WP_Error('no_actions', 'No actions found'));
}

foreach ($elements as $element) {
if ($element->__get('id') === $id ) {

switch ($process) {
case 'click-nba-dismiss':
$element->__set('dismissed', true);
\wp_send_json_success(['addClass' => 'dismissed']);
break;
case 'click-nba-action':
$callback = $element->__get('completeOnClickCallback');
$result = \call_user_func($callback) === true;
if ($result === true) {
$element->__set('completed', true);
}
\wp_send_json_success( [ 'redirect' => $element->__get('link') ] );
break;
}
}
}

\wp_send_json_error(new \WP_Error('action_not_found', 'Action not found'));
});

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "ionos-dashboard-page/next-best-actions",
"version": "0.1.0",
"title": "NBA",
"category": "widgets",
"icon": "index-card",
"description": "Next Best Actions",
"example": {},
"supports": {
"html": false
},
"textdomain": "ionos-essentials",
"editorScript": "file:./index.js",
"viewScript": [
"file:./view.js",
"wp-util"
],
"render": "file:./render.php"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php
/**
* This class represents the Next Best Action (NBA) model.
*/
namespace ionos_wordpress\essentials\dashboard\blocks\next_best_actions;

$model_path = __DIR__ . '/model.php';
if (! file_exists($model_path)) {
return;
}
require_once $model_path;

function getNBAData() {
return array(
new Model(
id: 'checkPluginsPage',
title: 'Check Plugins Page',
description: 'Check the plugins page for updates and security issues.',
link: admin_url('plugins.php'),
image: 'https://raw.githubusercontent.com/codeformm/mitaka-kichijoji-wapuu/main/mitaka-kichijoji-wapuu.png',
completeOnClickCallback: fn() => false,
callback: fn() => false,
),
new Model(
id: 'checkThemesPage',
title: 'Check Themes Page',
description: 'Check the themes page for updates and security issues.',
link: admin_url('themes.php'),
image: 'https://raw.githubusercontent.com/codeformm/mitaka-kichijoji-wapuu/main/mitaka-kichijoji-wapuu.png',
completeOnClickCallback: fn() => false,
callback: fn() => true,
),
new Model(
id: 'checkUpdatesPage',
title: 'Check Updates Page',
description: 'Check the updates page for updates and security issues.',
link: admin_url('update-core.php'),
image: 'https://raw.githubusercontent.com/codeformm/mitaka-kichijoji-wapuu/main/mitaka-kichijoji-wapuu.png',
completeOnClickCallback: fn() => true,
callback: fn() => true,
),
new Model(
id: 'checkSettingsPage',
title: 'Check Settings Page',
description: 'Check the settings page for updates and security issues.',
link: admin_url('options-general.php'),
image: 'https://raw.githubusercontent.com/codeformm/mitaka-kichijoji-wapuu/main/mitaka-kichijoji-wapuu.png',
completeOnClickCallback: fn() => true,
callback: fn() => true,
),
new Model(
id: 'checkUsersPage',
title: 'Check Users Page',
description: 'Check the users page for updates and security issues.',
link: admin_url('users.php'),
image: 'https://raw.githubusercontent.com/codeformm/mitaka-kichijoji-wapuu/main/mitaka-kichijoji-wapuu.png',
completeOnClickCallback: fn() => true,
callback: fn() => true,
)
);
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php
/**
* This class represents the Next Best Action (NBA) model.
*/

namespace ionos_wordpress\essentials\dashboard\blocks\next_best_actions;

/**
* Class NBA
*/
final class Model
{
const WP_OPTION_NAME='NBA_OPTION';

static protected array $_wp_option;

function __construct(
readonly string $id,
readonly string $title,
readonly string $description,
readonly string $link,
readonly mixed $completeOnClickCallback,
readonly string $image,
readonly mixed $callback,
readonly bool $completed = false,
readonly bool $dismissed = false
)
{}

function __set(string $optionName, mixed $value): void {
match ($optionName) {
'completed' => static::_setOption($this->id, 'completed', $value),
'dismissed' => static::_setOption($this->id, 'dismissed', $value),
default => throw new \InvalidArgumentException("Invalid property: $optionName"),
};
}

function __get(string $optionName): mixed {
return match ($optionName) {
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'link' => $this->link,
'completeOnClickCallback' => $this->completeOnClickCallback,
'image' => $this->image,
'callback' => $this->callback,
'completed' => static::_getOption($this->id, 'completed'),
'dismissed' => static::_getOption($this->id, 'dismissed'),
default => throw new \InvalidArgumentException("Invalid property: $optionName"),
};
}

protected static function _getWPOption() {
if(!isset(static::$_wp_option)) {
$option = \get_option(static::WP_OPTION_NAME);
static::$_wp_option = is_array( $option ) ? $option : [];
}
return static::$_wp_option;
}


protected static function _setOption(string $id, string $optionName, string $value) {
$wp_option = static::_getWPOption();
$wp_option[$id][$optionName] = $value;
\update_option(static::WP_OPTION_NAME, $wp_option);
}

protected static function _getOption(string $id, string $optionName): mixed {
$wp_option = static::_getWPOption();
return $wp_option[$id][$optionName] ?? false;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

// phpcs:disable WordPress.WP.GlobalVariablesOverride.Prohibited

namespace ionos_wordpress\essentials\dashboard\blocks\next_best_actions;

use ionos_wordpress\essentials\dashboard\blocks\next_best_actions\model\NBA;

$nba_data = __DIR__ . '/data.php';

if (! file_exists($nba_data)) {
return;
}
require_once $nba_data;

$actions = getNBAData();
if (! is_array($actions)) {
return;
}

printf('<h3>%s</h3>', \esc_html__('Next best actions ⚡', 'ionos-essentials'));
echo '<ul class="wp-block-list ionos-dashboard-nba ">';
foreach ($actions as $action) {
//$action->__set('dismissed', 0);
if ($action->__get('dismissed') === "1" || $action->__get('completed') === "1") {
continue;
}
printf('<div class="wp-block-button is-style-outline is-style-outline--2">
<a href="#" class="wp-block-button__link wp-element-button" callback-id="click-nba-dismiss" data-id="%s">%s</a>
</div>',
\esc_attr($action->__get('id')),
'Dismiss'
);
printf(
'<a href="%s" class="ionos-dashboard nba-action-link %s" callback-id="click-nba-action" data-id="%s" />%s',
\esc_attr($action->__get('link')),
$action->__get('completed') ? 'completed' : '',
\esc_attr($action->__get('id')),
\esc_html($action->__get('title'))
);
}
echo '</li></ul>';

add_action('wp_ajax_execute-nba-callback', function() {
\wp_send_json_error( new \WP_Error( 'geht_nicht', 'Test' ) );
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
document.querySelectorAll('.ionos-dashboard-nba a').forEach((link) => {
link.addEventListener('click', (event) => {
event.preventDefault();

wp.ajax
.send('execute-nba-callback', {
type: 'GET',
data: {
process: link.getAttribute('callback-id'),
id: link.getAttribute('data-id'),
},
})
.then((response) => {
if (response.redirect !== undefined) {
window.top.location.href = response.redirect;
}
if (response.addClass !== undefined) {
link.classList.add(response.addClass);
}
});
});
});