Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/lazy logs #89

Merged
merged 4 commits into from
Oct 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 86 additions & 2 deletions src/Controller/Logs/AlpdeskcoreLogsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@

namespace Alpdesk\AlpdeskCore\Controller\Logs;

use Alpdesk\AlpdeskCore\Library\Constants\AlpdeskCoreConstants;
use Alpdesk\AlpdeskCore\Utils\Utils;
use Contao\BackendUser;
use Contao\Controller;
use Contao\File;
use Contao\Input;
use Contao\System;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
Expand Down Expand Up @@ -94,13 +98,13 @@ private function scanDir(?string $filterValue = null): array
if (\count($content) > 0) {

$arrReturn[] = [
'logfile' => $logFile->name,
'content' => $content
'logfile' => $logFile->name
];

}

}

}

\usort($arrReturn, static function ($a, $b) {
Expand Down Expand Up @@ -210,4 +214,84 @@ public function endpoint(): Response

}

public function lazyLogs(Request $request): JsonResponse
{
try {

$csrfToken = $request->headers->get('contaoCsrfToken');
$csrfTokenObject = new CsrfToken($this->csrfTokenName, $csrfToken);

if (!$this->csrfTokenManager->isTokenValid($csrfTokenObject)) {
throw new \Exception('invalid csrfToken');
}

$backendUser = $this->security->getUser();

if (!$backendUser instanceof BackendUser) {
throw new \Exception('invalid access');
}

Utils::mergeUserGroupPermissions($backendUser);

if (!$backendUser->isAdmin && (int)$backendUser->alpdeskcorelogs_enabled !== 1) {
throw new \Exception('invalid access');
}

$requestBody = $request->getContent();
if (!\is_string($requestBody) || $requestBody === '') {
throw new \Exception('invalid payload');
}

$requestBodyObject = \json_decode($requestBody, true, 512, JSON_THROW_ON_ERROR);
if (
!\is_array($requestBodyObject) ||
!\array_key_exists('logFileName', $requestBodyObject) ||
$requestBodyObject['logFileName'] === null || $requestBodyObject['logFileName'] === ''
) {
throw new \Exception('invalid payload');
}

$logFile = new File('var/logs/' . $requestBodyObject['logFileName']);
if ($logFile->extension !== 'log' || !$logFile->exists()) {
throw new \Exception('invalid extension or file does not exists');
}

$filterValue = ($requestBodyObject['filterValue'] ?? null);

$content = $logFile->getContentAsArray();

if ($filterValue !== null && $filterValue !== '' && \count($content) > 0) {

$newContent = [];

foreach ($content as $contentItem) {

if (\str_contains((string)$contentItem, $filterValue)) {
$newContent[] = \str_replace($filterValue, '<strong class="filterMarked">' . $filterValue . '</strong>', $contentItem);
}

}

$content = $newContent;

}

return (new JsonResponse([
'error' => false,
'fileName' => 'var/logs/' . $requestBodyObject['logFileName'],
'message' => '',
'content' => $content
], AlpdeskCoreConstants::$STATUSCODE_OK));

} catch (\Throwable $tr) {

return (new JsonResponse([
'error' => true,
'message' => $tr->getMessage()
], AlpdeskCoreConstants::$STATUSCODE_COMMONERROR));

}

}

}
8 changes: 8 additions & 0 deletions src/Resources/config/routes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ alpdesk_logs_backend:
_scope: backend
methods: [ POST, GET ]

alpdesk_lazylogs_backend:
path: /contao/alpdeskcorelazylogs
defaults:
_controller: Alpdesk\AlpdeskCore\Controller\Logs\AlpdeskcoreLogsController::lazyLogs
_scope: backend
_token_check: false
methods: [ POST ]

alpdesk_auth:
path: /auth
defaults:
Expand Down
33 changes: 32 additions & 1 deletion src/Resources/public/css/alpdeskcore_logs.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@
color: #F47C00;
}

.alpdeskcore-errorContainer,
#alpdeskcorelogs_error {
margin-left: 15px;
margin-top: 15px;
display: inline-block;
padding: 10px;
background-color: #f60000;
background-color: #C9473D;
color: #fff;
}

Expand All @@ -74,4 +75,34 @@ html[data-color-scheme="dark"] {
background-color: #333;
}

}

.alpdeskcore-loader {
margin-top: 10px;
border: 4px solid #f3f3f3;
border-radius: 50%;
border-top: 4px solid #F47C00;
width: 25px;
height: 25px;
-webkit-animation: alpdeskcore-spin 1s linear infinite; /* Safari */
animation: alpdeskcore-spin 1s linear infinite;
}

/* Safari */
@-webkit-keyframes alpdeskcore-spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}

@keyframes alpdeskcore-spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
50 changes: 49 additions & 1 deletion src/Resources/public/js/alpdeskcore_logs.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,63 @@
const visible = children[1];
const container = children[2];

const requestToken = logFile.getAttribute('data-token');
const fileName = logFile.getAttribute('data-filename');
const filterValue = logFile.getAttribute('data-filtervalue');

visible.addEventListener('click', function () {

if (container.style.display === 'none' || container.style.display === '') {

const xhr = new XMLHttpRequest();

xhr.open('POST', '/contao/alpdeskcorelazylogs', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('contaoCsrfToken', requestToken);

xhr.onload = function () {

if (xhr.status === 200) {

let containerInnerHtml = '<div class="alpdeskcore-errorContainer">Error loading data</div>';

const data = JSON.parse(xhr.responseText);
if (
data.error !== undefined && data.error !== null &&
data.content !== undefined && data.content !== null &&
data.error === false
) {

containerInnerHtml = '';
data.content.forEach((val) => {
containerInnerHtml += '<div class="alpdeskcorelogitem"><p>' + val + '</p></div>';
});

}

container.innerHTML = containerInnerHtml;

} else {
container.innerHTML = '<div class="alpdeskcore-errorContainer">Error loading data</div>';
}


};

const jsonPayload = {
'logFileName': fileName,
'filterValue': filterValue
};

container.innerHTML = '<div class="alpdeskcore-loader"></div>';
container.style.display = 'block';

xhr.send(JSON.stringify(jsonPayload));

} else {
container.style.display = 'none';
}


});

}
Expand Down
11 changes: 3 additions & 8 deletions src/Resources/views/alpdeskcorelogs_be.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@

{% for key,value in logs %}

<div class="alpdeskcorelogfile">
<div class="alpdeskcorelogfile" data-token="{{ token }}" data-filename="{{ value.logfile }}"
data-filtervalue="{{ filterValue }}">

<a href="{{ route }}?deleteLog={{ value.logfile }}" title="Delete"
onclick="if(!confirm('{{ confirm }}'))return false;"
Expand All @@ -39,13 +40,7 @@

{{ value.logfile }}

<div class="alpdeskcorelogitemcontainer">
{% for keycontent,valuecontent in value.content %}
<div class="alpdeskcorelogitem">
<p>{{ valuecontent | raw }}</p>
</div>
{% endfor %}
</div>
<div class="alpdeskcorelogitemcontainer"></div>

</div>

Expand Down
Loading