Total Complexity | 70 |
Total Lines | 627 |
Duplicated Lines | 0 % |
Changes | 1 | ||
Bugs | 0 | Features | 0 |
Complex classes like SmfCommonSourceStep2 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.
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 SmfCommonSourceStep2, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
534 | abstract class SmfCommonSourceStep2 extends Step2BaseImporter |
||
535 | { |
||
536 | abstract public function substep0(); |
||
537 | |||
538 | public function substep1() |
||
539 | { |
||
540 | $to_prefix = $this->config->to_prefix; |
||
541 | |||
542 | $request = $this->db->query(" |
||
543 | SELECT |
||
544 | id_board, MAX(id_msg) AS id_last_msg, MAX(modified_time) AS last_edited |
||
545 | FROM {$to_prefix}messages |
||
546 | GROUP BY id_board"); |
||
547 | $modifyData = array(); |
||
548 | $modifyMsg = array(); |
||
549 | while ($row = $this->db->fetch_assoc($request)) |
||
550 | { |
||
551 | $this->setBoardProperty($row['id_board'], array('id_last_msg' => $row['id_last_msg'], 'id_msg_updated' => $row['id_last_msg'])); |
||
552 | |||
553 | $modifyData[$row['id_board']] = array( |
||
554 | 'last_msg' => $row['id_last_msg'], |
||
555 | 'last_edited' => $row['last_edited'], |
||
556 | ); |
||
557 | $modifyMsg[] = $row['id_last_msg']; |
||
558 | } |
||
559 | $this->db->free_result($request); |
||
560 | |||
561 | // Are there any boards where the updated message is not the last? |
||
562 | if (!empty($modifyMsg)) |
||
563 | { |
||
564 | $request = $this->db->query(" |
||
565 | SELECT id_board, id_msg, modified_time, poster_time |
||
566 | FROM {$to_prefix}messages |
||
567 | WHERE id_msg IN (" . implode(',', $modifyMsg) . ")"); |
||
568 | while ($row = $this->db->fetch_assoc($request)) |
||
569 | { |
||
570 | // Have we got a message modified before this was posted? |
||
571 | if (max($row['modified_time'], $row['poster_time']) < $modifyData[$row['id_board']]['last_edited']) |
||
572 | { |
||
573 | // Work out the ID of the message (This seems long but it won't happen much. |
||
574 | $request2 = $this->db->query(" |
||
575 | SELECT id_msg |
||
576 | FROM {$to_prefix}messages |
||
577 | WHERE modified_time = " . $modifyData[$row['id_board']]['last_edited'] . " |
||
578 | LIMIT 1"); |
||
579 | if ($this->db->num_rows($request2) != 0) |
||
580 | { |
||
581 | list ($id_msg) = $this->db->fetch_row($request2); |
||
582 | |||
583 | $this->setBoardProperty($row['id_board'], array('id_msg_updated' => $id_msg)); |
||
584 | } |
||
585 | $this->db->free_result($request2); |
||
586 | } |
||
587 | } |
||
588 | $this->db->free_result($request); |
||
589 | } |
||
590 | } |
||
591 | |||
592 | protected function setBoardProperty($board, $property, $where = null) |
||
593 | { |
||
594 | $to_prefix = $this->config->to_prefix; |
||
595 | |||
596 | $sets = array(); |
||
597 | foreach ($property as $k => $v) |
||
598 | { |
||
599 | $sets[] = $k . ' = ' . $v; |
||
600 | } |
||
601 | $set = implode(', ', $sets); |
||
602 | |||
603 | if ($where === null) |
||
604 | { |
||
605 | if (empty($board)) |
||
606 | { |
||
607 | return; |
||
608 | } |
||
609 | |||
610 | $where = "id_board = $board"; |
||
611 | } |
||
612 | |||
613 | $this->db->query(" |
||
614 | UPDATE {$to_prefix}boards |
||
615 | SET $set |
||
616 | WHERE $where"); |
||
617 | } |
||
618 | |||
619 | public function substep2() |
||
620 | { |
||
621 | $to_prefix = $this->config->to_prefix; |
||
622 | |||
623 | $request = $this->db->query(" |
||
624 | SELECT |
||
625 | id_group |
||
626 | FROM {$to_prefix}membergroups |
||
627 | WHERE min_posts = -1"); |
||
628 | |||
629 | $all_groups = array(); |
||
630 | while ($row = $this->db->fetch_assoc($request)) |
||
631 | { |
||
632 | $all_groups[] = $row['id_group']; |
||
633 | } |
||
634 | $this->db->free_result($request); |
||
635 | |||
636 | $request = $this->db->query(" |
||
637 | SELECT |
||
638 | id_board, member_groups |
||
639 | FROM {$to_prefix}boards |
||
640 | WHERE FIND_IN_SET(0, member_groups)"); |
||
641 | |||
642 | while ($row = $this->db->fetch_assoc($request)) |
||
643 | { |
||
644 | $member_groups = "'" . implode(',', array_unique(array_merge($all_groups, explode(',', $row['member_groups'])))) . "'"; |
||
645 | $this->setBoardProperty($row['id_board'], array('member_groups' => $member_groups)); |
||
646 | } |
||
647 | $this->db->free_result($request); |
||
648 | } |
||
649 | |||
650 | /** |
||
651 | * Fix various system totals |
||
652 | */ |
||
653 | public function substep3() |
||
654 | { |
||
655 | $to_prefix = $this->config->to_prefix; |
||
656 | |||
657 | // Get the number of messages... |
||
658 | $result = $this->db->query(" |
||
659 | SELECT |
||
660 | COUNT(*) AS totalMessages, MAX(id_msg) AS maxMsgID |
||
661 | FROM {$to_prefix}messages"); |
||
662 | $row = $this->db->fetch_assoc($result); |
||
663 | $this->db->free_result($result); |
||
664 | |||
665 | // Update the latest member. (Highest ID_MEMBER) |
||
666 | $result = $this->db->query(" |
||
667 | SELECT |
||
668 | id_member AS latestMember, real_name AS latestreal_name |
||
669 | FROM {$to_prefix}members |
||
670 | ORDER BY id_member DESC |
||
671 | LIMIT 1"); |
||
672 | |||
673 | if ($this->db->num_rows($result)) |
||
674 | { |
||
675 | $row += $this->db->fetch_assoc($result); |
||
676 | } |
||
677 | else |
||
678 | { |
||
679 | $row += array('latestMember' => '', 'latestreal_name' => ''); |
||
680 | } |
||
681 | |||
682 | $this->db->free_result($result); |
||
683 | |||
684 | // Update the member count. |
||
685 | $result = $this->db->query(" |
||
686 | SELECT |
||
687 | COUNT(*) AS totalMembers |
||
688 | FROM {$to_prefix}members"); |
||
689 | $row += $this->db->fetch_assoc($result); |
||
690 | $this->db->free_result($result); |
||
691 | |||
692 | // Get the number of topics. |
||
693 | $result = $this->db->query(" |
||
694 | SELECT |
||
695 | COUNT(*) AS totalTopics |
||
696 | FROM {$to_prefix}topics"); |
||
697 | $row += $this->db->fetch_assoc($result); |
||
698 | $this->db->free_result($result); |
||
699 | |||
700 | $this->db->query(" |
||
701 | REPLACE INTO {$to_prefix}settings |
||
702 | (variable, value) |
||
703 | VALUES ('latestMember', '$row[latestMember]'), |
||
704 | ('latestreal_name', '$row[latestreal_name]'), |
||
705 | ('totalMembers', '$row[totalMembers]'), |
||
706 | ('totalMessages', '$row[totalMessages]'), |
||
707 | ('maxMsgID', '$row[maxMsgID]'), |
||
708 | ('totalTopics', '$row[totalTopics]'), |
||
709 | ('disableHashTime', " . (time() + 7776000) . ")"); |
||
710 | } |
||
711 | |||
712 | /** |
||
713 | * Fix the post-based membergroups |
||
714 | */ |
||
715 | public function substep4() |
||
716 | { |
||
717 | $to_prefix = $this->config->to_prefix; |
||
718 | |||
719 | $request = $this->db->query(" |
||
720 | SELECT |
||
721 | id_group, min_posts |
||
722 | FROM {$to_prefix}membergroups |
||
723 | WHERE min_posts != -1 |
||
724 | ORDER BY min_posts DESC"); |
||
725 | |||
726 | $post_groups = array(); |
||
727 | $max = $this->db->fetch_assoc($request); |
||
728 | while ($row = $this->db->fetch_assoc($request)) |
||
729 | { |
||
730 | $post_groups[] = $row; |
||
731 | } |
||
732 | $this->db->free_result($request); |
||
733 | |||
734 | $case = "CASE WHEN posts > " . $max['min_posts'] . " THEN " . $max['id_group']; |
||
735 | |||
736 | $first = true; |
||
737 | foreach ($post_groups as $id => $group) |
||
738 | { |
||
739 | if ($first) |
||
740 | { |
||
741 | $case .= " WHEN posts BETWEEN " . $group['min_posts'] . " AND " . $max['min_posts'] . " THEN " . $group['id_group']; |
||
742 | $first = false; |
||
743 | } |
||
744 | else |
||
745 | { |
||
746 | $case .= " WHEN posts BETWEEN " . $group['min_posts'] . " AND " . $post_groups[$id - 1]['min_posts'] . " THEN " . $group['id_group']; |
||
747 | } |
||
748 | } |
||
749 | $case .= " ELSE 4 END"; |
||
750 | |||
751 | $this->db->query(" |
||
752 | UPDATE {$to_prefix}members |
||
753 | SET id_post_group = $case"); |
||
754 | } |
||
755 | |||
756 | /** |
||
757 | * Fix the boards total posts and topics. |
||
758 | */ |
||
759 | public function substep5() |
||
795 | } |
||
796 | } |
||
797 | |||
798 | public function substep6() |
||
799 | { |
||
800 | $to_prefix = $this->config->to_prefix; |
||
801 | |||
802 | while (true) |
||
803 | { |
||
804 | $resultTopic = $this->db->query(" |
||
805 | SELECT |
||
806 | t.id_topic, COUNT(m.id_msg) AS num_msg |
||
807 | FROM {$to_prefix}topics AS t |
||
808 | LEFT JOIN {$to_prefix}messages AS m ON (m.id_topic = t.id_topic) |
||
809 | GROUP BY t.id_topic |
||
810 | HAVING num_msg = 0 |
||
811 | LIMIT $_REQUEST[start], 200"); |
||
812 | |||
813 | $numRows = $this->db->num_rows($resultTopic); |
||
814 | |||
815 | if ($numRows > 0) |
||
816 | { |
||
817 | $stupidTopics = array(); |
||
818 | while ($topicArray = $this->db->fetch_assoc($resultTopic)) |
||
819 | { |
||
820 | $stupidTopics[] = $topicArray['id_topic']; |
||
821 | } |
||
822 | $this->db->query(" |
||
823 | DELETE FROM {$to_prefix}topics |
||
824 | WHERE id_topic IN (" . implode(',', $stupidTopics) . ') |
||
825 | LIMIT ' . count($stupidTopics)); |
||
826 | $this->db->query(" |
||
827 | DELETE FROM {$to_prefix}log_topics |
||
828 | WHERE id_topic IN (" . implode(',', $stupidTopics) . ')'); |
||
829 | } |
||
830 | $this->db->free_result($resultTopic); |
||
831 | |||
832 | if ($numRows < 200) |
||
833 | { |
||
834 | break; |
||
835 | } |
||
836 | |||
837 | // @todo this should not deal with $_REQUEST and alike |
||
838 | $_REQUEST['start'] += 200; |
||
839 | pastTime(6); |
||
840 | } |
||
841 | } |
||
842 | |||
843 | public function substep7() |
||
844 | { |
||
845 | $to_prefix = $this->config->to_prefix; |
||
846 | |||
847 | while (true) |
||
848 | { |
||
849 | $resultTopic = $this->db->query(" |
||
850 | SELECT |
||
851 | t.id_topic, MIN(m.id_msg) AS myid_first_msg, t.id_first_msg, |
||
852 | MAX(m.id_msg) AS myid_last_msg, t.id_last_msg, COUNT(m.id_msg) - 1 AS my_num_replies, |
||
853 | t.num_replies |
||
854 | FROM {$to_prefix}topics AS t |
||
855 | LEFT JOIN {$to_prefix}messages AS m ON (m.id_topic = t.id_topic) |
||
856 | GROUP BY t.id_topic |
||
857 | HAVING id_first_msg != myid_first_msg OR id_last_msg != myid_last_msg OR num_replies != my_num_replies |
||
858 | LIMIT $_REQUEST[start], 200"); |
||
859 | |||
860 | $numRows = $this->db->num_rows($resultTopic); |
||
861 | |||
862 | while ($topicArray = $this->db->fetch_assoc($resultTopic)) |
||
863 | { |
||
864 | $memberStartedID = $this->getMsgMemberID($topicArray['myid_first_msg']); |
||
865 | $memberUpdatedID = $this->getMsgMemberID($topicArray['myid_last_msg']); |
||
866 | |||
867 | $this->db->query(" |
||
868 | UPDATE {$to_prefix}topics |
||
869 | SET id_first_msg = '$topicArray[myid_first_msg]', |
||
870 | id_member_started = '$memberStartedID', id_last_msg = '$topicArray[myid_last_msg]', |
||
871 | id_member_updated = '$memberUpdatedID', num_replies = '$topicArray[my_num_replies]' |
||
872 | WHERE id_topic = $topicArray[id_topic] |
||
873 | LIMIT 1"); |
||
874 | } |
||
875 | $this->db->free_result($resultTopic); |
||
876 | |||
877 | if ($numRows < 200) |
||
878 | { |
||
879 | break; |
||
880 | } |
||
881 | |||
882 | // @todo this should not deal with $_REQUEST and alike |
||
883 | $_REQUEST['start'] += 100; |
||
884 | pastTime(7); |
||
885 | } |
||
886 | } |
||
887 | |||
888 | /** |
||
889 | * |
||
890 | * Get the id_member associated with the specified message. |
||
891 | * |
||
892 | * @param int $messageID |
||
893 | * @return int |
||
894 | */ |
||
895 | protected function getMsgMemberID($messageID) |
||
921 | } |
||
922 | |||
923 | /** |
||
924 | * Fix the board parents. |
||
925 | */ |
||
926 | public function substep8() |
||
927 | { |
||
928 | $to_prefix = $this->config->to_prefix; |
||
929 | |||
930 | // First, let's get an array of boards and parents. |
||
931 | $request = $this->db->query(" |
||
932 | SELECT |
||
933 | id_board, id_parent, id_cat |
||
934 | FROM {$to_prefix}boards"); |
||
935 | |||
936 | $child_map = array(); |
||
937 | $cat_map = array(); |
||
938 | while ($row = $this->db->fetch_assoc($request)) |
||
939 | { |
||
940 | $child_map[$row['id_parent']][] = $row['id_board']; |
||
941 | $cat_map[$row['id_board']] = $row['id_cat']; |
||
942 | } |
||
943 | $this->db->free_result($request); |
||
944 | |||
945 | // Let's look for any boards with obviously invalid parents... |
||
946 | foreach ($child_map as $parent => $dummy) |
||
947 | { |
||
948 | if ($parent != 0 && !isset($cat_map[$parent])) |
||
949 | { |
||
950 | // Perhaps it was supposed to be their id_cat? |
||
951 | foreach ($dummy as $board) |
||
952 | { |
||
953 | if (empty($cat_map[$board])) |
||
954 | { |
||
955 | $cat_map[$board] = $parent; |
||
956 | } |
||
957 | } |
||
958 | |||
959 | $child_map[0] = array_merge(isset($child_map[0]) ? $child_map[0] : array(), $dummy); |
||
960 | unset($child_map[$parent]); |
||
961 | } |
||
962 | } |
||
963 | |||
964 | // The above id_parents and id_cats may all be wrong; we know id_parent = 0 is right. |
||
965 | $solid_parents = array(array(0, 0)); |
||
966 | $fixed_boards = array(); |
||
967 | while (!empty($solid_parents)) |
||
968 | { |
||
969 | list ($parent, $level) = array_pop($solid_parents); |
||
970 | if (!isset($child_map[$parent])) |
||
971 | { |
||
972 | continue; |
||
973 | } |
||
974 | |||
975 | // Fix all of this board's children. |
||
976 | foreach ($child_map[$parent] as $board) |
||
977 | { |
||
978 | if ($parent != 0) |
||
979 | { |
||
980 | $cat_map[$board] = $cat_map[$parent]; |
||
981 | } |
||
982 | |||
983 | $this->setBoardProperty((int) $board, array('id_parent' => (int) $parent, 'id_cat' => (int) $cat_map[$board], 'child_level' => (int) $level)); |
||
984 | |||
985 | $fixed_boards[] = $board; |
||
986 | $solid_parents[] = array($board, $level + 1); |
||
987 | } |
||
988 | } |
||
989 | |||
990 | // Leftovers should be brought to the root. They had weird parents we couldn't find. |
||
991 | if (count($fixed_boards) < count($cat_map)) |
||
992 | { |
||
993 | $this->setBoardProperty(0, array('child_level' => 0, 'id_parent' => 0, 'child_level' => (int) $level), empty($fixed_boards) ? "1=1" : "id_board NOT IN (" . implode(', ', $fixed_boards) . ")"); |
||
994 | } |
||
995 | |||
996 | $this->fixInexistentCategories($cat_map); |
||
997 | } |
||
998 | |||
999 | /** |
||
1000 | * Assigns any board belonging to a category that doesn't exist |
||
1001 | * to a newly created category. |
||
1002 | */ |
||
1003 | protected function fixInexistentCategories($cat_map) |
||
1004 | { |
||
1005 | $to_prefix = $this->config->to_prefix; |
||
1006 | |||
1007 | // Last check: any boards not in a good category? |
||
1008 | $request = $this->db->query(" |
||
1009 | SELECT |
||
1010 | id_cat |
||
1011 | FROM {$to_prefix}categories"); |
||
1012 | $real_cats = array(); |
||
1013 | while ($row = $this->db->fetch_assoc($request)) |
||
1014 | { |
||
1015 | $real_cats[] = $row['id_cat']; |
||
1016 | } |
||
1017 | $this->db->free_result($request); |
||
1018 | |||
1019 | $fix_cats = array(); |
||
1020 | foreach ($cat_map as $cat) |
||
1021 | { |
||
1022 | if (!in_array($cat, $real_cats)) |
||
1023 | { |
||
1024 | $fix_cats[] = $cat; |
||
1025 | } |
||
1026 | } |
||
1027 | |||
1028 | if (!empty($fix_cats)) |
||
1029 | { |
||
1030 | $this->db->query(" |
||
1031 | INSERT INTO {$to_prefix}categories |
||
1032 | (name) |
||
1033 | VALUES ('General Category')"); |
||
1034 | $catch_cat = mysqli_insert_id($this->db->con); |
||
1035 | |||
1036 | $this->setBoardProperty(0, array('id_cat' => (int) $catch_cat), "id_cat IN (" . implode(', ', array_unique($fix_cats)) . ")"); |
||
1037 | } |
||
1038 | } |
||
1039 | |||
1040 | /** |
||
1041 | * Adjust boards and categories orders. |
||
1042 | */ |
||
1043 | public function substep9() |
||
1044 | { |
||
1045 | $to_prefix = $this->config->to_prefix; |
||
1046 | |||
1047 | $request = $this->db->query(" |
||
1048 | SELECT |
||
1049 | c.id_cat, c.cat_order, b.id_board, b.board_order |
||
1050 | FROM {$to_prefix}categories AS c |
||
1051 | LEFT JOIN {$to_prefix}boards AS b ON (b.id_cat = c.id_cat) |
||
1052 | ORDER BY c.cat_order, b.child_level, b.board_order, b.id_board"); |
||
1053 | $cat_order = -1; |
||
1054 | $board_order = -1; |
||
1055 | $curCat = -1; |
||
1056 | while ($row = $this->db->fetch_assoc($request)) |
||
1057 | { |
||
1058 | if ($curCat != $row['id_cat']) |
||
1059 | { |
||
1060 | $curCat = $row['id_cat']; |
||
1061 | if (++$cat_order != $row['cat_order']) |
||
1062 | { |
||
1063 | $this->db->query(" |
||
1064 | UPDATE {$to_prefix}categories |
||
1065 | SET cat_order = $cat_order |
||
1066 | WHERE id_cat = $row[id_cat] |
||
1067 | LIMIT 1"); |
||
1068 | } |
||
1069 | } |
||
1070 | if (!empty($row['id_board']) && ++$board_order != $row['board_order']) |
||
1071 | { |
||
1072 | $this->setBoardProperty($row['id_board'], array('board_order' => $board_order)); |
||
1073 | } |
||
1074 | } |
||
1075 | $this->db->free_result($request); |
||
1076 | } |
||
1077 | |||
1078 | /** |
||
1079 | * Fix attachment size, W & H values |
||
1080 | */ |
||
1081 | public function substep11() |
||
1139 | } |
||
1140 | } |
||
1141 | |||
1142 | protected function avatarFullPath($row) |
||
1143 | { |
||
1161 | } |
||
1162 | } |
||
1163 | |||
1164 | /** |
||
1165 | * Class SmfCommonSourceStep3 |
||
1166 | * |
||
1167 | * @class SmfCommonSourceStep3 |
||
1183 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.