Report.php 34.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
/***************************************************************
 *  Copyright notice
 *
 *  (c) 2010 Glowbase GmbH <support@glowbase.com>
 *  All rights reserved
 *
 ***************************************************************/

namespace qfq;

//use qfq;

require_once(__DIR__ . '/Define.php');
require_once(__DIR__ . '/Utils.php');
require_once(__DIR__ . '/Variables.php');
require_once(__DIR__ . '/Error.php');
18
19
//require_once(__DIR__ . '/Db.php');
require_once(__DIR__ . '/../Database.php');
20
21
require_once(__DIR__ . '/Link.php');
require_once(__DIR__ . '/Sendmail.php');
22
require_once(__DIR__ . '/../exceptions/UserReportExtension.php');
23
require_once(__DIR__ . '/../Evaluate.php');
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
const TOKEN_SQL = 'sql';
const TOKEN_HEAD = 'head';
const TOKEN_ALT_HEAD = 'althead';
const TOKEN_TAIL = 'tail';
const TOKEN_RBEG = 'rbeg';
const TOKEN_REND = 'rend';
const TOKEN_RENR = 'renr';
const TOKEN_RSEP = 'rsep';
const TOKEN_FBEG = 'fbeg';
const TOKEN_FEND = 'fend';
const TOKEN_FSEP = 'fsep';
const TOKEN_RBGD = 'rbgd';
const TOKEN_DEBUG = 'debug';

const TOKEN_FORM = 'form';

41
42
43

class Report {

Carsten  Rose's avatar
Carsten Rose committed
44
45
46
47
48
    /**
     * @var SIP
     */
    private $sip = null;

49
50
51
52
53
    /**
     * @var Store
     */
    private $store = null;

54
55
56
57
58
59
60
61
62
63
64
    /**
     * @var string
     */
    private $dbAlias = '';
    /**
     * @var Log
     */
    private $log = null;

    // frArray[10.50.5.sql][select ...]
    private $frArray = array();
65

66
67
    // $indexArray[10][50][5]   one entry per 'sql' statement
    private $indexArray = array();
68

69
70
71
72
    // TODO to explain
//	private $resultArray = array();
    private $levelCount = 0;
    //private $counter = 0;
73

74
75
76
77
    /**
     * @var Variables
     */
    private $variables = null;
78

79
80
81
82
83
84
85
86
87
    /**
     * @var Utils
     */
    private $utils = null;

    /**
     * @var Db
     */
    private $db = null;
88

89
90
91
92
93
    /**
     * @var Sendmail
     */
    private $sendmail = null;

94
95
96
97
    /**
     * @var array
     */
    private $pageDefaults = array();
98

99
100
101
    /**
     * @var array - Emulate global variable: will be set much earlier in other functions. Will be shown in error messages.
     */
102
103
    private $fr_error = array('uid' => '', 'pid' => '', 'row' => '', 'debug_level' => '0', 'full_level' => '');

104
105
    private $phpUnit = false;

106
107
    private $showDebugInfo = false;

108
109
    private $tokenList = array();

110
    /**
111
     * Report constructor.
112
     *
113
     * @param array $t3data
114
115
116
     * @param $sessionName
     * @param Evaluate $eval
     * @param bool $phpUnit
117
     */
118
    public function __construct(array $t3data, $sessionName, Evaluate $eval, $phpUnit = false) {
119
120

        $this->phpUnit = $phpUnit;
121

122
123
        Support::setIfNotSet($t3data, "uid", 0);

124
        $this->sip = new Sip($sessionName, $phpUnit);
125
        $this->store = Store::getInstance();
126

127
128
        $this->showDebugInfo = ($this->store->getVar(SYSTEM_SHOW_DEBUG_INFO, STORE_SYSTEM) === 'yes');

129
        $this->pageDefaults["msgbox"]["pagec"] = "Please confirm!";
130

131
132
133
        $this->pageDefaults["sip"]["paged"] = TOKEN_SIP;
        $this->pageDefaults["sip"]["pagee"] = TOKEN_SIP;
        $this->pageDefaults["sip"]["pagen"] = TOKEN_SIP;
134

135
136
137
138
139
140
        $this->pageDefaults["icon"]["paged"] = TOKEN_DELETE;
        $this->pageDefaults["icon"]["pagee"] = TOKEN_EDIT;
        $this->pageDefaults["icon"]["pageh"] = TOKEN_HELP;
        $this->pageDefaults["icon"]["pagei"] = TOKEN_INFO;
        $this->pageDefaults["icon"]["pagen"] = TOKEN_NEW;
        $this->pageDefaults["icon"]["pages"] = TOKEN_SHOW;
141

142
143
        $this->db = new Database();
        $this->utils = new Utils();
144
        $this->variables = new Variables($eval, $t3data["uid"]);
145

146
        // Set static values, which won't change during this run.
147
        $this->fr_error["pid"] = isset($this->variables->resultArray['global.']['page_id']) ? $this->variables->resultArray['global.']['page_id'] : 0;
148
        $this->fr_error["uid"] = $t3data['uid'];
149
        $this->fr_error["debug_level"] = 0;
150

Carsten  Rose's avatar
Carsten Rose committed
151
        // Sanitize function for POST and GET Parameters.
152
        // Merged URL-Parameter (key1, id etc...) in resultArray.
153
        $this->variables->resultArray = array_merge($this->variables->resultArray, array("global." => $this->variables->collectGlobalVariables()));
154

155
156
        // Create Logclass.
        $this->log = new Log($this->variables->resultArray['global.']);
157

158
159
        // Create sendmail Class. Take care to prepare a fr_log instance.
        $this->sendmail = new Sendmail($this->log);
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

        $this->tokenList[] = TOKEN_SQL;
        $this->tokenList[] = TOKEN_HEAD;
        $this->tokenList[] = TOKEN_ALT_HEAD;
        $this->tokenList[] = TOKEN_TAIL;
        $this->tokenList[] = TOKEN_RBEG;
        $this->tokenList[] = TOKEN_REND;
        $this->tokenList[] = TOKEN_RENR;
        $this->tokenList[] = TOKEN_RSEP;
        $this->tokenList[] = TOKEN_FBEG;
        $this->tokenList[] = TOKEN_FEND;
        $this->tokenList[] = TOKEN_FSEP;
        $this->tokenList[] = TOKEN_RBGD;
        $this->tokenList[] = TOKEN_DEBUG;

175
176
177
178
179
180
181
    }

    /**
     * Main function. Parses bodytext and iterates over all queries.
     *
     * @return string
     */
182
    public function process($bodyText) {
183

184
185
186
187
188
        //phpUnit Test: clean environment
        $this->frArray = array();
        $this->indexArray = array();
        $this->levelCount = 0;

189
        $this->log->set_fr_error($this->fr_error);
190

191
        // Iteration over Bodytext
192
        $ttLineArray = explode("\n", $bodyText);
193

194
195
196
        foreach ($ttLineArray as $index => $line) {
            // Fill $frArray, $indexArray, $resultArray
            $this->parseFRLine($line);
197
        }
198

199
200
201
202
203
204
        // Sort array
        $this->sortIndexArray($this->indexArray, $this->generateSortArg());

        // Report
        $content = $this->triggerReport();

205
        return $content;
206
    }
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

    /**
     * Split line in level, command, content and fill 'frArray', 'levelCount', 'indexArray'
     * Example: 10.50.5.sql = select * from person
     *
     * @param    string $ttLine : line to split in level, command, content
     * @return    void
     */
    private function parseFRLine($ttLine) {

        // 10.50.5.sql = select ...
        $arr = explode("=", trim($ttLine), 2);

        // 10.50.5.sql
        $key = strtolower(trim($arr[0]));

        // comment ?
224
225
        if (empty($key) || $key[0] === "#")
            return;
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246

        // select ...
        $value = trim($arr[1]);

        // 10.50.5.sql
        $arrKey = explode('.', $key);

        // frCmd = "sql"
        $frCmd = $arrKey[count($arrKey) - 1];

        // remove last item (cmd)
        unset($arrKey[count($arrKey) - 1]);

        // save elements only if there is a level specified
        if (count($arrKey)) {
            // level = "10.50.5"
            $level = implode(".", $arrKey);

            // fill Array
            $this->setLine($level, $frCmd, $value);
        }
247
    }
248

249
250
251
252
253
    /**
     * @param $level
     * @param $frCmd
     * @param $value
     */
254
255
256
257
258
259
260
261
    private function setLine($level, $frCmd, $value) {

        // store complete line reformatted in frArray
        $this->frArray[$level . "." . $frCmd] = $value;

        // per sql command
        //pro sql cmd wir der Indexarray abgefüllt. Dieser wird später verwendet um auf den $frArray zuzugreifen
        //if(preg_match("/^sql/i", $frCmd) == 1){
262
        if ($frCmd === TOKEN_FORM || $frCmd === TOKEN_SQL) {
263
264
265
266
267
            // Remember max level
            $this->levelCount = max(substr_count($level, '.') + 1, $this->levelCount);
            // $indexArray[10][50][5]
            $this->indexArray[] = explode(".", $level);
        }
268
269
270
271
272
273
274
275

        // set defaults
        if ($frCmd === TOKEN_SQL) {
            foreach ($this->tokenList as $key) {
                if (!isset($this->frArray[$level . "." . $key]))
                    $this->frArray[$level . "." . $key] = '';
            }
        }
276
    }
277
278
279
280

    /**
     * Sorts the associative array.
     *
281
282
     * @param    array $ary : The unsorted Level Array
     * @param    string $clause : the sort argument 0 ASC, 1 ASC... according to the number of columns
283
284
     * @return    The content that is displayed on the website
     */
285
    private function sortIndexArray(array &$ary, $clause, $ascending = true) {
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329

        $clause = str_ireplace('order by', '', $clause);
        $clause = preg_replace('/\s+/', ' ', $clause);
        $keys = explode(',', $clause);
        $dirMap = array('desc' => 1, 'asc' => -1);
        $def = $ascending ? -1 : 1;

        $keyAry = array();
        $dirAry = array();
        foreach ($keys as $key) {
            $key = explode(' ', trim($key));
            $keyAry[] = trim($key[0]);
            if (isset($key[1])) {
                $dir = strtolower(trim($key[1]));
                $dirAry[] = $dirMap[$dir] ? $dirMap[$dir] : $def;
            } else {
                $dirAry[] = $def;
            }
        }
        $fnBody = '';
        for ($i = count($keyAry) - 1; $i >= 0; $i--) {
            $k = $keyAry[$i];
            $t = $dirAry[$i];
            $f = -1 * $t;
            $aStr = '$a[\'' . $k . '\']';
            $bStr = '$b[\'' . $k . '\']';

            if (strpos($k, '(') !== false) {
                $aStr = '$a->' . $k;
                $bStr = '$b->' . $k;
            }

            if ($fnBody == '') {
                $fnBody .= "if({$aStr} == {$bStr}) { return 0; }\n";
                $fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";
            } else {
                $fnBody = "if({$aStr} == {$bStr}) {\n" . $fnBody;
                $fnBody .= "}\n";
                $fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";
            }
        }

        if ($fnBody) {
            $sortFn = create_function('$a,$b', $fnBody);
330
331
332
333
334

            // TODO: at the moment, $sortFn() triggers some E_NOTICE warnings. We stop these here for a short time.
            $errorSet = error_reporting();
            error_reporting($errorSet & ~E_NOTICE);

335
            usort($ary, $sortFn);
336
337

            error_reporting($errorSet);
338
        }
339
    }
340

341
342
343
344
345
    /**
     * generateSortArg
     *
     * @return string
     */
346
347
348
349
350
351
352
    private function generateSortArg() {

        $sortArg = "";

        for ($i = 0; $i < $this->levelCount; $i++) {
            $sortArg = $sortArg . $i . " ASC, ";
        }
353

354
        $sortArg = substr($sortArg, 0, strlen($sortArg) - 2);
355

356
        return $sortArg;
357
    }
358
359
360
361
362
363
364
365
366
367
368
369
370
371

    /**
     * Executes the queries recursive. This Method is called for each Sublevel.
     *
     * ROOTLEVEL
     * This method is called once from the main method.
     * For the first call the method executes the rootlevels
     *
     * SUBLEVEL
     * For each rootlevel the method calls it self whith the levelmode 0
     * If the next Level is a Sublevel it will be executed and $this->counter will be added by 1
     * The sublevel calls the method again for a following sublevel
     *
     * @param int $cur_level Which level it will call [10] = level 1, [10.10] = level 2 ...
372
373
     * @param string $super_level_array The Value-Array of the indexarray [0=>10, 1=>50]
     * @param int $counter The outer numeric Arraykey of indexarray
374
375
376
377
378
379
380
     * @return string                       The content that is displayed on the website
     * @throws codeException
     * @throws SqlReportException
     * @throws SyntaxReportException
     * @throws UserReportException
     */

381
382
    private function triggerReport($cur_level = 1, array $super_level_array = array(), $counter = 0) {
        $keys = array();
383
        $stat = array();
384
385
386
387
388
389

        $lineDebug = 0;
        $content = "";
        $rowTotal = 0;

        // CurrentLevel "10.10.50"
390
391
392
393
394
395
        if (isset($this->indexArray[$counter]) && is_array($this->indexArray[$counter])) {
            $full_level = implode(".", $this->indexArray[$counter]);
        } else {
            $full_level = '';
        }

396
        // Superlevel "10.10"
397
398
399
400
401
        if (isset($super_level_array) && is_array($super_level_array)) {
            $full_super_level = implode(".", $super_level_array);
        } else {
            $full_super_level = '';
        }
402
403
404
405
406
407
408

        //condition1: indexArray
        //condition2: full_level == Superlevel (but at the length of the Superlevel)
        while ($counter < count($this->indexArray) && $full_super_level == substr($full_level, 0, strlen($full_super_level))) {

            //True: The cur_level is a subquery -> continue
            if ($cur_level != count($this->indexArray[$counter])) {
409
410
411
412
413
414
                ++$counter;
                if (isset($this->indexArray[$counter]) && is_array($this->indexArray[$counter])) {
                    $full_level = implode(".", $this->indexArray[$counter]);
                } else {
                    $full_level = '';
                }
415
416
417
418
                continue;
            }

            // Set dbAlias if one is specified. Else keep the parent one.
419
420
            //TODO dbAlias
//            $this->dbAlias = $this->getValueParentDefault("db", $full_super_level, $full_level, $cur_level, DB);
421
422

            // Set debug, if one is specified else keep the parent one.
423
            $lineDebug = $this->getValueParentDefault(TOKEN_DEBUG, $full_super_level, $full_level, $cur_level, 0);
424
425

            // Prepare Error reporting
426
            $this->store->setVar(SYSTEM_SQL_RAW, $this->frArray[$full_level . "." . TOKEN_SQL], STORE_SYSTEM);
427
            $this->store->setVar(SYSTEM_REPORT_FULL_LEVEL, $full_level, STORE_SYSTEM);
428

429
430
431
            // Prepare SQL: replace variables. Actual 'line.total' or 'line.count' will recalculated: don't replace them now!
            unset($this->variables->resultArray[$full_level . ".line."]["total"]);
            unset($this->variables->resultArray[$full_level . ".line."]["count"]);
432
            $sql = $this->variables->doVariables($this->frArray[$full_level . "." . TOKEN_SQL]);
433

434
            $this->store->setVar(SYSTEM_SQL_FINAL, $sql, STORE_SYSTEM);
435
436
437

            //Execute SQL. All errors have been already catched.
            unset($result);
438
            $result = $this->db->sqlKeys($sql, $keys, $stat);
439
440
441

            // If an array is returned, $sql was a query, otherwise an 'insert', 'update', 'delete', ...
            // Query: total nummber of rows
442
443
            // insert, delete, update: number of affected rows
            $rowTotal = isset($stat[DB_NUM_ROWS]) ? $stat[DB_NUM_ROWS] : $stat[DB_AFFECTED_ROWS];
444
445

            $this->variables->resultArray[$full_level . ".line."]["total"] = $rowTotal;
446
447
448
            if (isset($stat[DB_INSERT_ID])) {
                $this->variables->resultArray[$full_level . ".line."]["insertId"] = $stat[DB_INSERT_ID];
            }
449
450
451

            // HEAD: If there is at least one record, do 'head'.
            if ($rowTotal > 0)
452
                $content .= $this->variables->doVariables($this->frArray[$full_level . "." . TOKEN_HEAD]);
453
454

            // Prepare row alteration
455
456
457
458
459
            $arrRbgd = explode("|", $this->frArray[$full_level . "." . TOKEN_RBGD]);
            if (count($arrRbgd) < 2) {
                $arrRbgd[] = '';
                $arrRbgd[] = '';
            }
460

461
462
463
464
465
466
467
468
469
470
471
472
473
474
            if (is_array($result)) {
                //---------------------------------
                // Process each row of resultset
                $columnValueSeperator = "";
                $rowIndex = 0;
                foreach ($result as $row) {
                    // record number counter
                    $this->variables->resultArray[$full_level . ".line."]["count"] = ++$rowIndex;

                    // replace {{<level>.line.count}} and {{<level>.line.total}} in __result__, if the variables specify their own full_level. This can't be replaced before firing the query.
                    for ($ii = 0; $ii < count($row); $ii++) {
                        $row[$ii] = str_replace("{{" . $full_level . ".line.count}}", $rowIndex, $row[$ii]);
                        $row[$ii] = str_replace("{{" . $full_level . ".line.total}}", $rowTotal, $row[$ii]);
                    }
475

476
477
                    // SEP set seperator (empty on first run)
                    $content .= $columnValueSeperator;
478
                    $columnValueSeperator = $this->variables->doVariables($this->frArray[$full_level . "." . TOKEN_RSEP]);
479

480
                    // RBGD: even/odd rows
481
                    $content .= str_replace(TOKEN_RBGD, $arrRbgd[$rowIndex % 2], $this->frArray[$full_level . "." . TOKEN_RBEG]);
482

483
484
485
                    //-----------------------------
                    // COLUMNS: Collect all columns
                    $content .= $this->collectRow($row, $keys, $full_level, $rowIndex);
486

487
                    // REND
488
                    $content .= $this->variables->doVariables($this->frArray[$full_level . "." . TOKEN_REND]);
489

490
491
                    // Trigger subqueries of this level
                    $content .= $this->triggerReport($cur_level + 1, $this->indexArray[$counter], $counter + 1);
492

493
                    // RENR
494
                    $content .= $this->variables->doVariables($this->frArray[$full_level . "." . TOKEN_RENR]);
495

496
                }
497
498
499
500
            }

            //Print althead or tail
            if ($rowTotal > 0) {
501
                $content .= $this->variables->doVariables($this->frArray[$full_level . "." . TOKEN_TAIL]);
502
            } else {
503
                $content .= $this->variables->doVariables($this->frArray[$full_level . "." . TOKEN_ALT_HEAD]);
504
505
            }

506
507
508
509
510
511
            ++$counter;
            if (isset($this->indexArray[$counter]) && is_array($this->indexArray[$counter])) {
                $full_level = implode(".", $this->indexArray[$counter]);
            } else {
                $full_level = '';
            }
512
513
514
        }

        return $content;
515
    }
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532

    /**
     * Determine value:
     * 1) if one specified in line: take it
     * 2) if one specified in upper level: take it
     * 3) if none above take default
     * Set value on $full_level
     *
     * @param    string $level_key - 'db' or 'debug'
     * @param    string $full_super_level - f.e.: 10.10.
     * @param    string $full_level - f.e.: 10.10.10.
     * @param    string $cur_level - f.e.: 2
     * @param    string $default - f.e.: 0
     * @return   string  The calculated value.
     */
    private function getValueParentDefault($level_key, $full_super_level, $full_level, $cur_level, $default) {

533
        if (!empty($this->frArray[$full_level . "." . $level_key])) {
534
535
536
537
538
539
540
541
542
543
544
            $value = $this->frArray[$full_level . "." . $level_key];
        } else {
            if ($cur_level == 1) {
                $value = $default;
            } else {
                $value = $this->variables->resultArray[$full_super_level . ".line."][$level_key];
            }
        }
        $this->variables->resultArray[$full_level . ".line."][$level_key] = $value;

        return ($value);
545
    }
546
547
548
549
550
551
552
553
554
555
556
557
558
559

    /**
     * Steps through 'row' and collects all columns
     *
     * @param array $row Recent row fetch from sql resultset.
     * @param array $keys List of all columnnames
     * @param string $full_level Recent position to work on.
     * @param string $rowIndex Index of recent row in resultset.
     * @return string               Collected content of all printable columns
     * @throws SyntaxReportException
     */
    private function collectRow(array $row, array $keys, $full_level, $rowIndex) {
        $content = "";

560
        $fsep = '';
561
562
        for ($ii = 0; $ii < count($keys); $ii++) {

563
564
565
            $this->store->setVar(SYSTEM_REPORT_COLUMN_INDEX, $ii + 1, STORE_SYSTEM);
            $this->store->setVar(SYSTEM_REPORT_COLUMN_NAME, $keys[$ii], STORE_SYSTEM);
            $this->store->setVar(SYSTEM_REPORT_COLUMN_VALUE, $row[$ii], STORE_SYSTEM);
566

567
568
569
            $flagOutput = false;
            $renderedColumn = $this->renderColumn($ii, $keys[$ii], $row[$ii], $full_level, $rowIndex, $flagOutput);
            if ($flagOutput) {
570
                //prints
571
                $content .= $this->variables->doVariables($fsep);
572
                $content .= $this->variables->doVariables($this->frArray[$full_level . "." . TOKEN_FBEG]);
573
                $content .= $renderedColumn;
574
575
                $content .= $this->variables->doVariables($this->frArray[$full_level . "." . TOKEN_FEND]);
                $fsep = $this->frArray[$full_level . "." . TOKEN_FSEP];
576
577
578
            }
        }
        return ($content);
579
    }
580
581
582
583

    /**
     * Renders column depending of column name (if name is a reserved column name)
     *
584
585
586
587
588
589
590
     * @param string $columnIndex
     * @param string $columnName
     * @param string $columnValue
     * @param string $full_level
     * @param string $rowIndex
     * @return string rendered column
     * @throws SyntaxReportException
591
     */
592
    private function renderColumn($columnIndex, $columnName, $columnValue, $full_level, $rowIndex, &$flagOutput) {
593
        $content = "";
594
595
        $flagControl = false;
        $flagOutput = true;
596

597
        if ($columnName[0] === "_") {
598
            $flagControl = true;
599
600
            $columnName = substr($columnName, 1);
        }
601

602
        //TODO: reserved names,not starting with '_' will be still accepted - stop this!
603
604
        switch ($columnName) {
            case "link":
605
                $link = new Link($this->fr_error, $this->sip);
606
                $content .= $link->renderLink($columnValue);
607
                break;
608

609
610
611
612
613
614
615
616
617
618
619
620
621
            case "exec":
                $content .= $this->myExec($columnValue);
                break;

            case "Page":
            case "Pagec":
            case "Paged":
            case "Pagee":
            case "Pageh":
            case "Pagei":
            case "Pagen":
            case "Pages":
                $linkValue = $this->doFixColPosPage($columnName, $columnValue);
622
623
            $link = new Link($this->fr_error, $this->sip);
            $content .= $link->renderLink($linkValue);
624
625
626
627
628
629
630
631
632
633
634
                break;

            case "page":
            case "pagec":
            case "paged":
            case "pagee":
            case "pageh":
            case "pagei":
            case "pagen":
            case "pages":
                $linkValue = $this->doPage($columnName, $columnValue);
635
636
            $link = new Link($this->fr_error, $this->sip);
            $content .= $link->renderLink($linkValue);
637
638
                break;

639
640
641
642
            case "bullet":
                if ($columnValue === '')
                    break;

Carsten  Rose's avatar
Carsten Rose committed
643
644
                // r:3|B:
                $linkValue = TOKEN_RENDER . ":3|" . TOKEN_BULLET . ":" . $columnValue;
645
646
647
648
649
650
651
652
                $link = new Link($this->fr_error, $this->sip);
                $content .= $link->renderLink($linkValue);
                break;

            case "check":
                if ($columnValue === '')
                    break;

Carsten  Rose's avatar
Carsten Rose committed
653
654
                // "r:3|C:
                $linkValue = TOKEN_RENDER . ":3|" . TOKEN_CHECK . ":" . $columnValue;
655
656
657
658
                $link = new Link($this->fr_error, $this->sip);
                $content .= $link->renderLink($linkValue);
                break;

659
660
            case "img":
                // "<path to image>|[alttext]|[text behind]" renders to: <img src="<path to image>" alt="[alttext]">[text behind]
Carsten  Rose's avatar
Carsten Rose committed
661
662
663
                if (empty($columnValue))
                    break;

664
                $tmp = explode("|", $columnValue, 3);
665
666
667
668
669
670
671
672
673
674
675

                // Fake values for tmp[1], tmp[2] to suppress access errors.
                $tmp[] = '';
                $tmp[] = '';

                if (empty($tmp[0]))
                    break;
                $attribute = Support::doAttribute('src', $tmp[0]);
                $attribute .= Support::doAttribute('alt', $tmp[1]);

                $content .= '<img ' . $attribute . '>' . $tmp[2];
676
677
678
679
680
                break;

            case "mailto":
                // "<email address>|[Real Name]"  renders to (encrypted via JS): <a href="mailto://<email address>"><email address></a> OR <a href="mailto://<email address>">[Real Name]</a>
                $tmp = explode("|", $columnValue, 2);
681
682
                if (empty($tmp[0]))
                    break;
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700

                $t1 = explode("@", $tmp[0], 2);
                $content .= "<script language=javascript><!--" . chr(10);
                if (empty($tmp[1])) $tmp[1] = $tmp[0];

                $content .= 'var contact = "' . substr($tmp[1], 0, 2) . '"' . chr(10);
                $content .= 'var contact1 = "' . substr($tmp[1], 2) . '"' . chr(10);
                $content .= 'var email = "' . $t1[0] . '"' . chr(10);
                $content .= 'var emailHost = "' . $t1[1] . '"' . chr(10);

                $content .= 'document.write("<a href=" + "mail" + "to:" + email + "@" + emailHost+ ">" + contact + "</a>")' . chr(10);
                $content .= 'document.write("<a href=" + "mail" + "to:" + email + "@" + emailHost+ ">" + contact1 + "</a>")' . chr(10);
                $content .= '//--></script>';
                break;

            case "sendmail":
                // 'Absender|Empfaenger, mehrere mit Komma getrennt|Betreff|Mailinhalt'
                $tmp = explode("|", $columnValue, 4);
701
702
703
                if (count($tmp) < 4) {
                    throw new SyntaxReportException ("Too few parameter for sendmail: $columnValue", "", null, __FILE__, __LINE__, $this->fr_error);
                }
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746

                $mail['receiver'] = $tmp[0];
                $mail['sender'] = $tmp[1];
                $mail['subject'] = $tmp[2];
                $mail['body'] = $tmp[3];

                $content = $this->sendmail->sendmail($mail);
                break;

            case "vertical":
                // '<Text>|[angle]|[width]|[height]|[tag]'   , width and heigth needs a unit (px, em ,...), 'tag' might be 'div', 'span', ...
                $arr = explode("|", $columnValue, 5);

                # angle
                $angle = $arr[1] ? $arr[1] : 270;

                # width
                $width = $arr[2] ? $arr[2] : "1em";
                $tmp = "width:$width; ";

                # height
                if ($arr[3])
                    $tmp .= "height:" . $arr[3] . "; ";

                # tag
                if ($arr[4]) {
                    $tag = explode(" ", trim($arr[4]), 2);
                    $tag_open = "<" . $arr[4] . " ";
                    $tag_close = "</" . $tag[0] . ">";
                } else {
                    $tag_open = "<div ";
                    $tag_close = "</div>";
                }

                # http://scottgale.com/blog/css-vertical-text/2010/03/01/
                #$style = "writing-mode:tb-rl; -webkit-transform:rotate(270deg); -moz-transform:rotate(270deg); -o-transform: rotate(270deg); white-space:nowrap; width:1em;  display: block;";
                $style = "width:1em;  filter: flipv fliph; transform: rotate(" . $angle . "deg) translate(-10em,0); transform-origin: 0 0; writing-mode:tb-rl; -webkit-transform:rotate(" . $angle . "deg); -moz-transform:rotate(" . $angle . "deg); -o-transform: rotate(" . $angle . "deg); white-space:nowrap; display: block;";

                #$style = "line-height: 1.5em; background:#eee; display: block; white-space: nowrap; padding-left: 3px; writing-mode: tb-rl; filter: flipv fliph; transform: rotate(270deg) translate(-10em,0); transform-origin: 0 0; -moz-transform: rotate(270deg) translate(-10em,0); -moz-transform-origin: 0 0; -webkit-transform: rotate(270deg) translate(-10em,0); -webkit-transform-origin: 0 0;";
                $content = $tag_open . 'style="' . $style . '">' . $arr[0] . $tag_close;
                break;

            default :
747
748
749
750
751
                if ($flagControl) {
                    $flagOutput = false;
                } else {
                    $content .= $columnValue;
                }
752
753
                break;
        }
754

755
756
        // Always save column values, even if they are hidden.
        $this->variables->resultArray[$full_level . "."][$columnName] = ($content == '' && $flagControl) ? $columnValue : $content;
757
758

        return $content;
759
    }
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776

    /**
     * Executes the Command in $cmd
     * RC: if RC==0 Returns Output, else 'RC - Output'
     *
     * @param    string $cmd : contains the Comand
     * @return   string  The content that is displayed on the website
     */
    private function myExec($cmd) {

        exec($cmd, $arr, $rc);

        $output = implode('<BR>', $arr);
        if ($rc != 0)
            $output = $rc . " - " . $output;

        return ($output);
777
    }
778
779
780
781
782
783

    /**
     * The main method of the PlugIn
     *
     * @param    string $content : The PlugIn content
     * @param    array $conf : The PlugIn configuration
Carsten  Rose's avatar
Carsten Rose committed
784
     * @return    string The content that is displayed on the website
785
     */
Carsten  Rose's avatar
Carsten Rose committed
786
787
788
    //Checkt ob der Beginn von Array2 gleich ist wie Array1
    // gibt true/false zurück

789
790
791
792
793
794
795
796
797
    /**
     * Renders PageX: convert position content to token content. Respect default values depending on PageX
     *
     * @param    string $columnName
     * @param    string $columnValue
     * @return string rendered link
     *
     * $columnValue:
     * -------------
798
     * [<page id|alias>[&param=value&...]] | [text] | [tooltip] | [msgbox] | [class] | [target] | [render mode]
799
     *
800
     * param[0]: <page id|alias>[&param=value&...]
801
802
803
804
805
806
807
808
809
810
811
812
     * param[2]: text
     * param[3]: tooltip
     * param[4]: msgbox
     * param[5]: class
     * param[6]: target
     * param[7]: render mode
     * @throws SyntaxReportException
     */
    private function doFixColPosPage($columnName, $columnValue) {

        $link = "";

813
814
815
        if (empty($columnName))
            return '';

816
        // Split definition
817
818
        $allParam = explode('|', $columnValue);
        if (count($allParam) > 8)
Carsten  Rose's avatar
Carsten Rose committed
819
            throw new SyntaxReportException ("Too many parameter (max=8): $columnValue", "", null, __FILE__, __LINE__, $this->fr_error);
820

821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
        $columnName[0] = 'p';        // make first 'P' lowercase

        // First Parameter: Split PageId|PageAlias and  URL Params
        $firstParam = explode('&', $allParam[0], 2);
        if (empty($firstParam[1])) {
            $firstParam[] = '';
        }

        $link .= $this->composeLinkPart(TOKEN_PAGE, $firstParam[0]);            // -- PageID --
        $link .= $this->composeLinkPart(TOKEN_URL_PARAM, $firstParam[1]);

        if (!empty($allParam[1]))
            $link .= $this->composeLinkPart(TOKEN_TEXT, $allParam[1]);             // -- Text --

        if (!empty($allParam[2]))
            $link .= $this->composeLinkPart(TOKEN_TOOL_TIP, $allParam[2]);         // -- tooltip --

        if (!empty($allParam[3]))
            $link .= $this->composeLinkPart(TOKEN_QUESTION, $allParam[3], $this->pageDefaults["msgbox"][$columnName]);                // -- msgbox

        if (!empty($allParam[4]))
            $link .= $this->composeLinkPart(TOKEN_CLASS, $allParam[4]);            // -- class --
843

844
845
        if (!empty($allParam[5]))
            $link .= $this->composeLinkPart(TOKEN_TARGET, $allParam[5]);           // -- target --
846

847
848
        if (!empty($allParam[6]))
            $link .= $this->composeLinkPart(TOKEN_RENDER, $allParam[6]);           // -- render mode --
Carsten  Rose's avatar
Carsten Rose committed
849

850
851
        if (!empty($allParam[7]))
            $allParam[7] = $this->pageDefaults["sip"][$columnName]; // if no SIP behaviour defined, use default
852

853
        $link .= TOKEN_SIP . "|";  // page always get a sip
854

855
856
        if ($this->pageDefaults["icon"][$columnName])
            $link .= $this->pageDefaults["icon"][$columnName] . "|";
857
858

        return ($link);
859
    }
860

Carsten  Rose's avatar
Carsten Rose committed
861
862
863
864
865
866
867
868
869
    /**
     * The main method of the PlugIn
     *
     * @param    string $content : The PlugIn content
     * @param    array $conf : The PlugIn configuration
     * @return   string The content that is displayed on the website
     */
    //Check ob arr1 nur 1 Feld mehr hat als arr2

870
871
872
873
874
875
876
877
878
879
880
    /**
     * If there is a value (or a defaultValue): compose it together with qualifier and delimiter.
     *
     * @param    string $qualifier
     * @param    string $value
     * @param    string $defaultValue
     *
     * @return    string        rendered link
     */
    private function composeLinkPart($qualifier, $value, $defaultValue = "") {

881
882
        if (empty($value))
            $value = $defaultValue;
883

884
        if (!empty($value))
885
886
887
            return ($qualifier . ":" . $value . "|");

        return '';
888
    }
889
890
891
892
893
894
895
896
897
898

    /**
     * Renders pageX: extract token and determine if any default value has be applied
     *
     * @param    string $columnName
     * @param    string $columnValue
     *
     * @return    string        rendered link
     */
    private function doPage($columnName, $columnValue) {
Carsten  Rose's avatar
Carsten Rose committed
899

900
901
902
903
904
        $defaultQuestion = '';

        $param = explode('|', $columnValue);

        # get all defaultvalues, depending on the columnname
905
906
        $defaultImage = $this->pageDefaults["icon"][$columnName];
        $defaultHash = $this->pageDefaults["sip"][$columnName];
Carsten  Rose's avatar
Carsten Rose committed
907

908
        # define defaultquestion only, if pagetype needs a question
909
        if ($this->pageDefaults["msgbox"][$columnName]) $defaultQuestion = 'q:' . $this->pageDefaults["msgbox"][$columnName];
910
911
912

        foreach ($param as $key) {
            switch (substr($key, 0, 1)) {
Carsten  Rose's avatar
Carsten Rose committed
913
914
915
916
917
918
919
920
921
                case TOKEN_PICTURE:
                case TOKEN_EDIT:
                case TOKEN_NEW:
                case TOKEN_DELETE:
                case TOKEN_HELP:
                case TOKEN_INFO:
                case TOKEN_SHOW:
                case TOKEN_BULLET:
                case TOKEN_CHECK:
922
923
                    $defaultImage = '';    // if any of the img token is given: no default
                    break;
Carsten  Rose's avatar
Carsten Rose committed
924
                case TOKEN_SIP:
925
926
                    $defaultHash = '';    // if a hash definition is given: no default
                    break;
Carsten  Rose's avatar
Carsten Rose committed
927
                case TOKEN_QUESTION:
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
                    $defaultQuestion = '';    // if a question is given: no default
                    break;
            }
        }

        $columnValue .= "|";

        // append defaulst
        if ($defaultImage) $columnValue .= $defaultImage . "|";
        if ($defaultHash) $columnValue .= $defaultHash . "|";
        if ($defaultQuestion) $columnValue .= $defaultQuestion . "|";

#debug($columnValue);

        return ($columnValue);
943
    }
944
945
946
947

    /**
     * Generate SortArgument
     *
948
949
     * @param $variable
     * @return string
950
951
952
953
954
955
     */
    private function getResultArrayIndex($variable) {

        $variable = substr($variable, 1, strlen($variable));
        return "[" . preg_replace_callback("/[a-z]/", "replaceToIndex", $variable) . "][" . preg_replace_callback("/[^a-z]/", "replaceToIndex", $variable) . "]";

956
    }
957

958
959
960
961
962
    /**
     * @param $arr1
     * @param $arr2
     * @return bool
     */
963
964
965
966
967
968
969
970
    private function compareArraystart($arr1, $arr2) {

        for ($i = 0; $i < count($arr1); $i++) {
            if ($arr1[$i] != $arr2[$i]) {
                return false;
            }
        }
        return true;
971
    }
972

973
974
975
976
977
    /**
     * @param $arr1
     * @param $arr2
     * @return bool
     */
978
979
980
981
982
983
    private function compareArraylength($arr1, $arr2) {

        if (count($arr1) + 1 == count($arr2)) {
            return true;
        }
        return false;
984
985
    }
}