Completed
Push — master ( c5384d...c1ead9 )
by Nazar
04:21
created

Transactions::search()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 5
1
<?php
2
/**
3
 * @package   Blockchain payment
4
 * @category  modules
5
 * @author    Nazar Mokrynskyi <[email protected]>
6
 * @copyright Copyright (c) 2015-2016, Nazar Mokrynskyi
7
 * @license   MIT License, see license.txt
8
 */
9
namespace cs\modules\Blockchain_payment;
10
use
11
	cs\Config,
12
	cs\CRUD_helpers,
13
	cs\Singleton;
14
15
/**
16
 * @method static $this instance($check = false)
17
 */
18
class Transactions {
19
	use CRUD_helpers {
20
		search as public;
21
	}
22
	use
23
		Singleton;
24
25
	protected $data_model     = [
26
		'id'                     => 'int',
27
		'amount'                 => 'float:0',
28
		'currency'               => 'text',
29
		'user'                   => 'int:0',
30
		'module'                 => 'text',
31
		'purpose'                => 'text',
32
		'description'            => 'text',
33
		'amount_btc'             => 'float:0.0005',
34
		'destination_address'    => 'text',
35
		'input_address'          => 'text',
36
		'created'                => 'int:0',
37
		'paid'                   => 'int:0',
38
		'confirmed'              => 'int:0',
39
		'secret'                 => 'text',
40
		'transaction_hash'       => 'text',
41
		'input_transaction_hash' => 'text'
42
	];
43
	protected $table          = '[prefix]blockchain_payment_transactions';
44
	protected $blockchain_url = 'https://blockchain.info';
45
46
	/**
47
	 * Returns database index
48
	 *
49
	 * @return int
50
	 */
51
	protected function cdb () {
52
		return Config::instance()->module('Blockchain_payment')->db('transactions');
53
	}
54
	/**
55
	 * Get transaction
56
	 *
57
	 * @param int|int[] $id
58
	 *
59
	 * @return array|false
0 ignored issues
show
Documentation introduced by
Should the return type not be array|false|integer|string? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
60
	 */
61
	function get ($id) {
62
		return $this->read($id);
63
	}
64
	/**
65
	 * Add new transaction
66
	 *
67
	 * @param float  $amount
68
	 * @param string $currency
69
	 * @param int    $user
70
	 * @param string $module
71
	 * @param string $purpose
72
	 * @param string $description
73
	 *
74
	 * @return false|int Id of created transaction on success of <b>false</> on failure
0 ignored issues
show
Documentation introduced by
Should the return type not be false|integer|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
75
	 *
76
	 */
77
	function add ($amount, $currency, $user, $module, $purpose, $description) {
78
		while ($secret = hash('sha512', random_bytes(1000))) {
79
			if ($this->search(['secret' => $secret, 'total_count' => true])) {
80
				break;
81
			}
82
		}
83
		$amount_btc = $currency == 'BTC' ? $amount : $this->convert_to_btc($amount, $currency);
84
		// Minimal acceptable payment
85
		if ($amount_btc < 0.0005) {
86
			$amount_btc = 0.0005;
87
		}
88
		$Config              = Config::instance();
89
		$destination_address = $Config->module('Blockchain_payment')->bitcoin_address;
90
		$callback            = $Config->base_url()."/Blockchain_payment?secret=$secret";
91
		$blockchain_receive  = file_get_json(
92
			"$this->blockchain_url/api/receive?method=create&address=$destination_address&callback=".urlencode($callback)
93
		);
94
		if (
95
			!isset($blockchain_receive['callback_url']) ||
96
			$blockchain_receive['callback_url'] !== $callback
97
		) {
98
			return false;
99
		}
100
		$input_address = $blockchain_receive['input_address'];
101
		return $this->create(
102
			$amount,
103
			$currency,
104
			$user,
105
			$module,
106
			$purpose,
107
			$description,
108
			$amount_btc,
109
			$destination_address,
110
			$input_address,
111
			time(),
112
			0,
113
			0,
114
			$secret,
115
			'',
116
			''
117
		);
118
	}
119
	/**
120
	 * Convert any supported currency to BTC (external API call)
121
	 *
122
	 * @param float  $amount
123
	 * @param string $currency
124
	 *
125
	 * @return float
126
	 */
127
	function convert_to_btc ($amount, $currency) {
128
		return (float)file_get_contents("$this->blockchain_url/tobtc?currency=$currency&value=$amount");
129
	}
130
	/**
131
	 * Set transaction as paid (not confirmed though) and set transaction hashed
132
	 *
133
	 * @param int    $id
134
	 * @param string $transaction_hash
135
	 * @param string $input_transaction_hash
136
	 *
137
	 * @return bool
138
	 */
139
	function set_as_paid ($id, $transaction_hash, $input_transaction_hash) {
140
		$data                           = $this->get($id);
141
		$data['paid']                   = time();
142
		$data['transaction_hash']       = $transaction_hash;
143
		$data['input_transaction_hash'] = $input_transaction_hash;
144
		return $this->update($data);
145
	}
146
	/**
147
	 * Set transaction as confirmed (each paid transaction should be confirmed in order to be completed)
148
	 *
149
	 * @param int $id
150
	 *
151
	 * @return bool
152
	 */
153
	function set_as_confirmed ($id) {
154
		$data              = $this->get($id);
155
		$data['confirmed'] = time();
156
		return $this->update($data);
157
	}
158
	/**
159
	 * Delete specified order
160
	 *
161
	 * @param int $id
162
	 *
163
	 * @return bool
164
	 */
165
	function del ($id) {
166
		return $this->delete($id);
167
	}
168
}
169