From e4c1e77336b0494de824385987c0978db391d10f Mon Sep 17 00:00:00 2001 From: DerHerrFeldmann Date: Thu, 13 Feb 2025 14:09:27 +0000 Subject: [PATCH 1/5] implement nba block --- .../essentials/inc/dashboard/index.php | 1 + .../blocks/next-best-actions/block.json | 17 +++ .../blocks/next-best-actions/edit.js | 14 ++ .../blocks/next-best-actions/index.js | 8 ++ .../blocks/next-best-actions/model/nba.php | 134 ++++++++++++++++++ .../blocks/next-best-actions/render.php | 45 ++++++ 6 files changed, 219 insertions(+) create mode 100644 packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/block.json create mode 100644 packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/edit.js create mode 100644 packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/index.js create mode 100644 packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php create mode 100644 packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php diff --git a/packages/wp-plugin/essentials/inc/dashboard/index.php b/packages/wp-plugin/essentials/inc/dashboard/index.php index 05e4bac4..6b13d53e 100644 --- a/packages/wp-plugin/essentials/inc/dashboard/index.php +++ b/packages/wp-plugin/essentials/inc/dashboard/index.php @@ -41,6 +41,7 @@ \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 diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/block.json b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/block.json new file mode 100644 index 00000000..13beeef0 --- /dev/null +++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/block.json @@ -0,0 +1,17 @@ +{ + "$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", + "render": "file:./render.php" +} diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/edit.js b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/edit.js new file mode 100644 index 00000000..712e160f --- /dev/null +++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/edit.js @@ -0,0 +1,14 @@ +import { __ } from '@wordpress/i18n'; +import { useBlockProps } from '@wordpress/block-editor'; +import ServerSideRender from '@wordpress/server-side-render'; + +export default function Edit(props) { + return ( +
+ +
+ ); +} diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/index.js b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/index.js new file mode 100644 index 00000000..0cf1a1df --- /dev/null +++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/index.js @@ -0,0 +1,8 @@ +import { registerBlockType } from '@wordpress/blocks'; +import Edit from './edit.js'; +import metadata from './block.json'; + +registerBlockType(metadata.name, { + edit: Edit, + save: () => null, // server-side rendering doesnt need a save function +}); diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php new file mode 100644 index 00000000..d5947035 --- /dev/null +++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php @@ -0,0 +1,134 @@ +id = $id; + $this->title = $title; + $this->description = $description; + $this->image = $image; + $this->link = $link; + $this->callback = $callback; + } + + /** + * Get ID. + * + * @return string + */ + public function get_id() { + return $this->id; + } + + /** + * Get title. + * + * @return string + */ + public function get_title() { + return $this->title; + } + + /** + * Get description. + * + * @return string + */ + public function get_description() { + return $this->description; + } + + /** + * Get image. + * + * @return string + */ + public function get_image() { + return $this->image; + } + + /** + * Get link. + * + * @return string + */ + public function get_link() { + return $this->link; + } + + /** + * Get callback. + * + * @return string + */ + public function get_callback() { + if ( is_callable( $this->callback ) ) { + $result = call_user_func( $this->callback ); + + if ( is_bool( $result ) ) { + return $result; + } + } + + return false; + } +} diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php new file mode 100644 index 00000000..4511f7fc --- /dev/null +++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php @@ -0,0 +1,45 @@ +%s', \esc_html__('Next best actions ⚡', 'ionos-essentials')); + +$actions = array( + new NBA( + id: 'checkPluginsPage', + title: 'Check Plugins Page', + description: 'Check the plugins page for updates and security issues.', + image: 'https://raw.githubusercontent.com/codeformm/mitaka-kichijoji-wapuu/main/mitaka-kichijoji-wapuu.png', + link: admin_url('plugins.php'), + callback: function() { + echo 'this is a test!'; + return true; + } + ) +); + +echo ''; + +// debug callback on dashboard +//echo '
';
+//$actions[0]->get_callback();
+//wp_die();

From 9bce76a955ae2223548ec0ab33a3bbe338ab0908 Mon Sep 17 00:00:00 2001
From: DerHerrFeldmann 
Date: Thu, 13 Feb 2025 21:28:39 +0000
Subject: [PATCH 2/5] set link to target _top

---
 .../src/dashboard/blocks/next-best-actions/render.php           | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php
index 4511f7fc..73a3766a 100644
--- a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php
+++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php
@@ -32,7 +32,7 @@
 echo '
    '; foreach ($actions as $action) { printf( - '
  • %s
  • ', + '
  • %s
  • ', \esc_url($action->get_link()), \esc_html($action->get_title()) ); From 45b59d180420f9c3c24f1bd2e2b62f6de3efe31b Mon Sep 17 00:00:00 2001 From: DerHerrFeldmann Date: Mon, 17 Feb 2025 22:16:46 +0000 Subject: [PATCH 3/5] refactor: simplify NBA class and enhance callback functionality --- .../blocks/next-best-actions/model/nba.php | 177 ++++++------------ .../blocks/next-best-actions/render.php | 32 ++-- 2 files changed, 75 insertions(+), 134 deletions(-) diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php index d5947035..68090b15 100644 --- a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php +++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php @@ -8,127 +8,58 @@ /** * Class NBA */ -class NBA { - /** - * ID of the NBA - * - * @var string - */ - private $id = ''; - - /** - * Title of the NBA - * - * @var string - */ - private $title = ''; - - /** - * Description of the NBA - * - * @var string - */ - private $description = ''; - - /** - * Image url of the NBA - * - * @var string - */ - private $image = ''; - - /** - * Link of the NBA - * - * @var string - */ - private $link = ''; - - /** - * Callback function of the NBA - * - * @var string - */ - private $callback = ''; - - /** - * NBA constructor. - * - * @param string $id - * @param string $title - * @param string $description - * @param string $image - * @param string $link - * @param string $callback - */ - public function __construct( $id, $title, $description, $image, $link, $callback ) { - $this->id = $id; - $this->title = $title; - $this->description = $description; - $this->image = $image; - $this->link = $link; - $this->callback = $callback; - } - - /** - * Get ID. - * - * @return string - */ - public function get_id() { - return $this->id; - } - - /** - * Get title. - * - * @return string - */ - public function get_title() { - return $this->title; - } - - /** - * Get description. - * - * @return string - */ - public function get_description() { - return $this->description; - } - - /** - * Get image. - * - * @return string - */ - public function get_image() { - return $this->image; - } - - /** - * Get link. - * - * @return string - */ - public function get_link() { - return $this->link; - } - - /** - * Get callback. - * - * @return string - */ - public function get_callback() { - if ( is_callable( $this->callback ) ) { - $result = call_user_func( $this->callback ); - - if ( is_bool( $result ) ) { - return $result; - } - } - - return false; - } +final class NBA +{ + const WP_OPTION_NAME='NBA_OPTION'; + + static protected array $_wp_option; + + function __construct( + readonly string $id, + readonly string $title, + readonly string $description, + 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, + 'image' => $this->image, + 'callback' => is_callable($this->callback) ? call_user_func($this->callback) : null, + 'completed' => static::_getOption($this->id, 'completed'), + 'dismissed' => static::_getOption($this->id, 'dismissed'), + default => throw new \InvalidArgumentException("Invalid property: $optionName"), + }; + } + + protected static function _getWPOption() { + $option = \get_option(static::WP_OPTION_NAME); + return is_array( $option ) ? $option : []; + } + + + protected static function _setOption(string $id, string $optionName, string $value) { + static::$_wp_option = static::_getWPOption(); + static::$_wp_option[$id][$optionName] = $value; + \update_option(static::WP_OPTION_NAME, static::$_wp_option); + } + + protected static function _getOption(string $id, string $optionName): mixed { + static::$_wp_option = static::_getWPOption(); + return static::$_wp_option[$id][$optionName] ?? null; + } } diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php index 73a3766a..80f04ec1 100644 --- a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php +++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php @@ -21,25 +21,35 @@ title: 'Check Plugins Page', description: 'Check the plugins page for updates and security issues.', image: 'https://raw.githubusercontent.com/codeformm/mitaka-kichijoji-wapuu/main/mitaka-kichijoji-wapuu.png', - link: admin_url('plugins.php'), - callback: function() { - echo 'this is a test!'; - return true; - } - ) + callback: function($action) { + $action->__set('completed', true); + wp_safe_redirect(admin_url('plugins.php')); + exit; + }, + ), + new NBA( + id: 'checkThemesPage', + title: 'Check Themes Page', + description: 'Check the themes page for updates and security issues.', + image: 'https://raw.githubusercontent.com/codeformm/mitaka-kichijoji-wapuu/main/mitaka-kichijoji-wapuu.png', + callback: function($action) { + $action->__set('completed', true); + wp_safe_redirect(admin_url('themes.php')); + exit; + }, + ), ); echo '
      '; foreach ($actions as $action) { printf( - '
    • %s
    • ', - \esc_url($action->get_link()), - \esc_html($action->get_title()) + '
    • %s
    • ', + \esc_html($action->__get('title')) . ' -> ' . ($action->__get('completed') ? 'Completed' : 'Not completed') ); } echo '
    '; -// debug callback on dashboard +//debug callback on dashboard //echo '
    ';
    -//$actions[0]->get_callback();
    +//$actions[0]->__set('completed', true);
     //wp_die();
    
    From 3427acb81181d8653d71cdc2898f29bc3b7ec8e6 Mon Sep 17 00:00:00 2001
    From: DerHerrFeldmann 
    Date: Mon, 17 Feb 2025 22:27:43 +0000
    Subject: [PATCH 4/5] refactor: optimize NBA option handling by caching WP
     options
    
    ---
     .../blocks/next-best-actions/model/nba.php        | 15 +++++++++------
     1 file changed, 9 insertions(+), 6 deletions(-)
    
    diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php
    index 68090b15..580de0f8 100644
    --- a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php
    +++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php
    @@ -47,19 +47,22 @@ function __get(string $optionName): mixed {
       }
     
       protected static function _getWPOption() {
    +    if(!isset(static::$_wp_option)) {
           $option = \get_option(static::WP_OPTION_NAME);
    -      return is_array( $option ) ? $option : [];
    +      static::$_wp_option = is_array( $option ) ? $option : [];
    +    }
    +    return static::$_wp_option;
       }
     
     
       protected static function _setOption(string $id, string $optionName, string $value) {
    -    static::$_wp_option = static::_getWPOption();
    -    static::$_wp_option[$id][$optionName] = $value;
    -    \update_option(static::WP_OPTION_NAME, static::$_wp_option);
    +    $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 {
    -    static::$_wp_option = static::_getWPOption();
    -    return static::$_wp_option[$id][$optionName] ?? null;
    +    $wp_option = static::_getWPOption();
    +    return $wp_option[$id][$optionName] ?? null;
       }
     }
    
    From ca35b9b409f1c5d0265d5e3afa4e0d93c269f495 Mon Sep 17 00:00:00 2001
    From: DerHerrFeldmann 
    Date: Fri, 21 Feb 2025 13:09:14 +0100
    Subject: [PATCH 5/5] implement dismiss logic
    
    ---
     .../essentials/inc/dashboard/index.php        | 45 +++++++++++++
     .../blocks/next-best-actions/block.json       |  4 ++
     .../blocks/next-best-actions/data.php         | 62 ++++++++++++++++++
     .../blocks/next-best-actions/edit.js          | 14 ----
     .../blocks/next-best-actions/index.js         |  9 +--
     .../{model/nba.php => model.php}              | 13 ++--
     .../blocks/next-best-actions/render.php       | 65 ++++++++-----------
     .../blocks/next-best-actions/view.js          | 22 +++++++
     8 files changed, 171 insertions(+), 63 deletions(-)
     create mode 100644 packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/data.php
     delete mode 100644 packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/edit.js
     rename packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/{model/nba.php => model.php} (86%)
     create mode 100644 packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/view.js
    
    diff --git a/packages/wp-plugin/essentials/inc/dashboard/index.php b/packages/wp-plugin/essentials/inc/dashboard/index.php
    index 6b13d53e..84a57c2f 100644
    --- a/packages/wp-plugin/essentials/inc/dashboard/index.php
    +++ b/packages/wp-plugin/essentials/inc/dashboard/index.php
    @@ -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;
     
     /*
    @@ -42,6 +45,7 @@
       \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
    @@ -166,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'));
    +});
    +
    diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/block.json b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/block.json
    index 13beeef0..549ebcf3 100644
    --- a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/block.json
    +++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/block.json
    @@ -13,5 +13,9 @@
       },
       "textdomain": "ionos-essentials",
       "editorScript": "file:./index.js",
    +  "viewScript": [
    +    "file:./view.js",
    +    "wp-util"
    +  ],
       "render": "file:./render.php"
     }
    diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/data.php b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/data.php
    new file mode 100644
    index 00000000..2798d5b3
    --- /dev/null
    +++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/data.php
    @@ -0,0 +1,62 @@
    + 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,
    +    )
    +  );
    +}
    +
    diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/edit.js b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/edit.js
    deleted file mode 100644
    index 712e160f..00000000
    --- a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/edit.js
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -import { __ } from '@wordpress/i18n';
    -import { useBlockProps } from '@wordpress/block-editor';
    -import ServerSideRender from '@wordpress/server-side-render';
    -
    -export default function Edit(props) {
    -  return (
    -    
    - -
    - ); -} diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/index.js b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/index.js index 0cf1a1df..0f8df3ce 100644 --- a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/index.js +++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/index.js @@ -1,8 +1 @@ -import { registerBlockType } from '@wordpress/blocks'; -import Edit from './edit.js'; -import metadata from './block.json'; - -registerBlockType(metadata.name, { - edit: Edit, - save: () => null, // server-side rendering doesnt need a save function -}); +(()=>{"use strict";var e={n:t=>{var o=t&&t.__esModule?()=>t.default:()=>t;return e.d(o,{a:o}),o},d:(t,o)=>{for(var r in o)e.o(o,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:o[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.wp.blocks,o=(window.wp.i18n,window.wp.blockEditor),r=window.wp.serverSideRender;var n=e.n(r);const i=window.ReactJSXRuntime,s=JSON.parse('{"UU":"ionos-dashboard-page/next-best-actions"}');(0,t.registerBlockType)(s.UU,{edit:function(e){return(0,i.jsx)("div",{...(0,o.useBlockProps)(),children:(0,i.jsx)(n(),{block:e.name,attributes:e.attributes})})},save:()=>null})})(); \ No newline at end of file diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model.php similarity index 86% rename from packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php rename to packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model.php index 580de0f8..adba215e 100644 --- a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model/nba.php +++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/model.php @@ -3,12 +3,12 @@ * This class represents the Next Best Action (NBA) model. */ -namespace ionos_wordpress\essentials\dashboard\blocks\next_best_actions\model; +namespace ionos_wordpress\essentials\dashboard\blocks\next_best_actions; /** * Class NBA */ -final class NBA +final class Model { const WP_OPTION_NAME='NBA_OPTION'; @@ -18,6 +18,8 @@ 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, @@ -38,8 +40,10 @@ function __get(string $optionName): mixed { 'id' => $this->id, 'title' => $this->title, 'description' => $this->description, + 'link' => $this->link, + 'completeOnClickCallback' => $this->completeOnClickCallback, 'image' => $this->image, - 'callback' => is_callable($this->callback) ? call_user_func($this->callback) : null, + 'callback' => $this->callback, 'completed' => static::_getOption($this->id, 'completed'), 'dismissed' => static::_getOption($this->id, 'dismissed'), default => throw new \InvalidArgumentException("Invalid property: $optionName"), @@ -63,6 +67,7 @@ protected static function _setOption(string $id, string $optionName, string $val protected static function _getOption(string $id, string $optionName): mixed { $wp_option = static::_getWPOption(); - return $wp_option[$id][$optionName] ?? null; + return $wp_option[$id][$optionName] ?? false; } } + diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php index 80f04ec1..cbd13199 100644 --- a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php +++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/render.php @@ -6,50 +6,41 @@ use ionos_wordpress\essentials\dashboard\blocks\next_best_actions\model\NBA; -$model_path = __DIR__ . '/model/nba.php'; +$nba_data = __DIR__ . '/data.php'; -if (! file_exists($model_path)) { +if (! file_exists($nba_data)) { return; } +require_once $nba_data; -require_once $model_path; -printf('

    %s

    ', \esc_html__('Next best actions ⚡', 'ionos-essentials')); +$actions = getNBAData(); +if (! is_array($actions)) { + return; +} -$actions = array( - new NBA( - id: 'checkPluginsPage', - title: 'Check Plugins Page', - description: 'Check the plugins page for updates and security issues.', - image: 'https://raw.githubusercontent.com/codeformm/mitaka-kichijoji-wapuu/main/mitaka-kichijoji-wapuu.png', - callback: function($action) { - $action->__set('completed', true); - wp_safe_redirect(admin_url('plugins.php')); - exit; - }, - ), - new NBA( - id: 'checkThemesPage', - title: 'Check Themes Page', - description: 'Check the themes page for updates and security issues.', - image: 'https://raw.githubusercontent.com/codeformm/mitaka-kichijoji-wapuu/main/mitaka-kichijoji-wapuu.png', - callback: function($action) { - $action->__set('completed', true); - wp_safe_redirect(admin_url('themes.php')); - exit; - }, - ), -); - -echo ''; -//debug callback on dashboard -//echo '
    ';
    -//$actions[0]->__set('completed', true);
    -//wp_die();
    +add_action('wp_ajax_execute-nba-callback', function() {
    +  \wp_send_json_error( new \WP_Error( 'geht_nicht', 'Test' ) );
    +});
    diff --git a/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/view.js b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/view.js
    new file mode 100644
    index 00000000..a1d27470
    --- /dev/null
    +++ b/packages/wp-plugin/essentials/src/dashboard/blocks/next-best-actions/view.js
    @@ -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);
    +        }
    +      });
    +  });
    +});