From 6fecf6533237880bd8c455bd7f0d017d1f89d385 Mon Sep 17 00:00:00 2001 From: Alec Geatches Date: Mon, 14 Oct 2024 12:06:42 -0600 Subject: [PATCH 1/4] Add `em_field_created` point --- .../editorial-metadata/editorial-metadata.php | 31 ++++++++++++------- modules/telemetry/telemetry.php | 20 ++++++++++++ 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/modules/editorial-metadata/editorial-metadata.php b/modules/editorial-metadata/editorial-metadata.php index 7da24ad..5a40085 100644 --- a/modules/editorial-metadata/editorial-metadata.php +++ b/modules/editorial-metadata/editorial-metadata.php @@ -270,8 +270,8 @@ public static function add_metadata_to_term( WP_Term $term ): WP_Term { return $term; } - $term_meta = []; - $term_meta[ self::METADATA_TYPE_KEY ] = get_term_meta( $term->term_id, self::METADATA_TYPE_KEY, true ); + $term_meta = []; + $term_meta[ self::METADATA_TYPE_KEY ] = get_term_meta( $term->term_id, self::METADATA_TYPE_KEY, true ); $term_meta[ self::METADATA_POSTMETA_KEY ] = get_term_meta( $term->term_id, self::METADATA_POSTMETA_KEY, true ); if ( '' === $term_meta[ self::METADATA_TYPE_KEY ] || '' === $term_meta[ self::METADATA_POSTMETA_KEY ] ) { @@ -294,7 +294,7 @@ public static function insert_editorial_metadata_term( array $args ): WP_Term|WP 'slug' => $args['slug'] ?? sanitize_title( $args['name'] ), 'description' => $args['description'] ?? '', ]; - $term_name = $args['name']; + $term_name = $args['name']; $inserted_term = wp_insert_term( $term_name, self::METADATA_TAXONOMY, $term_to_save ); @@ -304,13 +304,13 @@ public static function insert_editorial_metadata_term( array $args ): WP_Term|WP $term_id = $inserted_term['term_id']; - $metadata_type = $args['type']; - $metadata_postmeta_key = self::get_postmeta_key( $metadata_type, $term_id ); + $metadata_type = $args['type']; + $metadata_postmeta_key = self::get_postmeta_key( $metadata_type, $term_id ); $type_meta_result = add_term_meta( $term_id, self::METADATA_TYPE_KEY, $metadata_type ); if ( is_wp_error( $type_meta_result ) ) { return $type_meta_result; - } else if ( ! $type_meta_result ) { + } elseif ( ! $type_meta_result ) { // If we can't save the type, we should delete the term wp_delete_term( $term_id, self::METADATA_TAXONOMY ); return new WP_Error( 'invalid', __( 'Unable to create editorial metadata.', 'vip-workflow' ) ); @@ -319,7 +319,7 @@ public static function insert_editorial_metadata_term( array $args ): WP_Term|WP $postmeta_meta_result = add_term_meta( $term_id, self::METADATA_POSTMETA_KEY, $metadata_postmeta_key ); if ( is_wp_error( $postmeta_meta_result ) ) { return $postmeta_meta_result; - } else if ( ! $postmeta_meta_result ) { + } elseif ( ! $postmeta_meta_result ) { // If we can't save the postmeta key, we should delete the term delete_term_meta( $term_id, self::METADATA_TYPE_KEY ); wp_delete_term( $term_id, self::METADATA_TAXONOMY ); @@ -328,6 +328,15 @@ public static function insert_editorial_metadata_term( array $args ): WP_Term|WP $term_result = self::get_editorial_metadata_term_by( 'id', $term_id ); + if ( ! is_wp_error( $term_result ) ) { + /** + * Fires after a new editorial metadata field is added to the database. + * + * @param WP_Term $term The editorial metadata term object. + */ + do_action( 'vw_add_editorial_metadata_field', $term_result ); + } + return $term_result; } @@ -342,13 +351,13 @@ public static function update_editorial_metadata_term( int $term_id, array $args $old_term = self::get_editorial_metadata_term_by( 'id', $term_id ); if ( is_wp_error( $old_term ) ) { return $old_term; - } else if ( ! $old_term ) { + } elseif ( ! $old_term ) { return new WP_Error( 'invalid', __( "Editorial metadata doesn't exist.", 'vip-workflow' ), array( 'status' => 400 ) ); } $term_fields_to_update = [ - 'name' => isset( $args['name'] ) ? $args['name'] : $old_term->name, - 'slug' => isset( $args['slug'] ) ? $args['slug'] : $old_term->slug, + 'name' => isset( $args['name'] ) ? $args['name'] : $old_term->name, + 'slug' => isset( $args['slug'] ) ? $args['slug'] : $old_term->slug, 'description' => isset( $args['description'] ) ? $args['description'] : $old_term->description, ]; @@ -375,7 +384,7 @@ public static function delete_editorial_metadata_term( int $term_id ): bool|WP_E $term = self::get_editorial_metadata_term_by( 'id', $term_id ); if ( is_wp_error( $term ) ) { return $term; - } else if ( ! $term ) { + } elseif ( ! $term ) { return new WP_Error( 'invalid', __( "Editorial metadata term doesn't exist.", 'vip-workflow' ), array( 'status' => 400 ) ); } diff --git a/modules/telemetry/telemetry.php b/modules/telemetry/telemetry.php index c2b21f4..4d997b3 100644 --- a/modules/telemetry/telemetry.php +++ b/modules/telemetry/telemetry.php @@ -4,6 +4,7 @@ use Automattic\VIP\Telemetry\Tracks; use VIPWorkflow\Modules\CustomStatus; +use VIPWorkflow\Modules\EditorialMetadata; use VIPWorkflow\Modules\Shared\PHP\HelperUtilities; use WP_Post; use WP_Term; @@ -34,6 +35,9 @@ public static function init(): void { // Settings events add_action( 'vw_upgrade_version', [ __CLASS__, 'record_admin_update' ], 10, 2 ); add_action( 'vw_save_settings', [ __CLASS__, 'record_settings_update' ], 10, 2 ); + + // Editorial Metadata events + add_action( 'vw_add_editorial_metadata_field', [ __CLASS__, 'record_add_editorial_metadata_field' ], 10, 1 ); } // Custom Status events @@ -241,6 +245,22 @@ protected static function record_send_to_email_toggle( string $email_address ): self::$tracks->record_event( 'send_to_email_enabled' ); } } + + // Editorial Metadata events + + /** + * Record an event when an editorial metadata field is added + * + * @param WP_Term $editorial_metadata The name of the field + */ + public static function record_add_editorial_metadata_field( WP_Term $editorial_metadata ): void { + self::$tracks->record_event( 'em_field_created', [ + 'term_id' => $editorial_metadata->term_id, + 'name' => $editorial_metadata->name, + 'slug' => $editorial_metadata->slug, + 'type' => $editorial_metadata->meta[ EditorialMetadata::METADATA_TYPE_KEY ], + ] ); + } } Telemetry::init(); From c122baf6aa5ae7845209abaf9593724462220d44 Mon Sep 17 00:00:00 2001 From: Alec Geatches Date: Mon, 14 Oct 2024 12:17:29 -0600 Subject: [PATCH 2/4] Add `em_field_changed`/`em_field_deleted` datapoints --- .../editorial-metadata/editorial-metadata.php | 18 +++++++++- modules/telemetry/telemetry.php | 34 ++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/modules/editorial-metadata/editorial-metadata.php b/modules/editorial-metadata/editorial-metadata.php index 5a40085..f3158ca 100644 --- a/modules/editorial-metadata/editorial-metadata.php +++ b/modules/editorial-metadata/editorial-metadata.php @@ -371,6 +371,15 @@ public static function update_editorial_metadata_term( int $term_id, array $args $term_result = self::get_editorial_metadata_term_by( 'id', $term_id ); + if ( $term_result ) { + /** + * Fires after an editorial metadata field is updated in the database. + * + * @param WP_Term $editorial_metadata The updated editorial metadata WP_Term object. + */ + do_action( 'vw_update_editorial_metadata_field', $term_result ); + } + return $term_result; } @@ -401,7 +410,14 @@ public static function delete_editorial_metadata_term( int $term_id ): bool|WP_E return new WP_Error( 'invalid', __( 'Unable to delete editorial metadata term.', 'vip-workflow' ) ); } - do_action( 'vw_editorial_metadata_term_deleted', $term_id ); + /** + * Fires after an editorial metadata field is deleted. + * + * @param int $term_id The ID of the editorial metadata field being deleted + * @param string $term_name The name of the editorial metadata field being deleted + * @param string $term_slug The slug of the editorial metadata field being deleted + */ + do_action( 'vw_editorial_metadata_term_deleted', $term_id, $term->name, $term->slug ); return $result; } diff --git a/modules/telemetry/telemetry.php b/modules/telemetry/telemetry.php index 4d997b3..f40a91a 100644 --- a/modules/telemetry/telemetry.php +++ b/modules/telemetry/telemetry.php @@ -26,8 +26,8 @@ public static function init(): void { // Custom Status events add_action( 'transition_post_status', [ __CLASS__, 'record_custom_status_change' ], 10, 3 ); add_action( 'vw_add_custom_status', [ __CLASS__, 'record_add_custom_status' ], 10, 3 ); - add_action( 'vw_delete_custom_status', [ __CLASS__, 'record_delete_custom_status' ], 10, 3 ); add_action( 'vw_update_custom_status', [ __CLASS__, 'record_update_custom_status' ], 10, 2 ); + add_action( 'vw_delete_custom_status', [ __CLASS__, 'record_delete_custom_status' ], 10, 3 ); // Notification events add_action( 'vw_notification_status_change', [ __CLASS__, 'record_notification_sent' ], 10, 3 ); @@ -38,6 +38,8 @@ public static function init(): void { // Editorial Metadata events add_action( 'vw_add_editorial_metadata_field', [ __CLASS__, 'record_add_editorial_metadata_field' ], 10, 1 ); + add_action( 'vw_update_editorial_metadata_field', [ __CLASS__, 'record_update_editorial_metadata_field' ], 10, 1 ); + add_action( 'vw_editorial_metadata_term_deleted', [ __CLASS__, 'record_delete_editorial_metadata_field' ], 10, 3 ); } // Custom Status events @@ -261,6 +263,36 @@ public static function record_add_editorial_metadata_field( WP_Term $editorial_m 'type' => $editorial_metadata->meta[ EditorialMetadata::METADATA_TYPE_KEY ], ] ); } + + /** + * Record an event when an editorial metadata field is updated + * + * @param WP_Term $updated_status The updated status WP_Term object. + * @param array $update_args The arguments used to update the status. + */ + public static function record_update_editorial_metadata_field( WP_Term $editorial_metadata ): void { + self::$tracks->record_event( 'em_field_changed', [ + 'term_id' => $editorial_metadata->term_id, + 'name' => $editorial_metadata->name, + 'slug' => $editorial_metadata->slug, + 'type' => $editorial_metadata->meta[ EditorialMetadata::METADATA_TYPE_KEY ], + ] ); + } + + /** + * Record an event when an editorial metadata field is deleted + * + * @param int $term_id The editorial metadata field term ID + * @param string $term_name The editorial metadata name + * @param string $slug The editorial metadata slug + */ + public static function record_delete_editorial_metadata_field( int $term_id, string $term_name, string $slug ): void { + self::$tracks->record_event( 'em_field_deleted', [ + 'term_id' => $term_id, + 'name' => $term_name, + 'slug' => $slug, + ] ); + } } Telemetry::init(); From 58b9eb49a5ab70ab8e8233b0824b641bd0cd3941 Mon Sep 17 00:00:00 2001 From: Alec Geatches Date: Mon, 14 Oct 2024 12:46:04 -0600 Subject: [PATCH 3/4] Add type to deleted metadata field data, track EM fields used in publish --- .../editorial-metadata/editorial-metadata.php | 6 ++- modules/telemetry/telemetry.php | 37 ++++++++++++++++++- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/modules/editorial-metadata/editorial-metadata.php b/modules/editorial-metadata/editorial-metadata.php index f3158ca..ce66202 100644 --- a/modules/editorial-metadata/editorial-metadata.php +++ b/modules/editorial-metadata/editorial-metadata.php @@ -398,7 +398,8 @@ public static function delete_editorial_metadata_term( int $term_id ): bool|WP_E } // Delete the post meta for the term - $post_meta_key = self::get_postmeta_key( $term->meta[ self::METADATA_TYPE_KEY ], $term_id ); + $metadata_type = $term->meta[ self::METADATA_TYPE_KEY ]; + $post_meta_key = self::get_postmeta_key( $metadata_type, $term_id ); delete_post_meta_by_key( $post_meta_key ); delete_term_meta( $term_id, self::METADATA_TYPE_KEY ); @@ -416,8 +417,9 @@ public static function delete_editorial_metadata_term( int $term_id ): bool|WP_E * @param int $term_id The ID of the editorial metadata field being deleted * @param string $term_name The name of the editorial metadata field being deleted * @param string $term_slug The slug of the editorial metadata field being deleted + * @param string $metadata_type The type of field, e.g. 'date', 'text' */ - do_action( 'vw_editorial_metadata_term_deleted', $term_id, $term->name, $term->slug ); + do_action( 'vw_editorial_metadata_term_deleted', $term_id, $term->name, $term->slug, $metadata_type ); return $result; } diff --git a/modules/telemetry/telemetry.php b/modules/telemetry/telemetry.php index f40a91a..ec1e4e1 100644 --- a/modules/telemetry/telemetry.php +++ b/modules/telemetry/telemetry.php @@ -39,7 +39,7 @@ public static function init(): void { // Editorial Metadata events add_action( 'vw_add_editorial_metadata_field', [ __CLASS__, 'record_add_editorial_metadata_field' ], 10, 1 ); add_action( 'vw_update_editorial_metadata_field', [ __CLASS__, 'record_update_editorial_metadata_field' ], 10, 1 ); - add_action( 'vw_editorial_metadata_term_deleted', [ __CLASS__, 'record_delete_editorial_metadata_field' ], 10, 3 ); + add_action( 'vw_editorial_metadata_term_deleted', [ __CLASS__, 'record_delete_editorial_metadata_field' ], 10, 4 ); } // Custom Status events @@ -75,6 +75,13 @@ public static function record_custom_status_change( string $new_status, string $ 'new_status' => $new_status, 'post_id' => $post->ID, ] ); + + if ( 'publish' === $new_status ) { + self::$tracks->record_event( 'post_custom_status_published', [ + 'post_id' => $post->ID, + 'em_fields_filled' => self::get_filled_em_fields_for_post( $post->ID ), + ] ); + } } /** @@ -285,14 +292,40 @@ public static function record_update_editorial_metadata_field( WP_Term $editoria * @param int $term_id The editorial metadata field term ID * @param string $term_name The editorial metadata name * @param string $slug The editorial metadata slug + * @param string $metadata_type The type of field, e.g. 'date', 'text' */ - public static function record_delete_editorial_metadata_field( int $term_id, string $term_name, string $slug ): void { + public static function record_delete_editorial_metadata_field( int $term_id, string $term_name, string $slug, string $metadata_type ): void { self::$tracks->record_event( 'em_field_deleted', [ 'term_id' => $term_id, 'name' => $term_name, 'slug' => $slug, + 'type' => $metadata_type, ] ); } + + // Utility methods + + /** + * Get the number of filled editorial metadata fields for a post + * + * @param int $post_id The post ID + * @return int The number of fields with a value set + */ + private static function get_filled_em_fields_for_post( int $post_id ): int { + $editorial_metadata_terms = EditorialMetadata::get_editorial_metadata_terms(); + $filled_em_fields = 0; + + foreach ( $editorial_metadata_terms as $em_term ) { + $post_meta_key = $em_term->meta[ EditorialMetadata::METADATA_POSTMETA_KEY ]; + $post_meta_value = get_post_meta( $post_id, $post_meta_key, true ); + + if ( '' !== $post_meta_value ) { + ++$filled_em_fields; + } + } + + return $filled_em_fields; + } } Telemetry::init(); From d93246a271d7c217e83e5e0efed15643696347ad Mon Sep 17 00:00:00 2001 From: Alec Geatches Date: Mon, 14 Oct 2024 12:56:56 -0600 Subject: [PATCH 4/4] Add total EM field count to published event --- modules/telemetry/telemetry.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/modules/telemetry/telemetry.php b/modules/telemetry/telemetry.php index ec1e4e1..5386f91 100644 --- a/modules/telemetry/telemetry.php +++ b/modules/telemetry/telemetry.php @@ -77,9 +77,12 @@ public static function record_custom_status_change( string $new_status, string $ ] ); if ( 'publish' === $new_status ) { + $em_field_counts = self::get_em_field_counts_for_post( $post->ID ); + self::$tracks->record_event( 'post_custom_status_published', [ 'post_id' => $post->ID, - 'em_fields_filled' => self::get_filled_em_fields_for_post( $post->ID ), + 'em_fields_filled' => $em_field_counts['filled'], + 'em_fields_total' => $em_field_counts['total'], ] ); } } @@ -309,9 +312,11 @@ public static function record_delete_editorial_metadata_field( int $term_id, str * Get the number of filled editorial metadata fields for a post * * @param int $post_id The post ID - * @return int The number of fields with a value set + * @return array An associative array with keys: + * int 'filled_count': The number of filled fields + * int 'total_count': The total number of EM fields available */ - private static function get_filled_em_fields_for_post( int $post_id ): int { + private static function get_em_field_counts_for_post( int $post_id ): array { $editorial_metadata_terms = EditorialMetadata::get_editorial_metadata_terms(); $filled_em_fields = 0; @@ -324,7 +329,10 @@ private static function get_filled_em_fields_for_post( int $post_id ): int { } } - return $filled_em_fields; + return [ + 'filled' => $filled_em_fields, + 'total' => count( $editorial_metadata_terms ), + ]; } }