SearchableHelper::storeMethodTextValue()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2
Metric Value
dl 0
loc 12
ccs 9
cts 9
cp 1
rs 9.4286
cc 2
eloc 8
nc 2
nop 4
crap 2
1
<?php
2
namespace SilverStripe\Elastica;
3
4
class SearchableHelper {
5
6
7 10
	public static function addIndexedFields($name, &$spec, $ownerClassName) {
8
		// in the case of a relationship type will not be set
9 10
		if(isset($spec['type'])) {
10 10
			if($spec['type'] == 'string') {
11 10
				$unstemmed = array();
12 10
				$unstemmed['type'] = "string";
13 10
				$unstemmed['analyzer'] = "unstemmed";
14 10
				$unstemmed['term_vector'] = "yes";
15 10
				$extraFields = array('standard' => $unstemmed);
16
17 10
				$shingles = array();
18 10
				$shingles['type'] = "string";
19 10
				$shingles['analyzer'] = "shingles";
20 10
				$shingles['term_vector'] = "yes";
21 10
				$extraFields['shingles'] = $shingles;
22
23
				//Add autocomplete field if so required
24 10
				$autocomplete = \Config::inst()->get($ownerClassName, 'searchable_autocomplete');
25
26 10
				if(isset($autocomplete) && in_array($name, $autocomplete)) {
27 10
					$autocompleteField = array();
28 10
					$autocompleteField['type'] = "string";
29 10
					$autocompleteField['index_analyzer'] = "autocomplete_index_analyzer";
30 10
					$autocompleteField['search_analyzer'] = "autocomplete_search_analyzer";
31 10
					$autocompleteField['term_vector'] = "yes";
32 10
					$extraFields['autocomplete'] = $autocompleteField;
33 10
				}
34
35 10
				$spec['fields'] = $extraFields;
36
				// FIXME - make index/locale specific, get from settings
37 10
				$spec['analyzer'] = 'stemmed';
38 10
				$spec['term_vector'] = "yes";
39 10
			}
40 10
		}
41 10
	}
42
43
44
	/**
45
	 * @param string &$name
46
	 * @param boolean $storeMethodName
47
	 * @param boolean $recurse
48
	 */
49 10
	public static function assignSpecForRelationship(&$name, $resultType, &$spec, $storeMethodName, $recurse) {
50 10
		$resultTypeInstance = \Injector::inst()->create($resultType);
51 10
		$resultTypeMapping = array();
52
		// get the fields for the result type, but do not recurse
53 10
		if($recurse) {
54 10
			$resultTypeMapping = $resultTypeInstance->getElasticaFields($storeMethodName, false);
55 10
		}
56 10
		$resultTypeMapping['ID'] = array('type' => 'integer');
57 10
		if($storeMethodName) {
58 10
			$resultTypeMapping['__method'] = $name;
59 10
		}
60 10
		$spec = array('properties' => $resultTypeMapping);
61
		// we now change the name to the result type, not the method name
62 10
		$name = $resultType;
63 10
	}
64
65
66
	/**
67
	 * @param string $name
68
	 */
69 10
	public static function assignSpecForStandardFieldType($name, $class, &$spec, &$html_fields, &$mappings) {
0 ignored issues
show
Coding Style Naming introduced by
The parameter $html_fields is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
70 10
		if(($pos = strpos($class, '('))) {
71
			// Valid in the case of Varchar(255)
72 10
			$class = substr($class, 0, $pos);
73 10
		}
74
75 10
		if(array_key_exists($class, $mappings)) {
76 10
			$spec['type'] = $mappings[$class];
77 10
			if($spec['type'] === 'date') {
78 10
				$spec['format'] = SearchableHelper::getFormatForDate($class);
79 10
			}
80
81 10
			if($class === 'HTMLText' || $class === 'HTMLVarchar') {
82 10
				array_push($html_fields, $name);
83 10
			}
84 10
		}
85 10
	}
86
87
88 10
	public static function getFormatForDate($class) {
89 10
		$format = 'y-M-d'; // default
90
		switch ($class) {
91 10
			case 'Date':
92 10
				$format = 'y-M-d';
93 10
				break;
94 10
			case 'SS_Datetime':
95 10
				$format = 'y-M-d H:m:s';
96 10
				break;
97 10
			case 'Datetime':
98 10
				$format = 'y-M-d H:m:s';
99 10
				break;
100 10
			case 'Time':
101 10
				$format = 'H:m:s';
102 10
				break;
103
		}
104
105 10
		return $format;
106
	}
107
108
109
110 10
	public static function getListRelationshipMethods($instance) {
111 10
		$has_manys = $instance->has_many();
112 10
		$many_manys = $instance->many_many();
113
114
		// array of method name to retuned object ClassName for relationships returning lists
115 10
		$has_lists = $has_manys;
116 10
		foreach(array_keys($many_manys) as $key) {
117 10
			$has_lists[$key] = $many_manys[$key];
118 10
		}
119
120 10
		return $has_lists;
121
	}
122
123
124 10
	public static function isInSiteTree($classname) {
125 10
		$inSiteTree = ($classname === 'SiteTree' ? true : false);
126 10
		if(!$inSiteTree) {
127 10
			$class = new \ReflectionClass($classname);
128 10
			while($class = $class->getParentClass()) {
129 10
				$parentClass = $class->getName();
130 10
				if($parentClass == 'SiteTree') {
131 10
					$inSiteTree = true;
132 10
					break;
133
				}
134 10
			}
135 10
		}
136 10
		return $inSiteTree;
137
	}
138
139
140 10
	public static function storeMethodTextValue($instance, $field, &$fields, $html_fields) {
0 ignored issues
show
Coding Style Naming introduced by
The parameter $html_fields is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
141 10
		if(in_array($field, $html_fields)) {
142
			// Parse short codes in HTML, and then convert to text
143 10
			$fields[$field] = $instance->$field;
144 10
			$html = \ShortcodeParser::get_active()->parse($instance->$field());
145 10
			$txt = \Convert::html2raw($html);
146 10
			$fields[$field] = $txt;
147 10
		} else {
148
			// Plain text
149 10
			$fields[$field] = $instance->$field();
150
		}
151 10
	}
152
153
154 10
	public static function storeFieldHTMLValue($instance, $field, &$fields) {
155 10
		$fields[$field] = $instance->$field;
156 10
		if(gettype($instance->$field) !== 'NULL') {
157 10
			$html = \ShortcodeParser::get_active()->parse($instance->$field);
158 10
			$txt = \Convert::html2raw($html);
159 10
			$fields[$field] = $txt;
160 10
		}
161 10
	}
162
163
164 10
	public static function storeRelationshipValue($instance, $field, &$fields, $config, $recurse) {
165 10
		if(isset($config['properties']['__method'])) {
166 10
			$methodName = $config['properties']['__method'];
167 10
			$data = $instance->$methodName();
168 10
			$relArray = array();
169
170 10
			$has_ones = $instance->has_one();
171
			// get the fields of a has_one relational object
172 10
			if(isset($has_ones[$methodName])) {
173 10
				if($data->ID > 0) {
174
					$item = $data->getFieldValuesAsArray(false);
175
					$relArray = $item;
176
				}
177
178
			// get the fields for a has_many or many_many relational list
179 10
			} else {
180 10
				foreach($data->getIterator() as $item) {
181
					if($recurse) {
182
						// populate the subitem but do not recurse any further if more relationships
183
						$itemDoc = $item->getFieldValuesAsArray(false);
184
						array_push($relArray, $itemDoc);
185
					}
186 10
				}
187
			}
188
			// save the relation as an array (for now)
189 10
			$fields[$methodName] = $relArray;
190 10
		} else {
191 10
			$fields[$field] = $instance->$field;
192
		}
193 10
	}
194
195
196 10
	public static function findOrCreateSearchableClass($classname) {
197 10
		$doSC = \SearchableClass::get()->filter(array('Name' => $classname))->first();
198 10
		if(!$doSC) {
199 10
			$doSC = new \SearchableClass();
200 10
			$doSC->Name = $classname;
201 10
			$inSiteTree = SearchableHelper::isInSiteTree($classname);
202 10
			$doSC->InSiteTree = $inSiteTree;
203 10
			$doSC->write();
204 10
		}
205 10
		return $doSC;
206
	}
207
208
209 10
	public static function findOrCreateSearchableField($className, $fieldName, $searchableField, $searchableClass) {
210 10
		$filter = array('ClazzName' => $className, 'Name' => $fieldName);
211 10
		$doSF = \SearchableField::get()->filter($filter)->first();
212
213
214 10
		if(!$doSF) {
215 10
			$doSF = new \SearchableField();
216 10
			$doSF->ClazzName = $className;
217 10
			$doSF->Name = $fieldName;
218
219 10
			if(isset($searchableField['type'])) {
220 10
				$doSF->Type = $searchableField['type'];
221 10
			} else {
222 10
				$doSF->Name = $searchableField['properties']['__method'];
223 10
				$doSF->Type = 'relationship';
224
			}
225 10
			$doSF->SearchableClassID = $searchableClass->ID;
226
227 10
			if(isset($searchableField['fields']['autocomplete'])) {
228 10
				$doSF->Autocomplete = true;
229 10
			}
230
231 10
			$doSF->write();
232 10
			\DB::alteration_message("Created new searchable editable field " . $fieldName, "changed");
233 10
		}
234 10
	}
235
236
237
	/*
238
	Evaluate each field, e.g. 'Title', 'Member.Name'
239
	 */
240 10
	public static function fieldsToElasticaConfig($fields) {
241
		// Copied from DataObject::searchableFields() as there is no separate accessible method
242 10
		$rewrite = array();
243 10
		foreach($fields as $name => $specOrName) {
244 10
			$identifer = (is_int($name)) ? $specOrName : $name;
245 10
			$rewrite[$identifer] = array();
246 10
			if(!isset($rewrite[$identifer]['title'])) {
247 10
				$rewrite[$identifer]['title'] = (isset($labels[$identifer]))
248 10
					? $labels[$identifer] : \FormField::name_to_label($identifer);
249 10
			}
250 10
			if(!isset($rewrite[$identifer]['filter'])) {
251 10
				$rewrite[$identifer]['filter'] = 'PartialMatchFilter';
252 10
			}
253 10
		}
254
255 10
		return $rewrite;
256
	}
257
258
259
260
}
261