Link.php 38.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?PHP
/***************************************************************
 *  Copyright notice
 *
 *  (c) 2010 Glowbase GmbH <support@glowbase.com>
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
 *  free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  The GNU General Public License can be found at
 *  http://www.gnu.org/copyleft/gpl.html.
 *
 *  This script is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/

namespace qfq;

//use qfq;

require_once(__DIR__ . '/Define.php');
30
31
require_once(__DIR__ . '/../store/Store.php');
require_once(__DIR__ . '/../store/Sip.php');
32
require_once(__DIR__ . '/../exceptions/UserReportExtension.php');
33
require_once(__DIR__ . '/../helper/KeyValueStringParser.php');
34
35
36
37
38
39
40
41
42
43
44
45

/*
 * u:url
 * m:mailto
 * p:page
 * 
 * t:text
 * a:AltText
 * o:ToolTip
 * 
 * r:render   
 * g:target
46
 * c:class  [n|i|e|<class>]
47
48
49
50
51
52
53
54
55
56
57
58
59
 * q:question  <text>
 * e:encryption 0|1
 * 
 * E:edit
 * N:new
 * D:delete
 * H:Help
 * I:information
 * M:Magnifier
 * B:bullet
 * P:picture       [file]
 * C:checkbox    [name]
 * R:right 
Carsten  Rose's avatar
Carsten Rose committed
60
 * s:sip
61
 *
62
63
64
65
 * A:    A:[u:p:m]
 * G:    G:[N|..]
 */

66
67
68
69
70
71
72

const NAME_URL = 'url';
const NAME_MAIL = 'mail';
const NAME_PAGE = 'page';
const NAME_TEXT = 'text';
const NAME_ALT_TEXT = 'altText';
const NAME_TOOL_TIP = 'toolTip';
73
const NAME_TOOL_TIP_JS = 'toolTipJs';
74
75
const NAME_IMAGE = 'image';
const NAME_IMAGE_TITLE = 'imageTitle';
76
77
const NAME_GLYPH = 'glyph';
const NAME_GLYPH_TITLE = 'glyphTitle';
78
79
80
81
82
83
84
const NAME_DELETE = 'delete';
const NAME_RENDER = 'render';
const NAME_TARGET = 'target';
const NAME_LINK_CLASS = 'linkClass';
const NAME_LINK_CLASS_DEFAULT = 'linkClassDefault';
const NAME_QUESTION = 'question';
const NAME_ENCRYPTION = 'encryption';
Carsten  Rose's avatar
Carsten Rose committed
85
const NAME_SIP = 'sip';
86
const NAME_URL_PARAM = 'param';
87
const NAME_RIGHT = 'picturePositionRight';
88
const NAME_ACTION_DELETE = 'actionDelete';
89
90
91
92
93
94
95
96

const FINAL_HREF = 'finalHref';
const FINAL_ANCHOR = 'finalAnchor';
const FINAL_CONTENT = 'finalContent';
const FINAL_SYMBOL = 'finalSymbol';
const FINAL_TOOL_TIP = 'finalToolTip';
const FINAL_CLASS = 'finalClass';
const FINAL_QUESTION = 'finalQuestion';
97

Carsten  Rose's avatar
Carsten Rose committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
const TOKEN_URL = 'u';
const TOKEN_MAIL = 'm';
const TOKEN_PAGE = 'p';
const TOKEN_TEXT = 't';
const TOKEN_ALT_TEXT = 'a';
const TOKEN_TOOL_TIP = 'o';
const TOKEN_PICTURE = 'P';
const TOKEN_BULLET = 'B';
const TOKEN_CHECK = 'C';
const TOKEN_DELETE = 'D';
const TOKEN_EDIT = 'E';
const TOKEN_HELP = 'H';
const TOKEN_INFO = 'I';
const TOKEN_NEW = 'N';
const TOKEN_SHOW = 'S';
const TOKEN_RENDER = 'r';
const TOKEN_TARGET = 'g';
const TOKEN_CLASS = 'c';
const TOKEN_QUESTION = 'q';
const TOKEN_ENCRYPTION = 'e';
const TOKEN_SIP = 's';
const TOKEN_URL_PARAM = 'U';
const TOKEN_RIGHT = 'R';

122
123
124
125
126
const TOKEN_ACTION_DELETE = 'x';
const TOKEN_ACTION_DELETE_AJAX = 'a';
const TOKEN_ACTION_DELETE_REPORT = 'r';
const TOKEN_ACTION_DELETE_CLOSE = 'c';

Carsten  Rose's avatar
Carsten Rose committed
127
128
129
130
const TOKEN_CLASS_NONE = 'n';
const TOKEN_CLASS_INTERNAL = 'i';
const TOKEN_CLASS_EXTERNAL = 'e';

131
132
133
const LINK_ANCHOR = 'linkAnchor';
const LINK_PICTURE = 'linkPicture';

134
135
const NO_CLASS = 'no_class';

Carsten  Rose's avatar
Carsten Rose committed
136
137
const DEFAULT_BULLET_COLOR = 'green';
const DEFAULT_CHECK_COLOR = 'green';
138
const DEFAULT_RENDER_MODE = '0';
Carsten  Rose's avatar
Carsten Rose committed
139
140
const DEFAULT_QUESTION_TEXT = 'Please confirm';
const DEFAULT_QUESTION_LEVEL = 'info';
141
const DEFAULT_ACTION_DELETE = 'r';
Carsten  Rose's avatar
Carsten Rose committed
142

Carsten  Rose's avatar
Carsten Rose committed
143
144
145
146
const QUESTION_INDEX_TEXT = 0;
const QUESTION_INDEX_LEVEL = 1;
const QUESTION_INDEX_BUTTON_OK = 2;
const QUESTION_INDEX_BUTTON_FALSE = 3;
147
148
const QUESTION_INDEX_TIMEOUT = 4;
const QUESTION_INDEX_FLAG_MODAL = 5;
Carsten  Rose's avatar
Carsten Rose committed
149

150
151
152
153
/**
 * Class Link
 * @package qfq
 */
154
155
class Link {

156
157
158
    //TODO: delete muss noch implementiert werden
    private $delete = '';

Carsten  Rose's avatar
Carsten Rose committed
159
    /**
160
     * @var Sip
Carsten  Rose's avatar
Carsten Rose committed
161
162
163
     */
    private $sip = null;

164
165
166
167
168
    /**
     * @var Store
     */
    private $store = null;

Carsten  Rose's avatar
Carsten Rose committed
169
170
171
172
173
    /**
     * @var bool
     */
    private $phpUnit;

174
175
176
    /**
     * @var Utils
     */
Carsten  Rose's avatar
Carsten Rose committed
177

178
    private $renderControl = array();
179
    private $linkClassSelector = array(TOKEN_CLASS_INTERNAL => "internal ", TOKEN_CLASS_EXTERNAL => "external ");
180
181
    private $cssLinkClassInternal = '';
    private $cssLinkClassExternal = '';
182

183
    private $callTable = [
Carsten  Rose's avatar
Carsten Rose committed
184
185
186
187
188
189
190
        TOKEN_URL => 'buildUrl',
        TOKEN_MAIL => 'buildMail',
        TOKEN_PAGE => 'buildPage',
        TOKEN_TOOL_TIP => 'buildToolTip',
        TOKEN_PICTURE => 'buildPicture',
        TOKEN_BULLET => 'buildBullet',
        TOKEN_CHECK => 'buildCheck',
191
192
        TOKEN_DELETE => 'buildDeleteIcon',
        TOKEN_ACTION_DELETE => 'buildActionDelete',
Carsten  Rose's avatar
Carsten Rose committed
193
194
195
196
197
        TOKEN_EDIT => 'buildEdit',
        TOKEN_HELP => 'buildHelp',
        TOKEN_INFO => 'buildInfo',
        TOKEN_NEW => 'buildNew',
        TOKEN_SHOW => 'buildShow',
198
199
    ];

200
    private $tableVarName = [
Carsten  Rose's avatar
Carsten Rose committed
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
        TOKEN_URL => NAME_URL,
        TOKEN_MAIL => NAME_MAIL,
        TOKEN_PAGE => NAME_PAGE,
        TOKEN_TEXT => NAME_TEXT,
        TOKEN_ALT_TEXT => NAME_ALT_TEXT,
        TOKEN_TOOL_TIP => NAME_TOOL_TIP,
        TOKEN_PICTURE => NAME_IMAGE,
        TOKEN_BULLET => NAME_IMAGE,
        TOKEN_CHECK => NAME_IMAGE,
        TOKEN_DELETE => NAME_IMAGE,
        TOKEN_EDIT => NAME_IMAGE,
        TOKEN_HELP => NAME_IMAGE,
        TOKEN_INFO => NAME_IMAGE,
        TOKEN_NEW => NAME_IMAGE,
        TOKEN_SHOW => NAME_IMAGE,
        TOKEN_RENDER => NAME_RENDER,
        TOKEN_TARGET => NAME_TARGET,
        TOKEN_CLASS => NAME_LINK_CLASS,
        TOKEN_QUESTION => NAME_QUESTION,
        TOKEN_ENCRYPTION => NAME_ENCRYPTION,
        TOKEN_SIP => NAME_SIP,
        TOKEN_URL_PARAM => NAME_URL_PARAM,
223
        TOKEN_RIGHT => NAME_RIGHT,
224
        TOKEN_ACTION_DELETE => NAME_ACTION_DELETE,
225
226
    ];

227
228
229
230
231
232
233
234
235
236
237
238
239
240
    private $tokenMapping = [
        TOKEN_URL => LINK_ANCHOR,
        TOKEN_MAIL => LINK_ANCHOR,
        TOKEN_PAGE => LINK_ANCHOR,
        TOKEN_PICTURE => LINK_PICTURE,
        TOKEN_BULLET => LINK_PICTURE,
        TOKEN_CHECK => LINK_PICTURE,
        TOKEN_DELETE => LINK_PICTURE,
        TOKEN_EDIT => LINK_PICTURE,
        TOKEN_HELP => LINK_PICTURE,
        TOKEN_INFO => LINK_PICTURE,
        TOKEN_NEW => LINK_PICTURE,
        TOKEN_SHOW => LINK_PICTURE,
    ];
241

242
243
244
    /**
     * __construct
     *
245
     * @param Sip $sip
246
     * @param bool $phpUnit
247
     */
248
    public function __construct(Sip $sip, $phpUnit = false) {
Carsten  Rose's avatar
Carsten Rose committed
249
        $this->phpUnit = $phpUnit;
250
251
252
253
254

        if ($phpUnit) {
            $_SERVER['REQUEST_URI'] = 'localhost';
        }

Carsten  Rose's avatar
Carsten Rose committed
255
        $this->sip = $sip;
Carsten  Rose's avatar
Carsten Rose committed
256
        $this->store = Store::getInstance('', $phpUnit);
257
258
        $this->cssLinkClassInternal = $this->store->getVar(SYSTEM_CSS_LINK_CLASS_INTERNAL, STORE_SYSTEM);
        $this->cssLinkClassExternal = $this->store->getVar(SYSTEM_CSS_LINK_CLASS_EXTERNAL, STORE_SYSTEM);
259
260
261
262
263
264
265
266
267

        /*
         * mode:
         * 0: no output
         * 1: text
         * 2: url
         * 3: <a href=url>url</a>
         * 4: <a href=url>Text</a>
         *
Carsten  Rose's avatar
Carsten Rose committed
268
         *  r=render mode, u=url, t:text and/or image.
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
         *
         *                  [r][u][t] = mode
         */

        $this->renderControl[0][0][0] = 0;
        $this->renderControl[0][0][1] = 0;
        $this->renderControl[0][1][0] = 3;
        $this->renderControl[0][1][1] = 4;

        $this->renderControl[1][0][0] = 0;
        $this->renderControl[1][0][1] = 1;
        $this->renderControl[1][1][0] = 3;
        $this->renderControl[1][1][1] = 4;

        $this->renderControl[2][0][0] = 0;
        $this->renderControl[2][0][1] = 0;
        $this->renderControl[2][1][0] = 0;
        $this->renderControl[2][1][1] = 4;

        $this->renderControl[3][0][0] = 0;
        $this->renderControl[3][0][1] = 1;
        $this->renderControl[3][1][0] = 2;
        $this->renderControl[3][1][1] = 1;

        $this->renderControl[4][0][0] = 0;
        $this->renderControl[4][0][1] = 1;
        $this->renderControl[4][1][0] = 2;
        $this->renderControl[4][1][1] = 2;

        $this->renderControl[5][0][0] = 0;
        $this->renderControl[5][0][1] = 0;
        $this->renderControl[5][1][0] = 0;
        $this->renderControl[5][1][1] = 0;
302

303
    }
304
305
306
307

    /**
     * Build the whole link
     *
308
309
     * @param string $str Qualifier with params. 'report'-syntax. F.e.:  A:u:www.example.com|G:P:home.gif|t:Home"
     * @return string     The complete HTML encoded Link like <a href='http://example.com' class='external'><img src='iconf.gif' title='help text'>Description</a>
310
     * @throws UserReportException
311
     */
312
    public function renderLink($str) {
313

314
        $tokenGiven = array();
315

316
317
        if (empty($str))
            return '';
318

319
320
321
        $vars = $this->fillParameter($str, $tokenGiven);
        $vars = $this->processParameter($vars);
        $mode = $this->getModeRender($vars);
322

323
        $link = '';
324

325
326
        // 0-4 URL, plain email
        // 10-14 encrypted email
327
328
329
330
331
        switch ($mode) {
            // 0: No Output
            case '0':
            case '10':
            case '20':
332
            $link = "";
333
334
335
336
                break;

            // 1: 'text'
            case '1':
337
                $link = $vars[FINAL_CONTENT];
338
339
                break;
            case '11':
340
341
                $link = $vars[FINAL_CONTENT];
//                $link = $this->encryptMailtoJS($vars, false);
342
343
344
345
                break;

            // 2: 'url'
            case '2':
346
                $link = $vars[FINAL_HREF];
347
348
                break;
            case '12':
349
350
                $link = $vars[FINAL_HREF];
//                $link = $this->encryptMailtoJS($vars, false);
351
352
                break;

353
            // 3: <a href=url ...>url</a>
354
            case '3':
Carsten  Rose's avatar
Carsten Rose committed
355
//                $link = $htmlUrl . $vars[NAME_URL] . '</a>' . $vars[NAME_TOOL_TIP_JS][1];
356
                $link = Support::wrapTag($vars[FINAL_ANCHOR], $vars[FINAL_HREF]);
357
358
                break;
            case '13':
359
360
361
                $link = Support::wrapTag($vars[FINAL_ANCHOR], $vars[FINAL_HREF]);
//                $vars[NAME_TEXT] = $vars[NAME_MAIL];
//                $link = $this->encryptMailtoJS($vars, true);
362
363
                break;

364
            // 4: <a href=url ...>Text</a>
365
            case '4':
366
                $link = Support::wrapTag($vars[FINAL_ANCHOR], $vars[FINAL_CONTENT]);
367
368
                break;
            case '14':
369
370
                $link = Support::wrapTag($vars[FINAL_ANCHOR], $vars[FINAL_CONTENT]);
//                $link = $this->encryptMailtoJS($vars, true);
371
372
373
374
375
                break;
            case '21':
            case '22':
            case '23':
            case '24':
376
            //TODO: Alter Code, umstellen auf JS Client von RO. Vorlage koennte 'Delete' in Subrecord sein.
Carsten  Rose's avatar
Carsten Rose committed
377
            $link = "<a href=\"javascript: void(0);\" onClick=\"var del = new FR.Delete({recordId:'',sip:'',forward:'" .
378
                $vars[NAME_PAGE] . "'});\" " . $vars[NAME_LINK_CLASS] . ">" . $vars[NAME_TEXT] . "</a>";
379
380
        }

381
382
383
        return $link;
    }

384
    /**
385
     * @param string $str
386
     * @param array $tokenGiven
387
     * @return array
388
     * @throws UserReportException
389
     */
390
    private function fillParameter($str, array &$tokenGiven) {
391

392
        // define all possible vars: no more isset()
393
394
        $vars = $this->initVars();
        $flagArray = array();
395

Carsten  Rose's avatar
Carsten Rose committed
396
        // str="u:http://www.example.com|c:i|t:Hello World|q:Do you really want to delete the record 25:warn:yes:no"
397
        $param = explode("|", $str);
398

399
400
        // Parse all parameter, fill variables
        foreach ($param as $item) {
401

402
            // Skip empty entries
403
404
405
            if ($item === '') {
                continue;
            }
406

407
408
409
410
            // u:www.example.com
            $arr = explode(":", $item, 2);
            $key = isset($arr[0]) ? $arr[0] : '';
            $value = isset($arr[1]) ? $arr[1] : '';
411

412
            // Bookkeeping defined parameter.
413
414
415
416
417
418
            if (isset($tokenGiven[$key])) {
                throw new UserReportException ("Multiple definitions for key '$key'", ERROR_MULTIPLE_DEFINITION);
            }
            $tokenGiven[$key] = true;

            if (!isset($this->tableVarName[$key])) {
419
                throw new UserReportException ("Unknown link qualifier: '$key' - do you forget the one character qualifier?", ERROR_UNKNOWN_LINK_QUALIFIER);
420
421
422
            }
            $keyName = $this->tableVarName[$key]; // convert token to name

423
            if ($value === '') {
424
                $value = $this->checkEmptyValue($key, $value);
425
            }
426
            $value = $this->checkValue($key, $value);
427

428
429
            // Store value
            $vars[$keyName] = $value;
430

431
432
433
434
435
436
437
438
439
440
441
442
443
            // Check for double anchor or picture definition
            if (isset($this->tokenMapping[$key])) {
                $type = $this->tokenMapping[$key];

                if (isset($flagArray[$type])) {
                    throw new UserReportException ("Multiple definitions of url/mail/page or picture", ERROR_MULTIPLE_DEFINITION);
                }
                $flagArray[$type] = true;

//                if ($type === LINK_PICTURE) {
//                    $build = 'build' . strtoupper($keyName[0]) . substr($keyName, 1);
//                    $this->$build($vars, $value);
//                }
444
445
            }

446
447
448
449
            if (isset($this->callTable[$key])) {
                $build = $this->callTable[$key];
                $vars = $this->$build($vars, $value);
            }
450
451
        }

452
453
        // Final Checks
        $this->checkParam($tokenGiven);
454

455
456
457
458
459
460
461
462
463
        return $vars;
    }

    /**
     * Cleans and make existing the standard vars used every time to render a link.
     *
     * @return array
     */
    private function initVars() {
464

465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
        return [
            NAME_MAIL => '',
            NAME_URL => '',
            NAME_PAGE => '',

            NAME_TEXT => '',
            NAME_ALT_TEXT => '',
            NAME_IMAGE => '',
            NAME_IMAGE_TITLE => '',
            NAME_GLYPH => '',
            NAME_GLYPH_TITLE => '',
            NAME_QUESTION => '',
            NAME_TARGET => '',
            NAME_TOOL_TIP => '',
            NAME_TOOL_TIP_JS => '',
            NAME_URL_PARAM => '',

            NAME_RENDER => '0',
            NAME_RIGHT => 'l',
            NAME_SIP => '0',
            NAME_ENCRYPTION => '0',
            NAME_DELETE => '',

            NAME_LINK_CLASS => '', // class name
            NAME_LINK_CLASS_DEFAULT => '', // Depending of 'as page' or 'as url'. Only used if class is not explizit set.

491
492
            NAME_ACTION_DELETE => '',

493
494
495
496
497
498
499
            FINAL_HREF => '',
            FINAL_CONTENT => '',
            FINAL_SYMBOL => '',
            FINAL_TOOL_TIP => '',
            FINAL_CLASS => '',
            FINAL_QUESTION => ''
        ];
500

501
502
    }

503
    /**
504
505
     * Verify Empty values. If appropriate, set defaults, if not throw anexception.
     *
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
     * @param $key
     * @param $value
     * @return string
     * @throws UserReportException
     */
    private function checkEmptyValue($key, $value) {
        switch ($key) {
            case TOKEN_URL:
                throw new UserReportException ("Missing value for token '$key'", ERROR_MISSING_VALUE);
                break;
            case TOKEN_MAIL:
                throw new UserReportException ("Missing value for token '$key'", ERROR_MISSING_VALUE);
                break;
            case TOKEN_PAGE:
                $value = $this->store->getVar(TYPO3_PAGE_ID, STORE_TYPO3); // If no pageid|pagealias is defined, take current page
                break;
            case TOKEN_RIGHT:
                $value = 'r';
                break;
            case TOKEN_ENCRYPTION:
                $value = '1';
                break;
            case TOKEN_SIP:
                $value = '1';
                break;
Carsten  Rose's avatar
Carsten Rose committed
531
532
533
            case TOKEN_QUESTION:
                $value = DEFAULT_QUESTION_TEXT;
                break;
534
535
536
            case TOKEN_RENDER:
                $value = DEFAULT_RENDER_MODE;
                break;
537
538
539
            case TOKEN_ACTION_DELETE:
                $value = DEFAULT_ACTION_DELETE;
                break;
540
541
542
543
544
545
546
            default:
        }

        return $value;
    }

    /**
547
548
     * Validate value for token
     *
549
550
551
552
553
554
555
556
557
558
     * @param $key
     * @param $value
     * @return mixed
     * @throws UserReportException
     */
    private function checkValue($key, $value) {
        switch ($key) {
            case TOKEN_ENCRYPTION:
            case TOKEN_SIP:
                if ($value !== '0' && $value !== '1') {
559
                    throw new UserReportException ("Invalid value for token '$key': '$value''", ERROR_INVALID_VALUE);
560
561
                }
                break;
562
563
564
565
566
567
568
569
570
571
            case TOKEN_ACTION_DELETE:
                switch ($value) {
                    case TOKEN_ACTION_DELETE_AJAX:
                    case TOKEN_ACTION_DELETE_REPORT:
                    case TOKEN_ACTION_DELETE_CLOSE:
                        break;
                    default:
                        throw new UserReportException ("Invalid value for token '$key': '$value''", ERROR_INVALID_VALUE);
                }
                break;
572
573
574
575
576
577
            default:
        }

        return $value;
    }

578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
    /**
     * Check for double definition.
     *
     * @param array $tokenGiven
     * @throws UserReportException
     */
    private function checkParam(array $tokenGiven) {
        $countLinkAnchor = 0;
        $countLinkPicture = 0;

        foreach ($tokenGiven as $token => $value) {
            if (isset($this->tokenMapping[$token])) {
                switch ($this->tokenMapping[$token]) {
                    case LINK_ANCHOR:
                        $countLinkAnchor++;
                        break;
                    case LINK_PICTURE:
                        $countLinkPicture++;
                        break;
                    default:
                        break;
                }
            }
        }

        if ($countLinkAnchor > 1) {
604
605
            throw new UserReportException ("Multiple URL / PAGE and MAILTO definition", ERROR_MULTIPLE_URL_PAGE_MAILTO_DEFINITION);
        }
606

607
608
609
610
611
612
        if ($countLinkPicture > 1) {
            throw new UserReportException ("Multiple definitions for token picture/bullet/check/edit...delete'" . TOKEN_PAGE . "'", ERROR_MULTIPLE_DEFINITION);
        }

        if (isset($tokenGiven[TOKEN_MAIL]) && isset($tokenGiven[TOKEN_TARGET])) {
            throw new UserReportException ("Token Mail and Target at the same time not possible'" . TOKEN_PAGE . "'", ERROR_MULTIPLE_DEFINITION);
613
        }
614
    }
615
616

    /**
617
     * Compute final link parameter.
618
     *
619
620
621
     * @param $vars
     * @return string
     * @throws UserReportException
622
     */
623
    private function processParameter($vars) {
624

Carsten  Rose's avatar
Carsten Rose committed
625
        $vars[FINAL_HREF] = $this->doHref($vars); // must be called before doToolTip()
626
627
628
        $vars[FINAL_TOOL_TIP] = $this->doToolTip($vars);
        $vars[FINAL_CLASS] = $this->doCssClass($vars);
        $vars[FINAL_SYMBOL] = $this->doSymbol($vars);
Carsten  Rose's avatar
Carsten Rose committed
629
630
        $vars[FINAL_CONTENT] = $this->doContent($vars); // must be called after doSymbol()
        $vars[FINAL_QUESTION] = $this->doQuestion($vars);
631
        $vars[FINAL_ANCHOR] = $this->doAnchor($vars);
632

633
        return $vars;
634
    }
635
636

    /**
637
     * Concat final HREF string
638
     *
639
     * @param array $vars
640
     * @return string
641
     * @throws UserReportException
642
     */
643
644
    private function doHref(array &$vars) {
        $urlNParam = '';
645

646
647
648
649
        if ($vars[NAME_ACTION_DELETE] !== '') {
            $vars[NAME_URL_PARAM] = $this->adjustDeleteParameter($vars[NAME_ACTION_DELETE], $vars[NAME_URL_PARAM]);
        }

650
        if ($vars[NAME_MAIL] === '') {
651
652
653
654
655

            if (substr($vars[NAME_URL], 0, 1) === '?') {
                $vars[NAME_URL] = INDEX_PHP . $vars[NAME_URL];
            }

656
657
            // Either NAME_URL is empty or NAME_PAGE is empty
            $urlNParam = Support::concatUrlParam($vars[NAME_URL] . $vars[NAME_PAGE], $vars[NAME_URL_PARAM]);
658

Carsten  Rose's avatar
Carsten Rose committed
659
            if ($vars[NAME_SIP] === "1") {
660
661
                $paramArray = $this->sip->queryStringToSip($urlNParam, RETURN_ARRAY);
                $urlNParam = $paramArray['_url'];
662

663
                if ($this->store->getVar(SYSTEM_SHOW_DEBUG_INFO, STORE_SYSTEM) === 'yes') {
664
                    $vars[NAME_TOOL_TIP] .= PHP_EOL . PHP_EOL . OnArray::toString($paramArray, ' = ', PHP_EOL, "'");
665
666
                }
            }
667
668
            // Link: MAILTO
        } else {
669
            // If there is no encryption: handle the mailto as an ordinary URL
670
            if ($vars[NAME_ENCRYPTION] === '1') {
671
                throw new UserReportException ("Oops, sorry: encrypted mail not implemented ...", ERROR_NOT_IMPLEMENTED);
672
673
            } else {
                $urlNParam = "mailto:" . $vars[NAME_MAIL];
674
675
676
            }
        }

677
678
        return $urlNParam;
    }
679

680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
    /**
     * @param $tokenActionDelete
     * @param $nameUrlParam
     * @return string
     * @throws UserReportException
     */
    private function adjustDeleteParameter($tokenActionDelete, $nameUrlParam) {

        $kvp = new KeyValueStringParser();

        // Split in: [p => 'r=100&table=note&..', 'D' => ''... ],
//        $param = $kvp->parse($nameUrlParam, ':', '|');

//        Support::setIfNotSet($param, TOKEN_URL_PARAM);

        switch ($tokenActionDelete) {
            case TOKEN_ACTION_DELETE_AJAX:
                // TODO: Implement for AJAX (subrecord)
                throw new UserReportException ("Not implemented!", ERROR_NOT_IMPLEMENTED);
                break;
            case TOKEN_ACTION_DELETE_REPORT:
                $nameUrlParam .= '&' . SIP_MODE_ANSWER . '=' . MODE_HTML;
                $nameUrlParam .= '&' . SIP_TARGET_URL . '=' . $_SERVER['REQUEST_URI'];
                break;
            case TOKEN_ACTION_DELETE_CLOSE:
                // TODO: Implement for Form (primary Record wird geloescht)
                throw new UserReportException ("Not implemented!", ERROR_NOT_IMPLEMENTED);
                break;
            default:
                throw new UserReportException ("Invalid value for token '" . TOKEN_ACTION_DELETE . "': '$tokenActionDelete''", ERROR_INVALID_VALUE);
        }

        return $nameUrlParam;
    }

715
716
717
718
719
720
721
    /**
     * Return $vars[NAME_TOOL_TIP]. If $vars[NAME_TOOL_TIP] is empty, set $vars[NAME_GLYPH_TITLE] as tooltip.
     *
     * @param array $vars
     * @return mixed
     */
    private function doToolTip(array $vars) {
722

723
724
725
        // Set default tooltip
        if ($vars[NAME_TOOL_TIP] == '') {
            $vars[NAME_TOOL_TIP] = $vars[NAME_GLYPH_TITLE];
Carsten  Rose's avatar
Carsten Rose committed
726
        }
727

728
        return $vars[NAME_TOOL_TIP];
729
    }
730

731
    /**
732
     * Parse CSS Class Settings
733
     *
734
735
     * @param array $vars
     * @return    string
736
     */
737
    private function doCssClass(array $vars) {
738

739
        $class = ($vars[NAME_LINK_CLASS] === '') ? $vars[NAME_LINK_CLASS_DEFAULT] : $vars[NAME_LINK_CLASS];
Carsten  Rose's avatar
Carsten Rose committed
740

741
742
743
744
745
746
747
748
749
750
751
        switch ($class) {
            case TOKEN_CLASS_NONE:
                $class = '';
                break;
            case TOKEN_CLASS_INTERNAL:
            case TOKEN_CLASS_EXTERNAL:
                $class = $this->linkClassSelector[$vars[NAME_LINK_CLASS]] . ' ';
                break;
            default:
                break;
        }
752

753
754
755
        if ($class === NO_CLASS) {
            $class = '';
        }
756

757
758
759
        if ($vars[NAME_GLYPH] !== '') {
            $class .= 'btn btn-default ';
        }
760

761
        return $class;
762
    }
763

764
765
766
    /**
     * Create Image HTML Tag
     *
767
768
     * @param array $vars
     * @return string
769
     */
770
    private function doSymbol(array $vars) {
771
        $tags = '';
772
        $html = '';
773
774

        // Build Image
775
        if ($vars[NAME_IMAGE] !== '') {
776
777
            $tags .= Support::doAttribute('alt', $vars[NAME_ALT_TEXT]);
            $tags .= Support::doAttribute('src', $vars[NAME_IMAGE]);
778
            $tags .= Support::doAttribute('title', $vars[FINAL_TOOL_TIP] === '' ? $vars[NAME_IMAGE_TITLE] : $vars[FINAL_TOOL_TIP]);
779
            $html .= '<img ' . $tags . '>';
780
781
        }

782
783
784
785
786
787
        if ($vars[NAME_GLYPH] !== '') {
            $tags = Support::doAttribute('class', 'glyphicon ' . $vars[NAME_GLYPH]);
            $html .= Support::wrapTag('<span ' . $tags . '>', '', false);
        }

        return $html;
788
    }
789

790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
    /**
     * Concat Text and/or Image and or Glyph. $vars[NAME_RIGHT_PICTURE_POSITION]
     * Concat Text and/or Image and or Glyph. Depending of $vars[NAME_RIGHT_PICTURE_POSITION], swapp the position,
     *
     * @param array $vars
     * @return string
     */
    private function doContent(array $vars) {

        $htmlImage = $vars[FINAL_SYMBOL];

        // Compose Image & Text
        if ($htmlImage === '') {
            $content = $vars[NAME_TEXT];
        } elseif ($vars[NAME_TEXT] === '') {
            $content = $htmlImage;
        } else {
            if ($vars[NAME_RIGHT] === "l") {
                $content = implode(' ', [$htmlImage, $vars[NAME_TEXT]]);
            } else {
                $content = implode(' ', [$vars[NAME_TEXT], $htmlImage]);
            }
        }

        return $content;
    }

Carsten  Rose's avatar
Carsten Rose committed
817
818
819
820
821
822
823
824
825
826
827
828
829
830
    /**
     * Build 'alert' JS. $vars['question'] = '<text>:<color>:<button ok>:<button fail>'
     * Return JS Code to place in '<a>' tag. Be carefull: function creates a uniqe 'id' tag.
     *
     * @param array $vars
     * @return string
     */
    private function doQuestion(array $vars) {

        if ($vars[NAME_QUESTION] === '') {
            return '';
        }

        $arr = OnArray::explodeWithoutEscaped(':', $vars[NAME_QUESTION]);
831
        $arr = array_merge($arr, ['', '', '', '', '', '']);
Carsten  Rose's avatar
Carsten Rose committed
832
833
834
835
836
837
838
839

        $id = ($this->phpUnit === true) ? '12345' : uniqid('a_');
        $content = Support::doAttribute('id', $id);

        $text = $arr[QUESTION_INDEX_TEXT] === '' ? DEFAULT_QUESTION_TEXT : $arr[QUESTION_INDEX_TEXT];
        $level = ($arr[QUESTION_INDEX_LEVEL] === '') ? DEFAULT_QUESTION_LEVEL : $arr[QUESTION_INDEX_LEVEL];
        $ok = ($arr[QUESTION_INDEX_BUTTON_OK] === '') ? 'Ok' : $arr[QUESTION_INDEX_BUTTON_OK];
        $cancel = ($arr[QUESTION_INDEX_BUTTON_FALSE] === '') ? 'Cancel' : $arr[QUESTION_INDEX_BUTTON_FALSE];
840
841
842
        $timeout = ($arr[QUESTION_INDEX_TIMEOUT] === '') ? '0' : $arr[QUESTION_INDEX_TIMEOUT] * 1000;
        $flagModalStatus = ($arr[QUESTION_INDEX_FLAG_MODAL] === '') ? '1' : $arr[QUESTION_INDEX_FLAG_MODAL];
        $flagModal = ($flagModalStatus === "1") ? 'true' : 'false';
Carsten  Rose's avatar
Carsten Rose committed
843
844

        $js = <<<EOF
845
var alert = new QfqNS.Alert({ message: '$text', type: '$level', modal: $flagModal, timeout: $timeout, buttons: [
Carsten  Rose's avatar
Carsten Rose committed
846
847
    { label: '$ok', eventName: 'ok' },
    { label: '$cancel',eventName: 'cancel'}
848
] } );
Carsten  Rose's avatar
Carsten Rose committed
849
850
851
852
853
854
855
856
857
858
859
860
861
862
alert.on('alert.ok', function() {
  window.location = $('#$id').attr('href');
});

alert.show();
return false;
EOF;

        $content .= Support::doAttribute('onClick', $js);


        return $content;
    }

863
864
865
866
867
868
869
870
871
872
    /**
     * Create the HTML anchor.
     * - <a href="mailto:info@example.com" title=".." class="..">
     * - <a href="http://example.com" title=".." class="..">
     *
     * @param array $vars
     * @return string
     * @throws UserReportException
     */
    private function  doAnchor(array $vars) {
Carsten  Rose's avatar
Carsten Rose committed
873

874
875
        $attributes = '';

Carsten  Rose's avatar
Carsten Rose committed
876

877
878
879
880
        $attributes .= Support::doAttribute('href', $vars[FINAL_HREF]);
        $attributes .= Support::doAttribute('class', $vars[FINAL_CLASS]);
        $attributes .= Support::doAttribute('target', $vars[NAME_TARGET]);
        $attributes .= Support::doAttribute('title', $vars[FINAL_TOOL_TIP]);
Carsten  Rose's avatar
Carsten Rose committed
881
        $attributes .= $vars[FINAL_QUESTION];
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907

        $anchor = '<a ' . $attributes . '>';
        return $anchor;
    }

    /**
     * Get mode from table $this->renderControl, depending on $modeRender, $modeUrl, $modeText
     *
     * @param array $vars
     * @param string $prefix
     * @return string
     * @throws UserReportException
     */
    private function getModeRender(array $vars, $prefix = '') {

        $modeRender = $vars[NAME_RENDER];
        $modeUrl = ($vars[FINAL_HREF] === '') ? 0 : 1;
        $modeText = ($vars[FINAL_CONTENT] === '') ? 0 : 1;

        // Create 'fake' modes for encrypted 'mailto'
        $prefix = "";
        if ($vars[NAME_MAIL] != '') {
            $prefix = "1";
//            $vars[NAME_URL] = "dummy";
        }

908
        // Create 'fake' mode for ajax/html delete
909
910
911
912
913
914
915
916
917
918
919
920
921
922
        if ($vars[NAME_DELETE]) {
            $prefix = "2";
        }

        if (isset($this->renderControl[$modeRender][$modeUrl][$modeText])) {
            $mode = $prefix . $this->renderControl[$modeRender][$modeUrl][$modeText];
        } else {
            throw new UserReportException ("Undefined combination of 'rendering mode' / 'url' / 'text': " .
                $modeRender . ' / ' . $modeUrl . ' / ' . $modeText, ERROR_UNDEFINED_RENDER_CONTROL_COMBINATION);
        }

        return $mode;
    }

923
924
925
926
927
928
929
930
931
932
933
934
935
    /**
     *  Encrypt the mailto address via JS.
     *  Email address protected against email crawler (as long as they don't interpret JS).
     *
     *    <script language=javascript><!--
     *    var mm1 = name
     *    var mm2 = @domain.
     *    var ... = tld
     *    document.write("<a href=" + "mail" + "to:" + mm1 + mm2 + ... + ">" + name + "</a>")
     *    document.write("<a href=" + "mail" + "to:" + mm1 + mm2 + ... + ">" + @domain. + "</a>")
     *    document.write("<a href=" + "mail" + "to:" + mm1 + mm2 + ... + ">" + tld + "</a>")
     *    //--></script>';
     *
936
937
938
     * @param array $vars
     * @param bool|TRUE $href TRUE: create a '<a>',   false: just encrypt or show the email, no link.
     * @return string
939
     */
940
    private function encryptMailtoJS(array $vars, $href = true) {
941
942

        // Split $mailto
943
        $tmp = $this->splitAndAddDelimter($vars[NAME_MAIL], "@");
944
945
946
947
948
949
950
951
952
953
954
955
        $arr = array_merge($this->splitAndAddDelimter($tmp[0], "."), $this->splitAndAddDelimter($tmp[1], "."));

        $tt = "<script language=javascript><!--" . chr(10);
        $ii = 0;
        if ($href) {
            $dw = 'document.write("<a href=" + "mail" + "to:"';
            foreach ($arr as $value) {
                // Setup JS Variables
                $tt .= 'var mm' . $ii . '= "' . $value . '"' . chr(10);
                // Compose $dw (documentwrite statement)
                $dw .= ' + mm' . $ii++;
            }
956
            $dw .= ' + "' . $vars[NAME_LINK_CLASS] . str_replace('"', '\\"', $vars[NAME_TOOL_TIP_JS][0]) . '>"';
957
958
959
960
961
962
963
            $closeDw = '"</a>")';
        } else {
            $dw = 'document.write(';
            $closeDw = ')';
        }

        // Wrap mailto around text
964
        if ($vars[NAME_MAIL] == $vars[NAME_TEXT]) {
965
966
967
968
969
970
971
            // Text is an email: wrap every single part of mailto.
            $ii = 0;
            foreach ($arr as $value) {
                $tt .= $dw . " + mm" . $ii++ . ' + ' . $closeDw . chr(10);
            }
        } else {
            // Single wrap text
972
            $tt .= $dw . ' + "' . $vars[NAME_TEXT] . '" + ' . $closeDw . chr(10);
973
974
975
        }

        $tt .= '//--></script>';
976
        if ($href) $tt .= $vars[NAME_TOOL_TIP_JS][1];
977
978

        return ($tt);
979
    }
980
981
982
983
984
985
986
987
988
989

    /**
     * Split a string around the $delimiter.
     *
     * Append the delimiter to each part except the last one.
     *
     * @param $mailto
     * @param $delimiter
     * @return array
     */
990
991
    private function splitAndAddDelimter($mailto, $delimiter) {
        //TODO: Ich verstehe die Funktion nicht - funktioniert das hier wirklich?
992
993
994
995
996
997
998
999
1000
        $value = '';

        $arr = explode($delimiter, $mailto);            // split string

        foreach ($arr as $key => $value) {
            $arr[$key] = $value . $delimiter;
        }

        if (isset($key))