-
Notifications
You must be signed in to change notification settings - Fork 62
Debugging GravityView
Debugging GravityView Core and Extensions can be a little confusing at times. This document outlines some general debugging strategies and tricks to streamline issue identification and solving.
Almost all issues occur on a page that is either a View or a page with either an oEmbed or a shortcode.
For directory mode requests the first step is to obtain a var_dump
of the GF_Query::_introspect()
call once it's performed. This happens in the \GV\GF_Form::get_entries
method (if move/gfquery
branch is merged into a release, otherwise in the \GV\View::get_entries
method in older releases.
The best place to setup the var_dump
is right after the GF_Query::get()
call almost at the very bottom of the \GV\GF_Form::get_entries
method inside the add_fetch_callback
callback, where entry arrays are transformed into \GV\GF_Entry
objects and added to the Entry_Collection
that is returned.
This _introspect()
method, while marked as private/internal but provided by Gravity Forms for now, is a great way to find out the query's join, where, sort, limit and offset clauses. The same information is somewhat contained in the executed queries item of the array that the _introspect()
method returned.
If in the future the method is removed falling back to using the WordPress query
filter is also an option to get the generated SQL but it can be confusing to pinpoint the final query as one Gravity Forms query may actually be composed of several queries due to join and union generators in some cases.
Standard GravityView debug logging is also provided before the final ::get
call. So the Debug Bar plugin can usually be of help in cases where var_dump
ing is not possible.
Once the conditions and the SQL query have been analyzed the immediate issue with the database request should be quite evident. Incorrectly generated, erroneous or missing auxiliary (joins, casts) SQL is almost always an bug in GF_Query
itself, although we haven't had them for quite a while. Incorrect query clauses or parameters, values is usually the result of incorrectly passed search_criteria
or generated GF_Query::where()
call combinations in activated plugins (Advanced Filters, etc.).
Bubbling up through code to find out the source of the incorrect parameters and added WHERE conditionals is necessary to pinpoint the exact issue thereafter.
There are three hooks that have been used to alter entry set querying: gform_gf_query_sql
, gravityview/view/query
, gravityview/view/entries
. Weird custom code might tap into the lower-level WordPress query
filter, but this has not been observed in the wild.
Single entries are queried by converting a slug (usually an ID) to a simple get_entry()
call. Not much can go wrong, but we've seen issues with check_entry_display
querying resulting in permission errors. check_entry_display
issues are debugged in the same manner as get_entries()
issues above, as the call is to get_entries()
but with an extra entry ID condition.
Joined slugs may have their own issues in displaying a joined entry. The Joins plugin is pretty complicated and not used extensively for now, so it has quite a few bugs that have not been discovered yet.
This is a special case as most data is retrieved via the getData
AJAX call with parameters. There are various nuances in the JavaScript and the backend but most issues boil down issues in the final SQL. Resolving by bubbling up though code is the best strategy as well.
The Field Renderer will grab a Field
object and generate some output based on the View, the Entry and the Field template. Issues are, thus, inside templates and how they use the three components (via the $gravityview
context global) to output a designated value.
var_dump
ing is still your best friend here.
The edit entry code is pretty self-contained inside core itself. As the code is old and quite complicated it is usually advisable to try and reproduce an edit issue in a test case (unless it's a frontend logic issue). The _emulate_render
method inside the Edit Entry test suite allows for the easy automation and emulation of edit requests. Going through the tests will help quite a bit to understand how editing works.
When GravityView is deployed on a live website it is usually a part of a complex WordPress installation, which involves varying extensions and even custom code (in functions.php, etc.). It is very tempting to try debug an issue on a live website, but this is not only pretty dangerous but also pretty inconvenient.
Since var_dump
is our only friend in most cases we need not only full control to inject and mangle code as needed, but also turn off plugins, themes, replace plugins with older/newer versions (do bisects, etc.). This is why it's advisable to make a full copy and fiddle with an installation locally.
When doing this, however, make sure to disable any SMTP plugins, which might send double emails. Mailchimp plugins, turn off cron completely. It is important to make sure the cloned site doesn't contact the outside world.
It is also advisable to update GravityView and related extensions to latest development versions; we've seen instances where client sites have made changes to core and extension code. Switching off the theme and unrelated plugins will also help attain a cleaner and leaner installation to debug through and avoid looking for a needle in a haystack of custom code. The less code there is the better.
This is a beast of its own. Bugs have been discovered and fixed upstream on several occasions. Join generation, casts and NOT EXISTS
clauses are the most intricate parts of GF_Query
. It's useful to study its internals and provide tests and fixes for new issues that are found.
Alias generation and matching is also something that we've seen issues in, especially when using joins and unions features. Building tests for GF_Query
and upstream patching should be pretty simple as the WHERE and other clauses can be dumped on a real example and then ported to the test suite.
Read the 2.0 wiki and know it by heart to understand how to locate and pinpoint issues. var_dump
is your best friend. Write tests when bugs are found, have them pass.