Skip to content

Commit

Permalink
Add compatibility with Craft 5.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
bencroker committed Aug 9, 2024
1 parent 068f0d2 commit 98f31db
Show file tree
Hide file tree
Showing 7 changed files with 288 additions and 34 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Release Notes for Blitz

## 5.6.3 - Unreleased
## 5.7.0 - Unreleased

### Added

- Added compatibility for tracking of relation fields in Craft 5.3.0.
- Added compatibility for detecting eager-loading opportunities in the Blitz Hints utility in Craft 5.3.0.

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "putyourlightson/craft-blitz",
"description": "Intelligent static page caching for creating lightning-fast sites.",
"version": "5.6.3",
"version": "5.7.0",
"type": "craft-plugin",
"homepage": "https://putyourlightson.com/plugins/blitz",
"license": "proprietary",
Expand Down
2 changes: 2 additions & 0 deletions src/helpers/ElementQueryHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ public static function getNormalizedElementQueryIdParam(mixed $value): mixed

/**
* Returns whether the element query has numeric IDs that may be related element IDs.
*
* @see BaseRelationField::getRelationTargetIds()
*/
public static function hasRelatedElementIds(ElementQuery $elementQuery): bool
{
Expand Down
11 changes: 7 additions & 4 deletions src/helpers/HintsHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,14 @@ public static function getAll(): array
$hint = new HintModel();
$hint->setAttributes($record->getAttributes(), false);

$field = Craft::$app->getFields()->getFieldById($hint->fieldId);
if ($field) {
$hint->field = $field;
$hints[] = $hint;
if ($hint->fieldId > 0) {
$field = Craft::$app->getFields()->getFieldById($hint->fieldId);
if ($field) {
$hint->field = $field;
}
}

$hints[] = $hint;
}

return $hints;
Expand Down
50 changes: 26 additions & 24 deletions src/services/HintsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

use Craft;
use craft\base\Component;
use craft\base\FieldInterface;
use craft\elements\db\ElementQuery;
use putyourlightson\blitz\helpers\ElementQueryHelper;
use putyourlightson\blitz\models\HintModel;
Expand Down Expand Up @@ -58,10 +57,14 @@ public function checkElementQuery(ElementQuery $elementQuery): void
return;
}

// TODO: Figure out how to add field hints for related element IDs.
if ($elementQuery->eagerly || $elementQuery->wasEagerLoaded()) {
return;
}

// Required as of Craft 5.3.0.
if (ElementQueryHelper::hasRelatedElementIds($elementQuery)) {
//$this->addFieldHint($field->id);
$this->addFieldHint();

return;
}

Expand All @@ -70,10 +73,6 @@ public function checkElementQuery(ElementQuery $elementQuery): void
return;
}

if ($elementQuery->eagerly || $elementQuery->wasEagerLoaded()) {
return;
}

/** @see ElementQuery::wasEagerLoaded() */
$planHandle = $elementQuery->eagerLoadHandle;
if (str_contains($planHandle, ':')) {
Expand Down Expand Up @@ -116,17 +115,18 @@ public function save(): void
}

/**
* Adds a field hint.
* Adds a field hint. As of Craft 5.3.0, we may not be able to detect the field ID from the element query, if the relation field value is stored in the `content` column. In this case we set a field ID of zero, so we can still store it, maintaining unique keys.
*/
private function addFieldHint(int $fieldId): void
private function addFieldHint(int $fieldId = 0): void
{
$field = Craft::$app->getFields()->getFieldById($fieldId);
$fieldHandle = null;

if ($field === null) {
return;
if ($fieldId > 0) {
$field = Craft::$app->getFields()->getFieldById($fieldId);
$fieldHandle = $field->handle ?? null;
}

$hint = $this->createHintWithTemplateLine($field);
$hint = $this->createHintWithTemplateLine($fieldId, $fieldHandle);

if ($hint === null) {
return;
Expand All @@ -152,7 +152,7 @@ private function addFieldHint(int $fieldId): void
/**
* Returns a new hint with the template and line number of the rendered template.
*/
protected function createHintWithTemplateLine(FieldInterface $field): ?HintModel
protected function createHintWithTemplateLine(int $fieldId, ?string $fieldHandle = null): ?HintModel
{
$hint = null;
$traces = debug_backtrace();
Expand All @@ -167,7 +167,7 @@ protected function createHintWithTemplateLine(FieldInterface $field): ?HintModel
if ($templatePath && $line) {
if ($hint === null) {
$hint = new HintModel([
'fieldId' => $field->id,
'fieldId' => $fieldId,
'template' => $templatePath,
'line' => $line,
'stackTrace' => [$templatePath . ':' . $line],
Expand All @@ -178,15 +178,17 @@ protected function createHintWithTemplateLine(FieldInterface $field): ?HintModel
continue;
}

// Read the contents of the template file, since the code cannot be retrieved from the source context with `devMode` disabled.
$templateCode = file($this->getTemplatePath($template));
$code = $templateCode[$line - 1] ?? '';
preg_match('/(\w+?)\.' . $field->handle . '/', $code, $matches);
$routeVariable = $matches[1] ?? null;

// Don’t continue if the route variable is set.
if ($routeVariable && !empty($trace['args'][0]['variables'][$routeVariable])) {
return null;
if ($fieldHandle !== null) {
// Read the contents of the template file, since the code cannot be retrieved from the source context with `devMode` disabled.
$templateCode = file($this->getTemplatePath($template));
$code = $templateCode[$line - 1] ?? '';
preg_match('/(\w+?)\.' . $fieldHandle . '/', $code, $matches);
$routeVariable = $matches[1] ?? null;

// Don’t continue if the route variable is set.
if ($routeVariable && !empty($trace['args'][0]['variables'][$routeVariable])) {
return null;
}
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/templates/_utilities/hints/components/hints.twig
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@
{% for hint in hints %}
<tr>
<td>
Eager-load the “{{ hint.field.name }}” field.
{% set fieldHandle = hint.field.handle ?? 'relationFieldHandle' %}
Eager-load the {{ hint.field ? '' ~ hint.field.name ~ '' : 'relation' }} field.
<span class="info" style="vertical-align: top;">
Eager-load the <code>{{ hint.field.handle }}</code> field using <a href="https://craftcms.com/docs/5.x/development/eager-loading.html#lazy-eager-loading" target="_blank">lazy-eager-loading</a>:
<pre><code>&#123;% set {{ hint.field.handle }} = entry.{{ hint.field.handle }}.eagerly().all() %&#125;</code></pre>
Eager-load the {{ hint.field ? ('<code>' ~ fieldHandle ~ '</code>')|raw : 'relation' }} field using <a href="https://craftcms.com/docs/5.x/development/eager-loading.html#lazy-eager-loading" target="_blank">lazy-eager-loading</a>:
<pre><code>&#123;% set result = entry.{{ fieldHandle }}.eagerly().all() %&#125;</code></pre>
Or the <a href="https://craftcms.com/docs/5.x/development/eager-loading.html#the-with-query-param" target="_blank"><code>with()</code></a> query param:
<pre><code>
{{- "{% set entries = craft.entries" -}}
{{- "\n .with('" ~ hint.field.handle ~ "')" -}}
{{- "\n .with('" ~ fieldHandle ~ "')" -}}
{{- "\n .all()" -}}
{{- "\n%}" -}}
</code></pre>
Expand Down
Loading

0 comments on commit 98f31db

Please sign in to comment.