Complex classes like FrmFormMigrator 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 FrmFormMigrator, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 3 | abstract class FrmFormMigrator { |
||
| 4 | |||
| 5 | public $source_active; |
||
| 6 | |||
| 7 | public $slug; |
||
| 8 | public $path; |
||
| 9 | public $name; |
||
| 10 | |||
| 11 | public $response = array(); |
||
| 12 | public $tracking = 'frm_forms_imported'; |
||
| 13 | |||
| 14 | protected $fields_map = array(); |
||
| 15 | protected $current_source_form = null; |
||
| 16 | protected $current_section = array(); |
||
| 17 | |||
| 18 | /** |
||
| 19 | * Define required properties. |
||
| 20 | */ |
||
| 21 | public function __construct() { |
||
| 43 | |||
| 44 | private function maybe_add_to_import_page() { |
||
| 48 | |||
| 49 | public function import_page() { |
||
| 109 | |||
| 110 | /** |
||
| 111 | * Import all forms using ajax |
||
| 112 | */ |
||
| 113 | public function import_forms() { |
||
| 137 | |||
| 138 | /** |
||
| 139 | * Import a single form |
||
| 140 | */ |
||
| 141 | protected function import_form( $source_id ) { |
||
| 174 | |||
| 175 | protected function prepare_new_form( $source_id, $source_form_name ) { |
||
| 185 | |||
| 186 | protected function prepare_form( $form, &$new_form ) { |
||
| 189 | |||
| 190 | protected function prepare_fields( $fields, &$form ) { |
||
| 191 | $field_order = 1; |
||
| 192 | |||
| 193 | foreach ( $fields as $field ) { |
||
| 194 | $field = (array) $field; |
||
| 195 | |||
| 196 | $label = $this->get_field_label( $field ); |
||
| 197 | $type = $this->get_field_type( $field ); |
||
| 198 | |||
| 199 | // check if field is unsupported. If unsupported make note and continue |
||
| 200 | if ( $this->is_unsupported_field( $type ) ) { |
||
| 201 | $this->response['unsupported'][] = $label; |
||
| 202 | continue; |
||
| 203 | } |
||
| 204 | |||
| 205 | if ( $this->should_skip_field( $type ) ) { |
||
| 206 | $this->response['upgrade_omit'][] = $label; |
||
| 207 | continue; |
||
| 208 | } |
||
| 209 | |||
| 210 | $new_type = $this->convert_field_type( $type, $field ); |
||
| 211 | |||
| 212 | $new_field = FrmFieldsHelper::setup_new_vars( $new_type ); |
||
| 213 | $new_field['name'] = $label; |
||
| 214 | $new_field['field_order'] = $field_order; |
||
| 215 | $new_field['original'] = $type; |
||
| 216 | |||
| 217 | $this->prepare_field( $field, $new_field ); |
||
| 218 | |||
| 219 | $in_section = ! empty( $this->current_section ) && ! in_array( $new_type, $this->fields_with_end() ) && $new_type !== 'break'; |
||
| 220 | if ( $in_section ) { |
||
| 221 | $new_field['field_options']['in_section'] = $this->current_section['id']; |
||
| 222 | } |
||
| 223 | |||
| 224 | $form['fields'][] = $new_field; |
||
| 225 | |||
| 226 | if ( in_array( $new_type, $this->fields_with_end() ) ) { |
||
| 227 | $this->current_section = $field; |
||
| 228 | } elseif ( $new_type === 'break' || $new_type === 'end_divider' ) { |
||
| 229 | $this->current_section = array(); |
||
| 230 | } |
||
| 231 | |||
| 232 | // This may occassionally skip one level/order e.g. after adding a |
||
| 233 | // list field, as field_order would already be prepared to be used. |
||
| 234 | $field_order ++; |
||
| 235 | |||
| 236 | if ( isset( $new_field['fields'] ) && is_array( $new_field['fields'] ) && ! empty( $new_field['fields'] ) ) { |
||
| 237 | // we have (inner) fields to merge |
||
| 238 | |||
| 239 | $form['fields'] = array_merge( $form['fields'], $new_field['fields'] ); |
||
| 240 | // set the new field_order as it would have changed |
||
| 241 | $field_order = $new_field['current_order']; |
||
| 242 | } |
||
| 243 | } |
||
| 244 | } |
||
| 245 | |||
| 246 | protected function prepare_field( $field, &$new_field ) { |
||
| 247 | // customize this function |
||
| 248 | } |
||
| 249 | |||
| 250 | /** |
||
| 251 | * Add any field types that will need an end section field. |
||
| 252 | * |
||
| 253 | * @since 4.04.03 |
||
| 254 | */ |
||
| 255 | protected function fields_with_end() { |
||
| 258 | |||
| 259 | /** |
||
| 260 | * @since 4.04.03 |
||
| 261 | */ |
||
| 262 | protected function maybe_add_end_fields( &$fields ) { |
||
| 293 | |||
| 294 | /** |
||
| 295 | * @since 4.04.03 |
||
| 296 | */ |
||
| 297 | protected function insert_end_section( &$fields, &$order ) { |
||
| 304 | |||
| 305 | /** |
||
| 306 | * Replace the original combo field with a group. |
||
| 307 | * This switches the name field to individual fields. |
||
| 308 | * |
||
| 309 | * @since 4.04.03 |
||
| 310 | */ |
||
| 311 | protected function insert_fields_in_array( $subs, $start, $remove, &$fields ) { |
||
| 314 | |||
| 315 | /** |
||
| 316 | * @param string $type |
||
| 317 | * @param array $field |
||
| 318 | * @param string $use Which field type to prefer to consider $field as. |
||
| 319 | * This also eases the recursive use of the method, |
||
| 320 | * particularly the overrides in child classes, as |
||
| 321 | * there will be no need to rebuild the converter |
||
| 322 | * array at usage locations. |
||
| 323 | */ |
||
| 324 | protected function convert_field_type( $type, $field = array(), $use = '' ) { |
||
| 332 | |||
| 333 | /** |
||
| 334 | * Add the new form to the database and return AJAX data.å |
||
| 335 | * |
||
| 336 | * @param array $form Form to import. |
||
| 337 | * @param array $upgrade_omit No field alternative |
||
| 338 | */ |
||
| 339 | protected function add_form( $form, $upgrade_omit = array() ) { |
||
| 362 | |||
| 363 | /** |
||
| 364 | * @since 4.04.03 |
||
| 365 | * |
||
| 366 | * @param array $form parameters for the new form to be created. Only |
||
| 367 | * the name key is a must. The keys are the column |
||
| 368 | * names of the forms table in the DB. |
||
| 369 | * |
||
| 370 | * @return int The ID of the newly created form. |
||
| 371 | */ |
||
| 372 | protected function create_form( $form ) { |
||
| 378 | |||
| 379 | /** |
||
| 380 | * @since 4.04.03 |
||
| 381 | */ |
||
| 382 | protected function form_creation_error_response( $form ) { |
||
| 389 | |||
| 390 | /** |
||
| 391 | * @since 4.04.03 |
||
| 392 | * |
||
| 393 | * @param int $form_id |
||
| 394 | * @param array $form |
||
| 395 | */ |
||
| 396 | protected function create_fields( $form_id, &$form ) { |
||
| 402 | |||
| 403 | /** |
||
| 404 | * @since 4.04.03 |
||
| 405 | * |
||
| 406 | * @param array $form |
||
| 407 | */ |
||
| 408 | protected function create_emails( $form, $form_id ) { |
||
| 413 | |||
| 414 | /** |
||
| 415 | * @since 4.04.03 |
||
| 416 | * |
||
| 417 | * @param array $form |
||
| 418 | */ |
||
| 419 | protected function save_action( $action, $form, $form_id ) { |
||
| 437 | |||
| 438 | /** |
||
| 439 | * After a form has been successfully imported we track it, so that in the |
||
| 440 | * future we can alert users if they try to import a form that has already |
||
| 441 | * been imported. |
||
| 442 | * |
||
| 443 | * @param int $source_id Imported plugin form ID |
||
| 444 | * @param int $new_form_id Formidable form ID |
||
| 445 | */ |
||
| 446 | protected function track_import( $source_id, $new_form_id ) { |
||
| 454 | |||
| 455 | /** |
||
| 456 | * @return array |
||
| 457 | */ |
||
| 458 | private function get_tracked_import() { |
||
| 461 | |||
| 462 | /** |
||
| 463 | * @param int $source_id Imported plugin form ID |
||
| 464 | * |
||
| 465 | * @return int the ID of the created form or 0 |
||
| 466 | */ |
||
| 467 | private function is_imported( $source_id ) { |
||
| 482 | |||
| 483 | /** Start functions here that should be overridden **/ |
||
| 484 | |||
| 485 | /** |
||
| 486 | * @return array |
||
| 487 | */ |
||
| 488 | protected function unsupported_field_types() { |
||
| 491 | |||
| 492 | private function is_unsupported_field( $type ) { |
||
| 497 | |||
| 498 | /** |
||
| 499 | * Strict PRO fields with no Lite alternatives. |
||
| 500 | * |
||
| 501 | * @return array |
||
| 502 | */ |
||
| 503 | protected function skip_pro_fields() { |
||
| 506 | |||
| 507 | protected function should_skip_field( $type ) { |
||
| 512 | |||
| 513 | /** |
||
| 514 | * Replace 3rd-party form provider tags/shortcodes with our own Tags. |
||
| 515 | * |
||
| 516 | * @param string $string String to process the smart tag in. |
||
| 517 | * @param array $fields List of fields for the form. |
||
| 518 | * |
||
| 519 | * @return string |
||
| 520 | */ |
||
| 521 | protected function replace_smart_tags( $string, $fields ) { |
||
| 524 | |||
| 525 | /** |
||
| 526 | * Get ALL THE FORMS. |
||
| 527 | * |
||
| 528 | * @return array |
||
| 529 | */ |
||
| 530 | public function get_forms() { |
||
| 533 | |||
| 534 | public function get_form( $id ) { |
||
| 537 | |||
| 538 | /** |
||
| 539 | * @param object|array $source_form |
||
| 540 | * |
||
| 541 | * @return string |
||
| 542 | */ |
||
| 543 | protected function get_form_name( $source_form ) { |
||
| 546 | |||
| 547 | /** |
||
| 548 | * @param object|array $source_form |
||
| 549 | * |
||
| 550 | * @return array |
||
| 551 | */ |
||
| 552 | protected function get_form_fields( $source_form ) { |
||
| 555 | |||
| 556 | /** |
||
| 557 | * @param array $field |
||
| 558 | * |
||
| 559 | * @return string |
||
| 560 | */ |
||
| 561 | protected function get_field_type( $field ) { |
||
| 564 | |||
| 565 | /** |
||
| 566 | * @param array $field |
||
| 567 | * |
||
| 568 | * @return string |
||
| 569 | */ |
||
| 570 | protected function get_field_label( $field ) { |
||
| 585 | } |
||
| 586 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.