Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Customising the CMS /

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Fulltext search not picking up classname Page


Go to End


2 Posts   1110 Views

Avatar
zoose

Community Member, 4 Posts

2 September 2014 at 2:50pm

New site under development:
Environment: SS3.1.5, Windows Server 2012, MSSQL 2012, PHP 5.4

We've written FulltextSearchable::enable() into _config.php and created the fulltext index in SQL

Running a search returns no results for any Page or HomePage class records.
Dump of ClassInfo::dataClassesFor('SiteTree') shows the following:

Array ( [SiteTree] => SiteTree [BlogEntry] => BlogEntry [BlogTree] => BlogTree [BlogHolder] => BlogHolder [ErrorPage] => ErrorPage [RedirectorPage] => RedirectorPage [VirtualPage] => VirtualPage [SubsitesVirtualPage] => SubsitesVirtualPage [UserDefinedForm] => UserDefinedForm ) 

This results in the MSSQL->searchEngine() function producing $fullQuery as follows (only SiteTree half shown):

... UNION SELECT DISTINCT "SiteTree_Live"."ID", 'SiteTree' AS "Source", Rank AS "Relevance" FROM "SiteTree_Live" INNER JOIN CONTAINSTABLE("SiteTree_Live", (*), 'module') AS "ft" ON "SiteTree_Live"."ID"="ft"."KEY" WHERE ("SiteTree_Live"."ShowInSearch"!=0) AND ("SiteTree_Live"."SubsiteID" IN (0)) AND ("SiteTree_Live"."ClassName" IN ('SiteTree', 'BlogEntry', 'BlogTree', 'BlogHolder', 'ErrorPage', 'RedirectorPage', 'VirtualPage', 'SubsitesVirtualPage', 'UserDefinedForm', 'File')) ORDER BY "Relevance" DESC

What it's looking for is match from SiteTree_Live where the ClassName matches an item in the IN() list, and neither Page nor HomePage are in that list. This shouldn't possibly be intended default behaviour?

I can force HomePage into the ClassName list by adding a column to the $db array but this shouldn't have to happen. So why is Page not in the list?

Avatar
zoose

Community Member, 4 Posts

4 September 2014 at 4:24pm

Is this a bug?

In a plain vanilla install of 3.1.6 plus MSSQL module in Win server environment above, I can document undesirable behaviour.

To prove that class Page should be found, I tested the following:
- dumping SS_ClassLoader::instance()->getManifest()->getDescendantsOf('SiteTree') produces the following array:

Array ( [0] => Page [1] => ErrorPage [2] => RedirectorPage [3] => VirtualPage )

To confirm:
- dumping ClassInfo::subclassesFor('SiteTree') produces the following array:

Array ( [SiteTree] => SiteTree [Page] => Page [ErrorPage] => ErrorPage [RedirectorPage] => RedirectorPage [VirtualPage] => VirtualPage )

So we have two proofs that Page is recognised. But things start to unravel in ClassInfo::dataClassesFor():82
array_merge(ClassInfo::ancestry('SiteTree'),ClassInfo::subclassesFor('SiteTree')) creates a single array of both ancestors and children classes of SiteTree. Then on line 86 this array is looped over and each class is tested to see if there is a corresponding database table.

Object no
ViewableData no
DataObject no
SiteTree yes
Page no
ErrorPage yes
RedirectorPage yes
VirtualPage yes

In a default installation, pages of type Page will never be found by fulltext search until Page.php is extended is some way.

The snip below can be inserted into MSSQL::searchEngine() at around line 1417.

print_r("<em>SS_ClassLoader::instance()->getManifest()->getDescendantsOf('SiteTree')</em> ");
print_r(SS_ClassLoader::instance()->getManifest()->getDescendantsOf('SiteTree'));

print_r("<br><br><em>ClassInfo::subclassesFor('SiteTree')</em> ");
print_r(ClassInfo::subclassesFor('SiteTree'));

print_r("<br><br><em>ClassInfo::dataClassesFor('SiteTree')</em> ");
print_r(ClassInfo::dataClassesFor('SiteTree'));

$classesX = array_merge(
			ClassInfo::ancestry('SiteTree'),
			ClassInfo::subclassesFor('SiteTree'));
print_r("<br><br><em>array_merge(ClassInfo::ancestry('SiteTree'),ClassInfo::subclassesFor('SiteTree'))</em> ");
	foreach ($classesX as $classX) {
		print_r('<br>' . $classX);
			if (self::hasTable($classX)) {
				print_r(' yes');
			} else {
				print_r(' no');
			}
		}
die();