Collapse duplicated exceptions on ExceptionLogViewPage
authorTim Düsterhus <duesterhus@woltlab.com>
Tue, 23 Jun 2020 14:18:11 +0000 (16:18 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Tue, 23 Jun 2020 14:18:11 +0000 (16:18 +0200)
Closes #3044

wcfsetup/install/files/acp/style/layout.scss
wcfsetup/install/files/acp/templates/exceptionLogView.tpl
wcfsetup/install/files/lib/acp/page/ExceptionLogViewPage.class.php

index b0ced58e065a43a463828b4e65e45c8529646c6d..704b3e736889ab5d06c256cf8fa7e948b5f444de 100644 (file)
@@ -523,3 +523,9 @@ $wcfAcpSubMenuWidth: 300px;
        
        @include wcfFontHeadline;
 }
+
+.exceptionContainer {
+       &.collapsed .exceptionDetails {
+               display: none;
+       }
+}
index a52593dea89eb89e56696733d607fa75d06e6550..7a26735b7615d0d0cde4bb7a0daee97e1a125c09 100644 (file)
                $('.jsCopyException').click(function () {
                        $(this).select();
                });
+               
+               elBySelAll('.exceptionContainer', undefined, function (container) {
+                       var button = elBySel('.collapsibleButton', container);
+                       button.addEventListener('click', function (event) {
+                               if (container.classList.toggle('collapsed')) {
+                                       button.classList.add('fa-chevron-right');
+                                       button.classList.remove('fa-chevron-down');
+                               }
+                               else {
+                                       button.classList.remove('fa-chevron-right');
+                                       button.classList.add('fa-chevron-down');
+                               }
+                       });
+               })
        });
 </script>
 
 {if !$logFiles|empty}
        {if $logFile}
                {foreach from=$exceptions item='exception' key='exceptionKey'}
-                       <section id="{$exceptionKey}" class="section">
-                               <h2 class="sectionTitle">{$exception[message]}</h2>
-                               
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.date{/lang}</dt>
-                                       <dd>{$exception[date]|plainTime}</dd>
-                               </dl>
+                       <section id="{$exceptionKey}" class="section exceptionContainer{if $exception[collapsed]|isset && $exception[collapsed]} collapsed{/if}">
+                               <h2 class="sectionTitle">
+                                       <span class="collapsibleButton jsTooltip pointer icon icon16 fa-chevron-{if $exception[collapsed]|isset && $exception[collapsed]}right{else}down{/if}" title="{lang}wcf.global.button.collapsible{/lang}"></span>
+                                       {$exception[message]}
+                               </h2>
                                
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.requestURI{/lang}</dt>
-                                       <dd>{$exception[requestURI]}</dd>
-                               </dl>
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.referrer{/lang}</dt>
-                                       <dd>{$exception[referrer]}</dd>
-                               </dl>
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.userAgent{/lang}</dt>
-                                       <dd>{$exception[userAgent]}</dd>
-                               </dl>
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.memory{/lang}</dt>
-                                       <dd>{$exception[peakMemory]|filesizeBinary} / {if $exception[maxMemory] == -1}&infin;{else}{$exception[maxMemory]|filesizeBinary}{/if}</dd>
-                               </dl>
-                               {foreach from=$exception[chain] item=chain}
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.message{/lang}</dt>
-                                       <dd>{$chain[message]}</dd>
-                               </dl>
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.class{/lang}</dt>
-                                       <dd>{$chain[class]}</dd>
-                               </dl>
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.file{/lang}</dt>
-                                       <dd>{$chain[file]} ({$chain[line]})</dd>
-                               </dl>
-                               {if !$chain[information]|empty}
-                                       {foreach from=$chain[information] item=extraInformation}
-                                               <dl>
-                                                       <dt>{$extraInformation[0]}</dt>
-                                                       <dd>{$extraInformation[1]}</dd>
-                                               </dl>
+                               <div class="exceptionDetails">
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.date{/lang}</dt>
+                                               <dd>{$exception[date]|plainTime}</dd>
+                                       </dl>
+                                       
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.requestURI{/lang}</dt>
+                                               <dd>{$exception[requestURI]}</dd>
+                                       </dl>
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.referrer{/lang}</dt>
+                                               <dd>{$exception[referrer]}</dd>
+                                       </dl>
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.userAgent{/lang}</dt>
+                                               <dd>{$exception[userAgent]}</dd>
+                                       </dl>
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.memory{/lang}</dt>
+                                               <dd>{$exception[peakMemory]|filesizeBinary} / {if $exception[maxMemory] == -1}&infin;{else}{$exception[maxMemory]|filesizeBinary}{/if}</dd>
+                                       </dl>
+                                       {foreach from=$exception[chain] item=chain}
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.message{/lang}</dt>
+                                               <dd>{$chain[message]}</dd>
+                                       </dl>
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.class{/lang}</dt>
+                                               <dd>{$chain[class]}</dd>
+                                       </dl>
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.file{/lang}</dt>
+                                               <dd>{$chain[file]} ({$chain[line]})</dd>
+                                       </dl>
+                                       {if !$chain[information]|empty}
+                                               {foreach from=$chain[information] item=extraInformation}
+                                                       <dl>
+                                                               <dt>{$extraInformation[0]}</dt>
+                                                               <dd>{$extraInformation[1]}</dd>
+                                                       </dl>
+                                               {/foreach}
+                                       {/if}
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.stacktrace{/lang}</dt>
+                                               <dd>
+                                                       <ol start="0" class="nativeList">
+                                                               {foreach from=$chain[stack] item=stack}
+                                                               <li>{$stack[file]} ({$stack[line]}): {$stack[class]}{$stack[type]}{$stack[function]}(&hellip;)</li>
+                                                               {/foreach}
+                                                       </ol>
+                                               </dd>
+                                       </dl>
                                        {/foreach}
-                               {/if}
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.stacktrace{/lang}</dt>
-                                       <dd>
-                                               <ol start="0" class="nativeList">
-                                                       {foreach from=$chain[stack] item=stack}
-                                                       <li>{$stack[file]} ({$stack[line]}): {$stack[class]}{$stack[type]}{$stack[function]}(&hellip;)</li>
-                                                       {/foreach}
-                                               </ol>
-                                       </dd>
-                               </dl>
-                               {/foreach}
-                               <dl>
-                                       <dt><label for="copyException{$exceptionKey}">{lang}wcf.acp.exceptionLog.exception.copy{/lang}</label></dt>
-                                       <dd><textarea id="copyException{$exceptionKey}" rows="5" cols="40" class="jsCopyException" readonly>{$exception[0]}</textarea></dd>
-                               </dl>
+                                       <dl>
+                                               <dt><label for="copyException{$exceptionKey}">{lang}wcf.acp.exceptionLog.exception.copy{/lang}</label></dt>
+                                               <dd><textarea id="copyException{$exceptionKey}" rows="5" cols="40" class="jsCopyException" readonly>{$exception[0]}</textarea></dd>
+                                       </dl>
+                               </div>
                        </section>
                {/foreach}
 
index a6e8447a08db9900da5303f0f87f89a992924c8e..38ce4eb580b2e6cc4feca9e61e6ed48f5c2edcdb 100644 (file)
@@ -141,15 +141,22 @@ class ExceptionLogViewPage extends MultipleLinkPage {
                $this->calculateNumberOfPages();
                
                $i = 0;
-               
+               $seenHashes = [];
                foreach ($this->exceptions as $key => $val) {
                        $i++;
+                       
+                       $parsed = ExceptionLogUtil::parseException($val);
+                       if (isset($seenHashes[$parsed['stackHash']])) {
+                               $parsed['collapsed'] = true;
+                       }
+                       $seenHashes[$parsed['stackHash']] = true;
+                       
                        if ($i < $this->startIndex || $i > $this->endIndex) {
                                unset($this->exceptions[$key]);
                                continue;
                        }
                        try {
-                               $this->exceptions[$key] = ExceptionLogUtil::parseException($val);
+                               $this->exceptions[$key] = $parsed;
                        }
                        catch (\InvalidArgumentException $e) {
                                unset($this->exceptions[$key]);