$state State from StateExtractor. * @return string sha256 hex. */ public static function compute( array $state ) { foreach ( $state as $field => $value ) { $state[ $field ] = self::comparable( $field, $value ); } return hash( 'sha256', self::VERSION . '|' . Json::canonical( $state ) ); } /** * The value as fingerprints compare it. An absent custom field (null) compares equal to an * empty one (''), as it did before absent fields were recorded, so stored fingerprints stay valid. * * @param string|int $field Field key. * @param mixed $value Value. * @return mixed */ private static function comparable( $field, $value ) { return null === $value && 0 === strpos( (string) $field, 'meta:' ) ? '' : $value; } /** * Convenience: extract then hash. * * @param \WC_Subscription $subscription Subscription. * @param string[] $fields Fields. * @return string */ public static function of( \WC_Subscription $subscription, array $fields ) { return self::compute( StateExtractor::extract( $subscription, $fields ) ); } /** * Fields that differ between two states. * * @param array $before Before. * @param array $after After. * @return string[] */ public static function changed_fields( array $before, array $after ) { $changed = array(); foreach ( array_unique( array_merge( array_keys( $before ), array_keys( $after ) ) ) as $key ) { $a = self::comparable( $key, array_key_exists( $key, $before ) ? $before[ $key ] : null ); $b = self::comparable( $key, array_key_exists( $key, $after ) ? $after[ $key ] : null ); if ( Json::canonical( $a ) !== Json::canonical( $b ) ) { $changed[] = $key; } } sort( $changed, SORT_STRING ); return $changed; } /** * Fields to fingerprint for an operation: its touched fields plus the context set. * * @param string[] $touched Operation touched fields. * @param string $operation_id Operation ID. * @param array $params Operation params. * @return string[] */ public static function fields_for( array $touched, $operation_id = '', array $params = array() ) { $fields = array_values( array_unique( array_merge( $touched, Fields::CONTEXT ) ) ); sort( $fields, SORT_STRING ); /** * Filters the fields fingerprinted for a run. * * @param string[] $fields Fields. * @param string $operation_id Operation ID. * @param array $params Params. */ return (array) apply_filters( 'recast_fingerprint_fields', $fields, $operation_id, $params ); } }