Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like FileController 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 FileController, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
35 | class FileController extends AbstractController |
||
|
|||
36 | { |
||
37 | const SJIS = 'sjis-win'; |
||
38 | const UTF = 'UTF-8'; |
||
39 | private $error = null; |
||
40 | private $encode = ''; |
||
41 | |||
42 | 6 | public function __construct(){ |
|
48 | |||
49 | 3 | public function index(Application $app, Request $request) |
|
50 | { |
||
51 | 3 | $form = $app['form.factory']->createBuilder('form') |
|
52 | 3 | ->add('file', 'file') |
|
53 | 3 | ->add('create_file', 'text') |
|
54 | 3 | ->getForm(); |
|
55 | |||
56 | // user_data_dir |
||
57 | 3 | $topDir = $this->normalizePath($app['config']['user_data_realdir']); |
|
58 | // user_data_dirの親ディレクトリ |
||
59 | 3 | $htmlDir = $this->normalizePath($topDir.'/../'); |
|
60 | // カレントディレクトリ |
||
61 | 3 | $nowDir = $this->checkDir($request->get('tree_select_file'), $topDir) |
|
62 | ? $this->normalizePath($request->get('tree_select_file')) |
||
63 | 3 | : $topDir; |
|
64 | // パンくず表示用データ |
||
65 | 3 | $nowDirList = json_encode(explode('/', trim(str_replace($htmlDir, '', $nowDir), '/'))); |
|
66 | |||
67 | 3 | $isTopDir = ($topDir === $nowDir); |
|
68 | 3 | $parentDir = substr($nowDir, 0, strrpos($nowDir, '/')); |
|
69 | |||
70 | 3 | if ('POST' === $request->getMethod()) { |
|
71 | 2 | switch ($request->get('mode')) { |
|
72 | 2 | case 'create': |
|
73 | 1 | $this->create($app, $request); |
|
74 | 1 | break; |
|
75 | 1 | case 'upload': |
|
76 | 1 | $this->upload($app, $request); |
|
77 | 1 | break; |
|
78 | default: |
||
79 | 2 | break; |
|
80 | } |
||
81 | } |
||
82 | |||
83 | 3 | $tree = $this->getTree($topDir, $request); |
|
84 | 3 | $arrFileList = $this->getFileList($app, $nowDir); |
|
85 | |||
86 | 3 | $javascript = $this->getJsArrayList($tree); |
|
87 | 3 | $onload = "eccube.fileManager.viewFileTree('tree', arrTree, '" . $nowDir . "', 'tree_select_file', 'tree_status', 'move');"; |
|
88 | |||
89 | 3 | return $app->render('Content/file.twig', array( |
|
90 | 3 | 'form' => $form->createView(), |
|
91 | 3 | 'tpl_onload' => $onload, |
|
92 | 3 | 'tpl_javascript' => $javascript, |
|
93 | 3 | 'top_dir' => $topDir, |
|
94 | 3 | 'tpl_is_top_dir' => $isTopDir, |
|
95 | 3 | 'tpl_now_dir' => $nowDir, |
|
96 | 3 | 'html_dir' => $htmlDir, |
|
97 | 3 | 'now_dir_list' => $nowDirList, |
|
98 | 3 | 'tpl_parent_dir' => $parentDir, |
|
99 | 3 | 'arrFileList' => $arrFileList, |
|
100 | 3 | 'error' => $this->error, |
|
101 | )); |
||
102 | } |
||
103 | |||
104 | 1 | public function view(Application $app, Request $request) |
|
105 | { |
||
106 | 1 | $topDir = $app['config']['user_data_realdir']; |
|
107 | 1 | if ($this->checkDir($this->convertStrToServer($request->get('file')), $topDir)) { |
|
108 | 1 | $file = $this->convertStrToServer($request->get('file')); |
|
109 | 1 | setlocale(LC_ALL, "ja_JP.UTF-8"); |
|
110 | 1 | return $app->sendFile($file); |
|
111 | } |
||
112 | |||
113 | throw new NotFoundHttpException(); |
||
114 | } |
||
115 | |||
116 | 1 | public function create(Application $app, Request $request) |
|
117 | { |
||
118 | |||
119 | 1 | $form = $app['form.factory']->createBuilder('form') |
|
120 | 1 | ->add('file', 'file') |
|
121 | 1 | ->add('create_file', 'text') |
|
122 | 1 | ->getForm(); |
|
123 | |||
124 | 1 | $form->handleRequest($request); |
|
125 | |||
126 | 1 | if ($form->isValid()) { |
|
127 | |||
128 | 1 | $fs = new Filesystem(); |
|
129 | 1 | $filename = $form->get('create_file')->getData(); |
|
130 | |||
131 | 1 | $pattern = "/[^[:alnum:]_.\\-]/"; |
|
132 | 1 | $pattern2 = "/^\.(.*)$/"; |
|
133 | 1 | if (empty($filename)) { |
|
134 | $this->error = array('message' => 'フォルダ作成名が入力されていません。'); |
||
135 | 1 | } elseif (strlen($filename) > 0 && preg_match($pattern, $filename)) { |
|
136 | $this->error = array('message' => 'フォルダ名には、英数字、記号(_ - .)のみを入力して下さい。'); |
||
137 | 1 | } elseif (strlen($filename) > 0 && preg_match($pattern2, $filename)) { |
|
138 | $this->error = array('message' => '.から始まるフォルダ名は作成できません。'); |
||
139 | } else { |
||
140 | 1 | $topDir = $app['config']['user_data_realdir']; |
|
141 | 1 | $nowDir = $this->checkDir($request->get('now_dir'), $topDir) |
|
142 | ? $this->normalizePath($request->get('now_dir')) |
||
143 | 1 | : $topDir; |
|
144 | 1 | $fs->mkdir($nowDir . '/' . $filename); |
|
145 | } |
||
146 | } |
||
147 | } |
||
148 | |||
149 | 1 | public function delete(Application $app, Request $request) |
|
164 | |||
165 | 1 | public function download(Application $app, Request $request) |
|
194 | |||
195 | 1 | public function upload(Application $app, Request $request) |
|
217 | |||
218 | 3 | private function getJsArrayList($tree) |
|
232 | |||
233 | 3 | private function getTree($topDir, $request) |
|
269 | |||
270 | 3 | private function getFileList($app, $nowDir) |
|
316 | |||
317 | 3 | protected function normalizePath($path) |
|
321 | |||
322 | 6 | protected function checkDir($targetDir, $topDir) |
|
328 | |||
329 | 3 | View Code Duplication | private function convertStrFromServer($target) |
336 | |||
337 | 4 | View Code Duplication | private function convertStrToServer($target) |
344 | } |
||
345 |