Skip to content
Snippets Groups Projects
Debug.rst 10.64 KiB

Debug

QFQ Log

Setup in :ref:`configuration`

  • qfqLog
    • Filename where to log QFQ debug and error messages.
    • File is relative to the <site path> or absolute (starting with '/').
    • Content: error situations of QFQ and debug, if enabled.

All non SQL related information will be logged to QFQ log file.

SQL Log

Setup in :ref:`configuration`

  • sqlLog
    • Filename where to log SQL queries and statistical data.
    • File is relative to the <site path> or absolute (starting with '/').
    • Content: SQL queries and timestamp, formName/formId, fe_user, success, affected rows, newly created record id's and accessed from IP.
    • The global setting can be overwritten by defining sqlLog inside of a QFQ tt-content record.
  • sqlLogMode: all|modify|error|none

    • all: logs every SQL statement.
    • modify: logs only statements who might potentially change data.
    • error: logs only queries which generate SQL errors.
    • none: no query logging at all.
    • The global setting can be overwritten by defining sqlLogMode inside of a QFQ tt-content record.
  • showDebugInfo = [yes|no|auto],[download]

    If active, displays additional information in the Frontend (FE). This is typically helpful during development.

    • yes:

      • Form:

        • For every internal link/button, show tooltips with decoded SIP on mouseover.
        • Shows an 'Edit form'-button (wrench symbol) on a form. The link points to the T3 page with the :ref:`form-editor`.
      • Report: Will be configured per tt-content record.

        debugShowBodyText = 1

    • no: No debug info.

    • auto: Depending if there is a Typo3 BE session, set internally:

      • showDebugInfo = yes (BE session exist)
      • showDebugInfo = no (no BE session)
    • download:

      • During a download (especially by using wkhtml), temporary files are not deleted automatically. Also the wkhtmltopdf, pdfunite, pdf2img command lines will be logged to :ref:`QFQ_LOG`. Use this only to debug problems on download.

MAIL Log

Setup in :ref:`configuration`

  • mailLog
    • File which sendEmail logs sending mail.
    • File is relative to the <site path> or absolute (starting with '/').

Mail Log page (Table MailLog)

For debugging purposes you may like to add a Mail Log page in the frontend. The following QFQ code could be used for that purpose (put it in a QFQ PageContent element)

Use this code only on access restricted pages. GET/POST Parameter might be used to get access to unintended content.

Note: If you do not use/have the Ggroup table, then remove the "# Filters" block.:

# Page parameters
1.sql = SELECT @grId := '{{grId:C0:digit}}' AS _grId
2.sql = SELECT @summary := IF('{{summary:CE:alnumx}}' = 'true', 'true', 'false') AS _s

# Filters
10 {
  sql = SELECT "'", gr.id, IF(gr.id = @grId, "' selected>", "'>"), gr.value, ' (Id: ', gr.id, ')'
           FROM Ggroup AS gr
           INNER JOIN MailLog AS ml ON ml.grId = gr.id
           GROUP BY gr.id
  head = <form onchange='this.submit();' class='form-inline'><input type='hidden' name='id' value='{{pageAlias:T0}}'>
           Filter By Group: <select name='grId' class='form-control'><option value=''></option>
  rbeg = <option value=
  rend = </option>
  tail = </select>
}

20 {
  sql = SELECT IF(@summary = 'true', ' checked', '')
  head = <div class='checkbox'><label><input type='checkbox' name='summary' value='true'
  tail = >Summary</label></div></form>
}

# Mail Log
50 {
  sql = SELECT id, '</td><td>', grId, '</td><td>', xId, '</td><td>'
               , REPLACE(receiver, ',', '<br>'), '</td><td>', REPLACE(sender, ',', '<br>'), '</td><td>'
               , DATE_FORMAT(modified, '%d.%m.%Y<br>%H:%i:%s'), '</td><td style="word-break:break-word;">'
               , CONCAT('<b>', subject, '</b><br>', IF(@summary = 'true', CONCAT(SUBSTR(body, 1
                        , LEAST(IF(INSTR(body, '\n') = 0, 50, INSTR(body, '\n')), IF(INSTR(body, '<br>') = 0, 50
                        , INSTR(body, '<br>')))-1), ' ...'), CONCAT('<br>', REPLACE(body, '\n', '<br>'))) )
          FROM MailLog
          WHERE (grId = @grId OR @grId = 0)
          ORDER BY modified DESC
          LIMIT 100
  head = <table class="table table-condensed table-hover"><tr>
             <th>Id</th><th>grId</th><th>xId</th><th>To</th><th>From</th><th>Date</th><th>E-Mail</th></tr>
  tail = </table>
  rbeg = <tr><td>
  rend = </td></tr>
}

Redirect all mail to (catch all)

Setup in :ref:`configuration`

  • redirectAllMailTo=john@doe.com
    • During the development, it might be helpful to configure a 'catch all' email address, which QFQ uses as the final receiver instead of the original intended one.
    • The setting will:
      • Replace the 'To' with the configured one.
      • Clear 'CC' and 'Bcc'
      • Write a note and the original configured receiver at the top of the email body.

Show log files realtime

Use this code only on access restricted pages. GET/POST Parameter might be used to get access to unintended content.

Display QFQ log files in realtime. Put the following code in a QFQ page content element.:

#
# {{logfile:SU}}
#

# Show buttons to select log file.
10 {
  sql = SELECT '{{logfile:SU:::sql.log}}' AS '_=logfile'
  head = <p>
  tail = </p>

  20.sql = SELECT CONCAT('p:{{pageAlias:T}}&logfile=sql.log|t:sql.log|b:', IF('{{logfile:R}}'='sql.log','primary','')) AS _page, ' '
                  , CONCAT('p:{{pageAlias:T}}&logfile=qfq.log|t:qfq.log|b:', IF('{{logfile:R}}'='qfq.log','primary','')) AS _page, ' '
                  , CONCAT('p:{{pageAlias:T}}&logfile=mail.log|t:mail.log|b:', IF('{{logfile:R}}'='mail.log','primary','')) AS _page
}

# Show selected log file.
100 {
  sql = SELECT 'file:fileadmin/protected/log/{{logfile:R}}' AS _monitor
  head = <pre id="monitor-1">Please wait</pre>
}

Form Submit Log page

Use this code only on access restricted pages. GET/POST Parameter might be used to get access to unintended content.

Check the Form Submit Log page to see what have been submitted. Put the following code in a QFQ page content element.:

#
# Show all form submit. Optional filter by Form or FeUser.
#
# {{formId:SC0}}
# {{feUser:SCE:alnumx}}

# Filters
10 {
  sql = SELECT ''
  shead = <form onchange='this.submit()' class='form-inline'><input type='hidden' name='id' value='{{pageAlias:T0}}'>
  stail = </form>

  # Dropdown: Form
  20 {

    sql = SELECT "'", f.id, IF( f.id = '{{formId:SC0}}', "' selected>", "'>"), f.name, ' (', QIFEMPTY(COUNT(fsl.id),'-'), ')'
            FROM Form AS f
            LEFT JOIN FormSubmitLog AS fsl
              ON fsl.formId=f.id
            GROUP BY f.id
            ORDER BY f.name
    head = <label for='formId'>Form:</label> <select name='formId' id='formId' class='form-control'><option value=0></option>
    tail = </select>
    rbeg = <option value=
    rend = </option>
  }

  # Dropdown: feUser
  30 {
    sql = SELECT feUser, IF(feUser = '{{feUser:SCE:alnumx}}', "' selected>", "'>"), feUser, ' (', COUNT(id), ')'
            FROM FormSubmitLog
            WHERE feUser!=''
            GROUP BY feUser
            ORDER BY feUser
    head = <label for='feUser'>FE User:</label> <select name='feUser' id='feUser' class='form-control'><option value=''></option>
    tail = </select>
    rbeg = <option value='
    # just to sync syntax highlighter: '
    rend = </option>
  }
}

# Show Log
50 {
  sql = SELECT l.id
                , CONCAT('<b>Form</b>: ', f.name
                         , '<br><b>Record Id</b>: ', l.recordId
                         , '<br><b>Fe User</b>: ', l.feUser
                         , '<br><b>Date</b>: ', l.created
                         , '<br><b>Page Id</b>: ', l.pageId
                         , '<br><b>Session Id</b>: ', l.sessionId
                         , '<br><b>IP Address</b>: ', l.clientIp
                         , '<br><b>User Agent</b>: ', l.userAgent
                         , '<br><b>SIP Data</b>: <div style="margin-left:20px;">'
                         , "<script>var data = JSON.parse('", l.sipData, "'); for (var key in data) {
                            document.write('<b>' + key + '</b>: ' + data[key] + '<br>'); }</script>", '</div>')
                 , CONCAT("<script>var data = JSON.parse('", l.formData, "'); for (var key in data) {
                            document.write('<b>' + key + '</b>: ' + data[key] + '<br>'); }</script>")
            FROM FormSubmitLog AS l
            LEFT JOIN Form AS f
              ON f.id = l.formId
            WHERE (l.formId = '{{formId:SC0}}' OR '{{formId:SC0}}' = 0)
              AND (l.feUser = '{{feUser:SCE:alnumx}}' OR '{{feUser:SCE:alnumx}}' = '')
            ORDER BY l.created DESC
            LIMIT 100
  head = <table class="table table-hover">
         <tr><th>Id</th><th style="min-width:250px;">Environment</th><th>Submitted Data</th>
  tail = </table>
  rbeg = <tr>
  renr = </tr>
  fbeg = <td>
  fend = </td>
}