Completed
Branch master (56c2f5)
by
unknown
07:05
created

BackupGenerator::generateTxt()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
1
<?php
2
3
namespace Blocktrail\SDK;
4
5
use Blocktrail\SDK\Bitcoin\BIP32Key;
6
use Endroid\QrCode\QrCode;
7
8
/**
9
 * Class BackupGenerator
10
 */
11
class BackupGenerator {
12
13
    const QR_CODE_SIZE = 195;
14
15
    /**
16
     * path to fonts used for pdf generation
17
     *
18
     * @var string
19
     */
20
    protected $fontsPath;
21
22
    /**
23
     * array of data and QR codes for the blocktrail public keys
24
     *
25
     * @var null
26
     */
27
    protected $blocktrailPubKeyQRs = [];
28
29
    protected $identifier;
30
31
    protected $backupInfo;
32
33
    protected $extra;
34
35
    protected $options = [
36
        'page1' => true,
37
        'page2' => true,
38
        'page3' => true,
39
    ];
40
41
    /**
42
     * @param string $identifier
43
     * @param array  $backupInfo
44
     * @param array  $extra
45
     * @param null   $options
46
     */
47
    public function __construct($identifier, $backupInfo, $extra = null, $options = null) {
48
        /*
49
         * if DOMPDF is not already loaded we have to do it
50
         * they require a config file to be loaded, no autoloading :/
51
         */
52
        if (!defined('DOMPDF_ENABLE_AUTOLOAD')) {
53
            // disable DOMPDF's internal autoloader if you are using Composer
54
            define('DOMPDF_ENABLE_AUTOLOAD', false);
55
56
            //try the different possible locations for the config file, depending on if the sdk is included as a dependency or is the main project itself
57
            (@include_once __DIR__ . '/../../../dompdf/dompdf/dompdf_config.inc.php') || @include_once __DIR__ . '/../vendor/dompdf/dompdf/dompdf_config.inc.php';
58
        }
59
60
        //set the fonts path
61
        $this->fontsPath = dirname(__FILE__) . '/../resources/fonts';
62
63
        $this->identifier = $identifier;
64
        $this->backupInfo = $backupInfo;
65
        $this->extra = $extra ?: [];
66
        $this->options = array_merge($this->options, $options);
67
    }
68
69
    /**
70
     * process the blocktrail public keys and create qr codes for each one
71
     */
72
    protected function processBlocktrailPubKeys() {
73
        if (!isset($this->backupInfo['blocktrail_public_keys'])) {
74
            return;
75
        }
76
77
        //create QR codes for each blocktrail pub key
78
        foreach ($this->backupInfo['blocktrail_public_keys'] as $keyIndex => $key) {
79
            $key = $key instanceof BIP32Key ? $key : BIP32Key::create($key);
80
            $qrCode = new QrCode();
81
            $qrCode
82
                ->setText($key->key())
0 ignored issues
show
Documentation introduced by
$key->key() is of type object<BitWasp\Bitcoin\K...nistic\HierarchicalKey>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
83
                ->setSize(self::QR_CODE_SIZE-20)
84
                ->setPadding(10)
85
                ->setErrorCorrection('high')
86
                ->setForegroundColor(array('r' => 0, 'g' => 0, 'b' => 0, 'a' => 0))
87
                ->setBackgroundColor(array('r' => 255, 'g' => 255, 'b' => 255, 'a' => 0))
88
                ->setLabel("KeyIndex: ".$keyIndex."    Path: ".$key->path())
89
                ->setLabelFontSize(10)
90
            ;
91
            $this->blocktrailPubKeyQRs[] = array(
92
                'keyIndex'  => $keyIndex,
93
                'path'      => $key->path(),
94
                'qr'        => $qrCode->getDataUri(),
95
                'qrImg'     => $qrCode->getImage(),
96
            );
97
        }
98
    }
99
100
    /**
101
     * generate html document of backup details
102
     *
103
     * @return string
104
     */
105
    public function generateHTML() {
106
        //create blocktrail pub key QR codes if not already done
107
        if (!$this->blocktrailPubKeyQRs) {
108
            $this->processBlocktrailPubKeys();
109
        }
110
        $pubKeysHtml = "";
111
        foreach ($this->blocktrailPubKeyQRs as $pubKey) {
0 ignored issues
show
Bug introduced by
The expression $this->blocktrailPubKeyQRs of type null is not traversable.
Loading history...
112
            $pubKeysHtml .= "<img src='{$pubKey['qr']}' />";
113
        }
114
        $totalPubKeys = count($this->blocktrailPubKeyQRs);
115
116
        $backupInfo = $this->prepareBackupInfo();
117
        $extraInfo = $this->prepareExtraInfo();
118
119
        $passwordEncryptedSecret = null;
120
        if (isset($this->backupInfo['encrypted_secret'])) {
121
            $passwordEncryptedSecret = $this->backupInfo['encrypted_secret'];
122
        }
123
124
        $html = self::renderTemplate(__DIR__ . "/../resources/templates/recovery_sheet.html.php", [
125
            'identifier' => $this->identifier,
126
            'totalPubKeys' => $totalPubKeys,
127
            'pubKeysHtml' => $pubKeysHtml,
128
            'backupInfo' => $backupInfo,
129
            'extraInfo' => $extraInfo,
130
            'passwordEncryptedSecret' => $passwordEncryptedSecret,
131
            'options' => $this->options,
132
        ]);
133
134
        return $html;
135
    }
136
137
    protected function prepareBackupInfo() {
138
        $backupInfo = [];
139
140 View Code Duplication
        if (isset($this->backupInfo['primary_mnemonic'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
141
            $backupInfo[] = [
142
                'title' => 'Primary Mnemonic',
143
                'mnemonic' => $this->backupInfo['primary_mnemonic'],
144
            ];
145
        }
146 View Code Duplication
        if (isset($this->backupInfo['backup_mnemonic'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
147
            $backupInfo[] = [
148
                'title' => 'Primary Mnemonic',
149
                'mnemonic' => $this->backupInfo['backup_mnemonic'],
150
            ];
151
        }
152 View Code Duplication
        if (isset($this->backupInfo['encrypted_primary_seed'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
153
            $backupInfo[] = [
154
                'title' => 'Encrypted Primary Seed',
155
                'mnemonic' => $this->backupInfo['encrypted_primary_seed'],
156
            ];
157
        }
158 View Code Duplication
        if (isset($this->backupInfo['backup_seed'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
159
            $backupInfo[] = [
160
                'title' => 'Backup Seed',
161
                'mnemonic' => $this->backupInfo['backup_seed'],
162
            ];
163
        }
164 View Code Duplication
        if (isset($this->backupInfo['recovery_encrypted_secret'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
165
            $backupInfo[] = [
166
                'title' => 'Encrypted Recovery Secret',
167
                'mnemonic' => $this->backupInfo['recovery_encrypted_secret'],
168
            ];
169
        }
170
171
        return $backupInfo;
172
    }
173
174
    protected function prepareExtraInfo() {
175
        $extraInfo = [];
176
177
        foreach ($this->extra as $k => $v) {
178
            if (is_array($v)) {
179
                $extraInfo[] = $v;
180
            } else {
181
                $extraInfo[] = ['title' => $k, 'value' => $v];
182
            }
183
        }
184
185
        return $extraInfo;
186
    }
187
188
    public static function renderTemplate($file, $vars) {
189
        if (is_array($vars) && !empty($vars)) {
190
            extract($vars);
191
        }
192
193
        ob_start();
194
195
        include $file;
196
197
        return ob_get_clean();
198
    }
199
200
    /**
201
     * generate PDF document of backup details
202
     * @return string       pdf data, ready to be saved to file or streamed to browser
203
     */
204
    public function generatePDF() {
205
        $dompdf = new \DOMPDF();
206
        $html = $this->generateHTML();
207
        $dompdf->load_html($html);
208
209
        $dompdf->render();
210
        $pdfStream = $dompdf->output();
211
        return $pdfStream;
212
    }
213
214
    /**
215
     * generate text document of backup details (not implemented yet)
216
     *
217
     */
218
    public function generateTxt() {
219
        //...
220
    }
221
}
222