From bbe27999eb7a54a33c3c890e8f810438e1099f03 Mon Sep 17 00:00:00 2001 From: Jean-Fabien Barrois Date: Tue, 10 Feb 2015 10:38:24 +1300 Subject: [PATCH] BUGFIX Use correct query when searching for items managed by a tree dropdown field #3173 --- forms/TreeDropdownField.php | 15 +++-- tests/forms/TreeDropdownFieldTest.php | 97 +++++++++++++++++++++++++++ tests/forms/TreeDropdownFieldTest.yml | 25 +++++++ 3 files changed, 131 insertions(+), 6 deletions(-) create mode 100644 tests/forms/TreeDropdownFieldTest.php create mode 100644 tests/forms/TreeDropdownFieldTest.yml diff --git a/forms/TreeDropdownField.php b/forms/TreeDropdownField.php index 2f9f5d623..35d079e1a 100644 --- a/forms/TreeDropdownField.php +++ b/forms/TreeDropdownField.php @@ -460,15 +460,18 @@ class TreeDropdownField extends FormField { if ($row->ParentID) $parents[$row->ParentID] = true; $this->searchIds[$row->ID] = true; } + + $sourceObject = $this->sourceObject; + while (!empty($parents)) { - $res = DB::query('SELECT "ParentID", "ID" FROM "' . $this->sourceObject - . '" WHERE "ID" in ('.implode(',',array_keys($parents)).')'); + $items = $sourceObject::get() + ->filter("ID",array_keys($parents)); $parents = array(); - foreach($res as $row) { - if ($row['ParentID']) $parents[$row['ParentID']] = true; - $this->searchIds[$row['ID']] = true; - $this->searchExpanded[$row['ID']] = true; + foreach($items as $item) { + if ($item->ParentID) $parents[$item->ParentID] = true; + $this->searchIds[$item->ID] = true; + $this->searchExpanded[$item->ID] = true; } } } diff --git a/tests/forms/TreeDropdownFieldTest.php b/tests/forms/TreeDropdownFieldTest.php new file mode 100644 index 000000000..5e1f20c75 --- /dev/null +++ b/tests/forms/TreeDropdownFieldTest.php @@ -0,0 +1,97 @@ +'sub')); + $tree = $field->tree($request); + + $folder1 = $this->objFromFixture('Folder','folder1'); + $folder1Subfolder1 = $this->objFromFixture('Folder','folder1-subfolder1'); + + $parser = new CSSContentParser($tree); + $cssPath = 'ul.tree li#selector-TestTree-'.$folder1->ID.' li#selector-TestTree-'.$folder1Subfolder1->ID.' a span.item'; + $firstResult = $parser->getBySelector($cssPath); + $this->assertEquals( + (string)$firstResult[0], + $folder1Subfolder1->Name, + 'FileTest-folder1-subfolder1 is found, nested under folder1' + ); + + $subfolder = $this->objFromFixture('Folder','subfolder'); + $cssPath = 'ul.tree li#selector-TestTree-'.$subfolder->ID.' a span.item'; + $secondResult = $parser->getBySelector($cssPath); + $this->assertEquals( + (string)$secondResult[0], + $subfolder->Name, + 'FileTest-subfolder is found at root level' + ); + + // other folders which don't contain the keyword 'sub' are not returned in search results + $folder2 = $this->objFromFixture('Folder','folder2'); + $cssPath = 'ul.tree li#selector-TestTree-'.$folder2->ID.' a span.item'; + $noResult = $parser->getBySelector($cssPath); + $this->assertEquals( + $noResult, + array(), + 'FileTest-folder2 is not found' + ); + + $field = new TreeDropdownField('TestTree', 'Test tree', 'File'); + + // case insensitive search against keyword 'sub' for files + $request = new SS_HTTPRequest('GET','url',array('search'=>'sub')); + $tree = $field->tree($request); + + $parser = new CSSContentParser($tree); + + // Even if we used File as the source object, folders are still returned because Folder is a File + $cssPath = 'ul.tree li#selector-TestTree-'.$folder1->ID.' li#selector-TestTree-'.$folder1Subfolder1->ID.' a span.item'; + $firstResult = $parser->getBySelector($cssPath); + $this->assertEquals( + (string)$firstResult[0], + $folder1Subfolder1->Name, + 'FileTest-folder1-subfolder1 is found, nested under folder1' + ); + + // Looking for two files with 'sub' in their name, both under the same folder + $file1 = $this->objFromFixture('File','subfolderfile1'); + $file2 = $this->objFromFixture('File','subfolderfile2'); + $cssPath = 'ul.tree li#selector-TestTree-'.$subfolder->ID.' li#selector-TestTree-'.$file1->ID.' a'; + $firstResult = $parser->getBySelector($cssPath); + $this->assertEquals( + (string)$firstResult[0], + $file1->Name, + 'TestFile1InSubfolder is found nested under subfolder' + ); + + $cssPath = 'ul.tree li#selector-TestTree-'.$subfolder->ID.' li#selector-TestTree-'.$file2->ID.' a'; + $secondResult = $parser->getBySelector($cssPath); + $this->assertEquals( + (string)$secondResult[0], + $file2->Name, + 'TestFile2InSubfolder is found nested under subfolder' + ); + + // other files which don't include 'sub' are not returned in search results + $file3 = $this->objFromFixture('File','asdf'); + $cssPath = 'ul.tree li#selector-TestTree-'.$file3->ID; + $noResult = $parser->getBySelector($cssPath); + $this->assertEquals( + $noResult, + array(), + 'FileTest.txt is not found' + ); + } + +} + \ No newline at end of file diff --git a/tests/forms/TreeDropdownFieldTest.yml b/tests/forms/TreeDropdownFieldTest.yml new file mode 100644 index 000000000..0e77af985 --- /dev/null +++ b/tests/forms/TreeDropdownFieldTest.yml @@ -0,0 +1,25 @@ +Folder: + subfolder: + Name: FileTest-subfolder + folder1: + Name: FileTest-folder1 + folder2: + Name: FileTest-folder2 + folder1-subfolder1: + Name: FileTest-folder1-subfolder1 + ParentID: =>Folder.folder1 +File: + asdf: + Filename: assets/FileTest.txt + subfolderfile1: + Filename: assets/FileTest-subfolder/TestFile1InSubfolder.txt + Name: TestFile1InSubfolder + ParentID: =>Folder.subfolder + subfolderfile2: + Filename: assets/FileTest-subfolder/TestFile2InSubfolder.txt + Name: TestFile2InSubfolder + ParentID: =>Folder.subfolder + file1-folder1: + Filename: assets/FileTest-folder1/File1.txt + Name: File1.txt + ParentID: =>Folder.folder1 \ No newline at end of file