While XF2's Finder is quite neat, and the ability to use SqlExpression as a where clause covers most angles; using joins can avoid various MySQL-ism related to sub-query performance, and just make it easier to reason about an SQL query. Additionally, it means you can use more columns to drive logic rather than just the single column output of a subquery.
Sadly XF2's query system doesn't allow this, but the underling Finder join structure does permit it. The attached SqlJointTrait.php, injects a couple of functions (and extends
Note; container_type/container_id are on a previously joined table.
This shows how to create an SQL-join, populate the join conditions, and then use the alias like a normal entity column with existing Finder bits.
The major changes compared to the existing
Sadly XF2's query system doesn't allow this, but the underling Finder join structure does permit it. The attached SqlJointTrait.php, injects a couple of functions (and extends
resolveFieldToTableAndColumn
) to add new methods;- sqlJoin - define a new job, table, alias and define known columns
- sqlCondition - for a known join alias, rewrite the join condition using XF's join syntax but with support for parsing non-entity columns.
Code:
$finder->sqlJoin('xf_thread_watch', 'threadWatch', ['thread_id', 'user_id'], false);
$finder->sqlJoinConditions('threadWatch', [
[ '$container_type', '=', 'thread'],
['thread_id', '=', '$container_id'],
['user_id', '=', $visitor->user_id]
]);
$finder->where('threadWatch.user_id', '<>', null);
This shows how to create an SQL-join, populate the join conditions, and then use the alias like a normal entity column with existing Finder bits.
The major changes compared to the existing
Finder::join
method's condition parsing is the use of columnSqlName
when handling all columns when the $ is used. LHS are presumed local columns, unless the $ is used to use locate a column, and RHS is presumed a value unless $ is used to locate a column.