Subversion Repositories bysoftdeveloper

[/] [kernel/] [eztemplatesstatisticsreporter.php] - Blame information for rev 32

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1 cavin.deng
<?php
2
//
3
// Definition of eZTemplatesStatisticsReporter class
4
//
5
// Created on: <18-Feb-2005 17:21:17 dl>
6
//
7
// SOFTWARE NAME: eZ Publish
8
// SOFTWARE RELEASE: 4.2.0
9
// BUILD VERSION: 24182
10
// COPYRIGHT NOTICE: Copyright (C) 1999-2009 eZ Systems AS
11
// SOFTWARE LICENSE: GNU General Public License v2.0
12
// NOTICE: >
13
//   This program is free software; you can redistribute it and/or
14
//   modify it under the terms of version 2.0  of the GNU General
15
//   Public License as published by the Free Software Foundation.
16
//
17
//   This program is distributed in the hope that it will be useful,
18
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
19
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
//   GNU General Public License for more details.
21
//
22
//   You should have received a copy of version 2.0 of the GNU General
23
//   Public License along with this program; if not, write to the Free
24
//   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25
//   MA 02110-1301, USA.
26
//
27
//
28
 
29
/*! \file
30
*/
31
 
32
/*!
33
  \class eZTemplatesStatisticsReporter eztemplatesstatisticsreporter.php
34
  \brief Generates statistics of tempate usage.
35
 
36
*/
37 5 cavin.deng
@include_once('extension/bysoftdeveloper/kernel/ezdebug.php');
38 1 cavin.deng
class eZTemplatesStatisticsReporter
39
{
40
    /*!
41
     static
42
    */
43
    static function generateStatistics( $as_html = true )
44
    {
45
        $statStartTime = microtime( true );
46 32 alvawu
        $ini = eZINI::instance('site.ini');
47
        $activeExtensions = $ini->variable('ExtensionSettings', 'ActiveExtensions');
48
        $enable_highlight = false;
49
        $highlight_script = '';
50
        $highlight_event = '';
51
        $highlight_button = "";
52 1 cavin.deng
        $stats = '';
53 32 alvawu
 
54
        if(in_array('ezjscore', $activeExtensions) && in_array('ezsh', $activeExtensions))
55
        {
56
                $enable_highlight = true;
57
                $highlighturl = 'ezjscore/run/geshi/highlight';
58
                eZURI::transformURI($highlighturl, false);
59
                $highlight_event = "ondblclick='javascript:bysoftdeveloperHighlight();'";
60
                $highlight_button = '<input type="button" value="View" onclick="javascript:bysoftdeveloperHighlight();" />';
61
                $highlight_script = <<<EOT
62
                function bysoftdeveloperHighlight(){
63
                        var fp = document.getElementById('bysoftdeveloper-template-reporter-input').value;
64
                        if(typeof(fp) == 'undefined'|| fp == ''){alert('please select one tpl!'); return false;}
65
 
66
                        var url = '$highlighturl' + '/' + fp;
67
 
68
                        var options = {url:url, callback:bysoftdeveloperShowHighlightTpl};
69
                                function bysoftdeveloperShowHighlightTpl(result){
70
                                        document.getElementById('bysoftdeveloper-highlight-view').innerHTML = result;
71
                                        document.getElementById('bysoftdeveloper-highlight-view').style.display = '';
72
                                        goTo();
73
                            }
74
                                bysoftdeveloperAjax(options);
75
                }
76
                function bysoftdeveloperToggleHighlightView(){
77
 
78
                                var vp = document.getElementById('bysoftdeveloper-highlight-view');
79
                                if(vp.style.display == 'none'){vp.style.display = '';}else{vp.style.display = 'none';}
80
 
81
 
82
                }
83
EOT;
84 1 cavin.deng
 
85 32 alvawu
        }
86
 
87
        if($enable_highlight)
88
        {
89
        $stats = <<<EOT
90
        <style type="text/css">
91
#bysoftdeveloper-highlight-view{font-size: 110%; background:#c7edcc; position: relative; z-index: 99999;}
92
#bysoftdeveloper-highlight-view h1{font-size: 130%;border-bottom:1px dashed; margin-bottom: 5px; }
93
</style>
94
EOT;
95
        }
96
 
97 1 cavin.deng
        if ( !eZTemplate::isTemplatesUsageStatisticsEnabled() )
98
            return $stats;
99
 
100
        if ( $as_html )
101
        {
102 32 alvawu
                if($enable_highlight)
103
                {
104
                        $stats .= "<div><div style='text-align:center;background:green;color:#fff;cursor:pointer;font-weight:bold;' onclick='javascript:bysoftdeveloperToggleHighlightView();'>Tpl Highlight</div><div id='bysoftdeveloper-highlight-view' style='display:none;'></div></div>";
105
                }
106
                $stats .= "<h2>Templates used to render the page:</h2>";
107 1 cavin.deng
            $stats .= ( "<table id='templateusage' summary='List of used templates' style='border: 1px dashed black;' cellspacing='0'>" .
108
                   "<tr><th>Usages</th>" .
109
                   "<th>Requested template</th>" .
110
                   "<th>Template</th>" .
111
                   "<th>Template loaded</th>" .
112
                   "<th>Edit</th>" .
113
                   "<th>Override</th></tr>" );
114 8 cavin.deng
 
115
 
116
 
117
            // cavin.deng add these two variables
118
            $stats .= <<<EOT
119
            <tr>
120
                <td colspan="6" align="center">
121 32 alvawu
                        Template Path:<input size=150 type="text" value="" id="bysoftdeveloper-template-reporter-input" />$highlight_button
122 8 cavin.deng
                </td>
123
            </tr>
124
EOT;
125
 
126
            //$stats .= $show_design_path_script;
127 1 cavin.deng
        }
128
        else
129
        {
130
            $formatString = "%-40s%-40s%-40s\n";
131
            $stats .= "Templates usage statistics\n";
132
            $stats .= sprintf( $formatString, 'Templates', 'Requested template', 'Template loaded' );
133
        }
134
 
135
        if ( $as_html )
136
        {
137
            $iconSizeX = 16;
138
            $iconSizeY = 16;
139
            $templateViewFunction = 'visual/templateview';
140
            eZURI::transformURI( $templateViewFunction );
141
            $templateEditFunction = 'visual/templateedit';
142
            eZURI::transformURI( $templateEditFunction );
143
            $templateOverrideFunction = 'visual/templatecreate';
144
            eZURI::transformURI( $templateOverrideFunction );
145
 
146
            $std_base = eZTemplateDesignResource::designSetting( 'standard' );
147
            $wwwDir = eZSys::wwwDir();
148
            $editIconFile = "$wwwDir/design/$std_base/images/edit.gif";
149
            $overrideIconFile = "$wwwDir/design/$std_base/images/override-template.gif";
150
 
151
            $tdClass = 'used_templates_stats1';
152
            $j = 0;
153
 
154
            $currentSiteAccess = $GLOBALS['eZCurrentAccess']['name'];
155
        }
156
 
157
        $templatesUsageStatistics = eZTemplate::templatesUsageStatistics();
158
 
159
        $alreadyListedTemplate = $templateCounts = array();
160
 
161
        //Generate usage count for each unique template first.
162
        foreach( $templatesUsageStatistics as $templateInfo )
163
        {
164
            $actualTemplateName = $templateInfo['actual-template-name'];
165
 
166
            if ( !array_key_exists( $actualTemplateName, $templateCounts ) )
167
            {
168
                $templateCounts[$actualTemplateName] = 1;
169
 
170
            }
171
            else
172
            {
173
                ++$templateCounts[$actualTemplateName];
174
            }
175
        }
176
 
177
        // cavin.deng add these two variables
178
        $isWin = (substr(PHP_OS, 0, 3) == 'WIN') ? 1 : 0;
179
        $siteDir = eZSys::siteDir();
180
 
181
        //Then create the actual listing
182
        foreach ($templatesUsageStatistics as $templateInfo)
183
        {
184
            $actualTemplateName = $templateInfo['actual-template-name'];
185
            $requestedTemplateName = $templateInfo['requested-template-name'];
186
            $templateFileName = $templateInfo['template-filename'];
187
 
188
            if ( !in_array( $actualTemplateName, $alreadyListedTemplate ) )
189
            {
190
                $alreadyListedTemplate[] = $actualTemplateName;
191
                if ( $as_html )
192
                {
193
                    $tdClass = ( $j % 2 == 0 ) ? 'used_templates_stats1' : 'used_templates_stats2';
194
 
195
                    $requestedTemplateViewURI = $templateViewFunction . '/' . $requestedTemplateName;
196
                    $actualTemplateViewURI = $templateViewFunction . '/' . $actualTemplateName;
197
 
198
                    $templateEditURI = $templateEditFunction . '/' . $templateFileName;
199
                    $templateOverrideURI = $templateOverrideFunction . '/' . $actualTemplateName;
200
 
201
                    $actualTemplateNameOutput = ( $actualTemplateName == $requestedTemplateName ) ? "<span style=\"font-style: italic;\">&lt;No override&gt;</span>" : $actualTemplateName;
202
 
203
                    // cavin.deng modify this place, to offer full path base on OS
204
                    $fullFileName = str_replace('\\', '/', $siteDir . $templateFileName );
205
 
206
                    $stats .= (
207 32 alvawu
                           "<tr onclick=\"show_design_path('$fullFileName', this, event);\" $highlight_event>" .
208 1 cavin.deng
                           "<td class=\"$tdClass\">$templateCounts[$actualTemplateName]</td>" .
209
                           "<td class=\"$tdClass\"><a href=\"$requestedTemplateViewURI\">$requestedTemplateName</a></td>" .
210
                           "<td class=\"$tdClass\">$actualTemplateNameOutput</td>" .
211
                           "<td class=\"$tdClass\">$templateFileName</td>" .
212
                           "<td class=\"$tdClass\" align=\"center\"><a href=\"$templateEditURI/(siteAccess)/$currentSiteAccess\"><img src=\"$editIconFile\" width=\"$iconSizeX\" height=\"$iconSizeY\" alt=\"Edit template\" title=\"Edit template\" /></a></td>".
213
                           "<td class=\"$tdClass\" align=\"center\"><a href=\"$templateOverrideURI/(siteAccess)/$currentSiteAccess\"><img src=\"$overrideIconFile\" width=\"$iconSizeX\" height=\"$iconSizeY\" alt=\"Override template\" title=\"Override template\" /></a></td></tr>" );
214
 
215
                    $j++;
216
                }
217
                else
218
                {
219
                    $stats .= sprintf( $formatString, $requestedTemplateName, $actualTemplateName, $templateFileName );
220
                }
221
            }
222 8 cavin.deng
        }
223 1 cavin.deng
 
224
        // cavin.deng add float for template usage button
225
        $templateusageindiv = <<<EOT
226 5 cavin.deng
            $stats
227
        </table>
228 1 cavin.deng
EOT;
229
 
230
 
231
        $totalTemplatesCount = count( $templatesUsageStatistics );
232
        $totalUniqueTemplatesCopunt = count( array_keys( $alreadyListedTemplate ) );
233
        $statEndTime = microtime( true );
234
        $timeUsage = number_format( $statEndTime - $statStartTime, 4 );
235
 
236
        if ( $as_html )
237
        {
238
            $stats .= ( "<tr>" .
239
                        "<td class=\"$tdClass\">&nbsp;</td>" .
240
                   "<td class=\"$tdClass\">&nbsp;</td>" .
241
                   "<td class=\"$tdClass\">&nbsp;</td>" .
242
                   "<td class=\"$tdClass\">&nbsp;</td>".
243
                   "<td class=\"$tdClass\">&nbsp;</td>".
244
                   "<td class=\"$tdClass\">&nbsp;</td>".
245
                        "</tr>" );
246
            $stats .= "<tr><td colspan=\"4\" style=\"text-align: left;\"><b>&nbsp;Number of times templates used: $totalTemplatesCount<br />&nbsp;Number of unique templates used: $totalUniqueTemplatesCopunt</b></td></tr>";
247
            $stats .= "<tr><td colspan=\"4\" style=\"text-align: left;\"><b>&nbsp;Time used to render template usage: $timeUsage secs</b></td></tr>";
248
            $stats .= "</table>";
249
        }
250
        else
251
        {
252
            $stats .= "\nTotal templates count: " . $totalTemplatesCount . "\n" . "Total unique templates count: " . $totalUniqueTemplatesCopunt . "\n";
253
        }
254 32 alvawu
 
255 1 cavin.deng
                // cavin.deng add these js.
256
                $template_js = <<<EOT
257
        <script type="text/javascript">
258
                function show_design_path(file, trElement, e){
259
                        //var e = e || event || window.event;
260
 
261
                        // find input based on trElement;
262 5 cavin.deng
                        var input = document.getElementById('bysoftdeveloper-template-reporter-input');
263 1 cavin.deng
 
264
                        if( $isWin ){
265
                                file = file.replace(/\//g, "\\\\");
266
                        }
267
                        input.value=file;
268
                        input.select();
269 24 cavin.deng
                        if( e.stopPropagation )
270
                                e.stopPropagation();
271
                        else
272
                                e.cancelBubble = true
273 1 cavin.deng
                }
274 32 alvawu
 
275
                $highlight_script
276 1 cavin.deng
        </script>
277
EOT;
278
 
279
                //$stats = $stats . $templateusageindiv . $template_js;
280
                $stats = $templateusageindiv . $template_js;
281
 
282
        return $stats;
283
    }
284
 
285
 
286
    // used only by developer
287
    function __construct() {
288
        $this->Operators = array( 'array_intel', 'variables');
289
    }
290
 
291
    /*!
292
     Returns the operators in this class.
293
    */
294
    function &operatorList()
295
    {
296
        return $this->Operators;
297
    }
298
 
299
    function namedParameterPerOperator()
300
    {
301
        return true;
302
    }
303
 
304
    function namedParameterList()
305
    {
306
 
307
        return array(
308
            'array_intel' => array(
309
                'length' => array(
310
                    'type' => 'integer',
311
                    'required' => true,
312
                ),
313
                'offset' => array(
314
                    'type' => 'integer',
315
                    'required' => false,
316
                    'default' => 0
317
                )
318
            ),
319
            'variables' => array(
320
            ),
321
        );
322
    }
323
 
324
    function modify( $tpl, $operatorName, $operatorParameters, $rootNamespace,
325
                     $currentNamespace, &$operatorValue, $namedParameters )
326
    {
327
        switch ($operatorName) {
328
            case 'array_intel' :
329
                $temp = array();
330
                $length = $namedParameters['length'];
331
                $offset = $namedParameters['offset'];
332
                $values = array_values($operatorValue);
333
 
334
                $return = array();
335
                $groupCount = ceil(count($values) / $length);
336
                foreach ($values as $idx => $val) {
337
                    $gid = $idx % $groupCount;
338
                    $return[$gid][] = $val;
339
                }
340
 
341
                $operatorValue = $return;
342
                break;
343
            case 'variables':
344
                $operatorValue = $this->showVariables($tpl, $rootNamespace, $currentNamespace);
345
                break;
346
        }
347
    }
348
 
349
    /**
350
     * Show variables in template...
351
     *
352
     * @param ezTemplate $tpl
353
     * @param string $rootNamespace
354
     * @param string $currentNamespace
355
     */
356
    private function showVariables($tpl, $rootNamespace, $currentNamespace)
357
    {
358
        $result = '';
359
 
360
        // generate a uniqued id for these
361
        // current file should be the last template been fetched?
362
        $tplFile = end($tpl->TemplateFetchList);
363
        $id = md5(microtime(true) . $tplFile . uniqid(rand(), true) );
364
        $aId = 'bysoftdeveloper_variables_a_' . $id;
365
        $divId = 'bysoftdeveloper_variables_div_' . $id;
366
 
367
        $isWin = (substr(PHP_OS, 0, 3) == 'WIN') ? 1 : 0;
368
        $siteDir = eZSys::siteDir();
369
 
370
        if ($isWin) {
371
            $tplFilePath = str_replace('/', '\\', $siteDir . $tplFile);
372
        } else {
373
            $tplFilePath = str_replace('\\', '/', $siteDir . $tplFile);
374
        }
375
        $tplFilePathLength = strlen($tplFilePath);
376
        $tplFilePathLength = min($tplFilePathLength, 100);
377
 
378
 
379
        $result = <<<EOT
380
<a id="{$aId}" title="$tplFile" onclick="javascript:bysoftDeveloperShowWindow('{$divId}', event, '{$aId}');" style="text-decoration: underline;font-style:italic;font-weight:bold;">@^V^@</a>
381
<div id="{$divId}" style="display:none; position:absolute; z-index:999; width:700px; top: 10px; left: 10px; overflow: hidden;">
382
        <div style="background-color: green; color: white;" onmousedown="return bysoftDeveloperDragWindow(this, event);">
383
            Namespaces & Variables &nbsp;&nbsp;&nbsp;&nbsp;
384
            <a style="color:white;text-decoration:underline;" onclick="javascript:bysoftDeveloperCloseWindowById('{$divId}');">Close</a>
385
        </div>
386
        <div style="display: block; background-color: white; border: 3px solid green;">
387
                <table>
388
                        <tr align="center"><td colspan="4"><input type='text' value='{$tplFilePath}' size='{$tplFilePathLength}' /></td></tr>
389
                        <tr style="font-weight:bold;"><td>&nbsp;</td><td>Variable</td><td>Type</td><td>Value</td></tr>
390
EOT;
391
        $currentNamespaceRows = '';
392
        $otherNamespaceRows = '';
393
                foreach ($tpl->Variables as $namespace => $varArr) {
394
            if (!count($varArr)) {
395
                continue;
396
            }
397
            $isCurrentNamespace = false;
398
            if (!$namespace) {
399
                if ($currentNamespace) {
400
                    $namespace = 'GLOBAL';
401
                } else {
402
                    $namespace = 'ROOT';
403
                }
404
            } else if ($namespace == $currentNamespace) {
405
                $namespace .= ' [Current]';
406
                $isCurrentNamespace = true;
407
            }
408
            // no need, i think, or we will lost the variable register order
409
            //ksort($varArr);
410
 
411
            // style="border-bottom: 1px dashed black;"
412
            if ($isCurrentNamespace) {
413
                $currentNamespaceRows = <<<EOT
414
<tr><td colspan="4" style="font-weight:bold; background-color: #937983;color: white;">
415
    $namespace
416
</td></tr>
417
EOT;
418
            } else {
419
                $otherNamespaceRows .= <<<EOT
420
<tr><td colspan="4" style="font-weight:bold; background-color: #76A3B6;color: white;">
421
    $namespace
422
</td></tr>
423
EOT;
424
            }
425
 
426
            $line = <<<EOT
427
<tr style="border: 1px dashed black;">
428
    <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
429
    <td>%s</td>
430
    <td>%s</td>
431
    <td>%s</td>
432
</tr>
433
EOT;
434
 
435
            $rows = '';
436
            foreach ($varArr as $key => $val) {
437
                $output = '';
438
                $type = gettype($val);
439
                if (is_object($val)) {
440
                    $type = '[' . get_class($val) . ']';
441
                }
442
                // check if the array is simple array, if it is then print out it
443
                if (is_array($val)) {
444
                    if ($this->isSimpleArray($val)) {
445
                        $output = '<textarea cols="40">' . htmlspecialchars(print_r($val, true)) . '</textarea>';
446
                    } else {
447
                        // @todo, maybe we need explode the group.
448
                        $output = '';
449
                    }
450
                }
451
                if (!is_object($val) and !is_array($val)) {
452
                    $output = (string) $val;
453
                    if (is_bool($val)) {
454
                        if ($val) {
455
                            $output = 'True';
456
                        } else {
457
                            $output = 'False';
458
                        }
459
                    }
460
                    if (is_string($val)) {
461
                        $output = "<input type='text' size='50' name='ThisNameYouShouldNotCare' value='".htmlspecialchars($val)."' />";
462
                    }
463
                }
464
 
465
                $rows .= sprintf($line, $key, $type, $output);
466
            }
467
            if ($isCurrentNamespace) {
468
                $currentNamespaceRows .= $rows;
469
            } else {
470
                $otherNamespaceRows .= $rows;
471
            }
472
        }
473
        $result .= $currentNamespaceRows;
474
        $result .= $otherNamespaceRows;
475
        $result .= '</table>
476
        </div>
477
</div>';
478
        $javascript = <<<EOT
479
<script type="text/javascript">
480
 
481
        function bysoftDeveloperShowWindow(id, e, eA)
482
        {
483
                e = e || event || window.event;
484
 
485
                var element = document.getElementById(id);
486
                var x = y = 0;
487
                if (document.all) {//IE
488
                        x = (document.documentElement && document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft;
489
                        y = (document.documentElement && document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop;
490
            x += window.event.clientX;
491
            y += window.event.clientY;
492
                } else {//Good Browsers
493
                        x = e.pageX;
494
                        y = e.pageY;
495
                }
496
                // @todo, cavin.deng
497
                // to get top left;
498
                if (document.body) {
499
                        var currentTop = document.body.scrollTop;
500
                        var currentLeft = document.body.scrollLeft;
501
        } else {
502
                        var currentTop = document.documentElement.scrollTop;
503
                        var currentLeft = document.documentElement.scrollLeft;
504
        }
505
 
506
 
507
                var a = document.getElementById(eA);
508
                var aTop = a.offsetTop;
509
                var aLeft = a.offsetLeft;
510
 
511
                while (a = a.offsetParent) {
512
                        aTop += a.offsetTop;
513
                        aLeft += a.offsetLeft;
514
        }
515
                //var pos = _getPosition(a);
516
                //element.style.left = (aTop - currentTop) + 'px';
517
                //element.style.top = (aLeft - currentLeft) + 'px';
518
                // popUp(e, id);
519
                //bysoftDeveloperToggleWindowById(id);
520
                bysoftDeveloperToggleWindowById(id);
521
    }
522
 
523
    function _getPosition (obj) {
524
        var curleft = curtop = 0;
525
        if (obj.offsetParent) {
526
            curleft = obj.offsetLeft;
527
            curtop = obj.offsetTop;
528
            while (obj = obj.offsetParent) {
529
                curleft += obj.offsetLeft;
530
                curtop += obj.offsetTop;
531
            }
532
        }
533
        return [curleft,curtop];
534
    };
535
 
536
 
537
        // toggle a element by id or object,
538
        // if status afforded then set this element to that status
539
        function bysoftDeveloperToggleWindowById(e, status)
540
        {
541
                if( typeof e == 'string' ) e = document.getElementById(e);
542
 
543
                        if( status != undefined ){
544
                                var value = (status == 'block' || (status != 'none' && status) ) ? 'block' : 'none';
545
                                e.style.display = value;
546
                                return true;
547
                        }
548
 
549
                        if( e.style.display == 'block' ){
550
                                e.style.display = 'none';
551
                        }else if(e.style.display == 'none'){
552
                                e.style.display = 'block';
553
                        }else{
554
                                e.style.display = 'none';
555
                        }
556
        }
557
 
558
        function bysoftDeveloperCloseWindowById(e) {
559
                e = document.getElementById(e);
560
                e.style.display = 'none';
561
    }
562
 
563
        // drag popup window
564
    function bysoftDeveloperDragWindow(element, e){
565
        e = e || event || window.event;
566
 
567
        if( document.addEventListener ){
568
                document.addEventListener("mousemove", bysoftDeveloperStartDrag, true);
569
                document.addEventListener("mouseup", bysoftDeveloperStopDrag, true);
570
        }else{
571
                document.onmousemove = bysoftDeveloperStartDrag;
572
                document.onmouseup = bysoftDeveloperStopDrag;
573
        }
574
 
575
        var target = element.parentNode;
576
 
577
        var delatX = e.clientX - parseInt(target.style.left);
578
        var delatY = e.clientY - parseInt(target.style.top);
579
 
580
        function bysoftDeveloperStartDrag(e){
581
                e = e || event || window.event;
582
                target.style.left = (e.clientX - delatX) + 'px';
583
                target.style.top = (e.clientY - delatY) + 'px';
584
        }
585
 
586
        function bysoftDeveloperStopDrag(){
587
                if( document.removeEventListener ){
588
                        document.removeEventListener("mousemove", bysoftDeveloperStartDrag, true);
589
                        document.removeEventListener("mouseup", bysoftDeveloperStopDrag, true);
590
                }else{
591
                        document.onmousemove = "";
592
                        document.onmouseup = "";
593
                }
594
        }
595
    }
596
 
597
</script>
598
EOT;
599
        if (self::$developerVariablesJavascriptLoaded == false) {
600
            $result .= $javascript;
601
            self::$developerVariablesJavascriptLoaded =  true;
602
        }
603
        return $result;
604
    }
605
 
606
    public function isSimpleArray($arr)
607
    {
608
        foreach ($arr as $val) {
609
           if (is_object($val)) {
610
               return false;
611
           }
612
           if (is_array($val) && !$this->isSimpleArray($val)) {
613
               return false;
614
           }
615
        }
616
        return true;
617
    }
618
 
619
    public static $developerVariablesJavascriptLoaded = false;
620
 
621
}
622
 
623
?>