Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
Bitcoin_Wallet_Factory
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 3
56
0.00% covered (danger)
0.00%
0 / 1
 get_post_id_for_wallet
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 save_new
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
12
 get_by_post_id
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Save new Bitcoin wallets in WordPress, and fetch them via xpub or post id.
4 *
5 * @package    brianhenryie/bh-wp-bitcoin-gateway
6 */
7
8namespace BrianHenryIE\WP_Bitcoin_Gateway\API\Addresses;
9
10use Exception;
11use wpdb;
12
13/**
14 * Factory for wallets, saved in wp_posts.
15 */
16class Bitcoin_Wallet_Factory {
17
18    /**
19     * Given a post_id,
20     *
21     * NB: post_name is 200 characters long. zpub is 111 characters.
22     *
23     * @param string $xpub The master public key of the wallet.
24     *
25     * @return int|null The wp_posts ID when it exists, or null when absent.
26     */
27    public function get_post_id_for_wallet( string $xpub ): ?int {
28
29        $post_id = wp_cache_get( $xpub, Bitcoin_Wallet::POST_TYPE );
30
31        if ( false !== $post_id ) {
32            return (int) $post_id;
33        }
34
35        /**
36         * The WordPress wpdb object for database operations.
37         *
38         * TODO: Can this be replaced with a `get_posts( array( 'post_name' => $xpub, 'post_type' => Bitcoin_Wallet::POST_TYPE, 'numberposts' => 1 ) )` call?
39         *
40         * @var wpdb $wpdb
41         */
42        global $wpdb;
43        // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
44        // @phpstan-ignore-next-line
45        $post_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_name=%s", sanitize_title( $xpub ) ) );
46
47        if ( ! is_null( $post_id ) ) {
48            $post_id = intval( $post_id );
49            wp_cache_add( $xpub, $post_id, Bitcoin_Wallet::POST_TYPE );
50        }
51
52        return $post_id;
53    }
54
55    /**
56     * Create a new Bitcoin_Wallet WordPress post for the provided address and optionally specify the associated gateway.
57     *
58     * @param string  $master_public_key The xpub/ypub/zpub of the wallet.
59     * @param ?string $gateway_id The WC_Payment_Gateway the wallet is being used with.
60     *
61     * @return int The wp_posts ID.
62     * @throws Exception When `wp_insert_post()` fails.
63     */
64    public function save_new( string $master_public_key, ?string $gateway_id = null ): int {
65
66        // TODO: Validate xpub, throw exception.
67
68        $args = array();
69
70        $args['post_title']   = $master_public_key;
71        $args['post_status']  = ! is_null( $gateway_id ) ? 'active' : 'inactive';
72        $args['post_excerpt'] = $master_public_key;
73        $args['post_name']    = sanitize_title( $master_public_key ); // An indexed column.
74        $args['post_type']    = Bitcoin_Wallet::POST_TYPE;
75        $args['meta_input']   = array(
76            Bitcoin_Wallet::GATEWAY_IDS_META_KEY => array( $gateway_id ),
77        );
78
79        $post_id = wp_insert_post( $args, true );
80
81        if ( is_wp_error( $post_id ) ) {
82            throw new Exception( 'Failed to save new wallet as wp_post' );
83        }
84
85        return $post_id;
86    }
87
88    /**
89     * Given the id of the wp_posts row storing the bitcoin wallet, return the typed Bitcoin_Wallet object.
90     *
91     * @param int $post_id WordPress wp_posts ID.
92     *
93     * @return Bitcoin_Wallet
94     * @throws Exception When the post_type of the post returned for the given post_id is not a Bitcoin_Wallet.
95     */
96    public function get_by_post_id( int $post_id ): Bitcoin_Wallet {
97        return new Bitcoin_Wallet( $post_id );
98    }
99}