Complex classes like SearchableHelper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use SearchableHelper, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
4 | class SearchableHelper { |
||
5 | |||
6 | |||
7 | 10 | public static function addIndexedFields($name, &$spec, $ownerClassName) { |
|
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) { |
|
64 | |||
65 | |||
66 | /** |
||
67 | * @param string $name |
||
68 | */ |
||
69 | 10 | public static function assignSpecForStandardFieldType($name, $class, &$spec, &$html_fields, &$mappings) { |
|
86 | |||
87 | |||
88 | 10 | public static function getFormatForDate($class) { |
|
107 | |||
108 | |||
109 | |||
110 | 10 | public static function getListRelationshipMethods($instance) { |
|
122 | |||
123 | |||
124 | 10 | public static function isInSiteTree($classname) { |
|
138 | |||
139 | |||
140 | 10 | public static function storeMethodTextValue($instance, $field, &$fields, $html_fields) { |
|
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) { |
|
257 | |||
258 | |||
259 | |||
260 | } |
||
261 |
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
.