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 | 4 | public static function addIndexedFields($name, &$spec, $ownerClassName) { |
|
| 42 | |||
| 43 | |||
| 44 | /** |
||
| 45 | * @param string &$name |
||
| 46 | * @param boolean $storeMethodName |
||
| 47 | * @param boolean $recurse |
||
| 48 | */ |
||
| 49 | 4 | public static function assignSpecForRelationship(&$name, $resultType, &$spec, $storeMethodName, $recurse) { |
|
| 50 | 4 | $resultTypeInstance = \Injector::inst()->create($resultType); |
|
| 51 | 4 | $resultTypeMapping = array(); |
|
| 52 | // get the fields for the result type, but do not recurse |
||
| 53 | 4 | if($recurse) { |
|
| 54 | 4 | $resultTypeMapping = $resultTypeInstance->getElasticaFields($storeMethodName, false); |
|
| 55 | 4 | } |
|
| 56 | 4 | $resultTypeMapping['ID'] = array('type' => 'integer'); |
|
| 57 | 4 | if($storeMethodName) { |
|
| 58 | $resultTypeMapping['__method'] = $name; |
||
| 59 | } |
||
| 60 | 4 | $spec = array('properties' => $resultTypeMapping); |
|
| 61 | // we now change the name to the result type, not the method name |
||
| 62 | 4 | $name = $resultType; |
|
| 63 | 4 | } |
|
| 64 | |||
| 65 | |||
| 66 | /** |
||
| 67 | * @param string $name |
||
| 68 | */ |
||
| 69 | 4 | public static function assignSpecForStandardFieldType($name, $class, &$spec, &$html_fields, &$mappings) { |
|
| 86 | |||
| 87 | |||
| 88 | 4 | public static function getFormatForDate($class) { |
|
| 107 | |||
| 108 | |||
| 109 | |||
| 110 | 4 | public static function getListRelationshipMethods($instance) { |
|
| 122 | |||
| 123 | |||
| 124 | 1 | public static function isInSiteTree($classname) { |
|
| 138 | |||
| 139 | |||
| 140 | public static function storeMethodTextValue($instance, $field, &$fields, $html_fields) { |
||
| 141 | if(in_array($field, $html_fields)) { |
||
| 142 | // Parse short codes in HTML, and then convert to text |
||
| 143 | $fields[$field] = $instance->$field; |
||
| 144 | $html = \ShortcodeParser::get_active()->parse($instance->$field()); |
||
| 145 | $txt = \Convert::html2raw($html); |
||
| 146 | $fields[$field] = $txt; |
||
| 147 | } else { |
||
| 148 | // Plain text |
||
| 149 | $fields[$field] = $instance->$field(); |
||
| 150 | } |
||
| 151 | } |
||
| 152 | |||
| 153 | |||
| 154 | public static function storeFieldHTMLValue($instance, $field, &$fields) { |
||
| 155 | $fields[$field] = $instance->$field; |
||
| 156 | if(gettype($instance->$field) !== 'NULL') { |
||
| 157 | $html = \ShortcodeParser::get_active()->parse($instance->$field); |
||
| 158 | $txt = \Convert::html2raw($html); |
||
| 159 | $fields[$field] = $txt; |
||
| 160 | } |
||
| 161 | } |
||
| 162 | |||
| 163 | |||
| 164 | public static function storeRelationshipValue($instance, $field, &$fields, $config, $recurse) { |
||
| 165 | if(isset($config['properties']['__method'])) { |
||
| 166 | $methodName = $config['properties']['__method']; |
||
| 167 | $data = $instance->$methodName(); |
||
| 168 | $relArray = array(); |
||
| 169 | |||
| 170 | $has_ones = $instance->has_one(); |
||
| 171 | // get the fields of a has_one relational object |
||
| 172 | if(isset($has_ones[$methodName])) { |
||
| 173 | 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 | } else { |
||
| 180 | 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 | } |
||
| 187 | } |
||
| 188 | // save the relation as an array (for now) |
||
| 189 | $fields[$methodName] = $relArray; |
||
| 190 | } else { |
||
| 191 | $fields[$field] = $instance->$field; |
||
| 192 | } |
||
| 193 | } |
||
| 194 | |||
| 195 | |||
| 196 | public static function findOrCreateSearchableClass($classname) { |
||
| 197 | $doSC = \SearchableClass::get()->filter(array('Name' => $classname))->first(); |
||
| 198 | if(!$doSC) { |
||
| 199 | $doSC = new \SearchableClass(); |
||
| 200 | $doSC->Name = $classname; |
||
| 201 | $inSiteTree = SearchableHelper::isInSiteTree($classname); |
||
|
1 ignored issue
–
show
|
|||
| 202 | $doSC->InSiteTree = $inSiteTree; |
||
| 203 | $doSC->write(); |
||
| 204 | } |
||
| 205 | return $doSC; |
||
| 206 | } |
||
| 207 | |||
| 208 | |||
| 209 | public static function findOrCreateSearchableField($className, $fieldName, $searchableField, $searchableClass) { |
||
| 210 | $filter = array('ClazzName' => $className, 'Name' => $fieldName); |
||
| 211 | $doSF = \SearchableField::get()->filter($filter)->first(); |
||
| 212 | |||
| 213 | |||
| 214 | if(!$doSF) { |
||
| 215 | $doSF = new \SearchableField(); |
||
| 216 | $doSF->ClazzName = $className; |
||
| 217 | $doSF->Name = $fieldName; |
||
| 218 | |||
| 219 | if(isset($searchableField['type'])) { |
||
| 220 | $doSF->Type = $searchableField['type']; |
||
| 221 | } else { |
||
| 222 | $doSF->Name = $searchableField['properties']['__method']; |
||
| 223 | $doSF->Type = 'relationship'; |
||
| 224 | } |
||
| 225 | $doSF->SearchableClassID = $searchableClass->ID; |
||
| 226 | |||
| 227 | if(isset($searchableField['fields']['autocomplete'])) { |
||
| 228 | $doSF->Autocomplete = true; |
||
| 229 | } |
||
| 230 | |||
| 231 | $doSF->write(); |
||
| 232 | \DB::alteration_message("Created new searchable editable field " . $fieldName, "changed"); |
||
| 233 | } |
||
| 234 | } |
||
| 235 | |||
| 236 | |||
| 237 | /* |
||
| 238 | Evaluate each field, e.g. 'Title', 'Member.Name' |
||
| 239 | */ |
||
| 240 | 4 | 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.