Passed
Push — teampass_3.0 ( 425d48...b7c627 )
by Nils
06:24
created

nbLines()   B

Complexity

Conditions 10
Paths 40

Size

Total Lines 50
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 38
c 1
b 0
f 0
nc 40
nop 2
dl 0
loc 50
rs 7.6666

1 Method

Rating   Name   Duplication   Size   Complexity  
A checkPageBreak() 0 6 2

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Teampass - a collaborative passwords manager.
4
 * ---
5
 * This library is distributed in the hope that it will be useful,
6
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8
 * ---
9
 * @project   Teampass
10
 * @file      export.queries.php
11
 * ---
12
 * @author    Nils Laumaillé ([email protected])
13
 * @copyright 2009-2019 Teampass.net
14
 * @license   https://spdx.org/licenses/GPL-3.0-only.html#licenseText GPL-3.0
15
 * ---
16
 * @see       https://www.teampass.net
17
 */
18
19
20
require_once 'SecureHandler.php';
21
session_name('teampass_session');
22
session_start();
23
if (
24
    isset($_SESSION['CPM']) === false
25
    || $_SESSION['CPM'] != 1
26
    || isset($_SESSION['user_id']) === false || empty($_SESSION['user_id'])
27
    || isset($_SESSION['key']) === false || empty($_SESSION['key'])
28
) {
29
    die('Hacking attempt...');
30
}
31
32
33
// reference the Dompdf namespace
34
//use Dompdf\Dompdf;
35
36
// Load config if $SETTINGS not defined
37
if (isset($SETTINGS['cpassman_dir']) === false || empty($SETTINGS['cpassman_dir'])) {
38
    if (file_exists('../includes/config/tp.config.php')) {
39
        include_once '../includes/config/tp.config.php';
40
    } elseif (file_exists('./includes/config/tp.config.php')) {
41
        include_once './includes/config/tp.config.php';
42
    } elseif (file_exists('../../includes/config/tp.config.php')) {
43
        include_once '../../includes/config/tp.config.php';
44
    } else {
45
        throw new Exception("Error file '/includes/config/tp.config.php' not exists", 1);
46
    }
47
}
48
49
// Do checks
50
require_once $SETTINGS['cpassman_dir'] . '/includes/config/include.php';
51
require_once $SETTINGS['cpassman_dir'] . '/sources/checks.php';
52
if (checkUser($_SESSION['user_id'], $_SESSION['key'], 'items', $SETTINGS) === false) {
53
    // Not allowed page
54
    $_SESSION['error']['code'] = ERR_NOT_ALLOWED;
55
    include $SETTINGS['cpassman_dir'] . '/error.php';
56
    exit();
57
}
58
59
// No time limit
60
set_time_limit(0);
61
62
require_once $SETTINGS['cpassman_dir'] . '/includes/config/settings.php';
63
header('Content-type: text/html; charset=utf-8');
64
error_reporting(E_ERROR);
65
require_once $SETTINGS['cpassman_dir'] . '/sources/main.functions.php';
66
require_once $SETTINGS['cpassman_dir'] . '/sources/SplClassLoader.php';
67
68
// Connect to mysql server
69
require_once $SETTINGS['cpassman_dir'] . '/includes/libraries/Database/Meekrodb/db.class.php';
70
if (defined('DB_PASSWD_CLEAR') === false) {
71
    define('DB_PASSWD_CLEAR', defuseReturnDecrypted(DB_PASSWD, $SETTINGS));
72
}
73
DB::$host = DB_HOST;
74
DB::$user = DB_USER;
75
DB::$password = DB_PASSWD_CLEAR;
76
DB::$dbName = DB_NAME;
77
DB::$port = DB_PORT;
78
DB::$encoding = DB_ENCODING;
79
80
// Build tree
81
$tree = new SplClassLoader('Tree\NestedTree', $SETTINGS['cpassman_dir'] . '/includes/libraries');
82
$tree->register();
83
$tree = new Tree\NestedTree\NestedTree($pre . 'nested_tree', 'id', 'parent_id', 'title');
84
85
// User's language loading
86
require_once $SETTINGS['cpassman_dir'] . '/includes/language/' . $_SESSION['user_language'] . '.php';
87
88
// Prepare POST variables
89
$id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT);
90
$post_type = filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING);
91
$post_idTree = filter_input(INPUT_POST, 'idTree', FILTER_SANITIZE_NUMBER_INT);
92
$post_idsList = filter_input(INPUT_POST, 'idsList', FILTER_SANITIZE_STRING);
93
$post_file = filter_input(INPUT_POST, 'file', FILTER_SANITIZE_STRING);
94
$post_pdf_password = filter_input(INPUT_POST, 'pdf_password', FILTER_SANITIZE_STRING);
95
$post_number = filter_input(INPUT_POST, 'number', FILTER_SANITIZE_STRING);
96
$post_cpt = filter_input(INPUT_POST, 'cpt', FILTER_SANITIZE_STRING);
97
$post_file_link = filter_input(INPUT_POST, 'file_link', FILTER_SANITIZE_STRING);
98
$post_ids = filter_input(INPUT_POST, 'ids', FILTER_SANITIZE_STRING);
99
100
$post_key = filter_input(INPUT_POST, 'key', FILTER_SANITIZE_STRING);
101
$post_data = filter_input(INPUT_POST, 'data', FILTER_SANITIZE_STRING);
102
103
//Manage type of action asked
104
if (null !== $post_type) {
105
    switch ($post_type) {
106
            //CASE export in CSV format
107
        case 'export_to_csv_format':
108
            //Init
109
            $full_listing = array();
110
            $full_listing[0] = array(
111
                'id' => 'id',
112
                'label' => 'label',
113
                'description' => 'description',
114
                'pw' => 'pw',
115
                'login' => 'login',
116
                'restricted_to' => 'restricted_to',
117
                'perso' => 'perso',
118
                'url' => 'url',
119
                'email' => 'email',
120
                'kbs' => 'kb',
121
                'tags' => 'tag',
122
            );
123
124
            $id_managed = '';
125
            $i = 1;
126
            $items_id_list = array();
127
128
            foreach (json_decode(html_entity_decode($post_ids)) as $id) {
129
                if (
130
                    in_array($id, $_SESSION['forbiden_pfs']) === false
131
                    && in_array($id, $_SESSION['groupes_visibles']) === true
132
                ) {
133
                    $rows = DB::query(
134
                        'SELECT i.id as id, i.id_tree as id_tree, i.restricted_to as restricted_to, i.perso as perso,
135
                            i.label as label, i.description as description, i.pw as pw, i.login as login, i.url as url,
136
                            i.email as email,l.date as date, i.pw_iv as pw_iv,n.renewal_period as renewal_period
137
                        FROM ' . prefixTable('items') . ' as i
138
                        INNER JOIN ' . prefixTable('nested_tree') . ' as n ON (i.id_tree = n.id)
139
                        INNER JOIN ' . prefixTable('log_items') . ' as l ON (i.id = l.id_item)
140
                        WHERE i.inactif = %i
141
                        AND i.id_tree= %i
142
                        AND (l.action = %s OR (l.action = %s AND l.raison LIKE %s))
143
                        ORDER BY i.label ASC, l.date DESC',
144
                        '0',
145
                        intval($id),
146
                        'at_creation',
147
                        'at_modification',
148
                        'at_pw :%'
149
                    );
150
                    foreach ($rows as $record) {
151
                        $restricted_users_array = explode(';', $record['restricted_to']);
152
                        //exclude all results except the first one returned by query
153
                        if (empty($id_managed) === true || (int) $id_managed !== (int) $record['id']) {
154
                            if ((in_array($record['id_tree'], $_SESSION['personal_visible_groups']) === true)
155
                                || (in_array($record['id_tree'], $_SESSION['groupes_visibles']) === true
156
                                    && (empty($record['restricted_to']) === true
157
                                        || (in_array($_SESSION['user_id'], explode(';', $record['restricted_to'])) === true)))
158
                            ) {
159
                                // Run query
160
                                $dataItem = DB::queryfirstrow(
161
                                    'SELECT i.pw AS pw, s.share_key AS share_key
162
                                    FROM ' . prefixTable('items') . ' AS i
163
                                    INNER JOIN ' . prefixTable('sharekeys_items') . ' AS s ON (s.object_id = i.id)
164
                                    WHERE user_id = %i AND i.id = %i',
165
                                    $_SESSION['user_id'],
166
                                    $record['id']
167
                                );
168
169
                                // Uncrypt PW
170
                                if (DB::count() === 0) {
171
                                    // No share key found
172
                                    $pw = '';
173
                                } else {
174
                                    $pw = base64_decode(doDataDecryption(
175
                                        $dataItem['pw'],
176
                                        decryptUserObjectKey(
177
                                            $dataItem['share_key'],
178
                                            $_SESSION['user']['private_key']
179
                                        )
180
                                    ));
181
                                }
182
183
                                // get KBs
184
                                $arr_kbs = [];
185
                                $rows_kb = DB::query(
186
                                    'SELECT b.label, b.id
187
                                    FROM ' . prefixTable('kb_items') . ' AS a
188
                                    INNER JOIN ' . prefixTable('kb') . ' AS b ON (a.kb_id = b.id)
189
                                    WHERE a.item_id = %i',
190
                                    $record['id']
191
                                );
192
                                foreach ($rows_kb as $rec_kb) {
193
                                    array_push($arr_kbs, $rec_kb['label']);
194
                                }
195
196
                                // get TAGS
197
                                $arr_tags = [];
198
                                $rows_tag = DB::query(
199
                                    'SELECT tag
200
                                    FROM ' . prefixTable('tags') . '
201
                                    WHERE item_id = %i',
202
                                    $record['id']
203
                                );
204
                                foreach ($rows_tag as $rec_tag) {
205
                                    array_push($arr_tags, $rec_tag['tag']);
206
                                }
207
208
                                $full_listing[$i] = array(
209
                                    'id' => $record['id'],
210
                                    'label' => strip_tags(cleanString(html_entity_decode($record['label'], ENT_QUOTES | ENT_XHTML, 'UTF-8'), true)),
211
                                    'description' => htmlspecialchars_decode(addslashes(str_replace(array(';', '<br />'), array('|', "\n\r"), mysqli_escape_string($link, stripslashes(utf8_decode($record['description'])))))),
212
                                    'pw' => html_entity_decode($pw, ENT_QUOTES | ENT_XHTML, 'UTF-8'),
213
                                    'login' => strip_tags(cleanString(html_entity_decode($record['login'], ENT_QUOTES | ENT_XHTML, 'UTF-8'), true)),
214
                                    'restricted_to' => isset($record['restricted_to']) ? $record['restricted_to'] : '',
215
                                    'perso' => $record['perso'] === '0' ? 'False' : 'True',
216
                                    'url' => $record['url'] !== 'none' ? htmlspecialchars_decode($record['url']) : '',
217
                                    'email' => $record['email'] !== 'none' ? htmlspecialchars_decode($record['email']) : '',
218
                                    'kbs' => implode(' | ', $arr_kbs),
219
                                    'tags' => implode(' ', $arr_tags),
220
                                );
221
                                ++$i;
222
223
                                // log
224
                                logItems(
225
                                    $SETTINGS,
226
                                    (int) $record['id'],
227
                                    $record['label'],
228
                                    $_SESSION['user_id'],
229
                                    'at_export',
230
                                    $_SESSION['login'],
231
                                    'csv'
232
                                );
233
                            }
234
                        }
235
                        $id_managed = $record['id'];
236
                    }
237
                }
238
            }
239
240
            // Loop on Results, decode to UTF8 and write in CSV file
241
            $tmp = '';
242
            foreach ($full_listing as $value) {
243
                $value = array_map('utf8_decode', $value);
244
                $tmp .= array2csv($value);
245
            }
246
247
            echo '[{"content":"' . base64_encode($tmp) . '"}]';
248
            break;
249
250
            /*
251
         * PDF - step 1 - Prepare database
252
         */
253
        case 'initialize_export_table':
254
            DB::query('TRUNCATE TABLE ' . prefixTable('export'));
255
            break;
256
257
            /*
258
         * PDF - step 2 - Export the items inside database
259
         */
260
        case 'export_to_pdf_format':
261
            // Check KEY
262
            if ($post_key !== $_SESSION['key']) {
263
                echo prepareExchangedData(
264
                    array(
265
                        'error' => true,
266
                        'message' => langHdl('key_is_not_correct'),
267
                    ),
268
                    'encode'
269
                );
270
                break;
271
            }
272
273
            // decrypt and retrieve data in JSON format
274
            $dataReceived = prepareExchangedData($post_data, 'decode');
275
276
            // Prepare variables
277
            $post_id = filter_var($dataReceived['id'], FILTER_SANITIZE_NUMBER_INT);
278
            $post_ids = filter_var_array($dataReceived['ids'], FILTER_SANITIZE_NUMBER_INT);
279
280
            if (
281
                in_array($post_id, $_SESSION['forbiden_pfs']) === false
282
                && in_array($post_id, $_SESSION['groupes_visibles']) === true
283
            ) {
284
                // get path
285
                $tree->rebuild();
286
                $folders = $tree->getPath($post_id, true);
287
                $path = array();
288
                foreach ($folders as $val) {
289
                    array_push($path, $val->title);
290
                }
291
                $path = implode(' » ', $path);
292
293
                // send query
294
                $rows = DB::query(
295
                    'SELECT i.id as id, i.restricted_to as restricted_to, i.perso as perso, i.label as label, i.description as description, i.pw as pw, i.login as login, i.url as url, i.email as email,
296
                        l.date as date, i.pw_iv as pw_iv,
297
                        n.renewal_period as renewal_period
298
                        FROM ' . prefixTable('items') . ' as i
299
                        INNER JOIN ' . prefixTable('nested_tree') . ' as n ON (i.id_tree = n.id)
300
                        INNER JOIN ' . prefixTable('log_items') . ' as l ON (i.id = l.id_item)
301
                        WHERE i.inactif = %i
302
                        AND i.id_tree= %i
303
                        AND (l.action = %s OR (l.action = %s AND l.raison LIKE %s))
304
                        ORDER BY i.label ASC, l.date DESC',
305
                    '0',
306
                    $post_id,
307
                    'at_creation',
308
                    'at_modification',
309
                    'at_pw :%'
310
                );
311
312
                $id_managed = '';
313
                $i = 0;
314
                $items_id_list = array();
315
                foreach ($rows as $record) {
316
                    $restricted_users_array = explode(';', $record['restricted_to']);
317
                    //exclude all results except the first one returned by query
318
                    if (empty($id_managed) || $id_managed != $record['id']) {
319
                        if ((in_array($post_id, $_SESSION['personal_visible_groups']) && !($record['perso'] == 1 && $_SESSION['user_id'] == $record['restricted_to']) && !empty($record['restricted_to']))
320
                            || (!empty($record['restricted_to']) && !in_array($_SESSION['user_id'], $restricted_users_array))
321
                        ) {
322
                            //exclude this case
323
                        } else {
324
                            // Run query
325
                            $dataItem = DB::queryfirstrow(
326
                                'SELECT i.pw AS pw, s.share_key AS share_key
327
                                FROM ' . prefixTable('items') . ' AS i
328
                                INNER JOIN ' . prefixTable('sharekeys_items') . ' AS s ON (s.object_id = i.id)
329
                                WHERE user_id = %i AND i.id = %i',
330
                                $_SESSION['user_id'],
331
                                $record['id']
332
                            );
333
334
                            // Uncrypt PW
335
                            if (DB::count() === 0) {
336
                                // No share key found
337
                                $pw = '';
338
                            } else {
339
                                $pw = base64_decode(doDataDecryption(
340
                                    $dataItem['pw'],
341
                                    decryptUserObjectKey(
342
                                        $dataItem['share_key'],
343
                                        $_SESSION['user']['private_key']
344
                                    )
345
                                ));
346
                            }
347
348
                            // get KBs
349
                            $arr_kbs = '';
350
                            $rows_kb = DB::query(
351
                                'SELECT b.label, b.id
352
                                FROM ' . prefixTable('kb_items') . ' AS a
353
                                INNER JOIN ' . prefixTable('kb') . ' AS b ON (a.kb_id = b.id)
354
                                WHERE a.item_id = %i',
355
                                $record['id']
356
                            );
357
                            foreach ($rows_kb as $rec_kb) {
358
                                if (empty($arr_kbs)) {
359
                                    $arr_kbs = $rec_kb['label'];
360
                                } else {
361
                                    $arr_kbs .= ' | ' . $rec_kb['label'];
362
                                }
363
                            }
364
365
                            // get TAGS
366
                            $arr_tags = '';
367
                            $rows_tag = DB::query(
368
                                'SELECT tag
369
                                FROM ' . prefixTable('tags') . '
370
                                WHERE item_id = %i',
371
                                $record['id']
372
                            );
373
                            foreach ($rows_tag as $rec_tag) {
374
                                if (empty($arr_tags)) {
375
                                    $arr_tags = $rec_tag['tag'];
376
                                } else {
377
                                    $arr_tags .= ' ' . $rec_tag['tag'];
378
                                }
379
                            }
380
381
                            // store
382
                            DB::insert(
383
                                prefixTable('export'),
384
                                array(
385
                                    'id' => $record['id'],
386
                                    'description' => strip_tags(cleanString(html_entity_decode($record['description'], ENT_QUOTES | ENT_XHTML, 'UTF-8'), true)),
387
                                    'label' => cleanString(html_entity_decode($record['label'], ENT_QUOTES | ENT_XHTML, 'UTF-8'), true),
388
                                    'pw' => html_entity_decode($pw, ENT_QUOTES | ENT_XHTML, 'UTF-8'),
389
                                    'login' => strip_tags(cleanString(html_entity_decode($record['login'], ENT_QUOTES | ENT_XHTML, 'UTF-8'), true)),
390
                                    'path' => $path,
391
                                    'url' => strip_tags(cleanString(html_entity_decode($record['url'], ENT_QUOTES | ENT_XHTML, 'UTF-8'), true)),
392
                                    'email' => strip_tags(cleanString(html_entity_decode($record['email'], ENT_QUOTES | ENT_XHTML, 'UTF-8'), true)),
393
                                    'kbs' => $arr_kbs,
394
                                    'tags' => $arr_tags,
395
                                )
396
                            );
397
398
                            // log
399
                            logItems(
400
                                $SETTINGS,
401
                                (int) $record['id'],
402
                                $record['label'],
403
                                $_SESSION['user_id'],
404
                                'at_export',
405
                                $_SESSION['login'],
406
                                'pdf'
407
                            );
408
                        }
409
                    }
410
                    $id_managed = $record['id'];
411
                    $folder_title = $record['folder_title'];
412
                }
413
            }
414
415
            echo prepareExchangedData(
416
                array(
417
                    'error' => false,
418
                    'message' => '',
419
                ),
420
                'encode'
421
            );
422
            break;
423
424
        
425
426
        case 'finalize_export_pdf':
427
            // Check KEY
428
            if ($post_key !== $_SESSION['key']) {
429
                echo prepareExchangedData(
430
                    array(
431
                        'error' => true,
432
                        'message' => langHdl('key_is_not_correct'),
433
                    ),
434
                    'encode'
435
                );
436
                break;
437
            }
438
439
            // decrypt and retrieve data in JSON format
440
            $dataReceived = prepareExchangedData($post_data, 'decode');
441
442
            // Adapt header to pdf
443
            header('Content-type: application/pdf');
444
445
            // query
446
            $rows = DB::query('SELECT * FROM ' . prefixTable('export'));
447
            $counter = DB::count();
448
            if ($counter > 0) {
449
                // print
450
                //Some variables
451
                $table_full_width = 300;
452
                $table_col_width = array(40, 30, 30, 60, 27, 40, 25, 25);
453
                $prev_path = '';
454
455
                //Prepare the PDF file
456
                require_once($SETTINGS['cpassman_dir'] . '/includes/libraries/Pdf/tcpdf/config/tcpdf_config.php');
457
                include $SETTINGS['cpassman_dir'] . '/includes/libraries/Pdf/tcpdf/tcpdf.php';
458
459
                $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
460
                $pdf->SetProtection(array('print'), $dataReceived['pdf_password'], null);
461
462
                // set document information
463
                $pdf->SetCreator(PDF_CREATOR);
464
                $pdf->SetAuthor($_SESSION['lastname']." ".$_SESSION['name']);
465
                $pdf->SetTitle('Teampass export');
466
467
                // set default header data
468
                $pdf->SetHeaderData(
469
                    $SETTINGS['cpassman_dir'] . '/includes/images/teampass-logo2-home.png',
470
                    PDF_HEADER_LOGO_WIDTH,
471
                    'Teampass export',
472
                    $_SESSION['lastname']." ".$_SESSION['name'].' @ '.date($SETTINGS['date_format']." ".$SETTINGS['time_format'], time())
473
                );
474
475
                // set header and footer fonts
476
                $pdf->setHeaderFont(Array('helvetica', '', PDF_FONT_SIZE_MAIN));
477
                $pdf->setFooterFont(Array('helvetica', '', PDF_FONT_SIZE_DATA));
478
479
                // set default monospaced font
480
                $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
481
482
                // set margins
483
                $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
484
                $pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
485
                $pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
486
487
                // set auto page breaks
488
                $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
489
                
490
                // set image scale factor
491
                $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
492
493
                $pdf->getAliasNbPages();
494
                $pdf->addPage('L');
495
496
                $prev_path = '';
497
                $html_table = '
498
                <html><head>
499
                <style>
500
                    table {
501
                        border-collapse: collapse;
502
                        margin: 25px 0;
503
                        /*!font-size: 0.9em;
504
                        font-family: sans-serif;
505
                        box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);*/
506
                    }
507
                    thead tr {
508
                        background-color: #009879;
509
                        color: #ffffff;
510
                        text-align: left;
511
                    }
512
                    th,
513
                    td {
514
                        padding: 12px 15px;
515
                    }
516
                    tbody tr {
517
                        border-bottom: 1px solid #dddddd;
518
                    }
519
                    tbody tr:nth-of-type(even) {
520
                        background-color: #f3f3f3;
521
                    }
522
                    tbody tr:last-of-type {
523
                        border-bottom: 2px solid #009879;
524
                    }
525
                </style>
526
                </head>
527
                <body>
528
                <table>
529
                    <thead>
530
                        <tr>
531
                            <th>Label</th>
532
                            <th>Login</th>
533
                            <th>Password</th>
534
                            <th>Description</th>
535
                            <th>Email</th>
536
                            <th>URL</th>
537
                        </tr>
538
                    </thead>
539
                    <tbody>';
540
541
                foreach ($rows as $record) {
542
                    // Manage path
543
                    if ($prev_path !== $record['path']) {
544
                        $html_table .= '
545
                            <tr>
546
                                <td colspan="6">'.$record['path'].'</td>
547
                            </tr>';
548
                    }
549
                    $prev_path = $record['path'];
550
551
                    // build
552
                    $html_table .= '
553
                    <tr>
554
                        <td>'.$record['label'].'</td>
555
                        <td>'.$record['login'].'</td>
556
                        <td>'.$record['pw'].'</td>
557
                        <td>'.$record['description'].'</td>
558
                        <td>'.$record['email'].'</td>
559
                        <td>'.$record['url'].'</td>
560
                    </tr>';
561
                }
562
                $html_table .= '
563
                    </tbody>
564
                </table>
565
                </body></html>';
566
567
                $pdf->writeHTML($html_table, true, false, false, false, '');
568
569
                //log
570
                logEvents($SETTINGS, 'pdf_export', '', $_SESSION['user_id'], $_SESSION['login']);
571
572
                //clean table
573
                DB::query('TRUNCATE TABLE ' . prefixTable('export'));
574
575
                // Send back the file in Blob
576
                echo $pdf->Output(null, 'I');
577
            }
578
            break;
579
580
            //CASE export in HTML format
581
        case 'export_to_html_format':
582
            // step 1:
583
            // - prepare export file
584
            // - get full list of objects id to export
585
            include $SETTINGS['cpassman_dir'] . '/includes/config/include.php';
586
            include_once $SETTINGS['cpassman_dir'] . '/includes/libraries/Encryption/GibberishAES/GibberishAES.php';
587
            $idsList = array();
588
            $objNumber = 0;
589
590
            foreach (explode(';', $post_ids) as $id) {
591
                if (
592
                    in_array($id, $_SESSION['forbiden_pfs']) === false
593
                    && in_array($id, $_SESSION['groupes_visibles']) === true
594
                    && (in_array($id, $_SESSION['no_access_folders']) === false)
595
                ) {
596
                    // count elements to display
597
                    $result = DB::query(
598
                        'SELECT i.id AS id, i.label AS label, i.restricted_to AS restricted_to, i.perso AS perso
599
                    FROM ' . prefixTable('items') . ' as i
600
                    INNER JOIN ' . prefixTable('nested_tree') . ' as n ON (i.id_tree = n.id)
601
                    INNER JOIN ' . prefixTable('log_items') . ' as l ON (i.id = l.id_item)
602
                    WHERE i.inactif = %i
603
                    AND i.id_tree= %i
604
                    AND (l.action = %s OR (l.action = %s AND l.raison LIKE %s))
605
                    ORDER BY i.label ASC, l.date DESC',
606
                        '0',
607
                        $id,
608
                        'at_creation',
609
                        'at_modification',
610
                        'at_pw :%'
611
                    );
612
                    foreach ($result as $record) {
613
                        $restricted_users_array = explode(';', $record['restricted_to']);
614
                        if (((in_array($id, $_SESSION['personal_visible_groups']) === true
615
                                && !($record['perso'] == 1 && $_SESSION['user_id'] == $record['restricted_to'])
616
                                && empty($record['restricted_to']) === false)
617
                                || (empty($record['restricted_to']) === false
618
                                    && in_array($_SESSION['user_id'], $restricted_users_array) === false)
619
                                || (in_array($id, $_SESSION['groupes_visibles']))) && (in_array($record['id'], $idsList) === false)
620
                        ) {
621
                            array_push($idsList, $record['id']);
622
                            ++$objNumber;
623
                        }
624
                    }
625
                }
626
            }
627
628
            // prepare export file
629
            //save the file
630
            $html_file = '/teampass_export_' . time() . '_' . generateKey() . '.html';
631
            //print_r($full_listing);
632
            $outstream = fopen($SETTINGS['path_to_files_folder'] . $html_file, 'w');
633
            if ($outstream === false) {
634
                echo '[{"error":"true"}]';
635
                break;
636
            }
637
            fwrite(
638
                $outstream,
639
                '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
640
    <head>
641
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
642
    <title>TeamPass Off-line mode</title>
643
    <style>
644
    body{font-family:sans-serif; font-size:11pt; background:#DCE0E8;}
645
    thead th{font-size:13px; font-weight:bold; background:#344151; padding:4px 10px 4px 10px; font-family:arial; color:#FFFFFF;}
646
    tr.line0 td {background-color:#FFFFFF; border-bottom:1px solid #CCCCCC; font-family:arial; font-size:11px;}
647
    tr.line1 td {background-color:#F0F0F0; border-bottom:1px solid #CCCCCC; font-family:arial; font-size:11px;}
648
    tr.path td {background-color:#C0C0C0; font-family:arial; font-size:11px; font-weight:bold;}
649
    #footer{width: 980px; height: 20px; line-height: 16px; margin: 10px auto 0 auto; padding: 10px; font-family: sans-serif; font-size: 10px; color:#000000;}
650
    #header{padding:10px; font-size:18px; background:#344151; color:#FFFFFF; border:2px solid #222E3D;}
651
    #itemsTable{width:100%;}
652
    #information{margin:10px 0 10px 0; background:#344151; color:#FFFFFF; border:2px solid #222E3D;}
653
    </style>
654
    </head>
655
    <body>
656
    <input type="hidden" id="generation_date" value="' . GibberishAES::enc(/** @scrutinizer ignore-type */ (string) time(), $post_pdf_password) . '" />
657
    <div id="header">
658
    ' . TP_TOOL_NAME . ' - Off Line mode
659
    </div>
660
    <div style="margin:10px; font-size:9px;">
661
    <i>This page was generated by <b>' . $_SESSION['name'] . ' ' . $_SESSION['lastname'] . '</b>, the ' . date('Y/m/d H:i:s') . '.</i>
662
    <span id="info_page" style="margin-left:20px; font-weight:bold; font-size: 14px; color:red;"></span>
663
    </div>
664
    <div id="information"></div>
665
    <div style="margin:10px;">
666
    Enter the decryption key : <input type="password" id="saltkey" onchange="uncryptTable()" />
667
    &nbsp;<button onclic="uncryptTable()">Refresh</button>
668
    </div>
669
    <div>
670
    <table id="itemsTable">
671
        <thead><tr>
672
            <th style="width:15%;">' . $LANG['label'] . '</th>
673
            <th style="width:10%;">' . $LANG['pw'] . '</th>
674
            <th style="width:30%;">' . $LANG['description'] . '</th>
675
            <th style="width:5%;">' . $LANG['user_login'] . '</th>
676
            <th style="width:20%;">' . $LANG['url'] . '</th>
677
        </tr></thead>
678
        <tbody id="itemsTable_tbody">'
679
            );
680
681
            fclose($outstream);
682
683
            // send back and continue
684
            //echo '[{"loop":"true", "number":"'.$objNumber.'", "file":"'.$SETTINGS['path_to_files_folder'].$html_file.'" , "file_link":"'.$SETTINGS['url_to_files_folder'].$html_file.'"}]';
685
            break;
686
687
            //CASE export in HTML format - Iteration loop
688
        case 'export_to_html_format_loop':
689
            // do checks ... if fails, return an error
690
            if (null === $post_idTree || null === $post_idsList) {
691
                echo '[{"error":"true"}]';
692
                break;
693
            }
694
695
            // exclude this folder if not allowed
696
            if (
697
                in_array($post_idTree, $_SESSION['forbiden_pfs']) === true
698
                || in_array($post_idTree, $_SESSION['groupes_visibles']) === false
699
                || (in_array($post_idTree, $_SESSION['no_access_folders']) === true)
700
            ) {
701
                echo '[{"loop":"true", "number":"' . $post_number . '", "cpt":"' . $post_cpt . '", "file":"' . $post_file . '", "idsList":"' . $post_idsList . '" , "file_link":"' . $post_file_link . '"}]';
702
                break;
703
            }
704
705
            $full_listing = array();
706
            $items_id_list = array();
707
            include $SETTINGS['cpassman_dir'] . '/includes/config/include.php';
708
            include_once $SETTINGS['cpassman_dir'] . '/includes/libraries/Encryption/GibberishAES/GibberishAES.php';
709
710
            $rows = DB::query(
711
                'SELECT i.id as id, i.url as url, i.perso as perso, i.label as label, i.description as description, i.pw as pw, i.login as login, i.id_tree as id_tree,
712
                l.date as date, i.pw_iv as pw_iv,
713
                n.renewal_period as renewal_period
714
            FROM ' . prefixTable('items') . ' as i
715
            INNER JOIN ' . prefixTable('nested_tree') . ' as n ON (i.id_tree = n.id)
716
            INNER JOIN ' . prefixTable('log_items') . ' as l ON (i.id = l.id_item)
717
            WHERE i.inactif = %i
718
            AND i.id_tree= %i
719
            AND (l.action = %s OR (l.action = %s AND l.raison LIKE %s))
720
            ORDER BY i.label ASC, l.date DESC',
721
                '0',
722
                $post_idTree,
723
                'at_creation',
724
                'at_modification',
725
                'at_pw :%'
726
            );
727
728
            foreach ($rows as $record) {
729
                //exclude all results except the first one returned by query
730
                if (empty($id_managed) || $id_managed != $record['id']) {
731
                    // decrypt PW
732
                    if (empty($post_salt_key) === false && null !== $post_salt_key) {
733
                        $pw = cryption(
734
                            $record['pw'],
735
                            mysqli_escape_string($link, stripslashes($post_salt_key)),
736
                            'decrypt',
737
                            $SETTINGS
738
                        );
739
                    } else {
740
                        $pw = cryption(
741
                            $record['pw'],
742
                            '',
743
                            'decrypt',
744
                            $SETTINGS
745
                        );
746
                    }
747
                    array_push(
748
                        $full_listing,
749
                        array(
750
                            'id_tree' => $record['id_tree'],
751
                            'id' => $record['id'],
752
                            'label' => $record['label'],
753
                            'description' => addslashes(str_replace(array(';', '<br />'), array('|', "\n\r"), mysqli_escape_string($link, stripslashes(utf8_decode($record['description']))))),
754
                            'pw' => $pw['string'],
755
                            'login' => $record['login'],
756
                            'url' => $record['url'],
757
                            'perso' => $record['perso'],
758
                        )
759
                    );
760
                    ++$i;
761
                    array_push($items_id_list, $record['id']);
762
763
                    // log
764
                    /*logItems(
765
                        $record['id'],
766
                        $record['l SeekableIteratorabel'],
767
                        $_SESSION['user_id'],
768
                        'at_export',
769
                        $_SESSION['login'],
770
                        'html'
771
                    );*/
772
                }
773
                $id_managed = $record['id'];
774
            }
775
776
            //save in export file
777
            $outstream = fopen($post_file . '.txt', 'a');
778
            if ($outstream === false) {
779
                echo '[{"error":"true"}]';
780
                break;
781
            }
782
783
            $lineType = 'line1';
784
            $idTree = '';
785
            foreach ($full_listing as $elem) {
786
                if ($lineType == 'line0') {
787
                    $lineType = 'line1';
788
                } else {
789
                    $lineType = 'line0';
790
                }
791
                if (empty($elem['description'])) {
792
                    $desc = '&nbsp;';
793
                } else {
794
                    $desc = addslashes($elem['description']);
795
                }
796
                if (empty($elem['login'])) {
797
                    $login = '&nbsp;';
798
                } else {
799
                    $login = addslashes($elem['login']);
800
                }
801
                if (empty($elem['url'])) {
802
                    $url = '&nbsp;';
803
                } else {
804
                    $url = addslashes($elem['url']);
805
                }
806
807
                // Prepare tree
808
                if ($idTree != $elem['id_tree']) {
809
                    $arbo = $tree->getPath($elem['id_tree'], true);
810
                    foreach ($arbo as $folder) {
811
                        $arboHtml_tmp = htmlspecialchars(stripslashes($folder->title), ENT_QUOTES);
812
                        if (empty($arboHtml)) {
813
                            $arboHtml = $arboHtml_tmp;
814
                        } else {
815
                            $arboHtml .= ' » ' . $arboHtml_tmp;
816
                        }
817
                    }
818
                    fputs(
819
                        $outstream,
820
                        '
821
        <tr class="path"><td colspan="5">' . $arboHtml . '</td></tr>'
822
                    );
823
                    $idTree = $elem['id_tree'];
824
                }
825
826
                $encPw = GibberishAES::enc($elem['pw'], $post_pdf_password);
827
                fputs(
828
                    $outstream,
829
                    '
830
        <tr class="' . $lineType . '">
831
            <td>' . addslashes($elem['label']) . '</td>
832
            <td align="center"><span class="span_pw" id="span_' . $elem['id'] . '"><a href="#" onclick="decryptme(' . $elem['id'] . ', \'' . $encPw . '\');return false;">Decrypt </a></span><input type="hidden" id="hide_' . $elem['id'] . '" value="' . $encPw . '" /></td>
833
            <td>' . $desc . '</td>
834
            <td align="center">' . $login . '</td>
835
            <td align="center">' . $url . '</td>
836
            </tr>'
837
                );
838
            }
839
840
            fclose($outstream);
841
842
            // send back and continue
843
            echo '[{"loop":"true", "number":"' . $post_number . '", "cpt":"' . $post_cpt . '", "file":"' . $post_file . '", "idsList":"' . $post_idsList . '" , "file_link":"' . $post_file_link . '"}]';
844
            break;
845
846
            //CASE export in HTML format - Iteration loop
847
        case 'export_to_html_format_finalize':
848
            // Load includes
849
            include $SETTINGS['cpassman_dir'] . '/includes/config/include.php';
850
            require_once $SETTINGS['cpassman_dir'] . '/includes/libraries/Encryption/GibberishAES/GibberishAES.php';
851
852
            // read the content of the temporary file
853
            $handle = fopen($post_file . '.txt', 'r');
854
            if ($handle === false) {
855
                echo '[{"error":"true"}]';
856
                break;
857
            }
858
            $contents = fread($handle, filesize($post_file . '.txt'));
859
            if ($contents === false) {
860
                echo '[{"error":"true"}]';
861
                break;
862
            }
863
            fclose($handle);
864
            if (is_file($post_file . '.txt')) {
865
                unlink($post_file . '.txt');
866
            }
867
868
            // Encrypt its content
869
            //$contents = GibberishAES::enc($contents, $post_pdf_password);
870
            $encrypted_text = '';
871
            $chunks = explode('|#|#|', chunk_split($contents, 10000, '|#|#|'));
872
            foreach ($chunks as $chunk) {
873
                if (empty($encrypted_text) === true) {
874
                    $encrypted_text = GibberishAES::enc(/** @scrutinizer ignore-type */ $chunk, $post_pdf_password);
875
                } else {
876
                    $encrypted_text .= '|#|#|' . GibberishAES::enc(/** @scrutinizer ignore-type */ $chunk, $post_pdf_password);
877
                }
878
            }
879
880
            // open file
881
            $outstream = fopen($post_file, 'a');
882
            if ($outstream === false) {
883
                echo '[{"error":"true"}]';
884
                break;
885
            }
886
887
            fputs(
888
                $outstream,
889
                '</tbody>
890
        </table></div>
891
        <input type="button" value="Hide all" onclick="hideAll()" />
892
        <div id="footer" style="text-align:center;">
893
            <a href="https://teampass.net/about/" target="_blank" style="">' . TP_TOOL_NAME . '&nbsp;' . TP_VERSION_FULL . '&nbsp;' . TP_COPYRIGHT . '</a>
894
        </div>
895
        <div id="enc_html" style="display:none;">' . $encrypted_text . '</div>
896
        </body>
897
    </html>
898
    <script type="text/javascript">
899
        function uncryptTable()
900
        {
901
            // uncrypt file generation date
902
            try {
903
                var file_date = decryptedTable = GibberishAES.dec(
904
                    document.getElementById("generation_date").value,
905
                    document.getElementById("saltkey").value
906
                );
907
            }
908
            catch(e) {
909
                console.info("Key not correct");
910
                document.getElementById("itemsTable_tbody").innerHTML = "";
911
                document.getElementById("itemsTable").style.display  = "none";
912
                document.getElementById("info_page").innerHTML = "ERROR - " + e;
913
                return false;
914
            }
915
916
            // Check date
917
            if (~~(Date.now()/ 1000) - parseInt(file_date) < 604800) {
918
                console.info("File is valid");
919
                document.getElementById("info_page").innerHTML = "";
920
921
                // Uncrypt the table
922
                try {
923
                    var encodedString = document.getElementById("enc_html").innerHTML;
924
                    var splitedString = encodedString.split("|#|#|");
925
                    var decryptedTable = "";
926
                    var i;
927
                    for (i = 0; i < splitedString.length; i++) {
928
                        decryptedTable += GibberishAES.dec(
929
                            splitedString[i],
930
                            document.getElementById("saltkey").value
931
                        );
932
                    }
933
                }
934
                catch(e) {
935
                    console.info("Key not correct");
936
                    document.getElementById("itemsTable_tbody").innerHTML = "";
937
                    document.getElementById("itemsTable").style.display  = "none";
938
                    document.getElementById("info_page").innerHTML = "ERROR - " + e;
939
                    return false;
940
                }
941
942
                document.getElementById("itemsTable_tbody").innerHTML = decryptedTable;
943
                document.getElementById("itemsTable").style.display  = "block";
944
            } else {
945
                document.getElementById("info_page").innerHTML = "This file is too old. It cannot be shown anymore!";
946
                console.info("File is NOT valid any more!");
947
                document.getElementById("itemsTable").style.display  = "none";
948
            }
949
        }
950
        function decryptme(id, string)
951
        {
952
            if (document.getElementById("saltkey").value != "") {
953
                var decryptedPw;
954
955
                try {
956
                    decryptedPw = GibberishAES.dec(string, document.getElementById("saltkey").value)
957
                }
958
                catch(e) {
959
                    alert (e);
960
                    return decryptedPw;
961
                }
962
963
                document.getElementById("span_"+id).innerHTML = "<input type=\"text\" value=\"" +  decryptedPw + "\" id=\"pass_input_" + id + "\">" +
964
                    "&nbsp;<a href=\"#\" onclick=\"encryptme("+id+");return false;\"><span style=\"font-size:7px;\">[Hide]</span></a>";
965
                document.getElementById("pass_input_"+id).select();
966
            } else {
967
                alert("Decryption Key is empty!");
968
            }
969
        }
970
        function encryptme(id)
971
        {
972
            document.getElementById("span_"+id).innerHTML = "<a href=\"#\" onclick=\"decryptme("+id+", \'"+document.getElementById("hide_"+id).value+"\')\">Decrypt</a>";
973
        }
974
        function hideAll()
975
        {
976
            var elements = document.getElementsByClassName("span_pw");
977
            for (var i=0, im=elements.length; im>i; i++) {
978
                var dataPw = elements[i].id.split("_");
979
                elements[i].innerHTML = "<a href=\"#\" onclick=\"decryptme("+dataPw[1]+", \'"+document.getElementById("hide_"+dataPw[1]).value+"\')\">Decrypt</a>";
980
            }
981
        }
982
    		function prepareString(string) {
983
    			try {
984
    				 result = decodeURIComponent(string);
985
    			}
986
    			catch (e) {
987
    				 result =  unescape(string);
988
    			}
989
    			return result;
990
    		}
991
        (function(e,r){"object"==typeof exports?module.exports=r():"function"==typeof define&&define.amd?define(r):e.GibberishAES=r()})(this,function(){"use strict";var e=14,r=8,n=!1,f=function(e){try{return unescape(encodeURIComponent(e))}catch(r){throw"Error on UTF-8 encode"}},c=function(e){try{return prepareString(escape(e))}catch(r){throw"Bad Key"}},t=function(e){var r,n,f=[];for(16>e.length&&(r=16-e.length,f=[r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r]),n=0;e.length>n;n++)f[n]=e[n];return f},a=function(e,r){var n,f,c="";if(r){if(n=e[15],n>16)throw"Decryption error: Maybe bad key";if(16===n)return"";for(f=0;16-n>f;f++)c+=String.fromCharCode(e[f])}else for(f=0;16>f;f++)c+=String.fromCharCode(e[f]);return c},o=function(e){var r,n="";for(r=0;e.length>r;r++)n+=(16>e[r]?"0":"")+e[r].toString(16);return n},d=function(e){var r=[];return e.replace(/(..)/g,function(e){r.push(parseInt(e,16))}),r},u=function(e,r){var n,c=[];for(r||(e=f(e)),n=0;e.length>n;n++)c[n]=e.charCodeAt(n);return c},i=function(n){switch(n){case 128:e=10,r=4;break;case 192:e=12,r=6;break;case 256:e=14,r=8;break;default:throw"Invalid Key Size Specified:"+n}},b=function(e){var r,n=[];for(r=0;e>r;r++)n=n.concat(Math.floor(256*Math.random()));return n},h=function(n,f){var c,t=e>=12?3:2,a=[],o=[],d=[],u=[],i=n.concat(f);for(d[0]=L(i),u=d[0],c=1;t>c;c++)d[c]=L(d[c-1].concat(i)),u=u.concat(d[c]);return a=u.slice(0,4*r),o=u.slice(4*r,4*r+16),{key:a,iv:o}},l=function(e,r,n){r=S(r);var f,c=Math.ceil(e.length/16),a=[],o=[];for(f=0;c>f;f++)a[f]=t(e.slice(16*f,16*f+16));for(0===e.length%16&&(a.push([16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]),c++),f=0;a.length>f;f++)a[f]=0===f?x(a[f],n):x(a[f],o[f-1]),o[f]=s(a[f],r);return o},v=function(e,r,n,f){r=S(r);var t,o=e.length/16,d=[],u=[],i="";for(t=0;o>t;t++)d.push(e.slice(16*t,16*(t+1)));for(t=d.length-1;t>=0;t--)u[t]=p(d[t],r),u[t]=0===t?x(u[t],n):x(u[t],d[t-1]);for(t=0;o-1>t;t++)i+=a(u[t]);return i+=a(u[t],!0),f?i:c(i)},s=function(r,f){n=!1;var c,t=M(r,f,0);for(c=1;e+1>c;c++)t=g(t),t=y(t),e>c&&(t=k(t)),t=M(t,f,c);return t},p=function(r,f){n=!0;var c,t=M(r,f,e);for(c=e-1;c>-1;c--)t=y(t),t=g(t),t=M(t,f,c),c>0&&(t=k(t));return t},g=function(e){var r,f=n?D:B,c=[];for(r=0;16>r;r++)c[r]=f[e[r]];return c},y=function(e){var r,f=[],c=n?[0,13,10,7,4,1,14,11,8,5,2,15,12,9,6,3]:[0,5,10,15,4,9,14,3,8,13,2,7,12,1,6,11];for(r=0;16>r;r++)f[r]=e[c[r]];return f},k=function(e){var r,f=[];if(n)for(r=0;4>r;r++)f[4*r]=F[e[4*r]]^R[e[1+4*r]]^j[e[2+4*r]]^z[e[3+4*r]],f[1+4*r]=z[e[4*r]]^F[e[1+4*r]]^R[e[2+4*r]]^j[e[3+4*r]],f[2+4*r]=j[e[4*r]]^z[e[1+4*r]]^F[e[2+4*r]]^R[e[3+4*r]],f[3+4*r]=R[e[4*r]]^j[e[1+4*r]]^z[e[2+4*r]]^F[e[3+4*r]];else for(r=0;4>r;r++)f[4*r]=E[e[4*r]]^U[e[1+4*r]]^e[2+4*r]^e[3+4*r],f[1+4*r]=e[4*r]^E[e[1+4*r]]^U[e[2+4*r]]^e[3+4*r],f[2+4*r]=e[4*r]^e[1+4*r]^E[e[2+4*r]]^U[e[3+4*r]],f[3+4*r]=U[e[4*r]]^e[1+4*r]^e[2+4*r]^E[e[3+4*r]];return f},M=function(e,r,n){var f,c=[];for(f=0;16>f;f++)c[f]=e[f]^r[n][f];return c},x=function(e,r){var n,f=[];for(n=0;16>n;n++)f[n]=e[n]^r[n];return f},S=function(n){var f,c,t,a,o=[],d=[],u=[];for(f=0;r>f;f++)c=[n[4*f],n[4*f+1],n[4*f+2],n[4*f+3]],o[f]=c;for(f=r;4*(e+1)>f;f++){for(o[f]=[],t=0;4>t;t++)d[t]=o[f-1][t];for(0===f%r?(d=m(w(d)),d[0]^=K[f/r-1]):r>6&&4===f%r&&(d=m(d)),t=0;4>t;t++)o[f][t]=o[f-r][t]^d[t]}for(f=0;e+1>f;f++)for(u[f]=[],a=0;4>a;a++)u[f].push(o[4*f+a][0],o[4*f+a][1],o[4*f+a][2],o[4*f+a][3]);return u},m=function(e){for(var r=0;4>r;r++)e[r]=B[e[r]];return e},w=function(e){var r,n=e[0];for(r=0;4>r;r++)e[r]=e[r+1];return e[3]=n,e},A=function(e,r){var n,f=[];for(n=0;e.length>n;n+=r)f[n/r]=parseInt(e.substr(n,r),16);return f},C=function(e){var r,n=[];for(r=0;e.length>r;r++)n[e[r]]=r;return n},I=function(e,r){var n,f;for(f=0,n=0;8>n;n++)f=1===(1&r)?f^e:f,e=e>127?283^e<<1:e<<1,r>>>=1;return f},O=function(e){var r,n=[];for(r=0;256>r;r++)n[r]=I(e,r);return n},B=A("637c777bf26b6fc53001672bfed7ab76ca82c97dfa5947f0add4a2af9ca472c0b7fd9326363ff7cc34a5e5f171d8311504c723c31896059a071280e2eb27b27509832c1a1b6e5aa0523bd6b329e32f8453d100ed20fcb15b6acbbe394a4c58cfd0efaafb434d338545f9027f503c9fa851a3408f929d38f5bcb6da2110fff3d2cd0c13ec5f974417c4a77e3d645d197360814fdc222a908846eeb814de5e0bdbe0323a0a4906245cc2d3ac629195e479e7c8376d8dd54ea96c56f4ea657aae08ba78252e1ca6b4c6e8dd741f4bbd8b8a703eb5664803f60e613557b986c11d9ee1f8981169d98e949b1e87e9ce5528df8ca1890dbfe6426841992d0fb054bb16",2),D=C(B),K=A("01020408102040801b366cd8ab4d9a2f5ebc63c697356ad4b37dfaefc591",2),E=O(2),U=O(3),z=O(9),R=O(11),j=O(13),F=O(14),G=function(e,r,n){var f,c=b(8),t=h(u(r,n),c),a=t.key,o=t.iv,d=[[83,97,108,116,101,100,95,95].concat(c)];return e=u(e,n),f=l(e,a,o),f=d.concat(f),T.encode(f)},H=function(e,r,n){var f=T.decode(e),c=f.slice(8,16),t=h(u(r,n),c),a=t.key,o=t.iv;return f=f.slice(16,f.length),e=v(f,a,o,n)},L=function(e){function r(e,r){return e<<r|e>>>32-r}function n(e,r){var n,f,c,t,a;return c=2147483648&e,t=2147483648&r,n=1073741824&e,f=1073741824&r,a=(1073741823&e)+(1073741823&r),n&f?2147483648^a^c^t:n|f?1073741824&a?3221225472^a^c^t:1073741824^a^c^t:a^c^t}function f(e,r,n){return e&r|~e&n}function c(e,r,n){return e&n|r&~n}function t(e,r,n){return e^r^n}function a(e,r,n){return r^(e|~n)}function o(e,c,t,a,o,d,u){return e=n(e,n(n(f(c,t,a),o),u)),n(r(e,d),c)}function d(e,f,t,a,o,d,u){return e=n(e,n(n(c(f,t,a),o),u)),n(r(e,d),f)}function u(e,f,c,a,o,d,u){return e=n(e,n(n(t(f,c,a),o),u)),n(r(e,d),f)}function i(e,f,c,t,o,d,u){return e=n(e,n(n(a(f,c,t),o),u)),n(r(e,d),f)}function b(e){for(var r,n=e.length,f=n+8,c=(f-f%64)/64,t=16*(c+1),a=[],o=0,d=0;n>d;)r=(d-d%4)/4,o=8*(d%4),a[r]=a[r]|e[d]<<o,d++;return r=(d-d%4)/4,o=8*(d%4),a[r]=a[r]|128<<o,a[t-2]=n<<3,a[t-1]=n>>>29,a}function h(e){var r,n,f=[];for(n=0;3>=n;n++)r=255&e>>>8*n,f=f.concat(r);return f}var l,v,s,p,g,y,k,M,x,S=[],m=A("67452301efcdab8998badcfe10325476d76aa478e8c7b756242070dbc1bdceeef57c0faf4787c62aa8304613fd469501698098d88b44f7afffff5bb1895cd7be6b901122fd987193a679438e49b40821f61e2562c040b340265e5a51e9b6c7aad62f105d02441453d8a1e681e7d3fbc821e1cde6c33707d6f4d50d87455a14eda9e3e905fcefa3f8676f02d98d2a4c8afffa39428771f6816d9d6122fde5380ca4beea444bdecfa9f6bb4b60bebfbc70289b7ec6eaa127fad4ef308504881d05d9d4d039e6db99e51fa27cf8c4ac5665f4292244432aff97ab9423a7fc93a039655b59c38f0ccc92ffeff47d85845dd16fa87e4ffe2ce6e0a30143144e0811a1f7537e82bd3af2352ad7d2bbeb86d391",8);for(S=b(e),y=m[0],k=m[1],M=m[2],x=m[3],l=0;S.length>l;l+=16)v=y,s=k,p=M,g=x,y=o(y,k,M,x,S[l+0],7,m[4]),x=o(x,y,k,M,S[l+1],12,m[5]),M=o(M,x,y,k,S[l+2],17,m[6]),k=o(k,M,x,y,S[l+3],22,m[7]),y=o(y,k,M,x,S[l+4],7,m[8]),x=o(x,y,k,M,S[l+5],12,m[9]),M=o(M,x,y,k,S[l+6],17,m[10]),k=o(k,M,x,y,S[l+7],22,m[11]),y=o(y,k,M,x,S[l+8],7,m[12]),x=o(x,y,k,M,S[l+9],12,m[13]),M=o(M,x,y,k,S[l+10],17,m[14]),k=o(k,M,x,y,S[l+11],22,m[15]),y=o(y,k,M,x,S[l+12],7,m[16]),x=o(x,y,k,M,S[l+13],12,m[17]),M=o(M,x,y,k,S[l+14],17,m[18]),k=o(k,M,x,y,S[l+15],22,m[19]),y=d(y,k,M,x,S[l+1],5,m[20]),x=d(x,y,k,M,S[l+6],9,m[21]),M=d(M,x,y,k,S[l+11],14,m[22]),k=d(k,M,x,y,S[l+0],20,m[23]),y=d(y,k,M,x,S[l+5],5,m[24]),x=d(x,y,k,M,S[l+10],9,m[25]),M=d(M,x,y,k,S[l+15],14,m[26]),k=d(k,M,x,y,S[l+4],20,m[27]),y=d(y,k,M,x,S[l+9],5,m[28]),x=d(x,y,k,M,S[l+14],9,m[29]),M=d(M,x,y,k,S[l+3],14,m[30]),k=d(k,M,x,y,S[l+8],20,m[31]),y=d(y,k,M,x,S[l+13],5,m[32]),x=d(x,y,k,M,S[l+2],9,m[33]),M=d(M,x,y,k,S[l+7],14,m[34]),k=d(k,M,x,y,S[l+12],20,m[35]),y=u(y,k,M,x,S[l+5],4,m[36]),x=u(x,y,k,M,S[l+8],11,m[37]),M=u(M,x,y,k,S[l+11],16,m[38]),k=u(k,M,x,y,S[l+14],23,m[39]),y=u(y,k,M,x,S[l+1],4,m[40]),x=u(x,y,k,M,S[l+4],11,m[41]),M=u(M,x,y,k,S[l+7],16,m[42]),k=u(k,M,x,y,S[l+10],23,m[43]),y=u(y,k,M,x,S[l+13],4,m[44]),x=u(x,y,k,M,S[l+0],11,m[45]),M=u(M,x,y,k,S[l+3],16,m[46]),k=u(k,M,x,y,S[l+6],23,m[47]),y=u(y,k,M,x,S[l+9],4,m[48]),x=u(x,y,k,M,S[l+12],11,m[49]),M=u(M,x,y,k,S[l+15],16,m[50]),k=u(k,M,x,y,S[l+2],23,m[51]),y=i(y,k,M,x,S[l+0],6,m[52]),x=i(x,y,k,M,S[l+7],10,m[53]),M=i(M,x,y,k,S[l+14],15,m[54]),k=i(k,M,x,y,S[l+5],21,m[55]),y=i(y,k,M,x,S[l+12],6,m[56]),x=i(x,y,k,M,S[l+3],10,m[57]),M=i(M,x,y,k,S[l+10],15,m[58]),k=i(k,M,x,y,S[l+1],21,m[59]),y=i(y,k,M,x,S[l+8],6,m[60]),x=i(x,y,k,M,S[l+15],10,m[61]),M=i(M,x,y,k,S[l+6],15,m[62]),k=i(k,M,x,y,S[l+13],21,m[63]),y=i(y,k,M,x,S[l+4],6,m[64]),x=i(x,y,k,M,S[l+11],10,m[65]),M=i(M,x,y,k,S[l+2],15,m[66]),k=i(k,M,x,y,S[l+9],21,m[67]),y=n(y,v),k=n(k,s),M=n(M,p),x=n(x,g);return h(y).concat(h(k),h(M),h(x))},T=function(){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r=e.split(""),n=function(e){var n,f,c=[],t="";for(Math.floor(16*e.length/3),n=0;16*e.length>n;n++)c.push(e[Math.floor(n/16)][n%16]);for(n=0;c.length>n;n+=3)t+=r[c[n]>>2],t+=r[(3&c[n])<<4|c[n+1]>>4],t+=void 0!==c[n+1]?r[(15&c[n+1])<<2|c[n+2]>>6]:"=",t+=void 0!==c[n+2]?r[63&c[n+2]]:"=";for(f=t.slice(0,64)+"\n",n=1;Math.ceil(t.length/64)>n;n++)f+=t.slice(64*n,64*n+64)+(Math.ceil(t.length/64)===n+1?"":"\n");return f},f=function(r){r=r.replace(/\n/g,"");var n,f=[],c=[],t=[];for(n=0;r.length>n;n+=4)c[0]=e.indexOf(r.charAt(n)),c[1]=e.indexOf(r.charAt(n+1)),c[2]=e.indexOf(r.charAt(n+2)),c[3]=e.indexOf(r.charAt(n+3)),t[0]=c[0]<<2|c[1]>>4,t[1]=(15&c[1])<<4|c[2]>>2,t[2]=(3&c[2])<<6|c[3],f.push(t[0],t[1],t[2]);return f=f.slice(0,f.length-f.length%16)};return"function"==typeof Array.indexOf&&(e=r),{encode:n,decode:f}}();return{size:i,h2a:d,expandKey:S,encryptBlock:s,decryptBlock:p,Decrypt:n,s2a:u,rawEncrypt:l,rawDecrypt:v,dec:H,openSSLKey:h,a2h:o,enc:G,Hash:{MD5:L},Base64:T}});
992
993
        $("a").click(function(event){
994
            event.preventDefault();
995
        });
996
    </script>'
997
            );
998
999
            fclose($outstream);
1000
1001
            echo '[{"text":"<a href=\'' .
1002
                $post_file_link .
1003
                '\' target=\'_blank\'>' . $LANG['pdf_download'] . '</a>"}]';
1004
            break;
1005
    }
1006
}
1007
1008
//SPECIFIC FUNCTIONS FOR FPDF
1009
1010
/**
1011
 * Should we incloude  apage break in pdf.
1012
 *
1013
 * @param int $height Height of cell to add
1014
 */
1015
function checkPageBreak($height)
1016
{
1017
    global $pdf;
1018
    //Continue on a new page if needed
1019
    if ($pdf->GetY() + $height > $pdf->PageBreakTrigger) {
1020
        $pdf->addPage($pdf->CurOrientation);
1021
    }
1022
}
1023
1024
1025
/**
1026
 * Converts an array to CSV format.
1027
 *
1028
 * @param array  $fields      Array of fields
1029
 * @param string $delimiter   What delimiter is used in CSV
1030
 * @param string $enclosure   What enclosure is used in CSV
1031
 * @param string $escape_char What escape character is used in CSV
1032
 *
1033
 * @return string
1034
 */
1035
function array2csv($fields, $delimiter = ';', $enclosure = '"', $escape_char = '\\')
1036
{
1037
    $buffer = fopen('php://temp', 'r+');
1038
    if ($buffer === false) {
1039
        return "";
1040
    }
1041
    fputcsv($buffer, $fields, $delimiter, $enclosure, $escape_char);
1042
    rewind($buffer);
1043
    $csv = fgets($buffer);
1044
    fclose($buffer);
1045
1046
    return $csv;
1047
}
1048