$task Task data. * * @return string The address, or an empty string when the task carries none. */ public static function assignee_email( array $task ): string { $name = $task['assignee']['name'] ?? null; if ( ! is_scalar( $name ) ) { return ''; } $candidate = trim( (string) $name ); return false === is_email( $candidate ) ? '' : $candidate; } /** * Reading the Kordiam assignee ID off a task. * * @param array $task Task data. * * @return int Assignee ID, or 0 when absent. */ public static function assignee_id( array $task ): int { $id = $task['assignee']['id'] ?? null; return is_numeric( $id ) ? (int) $id : 0; } /** * Finding the WordPress user for a task's assignee. * * @param array $task Task data. * * @return int User ID, or 0 when nobody on this site matches. */ public static function user_id_for_task( array $task ): int { $email = self::assignee_email( $task ); if ( '' === $email ) { return 0; } $user = get_user_by( 'email', $email ); if ( ! is_object( $user ) || ! isset( $user->ID ) || ! is_numeric( $user->ID ) ) { return 0; } return (int) $user->ID; } /** * Finding the first task whose assignee exists on this site. * * @param array> $tasks Story tasks. * * @return array{user_id: int, assignee_id: int}|null The match, or null when none of the assignees is known here. */ public static function first_known_assignee( array $tasks ): ?array { foreach ( $tasks as $task ) { $user_id = self::user_id_for_task( $task ); if ( $user_id > 0 ) { return array( 'user_id' => $user_id, 'assignee_id' => self::assignee_id( $task ), ); } } return null; } /** * Setting a post's author and remembering the Kordiam ID behind it (used by export). * * @param array $post_data Post data being assembled. * @param int $user_id WordPress user ID. * @param int $assignee_id Kordiam assignee ID. * * @return array Post data with the author set. */ public static function assign( array $post_data, int $user_id, int $assignee_id ): array { if ( $user_id <= 0 ) { return $post_data; } $post_data['post_author'] = $user_id; if ( $assignee_id > 0 ) { self::remember_kordiam_id( $user_id, $assignee_id ); } return $post_data; } /** * Reading the Kordiam assignee ID stored against a user. * * @param int $user_id WordPress user ID. * * @return int Assignee ID, or 0 when none is stored. */ public static function kordiam_id_for_user( int $user_id ): int { $stored = self::read_user_meta( $user_id, MetaKeys::AUTHOR_ID ); if ( is_numeric( $stored ) ) { return (int) $stored; } $legacy = self::read_user_meta( $user_id, MetaKeys::legacy_user_meta()[ MetaKeys::AUTHOR_ID ] ); return is_numeric( $legacy ) ? (int) $legacy : 0; } /** * Storing the Kordiam assignee ID against a user. * * @param int $user_id WordPress user ID. * @param int $assignee_id Kordiam assignee ID. */ private static function remember_kordiam_id( int $user_id, int $assignee_id ): void { // VIP uses its own attribute store; the constant alone does not guarantee the helper. if ( defined( 'WPCOM_IS_VIP_ENV' ) && WPCOM_IS_VIP_ENV && function_exists( 'update_user_attribute' ) ) { update_user_attribute( $user_id, MetaKeys::AUTHOR_ID, (string) $assignee_id ); return; } update_user_meta( $user_id, MetaKeys::AUTHOR_ID, $assignee_id ); } /** * Reading a user meta value, honouring the VIP attribute store. * * @param int $user_id WordPress user ID. * @param string $meta_key Meta key. * * @return mixed Stored value. */ private static function read_user_meta( int $user_id, string $meta_key ) { if ( defined( 'WPCOM_IS_VIP_ENV' ) && WPCOM_IS_VIP_ENV && function_exists( 'get_user_attribute' ) ) { return get_user_attribute( $user_id, $meta_key ); } return get_user_meta( $user_id, $meta_key, true ); } }