Skip to content

Commit

Permalink
ENH Optimise site search
Browse files Browse the repository at this point in the history
  • Loading branch information
emteknetnz committed Jun 27, 2023
1 parent 96c81fe commit 4122799
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 8 deletions.
45 changes: 38 additions & 7 deletions src/Extensions/ElementalPageExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,50 @@ public function MetaTags(&$tags)
}
}

/**
* @internal
*/
private static ?array $cachedElementalAreaDataLists = null;

/**
* Call some function over all elements belonging to this page
*/
private function loopThroughElements(callable $callback): void
{
foreach ($this->owner->hasOne() as $key => $class) {
if ($class !== ElementalArea::class) {
continue;
// would delete all the legacy stuff when doing proper PR, it's just here
// so that it's easy for me to benchmark old performance compared to new
$legacy = false;
if ($legacy) {
foreach ($this->owner->hasOne() as $key => $class) {
if ($class !== ElementalArea::class) {
continue;
}
/** @var ElementalArea $area */
$area = $this->owner->$key();
if ($area) {
foreach ($area->Elements() as $element) {
$callback($element);
}
}
}
} else {
if (is_null(self::$cachedElementalAreaDataLists)) {
self::$cachedElementalAreaDataLists = [];
foreach (ElementalArea::get()->eagerLoad('Elements') as $elementalArea) {
self::$cachedElementalAreaDataLists[$elementalArea->ID] = $elementalArea;
}
}
/** @var ElementalArea $area */
$area = $this->owner->$key();
if ($area) {
foreach ($area->Elements() as $element) {
foreach ($this->owner->hasOne() as $relation => $class) {
if (!is_a($class, ElementalArea::class, true)) {
continue;
}
$elementalAreaID = $this->owner->{"{$relation}ID"};
if ($elementalAreaID && array_key_exists($elementalAreaID, self::$cachedElementalAreaDataLists)) {
$elementalArea = self::$cachedElementalAreaDataLists[$elementalAreaID];
} else {
$elementalArea = $this->owner->$relation();
}
foreach ($elementalArea->Elements() as $element) {
$callback($element);
}
}
Expand Down
34 changes: 33 additions & 1 deletion src/Models/BaseElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,39 @@ public function getSearchIndexable(): bool
public function getContentForSearchIndex(): string
{
// Strips tags but be sure there's a space between words.
$content = trim(strip_tags(str_replace('<', ' <', $this->forTemplate() ?? '') ?? ''));
// $content = trim(strip_tags(str_replace('<', ' <', $this->forTemplate() ?? '') ?? ''));

$contents = [];
foreach ($this->config()->get('db') as $fieldName => $fieldType) {
// https://docs.silverstripe.org/en/developer_guides/model/data_types_and_casting/
// probably won't actually get things like 'CanViewType' in db config
if ($fieldName === 'LastEdited'
|| $fieldName === 'Created'
|| $fieldName === 'CanViewType'
|| $fieldName === 'CanEditType'
|| $fieldName === 'Version'
|| $fieldName === 'ShowInMenus'
|| $fieldName === 'ShowInSearch'
|| $fieldName === 'Sort'
|| $fieldName === 'HasBrokenFile'
|| $fieldName === 'HasBrokenLink'
|| $fieldName === 'ReportClass'
|| substr($fieldType, -2) === 'ID'
|| substr($fieldType, -3) === 'Key'
|| substr($fieldName, -9) === 'ClassName'
|| substr($fieldType, -4) === 'Hash'
) {
continue;
}
$contents[] = $this->$fieldName;
}
// use a pipes to delimite different fields rather than space so that you don't
// accidentally join results of two columns that are next to each other in a table
$content = implode('||', $contents);

// Strips tags and be sure there's a space between words.
$content = trim(strip_tags(str_replace('<', ' <', $content)));

// Allow projects to update indexable content of third-party elements.
$this->extend('updateContentForSearchIndex', $content);
return $content;
Expand Down

0 comments on commit 4122799

Please sign in to comment.