Viewing File: /usr/local/cpanel/base/frontend/jupiter/raw/index.html.tt

[% SET CPANEL.CPVAR.dprefix = "../";

    SET settings = execute('LogManager', 'get_settings');
    SET downloads = execute('LogManager', 'list_archives', {
        'api.sort'         => 1,
        'api.sort_column'  => 'mtime',
        'api.sort_reverse' => 1,
    });
    SET default_retention = CPANEL.CPCONF().web_log_retention_days || 0;
%]

[% css_code = PROCESS css_block %]
[% js_code = PROCESS js_block %]
[% WRAPPER '_assets/master.html.tt'
    app_key = 'raw_access'
    page_styles = css_code
    page_js = js_code
-%]

[% SET list_raw_logs =  Api2.exec("Stats", "listrawlogs", {} ); %]

<div class="body-content">
    <p id="descIntro" class="description">
        [% locale.maketext("Raw Access Logs allow you to see who has visited your website without displaying graphs, charts, or other graphics. You can use the Raw Access Logs menu to download a zipped version of the server’s access log for your site. This can be very useful when you want to quickly see who has visited your site.")  %]
    </p>

    <div class="section">
        <h2 id="hdrConfigureLogs">
            [% locale.maketext("Configure Logs") %]
        </h2>
        [% IF settings.status %]
        <form id="formConfigureLogs" action="../logmanager/savesettings.html">
            <div class="form-group">
                <div class="checkbox">
                    <label>
                        <input type="checkbox" id="chkArchiveLogs" name="archivelogs" value="1" [% IF settings.data.archive_logs %]checked[% END %]>
                        [% IF CPANEL.CPCONF().dumplogs %]
                            [% locale.maketext( 'Archive log files to your home directory after the system processes statistics. The system currently processes logs every [quant,_1,hour,hours].', CPANEL.CPCONF().cycle_hours.html() ) %]
                        [% ELSE %]
                            [% locale.maketext('Archive logs in your home directory at the end of each month.') %]
                        [% END %]
                    </label>
                </div>
                <div class="checkbox">
                    <label>
                        <input type="checkbox" id="chkPruneArchive" name="remoldarchivedlogs" value="1" [% IF settings.data.prune_archive %]checked[% END %]>
                        [% locale.maketext("Remove the previous month’s archived logs from your home directory at the end of each month.") %]
                    </label>
                </div>
                [% IF settings.status %]
                [% SET has_custom_retention = (!settings.data.using_default) %]
                [% SET current_retention = has_custom_retention ? settings.data.retention_days : 0 %]
                <div class="checkbox">
                    <label>
                        <input type="checkbox" id="chkCustomRetention" name="custom_retention" value="1" [% IF has_custom_retention %]checked[% END %]>
                        [% locale.maketext("Set a custom retention period for archived logs.") %]
                    </label>
                </div>
                <div class="help-block retention-default-note">
                    [% IF has_custom_retention %]
                        [% IF current_retention == 0 %]
                            [% locale.maketext("Current retention: indefinite - no automatic removal.") %]
                        [% ELSE %]
                            [% locale.maketext("Current retention: [quant,_1,day,days].", current_retention) %]
                        [% END %]
                    [% ELSIF default_retention > 0 %]
                        [% locale.maketext("Current retention: server default ([quant,_1,day,days]).", default_retention) %]
                    [% ELSE %]
                        [% locale.maketext("Current retention: server default (indefinite - no automatic removal).") %]
                    [% END %]
                </div>
                <div id="retentionInputWrapper" class="retention-input-wrapper" [% IF !has_custom_retention %]style="display: none;"[% END %]>
                    <div class="retention-input-row">
                        <input type="number" 
                               id="retentionDays" 
                               name="retention_days" 
                               class="form-control retention-days-field" 
                               min="0"
                               max="999"
                               [% IF !has_custom_retention %]disabled[% END %]
                               value="[% IF has_custom_retention %][% current_retention %][% ELSIF default_retention > 0 %][% default_retention %][% ELSE %]30[% END %]">
                        <span>[% locale.maketext("Days") %]</span>
                    </div>
                </div>
                [% END %]
            </div>
            
            <div class="form-group">
                <input id="btnSave" type="submit" class="btn btn-primary" value="[% locale.maketext("Save") %]" />
            </div>
        </form>
        [% ELSE %]
            [% FOREACH error IN settings.errors %]
                <div class="alert alert-danger" role="alert">
                    <span class='glyphicon glyphicon-remove-sign' aria-hidden="true"></span>
                    <div class='alert-message'>
                        <strong class="alert-title">
                            [% locale.maketext('Error:') %]
                        </strong>
                        <span class="alert-body">
                            <span id="error-[% loop.index() %]">
                                [% error.html() %]
                            </span>
                        </span>
                    </div>
                </div>
            [% END %]
        [% END %]
    </div>

    <div class="section">
        <h2 id="hdrDownload">
            [% locale.maketext("Download Current Raw Access Logs") %]
        </h2>
        [% IF CPANEL.CPCONF().dumplogs %]
          <div class="alert alert-warning">
              <span class="glyphicon glyphicon-exclamation-sign"></span>
              <div class="alert-message">
                  [% locale.maketext('Raw logs may only contain a few hours’ worth of data because they are discarded after the system processes them.') %]
                  [% locale.maketext('If archiving is enabled, the system archives the raw log data before the system discards it.') %]
              </div>
          </div>
        [% ELSIF !CPANEL.CPCONF().keeplogs %]
          <div class="alert alert-warning">
              <span class="glyphicon glyphicon-exclamation-sign"></span>
              <div class="alert-message">
                  [% locale.maketext('The system empties raw logs at the beginning of each month.') %]
                  [% locale.maketext('If archiving is enabled, the system archives the raw log data before the system discards it.') %]
              </div>
          </div>
        [% END %]
        <p id="descDownload">
            [% locale.maketext("Click the domain name that corresponds to the raw access log that you want to download.") %]
        </p>
        <table class="sortable table table-striped responsive-table" id="rtt">
            <thead>
                <tr>
                    <th>
                        [% locale.maketext("Domain") %]
                    </th>
                    <th>
                        [% locale.maketext("Last Update") %]
                    </th>
                    <th>
                        [% locale.maketext("Disk Usage") %]
                    </th>
                    <th>
                        [% locale.maketext("Linked Domains") %]
                    </th>
                </tr>
            </thead>
            <tbody>
                [% IF list_raw_logs.size; %]
                    [% FOREACH raw_logs IN list_raw_logs; %]
                        <tr>
                            <td class="row1" data-title="[% locale.maketext('Domain') %]">
                                <a href="[%  raw_logs.link | url %]" class="download-link">
                                    <span class="glyphicon glyphicon-download download-icon" aria-hidden="true"></span>
                                    [%  raw_logs.domain.html() %]
                                </a>
                            </td>
                            <td class="raw1" data-title="[% locale.maketext('Last Update') %]">
                                [%  raw_logs.humanupdatetime.html() %]
                            </td>
                            <td class="raw1" data-title="[% locale.maketext('Disk Usage') %]">
                                [%  raw_logs.humansize.html() %]
                            </td>
                            <td class="row1-end" data-title="[% locale.maketext('Linked Domains') %]">
                                <div class="linked_domains" >
                                    [% FOREACH linked_domain IN raw_logs.linked_domains %]
                                        <div class="linked_domain">[% linked_domain.domain.html() %]</div>
                                    [% END %]
                                </div>
                            </td>
                        </tr>
                    [% END %]
                [% END %]
            </tbody>
        </table>
    </div>

    <div class="section">
        <h2 id="hdrArchived">
            [% locale.maketext("Archived Raw Logs") %]
        </h2>
        <p id="descArchived">
            [% locale.maketext("Click on a log archive to download it, or use the delete button to remove it.") %]
        </p>
        [% IF downloads.status %]
            [% IF downloads.data.size() %]
            <table class="table table-striped responsive-table" id="archivedLogsTable">
                <thead>
                    <tr>
                        <th>[% locale.maketext("Archive") %]</th>
                        <th>[% locale.maketext("Date Created") %]</th>
                        <th>[% locale.maketext("Actions") %]</th>
                    </tr>
                </thead>
                <tbody>
                [% FOREACH download IN downloads.data;
                    SET url = "${CPANEL.ENV.cp_security_token}/getlogarchive/" _ download.file;
                    SET link_text = download.file.html();
                    SET safe_filename = download.file.uri();
                %]
                    <tr id="archive-row-[% link_text.slugify() %]">
                        <td class="archive-name-cell" data-title="[% locale.maketext('Archive') %]">
                            <a id="raw-access-archive-[% link_text.slugify() %]"
                               aria-label="[% locale.maketext('Download the “[_1]” log archive.', link_text) %]"
                               href="[% url %]" class="download-link">
                                <span class="glyphicon glyphicon-download download-icon" aria-hidden="true"></span>
                                [% link_text %]
                            </a>
                        </td>
                        <td class="archive-date-cell" data-title="[% locale.maketext('Date Created') %]">[% locale.datetime(download.mtime, 'date_format_medium') %]</td>
                        <td class="archive-actions-cell" data-title="[% locale.maketext('Actions') %]">
                            <button class="btn btn-link delete-archive-btn" 
                                    type="button"
                                    data-filename="[% safe_filename %]"
                                    data-displayname="[% link_text %]"
                                    data-rowid="[% link_text.slugify() %]">
                                <span class="glyphicon glyphicon-trash"></span>
                                [% locale.maketext("Delete") %]
                            </button>
                        </td>
                    </tr>
                [% END %]
                </tbody>
            </table>

            [% ELSE %]

                <div class="alert alert-info" role="alert">
                    <span class='glyphicon glyphicon-info-sign' aria-hidden="true"></span>
                    <div class='alert-message'>
                        <strong class="alert-title">
                            [% locale.maketext('Notice:') %]
                        </strong>
                        <span class="alert-body">
                            <span id="info">
                                [% locale.maketext('No archived log files currently exist.') %]
                            </span>
                        </span>
                    </div>
                </div>

            [% END %]
        [% ELSE %]
            [% FOREACH error IN downloads.errors %]
                <div class="alert alert-danger" role="alert">
                    <span class='glyphicon glyphicon-remove-sign' aria-hidden="true"></span>
                    <div class='alert-message'>
                        <strong class="alert-title">
                            [% locale.maketext('Error:') %]
                        </strong>
                        <span class="alert-body">
                            <span id="error-[% loop.index() %]">
                                [% error.html() %]
                            </span>
                        </span>
                    </div>
                </div>
            [% END %]
        [% END %]
    </div>

    <!-- Delete Confirmation Modal -->
    <div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                    <h4 class="modal-title" id="deleteModalLabel">[% locale.maketext("Delete Log Archive") %]</h4>
                </div>
                <div class="modal-body">
                    <p>[% locale.maketext('Are you sure you want to delete the “[_1]” archive? This action cannot be undone.', '<strong id="deleteArchiveName"></strong>') %]</p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">[% locale.maketext("Cancel") %]</button>
                    <button type="button" class="btn btn-danger" id="confirmDeleteButton">[% locale.maketext("Delete") %]</button>
                </div>
            </div>
        </div>
    </div>
</div>
[% END #wrapper -%]
[% BLOCK css_block %]
<style type="text/css">
    #formConfigureLogs .checkbox {
        margin-bottom: 8px;
    }
    .download-link {
        display: inline-flex;
        align-items: center;
        gap: 6px;
    }
    .download-icon {
        margin-right: 6px;
    }
    .retention-input-wrapper {
        margin-left: 20px;
        margin-top: 5px;
        margin-bottom: 10px;
    }
    .retention-default-note {
        margin-left: 20px;
        margin-bottom: 10px;
        margin-top: -5px;
    }
    .retention-input-row {
        display: flex;
        align-items: center;
        gap: 8px;
    }
    .retention-days-field {
        width: 80px;
    }
    .retention-input-wrapper .help-block {
        margin-left: 0;
        margin-top: 5px;
        margin-bottom: 0;
    }
    #archivedLogsTable .btn-link {
        padding: 2px 6px;
    }
    #archivedLogsTable .btn-link .glyphicon {
        margin-right: 5px;
    }
    #archivedLogsTable tr.deleting {
        opacity: 0.5;
        pointer-events: none;
    }
</style>
[% END %]
[% BLOCK js_block %]
<script type="text/javascript">
(function() {
    'use strict';

    var pendingDelete = null;

    function initRetentionCheckbox() {
        var checkbox = document.getElementById('chkCustomRetention');
        var wrapper = document.getElementById('retentionInputWrapper');
        var input = document.getElementById('retentionDays');
        
        if (checkbox && wrapper && input) {
            checkbox.addEventListener('change', function() {
                wrapper.style.display = this.checked ? 'block' : 'none';
                input.disabled = !this.checked;
                if (this.checked) {
                    input.focus();
                }
            });
        }
    }

    function showModal() {
        var modal = document.getElementById('deleteModal');
        if (!modal) return;

        modal.style.display = 'block';
        modal.classList.add('show', 'in');
        document.body.classList.add('modal-open');

        var backdrop = document.createElement('div');
        backdrop.className = 'modal-backdrop fade in';
        backdrop.id = 'deleteModalBackdrop';
        document.body.appendChild(backdrop);
    }

    function closeModal() {
        var modal = document.getElementById('deleteModal');
        if (!modal) return;

        modal.style.display = 'none';
        modal.classList.remove('show', 'in');
        document.body.classList.remove('modal-open');

        var backdrop = document.getElementById('deleteModalBackdrop');
        if (backdrop) {
            backdrop.remove();
        }
    }

    function deleteArchive(filename, rowId) {
        var row = document.getElementById('archive-row-' + rowId);
        if (!row) return;

        row.classList.add('deleting');
        closeModal();

        var apiUrl = '[% CPANEL.ENV.cp_security_token %]/execute/LogManager/delete_archive?file=' + encodeURIComponent(filename);

        fetch(apiUrl, {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
        })
        .then(function(response) { return response.json(); })
        .then(function(data) {
            if (data.status) {
                row.remove();
                var table = document.getElementById('archivedLogsTable');
                if (table && table.querySelectorAll('tbody tr').length === 0) {
                    location.reload();
                }
            } else {
                row.classList.remove('deleting');
                alert(data.errors ? data.errors[0] : '[% locale.maketext("Failed to delete the archive.") %]');
            }
        })
        .catch(function() {
            row.classList.remove('deleting');
            alert('[% locale.maketext("An error occurred while deleting the archive.") %]');
        });
    }

    function initDeleteModal() {
        var deleteButtons = document.querySelectorAll('.delete-archive-btn');
        deleteButtons.forEach(function(button) {
            button.addEventListener('click', function(e) {
                e.preventDefault();
                pendingDelete = {
                    filename: this.getAttribute('data-filename'),
                    displayName: this.getAttribute('data-displayname'),
                    rowId: this.getAttribute('data-rowid')
                };
                document.getElementById('deleteArchiveName').textContent = pendingDelete.displayName;
                showModal();
            });
        });

        var confirmButton = document.getElementById('confirmDeleteButton');
        if (confirmButton) {
            confirmButton.addEventListener('click', function() {
                if (pendingDelete) {
                    deleteArchive(pendingDelete.filename, pendingDelete.rowId);
                }
            });
        }

        var closeButtons = document.querySelectorAll('#deleteModal [data-dismiss="modal"]');
        closeButtons.forEach(function(button) {
            button.addEventListener('click', closeModal);
        });

        document.addEventListener('click', function(e) {
            if (e.target && e.target.id === 'deleteModal') {
                closeModal();
            }
        });
    }

    document.addEventListener('DOMContentLoaded', function() {
        initRetentionCheckbox();
        initDeleteModal();
    });
})();
</script>
[% END %]
Back to Directory File Manager