Skip to content

Commit

Permalink
Merge pull request #240 from newfold-labs/enhance/PRESS2-856-analytics
Browse files Browse the repository at this point in the history
Implement Analytics
  • Loading branch information
arunshenoy99 authored Jun 4, 2023
2 parents 2f54718 + 9666a96 commit 3d9202d
Show file tree
Hide file tree
Showing 28 changed files with 511 additions and 211 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/lint-check-spa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,14 @@ jobs:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-node-

- name: Setup Registry
run: printf "@newfold-labs:registry=https://npm.pkg.github.com/\n//npm.pkg.github.com/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc
if: steps.cache.outputs.cache-hit != 'true'

# Installs @wordpress/scripts for lint checks if it does not exist in the cache.
- name: Install dependencies
run: npm i @wordpress/scripts
run: npm i @wordpress/scripts @newfold-labs/js-utility-ui-analytics
if: steps.cache.outputs.cache-hit != 'true'

# Gets the files changed wrt to trunk and filters out the js files.
Expand Down
68 changes: 52 additions & 16 deletions includes/Data/Events.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,65 @@
namespace NewfoldLabs\WP\Module\Onboarding\Data;

/**
* List of Onboarding events.
* Contains data related to Onboarding Hiive Events.
*/
final class Events {
/**
* The category of an event.
*
* @var string
*/
protected static $category = 'wp-onboarding';

/**
* Contains a list of events with the key being the event slug.
*
* @var array
*/
protected static $events = array(
'nfd-module-onboarding-event-pageview' => array(
'category' => 'Admin',
'action' => 'pageview',
),
/**
* List of valid actions that an event can perform.
*
* A value of true indicates that the action is valid, set it to null if you want to invalidate an action.
*
* @var array
*/
protected static $valid_actions = array(
'pageview' => true,
'sidebar-opened' => true,
'sidebar-closed' => true,
'wp-experience' => true,
'primary-type' => true,
'secondary-type' => true,
'tax-information' => true,
'selected-style' => true,
'default-style' => true,
'customize-design' => true,
'font-selection' => true,
'theme-header' => true,
'homepage-layout' => true,
'top-priority' => true,
'top-priority-skipped' => true,
'exit-to-wordpress' => true,
'products-info' => true,
'yith-wonder/company-page-layout' => true,
'yith-wonder/contact-us-layout' => true,
'yith-wonder/blog-page-layout' => true,
'yith-wonder/testimonials-page-layout' => true,
'site-features' => true,
'color-selection' => true,
'color-selection-reset' => true,
);

/**
* Retrieves the active theme color variations.
* Returns the list of valid actions that an event can perform
*
* @return array
*/
public static function get_valid_actions() {
return self::$valid_actions;
}

/**
* Valid category of on event.
*
* @param array $event_slug Event data.
* @return array|boolean
* @return string
*/
public static function get_event( $event_slug ) {
return self::$events[ $event_slug ] ? self::$events[ $event_slug ] : false;
public static function get_category() {
return self::$category;
}
}
157 changes: 98 additions & 59 deletions includes/RestApi/EventsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,100 +3,139 @@

use NewfoldLabs\WP\Module\Onboarding\Data\Events;
use NewfoldLabs\WP\Module\Onboarding\Permissions;
use NewfoldLabs\WP\Module\Onboarding\Services\EventService;

/**
* [Class EventsController]
* Controller to send analytics events.
*/
class EventsController extends \WP_REST_Controller {

/**
* This is the REST API namespace that will be used for our custom API
* The namespace of the controller.
*
* @var string
*/
protected $namespace = 'newfold-onboarding/v1';
protected $namespace = 'newfold-onboarding/v1';

/**
* This is the REST endpoint
*
* @var string
*/
protected $rest_base = '/events';
/**
* The REST base endpoint.
*
* @var string
*/
protected $rest_base = '/events';

/**
* Register REST routes for EventsController class.
*
* @return void
*/
/**
* Register routes that the controller will expose.
*
* @return void
*/
public function register_routes() {
\register_rest_route(
$this->namespace,
$this->rest_base,
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array( $this, 'send_event' ),
'callback' => array( $this, 'send' ),
'permission_callback' => array( Permissions::class, 'rest_is_authorized_admin' ),
'args' => $this->get_send_args(),
),
)
);

\register_rest_route(
$this->namespace,
$this->rest_base . '/batch',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array( $this, 'send_batch' ),
'permission_callback' => array( Permissions::class, 'rest_is_authorized_admin' ),
'args' => $this->get_send_event_args(),
),
)
);
}

/**
* Get args for the send_event endpoint.
*
* @return array
*/
public function get_send_event_args() {
return array(
'slug' => array(
'required' => true,
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
),
'data' => array(
'type' => 'object',
),
);
/**
* Args for a single event.
*
* @return array
*/
public function get_send_args() {
return array(
'action' => array(
'required' => true,
'description' => __( 'Event action', 'wp-module-onboarding' ),
'type' => 'string',
'sanitize_callback' => 'sanitize_title',
'validate_callback' => array( EventService::class, 'validate_action' ),
),
'category' => array(
'default' => Events::get_category(),
'description' => __( 'Event category', 'wp-module-onboarding' ),
'type' => 'string',
'sanitize_callback' => 'sanitize_title',
'validate_callback' => array( EventService::class, 'validate_category' ),
),
'data' => array(
'description' => __( 'Event data', 'wp-module-onboarding' ),
'type' => 'object',
),
);
}

/**
* Sends a Hiive Event to the data module API.
*
* @param \WP_REST_Request $request The incoming request object.
* @return \WP_REST_Response|\WP_Error
*/
public function send( \WP_REST_Request $request ) {
return EventService::send( $request->get_params() );
}

/**
* Send events to the data module events API.
*
* @param \WP_REST_Request $request Request model.
*
* @return \WP_REST_Response|\WP_Error
*/
public function send_event( \WP_REST_Request $request ) {
$event = Events::get_event( $request->get_param( 'slug' ) );
if ( ! $event ) {
/**
* Sends an array of Hiive Events to the data module API programmatically.
*
* @param \WP_REST_Request $request The incoming request object.
* @return \WP_REST_Response|\WP_Error
*/
public function send_batch( \WP_REST_Request $request ) {
$events = $request->get_json_params();
if ( ! rest_is_array( $events ) ) {
return new \WP_Error(
'event-error',
'No such event found',
array( 'status' => 404 )
'nfd_module_onboarding_error',
__( 'Request does not contain an array of events.', 'wp-module-onboarding' )
);
}

$event['data'] = $request->get_param( 'data' );

if ( ! empty( $event['data'] ) && ! empty( $event['data']['stepID'] ) ) {
$event['data']['page'] = \admin_url( '/index.php?page=nfd-onboarding#' . $event['data']['stepID'] );
$response_errors = array();
foreach ( $events as $index => $event ) {
$response = EventService::send( $event );
if ( is_wp_error( $response ) ) {
array_push(
$response_errors,
array(
'index' => $index,
'data' => $response,
)
);
}
}

$event_data_request = new \WP_REST_Request(
\WP_REST_Server::CREATABLE,
NFD_MODULE_DATA_EVENTS_API
);
$event_data_request->set_body_params( $event );
$response = \rest_do_request( $event_data_request );
if ( $response->is_error() ) {
return $response->as_error();
if ( ! empty( $response_errors ) ) {
return new \WP_Error(
'nfd_module_onboarding_error',
__( 'Some events failed.', 'wp-module-onboarding' ),
array(
'data' => $response_errors,
)
);
}

return new \WP_REST_Response(
$response,
$response->status
array(),
202
);
}
}
83 changes: 83 additions & 0 deletions includes/Services/EventService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

namespace NewfoldLabs\WP\Module\Onboarding\Services;

use NewfoldLabs\WP\Module\Onboarding\Data\Events;

/**
* Class for handling analytics events.
*/
class EventService {

/**
* Sends a Hiive Event to the data module API.
*
* @param array $event The event to send.
* @return WP_REST_Response|WP_Error
*/
public static function send( $event ) {
$event = self::validate( $event );
if ( ! $event ) {
return new \WP_Error(
'nfd_module_onboarding_error',
__( 'Bad event structure/value.', 'wp-module-onboarding' )
);
}

$event_data_request = new \WP_REST_Request(
\WP_REST_Server::CREATABLE,
NFD_MODULE_DATA_EVENTS_API
);
$event_data_request->set_body_params( $event );

$response = rest_do_request( $event_data_request );
if ( $response->is_error() ) {
return $response->as_error();
}

return $response;
}

/**
* Validates the category of an event.
*
* @param string $category The category of an event.
* @return boolean
*/
public static function validate_category( $category ) {
return Events::get_category() === $category;
}

/**
* Validates the action performed in an event.
*
* @param string $action The action performed in an event.
* @return boolean
*/
public static function validate_action( $action ) {
$valid_actions = Events::get_valid_actions();
if ( ! isset( $valid_actions[ $action ] ) ) {
return false;
}

return true;
}

/**
* Sanitizes and validates the action and category parameters of an event.
*
* @param array $event The event to sanitize and validate.
* @return array|boolean
*/
public static function validate( $event ) {
if ( ! isset( $event['action'] ) || ! self::validate_action( $event['action'] ) ) {
return false;
}

if ( ! isset( $event['category'] ) || ! self::validate_category( $event['category'] ) ) {
return false;
}

return $event;
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"test:unit": "npx wp-env run phpunit 'phpunit -c /var/www/html/wp-content/plugins//phpunit.xml --verbose'"
},
"dependencies": {
"@newfold-labs/js-utility-ui-analytics": "1.0.0",
"@wordpress/interface": "^5.10.0",
"@wordpress/style-engine": "^0.11.0",
"classnames": "^2.3.1",
Expand Down
Loading

0 comments on commit 3d9202d

Please sign in to comment.