Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Bitcoin_Wallet_Factory
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 4
110
0.00% covered (danger)
0.00%
0 / 1
 get_by_wp_post_id
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 get_by_wp_post
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 get_address_index
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 get_gateways_from_meta
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2/**
3 * Custom post type in WordPress, keyed with GUID of the wallet.
4 *
5 * @package    brianhenryie/bh-wp-bitcoin-gateway
6 */
7
8namespace BrianHenryIE\WP_Bitcoin_Gateway\API\Repositories\Factories;
9
10use BrianHenryIE\WP_Bitcoin_Gateway\API\Model\Wallet\Bitcoin_Wallet;
11use BrianHenryIE\WP_Bitcoin_Gateway\API\Model\Wallet\Bitcoin_Wallet_Status;
12use BrianHenryIE\WP_Bitcoin_Gateway\API\Model\Wallet\Bitcoin_Wallet_WP_Post_Interface;
13use BrianHenryIE\WP_Bitcoin_Gateway\Brick\Money\Exception\UnknownCurrencyException;
14use BrianHenryIE\WP_Bitcoin_Gateway\Brick\Money\Money;
15use InvalidArgumentException;
16use WP_Post;
17
18/**
19 * Factory for creating Bitcoin_Wallet objects from WordPress posts.
20 *
21 * Converts wp_posts custom post types and their associated post_meta into typed Bitcoin_Wallet domain objects.
22 */
23class Bitcoin_Wallet_Factory {
24
25    /**
26     * @param int $post_id The WordPress post id this wallet is stored under.
27     *
28     * @throws InvalidArgumentException When the supplied post_id is not a post of this type.
29     * @throws UnknownCurrencyException If BTC is not correctly added to brick/money.
30     */
31    public function get_by_wp_post_id( int $post_id ): Bitcoin_Wallet {
32        $post = get_post( $post_id );
33        if ( ! ( $post instanceof WP_Post ) || Bitcoin_Wallet_WP_Post_Interface::POST_TYPE !== $post->post_type ) {
34            throw new InvalidArgumentException( 'post_id ' . $post_id . ' is not a ' . Bitcoin_Wallet_WP_Post_Interface::POST_TYPE . ' post object' );
35        }
36
37        return $this->get_by_wp_post( $post );
38    }
39
40    /**
41     * Create a Bitcoin_Wallet object from a WordPress post + its post_meta.
42     *
43     * @param WP_Post $post The WordPress post representing the wallet.
44     * @return Bitcoin_Wallet The Bitcoin wallet object.
45     * @throws UnknownCurrencyException If BTC is not correctly added to brick/money.
46     */
47    public function get_by_wp_post( WP_Post $post ): Bitcoin_Wallet {
48        return new Bitcoin_Wallet(
49            post_id: $post->ID,
50            xpub: $post->post_title,
51            status: Bitcoin_Wallet_Status::from( $post->post_status ),
52            address_index: $this->get_address_index( $post ),
53            gateways: $this->get_gateways_from_meta( $post ),
54        );
55    }
56
57    /**
58     * Get the index of the last generated address, so generating new addresses can start higher.
59     *
60     * @param WP_Post $post The WordPress post representing the wallet.
61     * @return int|null The index of the last derived address or null.
62     */
63    protected function get_address_index( WP_Post $post ): ?int {
64        $index = get_post_meta( $post->ID, Bitcoin_Wallet_WP_Post_Interface::LAST_DERIVED_ADDRESS_INDEX_META_KEY, true );
65        return is_numeric( $index ) ? intval( $index ) : null; // Empty string '' will parse to 0.
66    }
67
68    /**
69     * Get the array of integrations/gateway_ids that are using this wallet.
70     *
71     * @param WP_Post $post The WordPress post representing the wallet.
72     * @return array<array{integration:class-string, gateway_id:string}>
73     */
74    protected function get_gateways_from_meta( WP_Post $post ): array {
75        $meta_string = get_post_meta( $post->ID, Bitcoin_Wallet_WP_Post_Interface::GATEWAYS_DETAILS_META_KEY, true );
76        if ( empty( $meta_string ) || ! is_string( $meta_string ) ) {
77            // TODO: log.
78            return array();
79        }
80        /** @var null|array<array{integration:class-string, gateway_id:string}> $result */
81        $result = json_decode( $meta_string, true );
82        if ( ! is_array( $result ) ) {
83            // TODO: log.
84            return array();
85        }
86        return $result;
87    }
88}