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 CKFinder 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 CKFinder, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
16 | class CKFinder |
||
17 | { |
||
18 | var $BasePath ; |
||
19 | var $Width ; |
||
20 | var $Height ; |
||
21 | var $SelectFunction ; |
||
22 | var $SelectFunctionData ; |
||
23 | var $SelectThumbnailFunction ; |
||
24 | var $SelectThumbnailFunctionData ; |
||
25 | var $DisableThumbnailSelection = false ; |
||
26 | var $ClassName = '' ; |
||
27 | var $Id = '' ; |
||
28 | var $ResourceType ; |
||
29 | var $StartupPath ; |
||
30 | var $RememberLastFolder = true ; |
||
31 | var $StartupFolderExpanded = false ; |
||
32 | |||
33 | // PHP 4 Constructor |
||
34 | function CKFinder( $basePath = CKFINDER_DEFAULT_BASEPATH, $width = '100%', $height = 400, $selectFunction = null ) |
||
35 | { |
||
36 | $this->BasePath = empty( $basePath ) ? CKFINDER_DEFAULT_BASEPATH : $basePath ; |
||
37 | $this->Width = empty( $width ) ? '100%' : $width ; |
||
38 | $this->Height = empty( $height ) ? 400 : $height ; |
||
39 | $this->SelectFunction = $selectFunction ; |
||
40 | $this->SelectThumbnailFunction = $selectFunction ; |
||
41 | } |
||
42 | |||
43 | // Renders CKFinder in the current page. |
||
44 | function Create() |
||
45 | { |
||
46 | echo $this->CreateHtml() ; |
||
47 | } |
||
48 | |||
49 | // Gets the HTML needed to create a CKFinder instance. |
||
50 | function CreateHtml() |
||
51 | { |
||
52 | $className = $this->ClassName ; |
||
53 | if ( !empty( $className ) ) |
||
54 | $className = ' class="' . $className . '"' ; |
||
55 | |||
56 | $id = $this->Id ; |
||
57 | if ( !empty( $id ) ) |
||
58 | $id = ' id="' . $id . '"' ; |
||
59 | |||
60 | return '<iframe src="' . $this->_BuildUrl() . '" width="' . $this->Width . '" ' . |
||
61 | 'height="' . $this->Height . '"' . $className . $id . ' frameborder="0" scrolling="no"></iframe>' ; |
||
62 | } |
||
63 | |||
64 | function _BuildUrl( $url = "" ) |
||
65 | { |
||
66 | if ( !$url ) |
||
67 | $url = $this->BasePath ; |
||
68 | |||
69 | $qs = "" ; |
||
70 | |||
71 | if ( empty( $url ) ) |
||
72 | $url = CKFINDER_DEFAULT_BASEPATH ; |
||
73 | |||
74 | if ( $url[ strlen( $url ) - 1 ] != '/' ) |
||
75 | $url = $url . '/' ; |
||
76 | |||
77 | $url .= 'ckfinder.html' ; |
||
78 | |||
79 | if ( !empty( $this->SelectFunction ) ) |
||
80 | $qs .= '?action=js&func=' . $this->SelectFunction ; |
||
81 | |||
82 | if ( !empty( $this->SelectFunctionData ) ) |
||
83 | { |
||
84 | $qs .= $qs ? "&" : "?" ; |
||
85 | $qs .= 'data=' . rawurlencode($this->SelectFunctionData) ; |
||
86 | } |
||
87 | |||
88 | if ( $this->DisableThumbnailSelection ) |
||
89 | { |
||
90 | $qs .= $qs ? "&" : "?" ; |
||
91 | $qs .= "dts=1" ; |
||
92 | } |
||
93 | else if ( !empty( $this->SelectThumbnailFunction ) || !empty( $this->SelectFunction ) ) |
||
94 | { |
||
95 | $qs .= $qs ? "&" : "?" ; |
||
96 | $qs .= 'thumbFunc=' . ( !empty( $this->SelectThumbnailFunction ) ? $this->SelectThumbnailFunction : $this->SelectFunction ) ; |
||
97 | |||
98 | if ( !empty( $this->SelectThumbnailFunctionData ) ) |
||
99 | $qs .= '&tdata=' . rawurlencode( $this->SelectThumbnailFunctionData ) ; |
||
100 | else if ( empty( $this->SelectThumbnailFunction ) && !empty( $this->SelectFunctionData ) ) |
||
101 | $qs .= '&tdata=' . rawurlencode( $this->SelectFunctionData ) ; |
||
102 | } |
||
103 | |||
104 | if ( !empty( $this->StartupPath ) ) |
||
105 | { |
||
106 | $qs .= ( $qs ? "&" : "?" ) ; |
||
107 | $qs .= "start=" . urlencode( $this->StartupPath . ( $this->StartupFolderExpanded ? ':1' : ':0' ) ) ; |
||
108 | } |
||
109 | |||
110 | if ( !empty( $this->ResourceType ) ) |
||
111 | { |
||
112 | $qs .= ( $qs ? "&" : "?" ) ; |
||
113 | $qs .= "type=" . urlencode( $this->ResourceType ) ; |
||
114 | } |
||
115 | |||
116 | if ( !$this->RememberLastFolder ) |
||
117 | { |
||
118 | $qs .= ( $qs ? "&" : "?" ) ; |
||
119 | $qs .= "rlf=0" ; |
||
120 | } |
||
121 | |||
122 | if ( !empty( $this->Id ) ) |
||
123 | { |
||
124 | $qs .= ( $qs ? "&" : "?" ) ; |
||
125 | $qs .= "id=" . urlencode( $this->Id ) ; |
||
126 | } |
||
127 | |||
128 | return $url . $qs ; |
||
129 | } |
||
130 | |||
131 | // Static "Create". |
||
132 | function CreateStatic( $basePath = CKFINDER_DEFAULT_BASEPATH, $width = '100%', $height = 400, $selectFunction = null ) |
||
133 | { |
||
134 | $finder = new CKFinder( $basePath, $width, $height, $selectFunction ) ; |
||
135 | $finder->Create() ; |
||
136 | } |
||
137 | |||
138 | // Static "SetupFCKeditor". |
||
139 | function SetupFCKeditor( &$editorObj, $basePath = CKFINDER_DEFAULT_BASEPATH, $imageType = null, $flashType = null ) |
||
140 | { |
||
141 | if ( empty( $basePath ) ) |
||
142 | $basePath = CKFINDER_DEFAULT_BASEPATH ; |
||
143 | |||
144 | // If it is a path relative to the current page. |
||
145 | if ( $basePath[0] != '/' ) |
||
146 | { |
||
147 | $basePath = substr( $_SERVER[ 'REQUEST_URI' ], 0, strrpos( $_SERVER[ 'REQUEST_URI' ], '/' ) + 1 ) . |
||
148 | $basePath ; |
||
149 | } |
||
150 | |||
151 | $ckfinder = new CKFinder( $basePath ) ; |
||
152 | $ckfinder->SetupFCKeditorObject( $editorObj, $imageType, $flashType ); |
||
153 | } |
||
154 | |||
155 | // Non-static method of attaching CKFinder to FCKeditor |
||
156 | function SetupFCKeditorObject( &$editorObj, $imageType = null, $flashType = null ) |
||
157 | { |
||
158 | $url = $this->BasePath ; |
||
159 | |||
160 | // If it is a path relative to the current page. |
||
161 | if ( isset($url[0]) && $url[0] != '/' ) |
||
162 | { |
||
163 | $url = substr( $_SERVER[ 'REQUEST_URI' ], 0, strrpos( $_SERVER[ 'REQUEST_URI' ], '/' ) + 1 ) . $url ; |
||
164 | } |
||
165 | |||
166 | $url = $this->_BuildUrl( $url ) ; |
||
167 | $qs = ( strpos($url, "?") !== false ) ? "&" : "?" ; |
||
168 | |||
169 | if ( $this->Width !== '100%' && is_numeric( str_replace( "px", "", strtolower( $this->Width ) ) ) ) |
||
170 | { |
||
171 | $width = intval( $this->Width ); |
||
172 | $editorObj->Config['LinkBrowserWindowWidth'] = $width ; |
||
173 | $editorObj->Config['ImageBrowserWindowWidth'] = $width ; |
||
174 | $editorObj->Config['FlashBrowserWindowWidth'] = $width ; |
||
175 | } |
||
176 | if ( $this->Height !== 400 && is_numeric( str_replace( "px", "", strtolower( $this->Height ) ) ) ) |
||
177 | { |
||
178 | $height = intval( $this->Height ); |
||
179 | $editorObj->Config['LinkBrowserWindowHeight'] = $height ; |
||
180 | $editorObj->Config['ImageBrowserWindowHeight'] = $height ; |
||
181 | $editorObj->Config['FlashBrowserWindowHeight'] = $height ; |
||
182 | } |
||
183 | |||
184 | $editorObj->Config['LinkBrowserURL'] = $url ; |
||
185 | $editorObj->Config['ImageBrowserURL'] = $url . $qs . 'type=' . ( empty( $imageType ) ? 'Images' : $imageType ) ; |
||
186 | $editorObj->Config['FlashBrowserURL'] = $url . $qs . 'type=' . ( empty( $flashType ) ? 'Flash' : $flashType ) ; |
||
187 | |||
188 | $dir = substr( $url, 0, strrpos( $url, "/" ) + 1 ) ; |
||
189 | $editorObj->Config['LinkUploadURL'] = $dir . urlencode( 'core/connector/php/connector.php?command=QuickUpload&type=Files' ) ; |
||
190 | $editorObj->Config['ImageUploadURL'] = $dir . urlencode( 'core/connector/php/connector.php?command=QuickUpload&type=') . ( empty( $imageType ) ? 'Images' : $imageType ) ; |
||
191 | $editorObj->Config['FlashUploadURL'] = $dir . urlencode( 'core/connector/php/connector.php?command=QuickUpload&type=') . ( empty( $flashType ) ? 'Flash' : $flashType ) ; |
||
192 | } |
||
193 | |||
194 | // Static "SetupCKEditor". |
||
195 | function SetupCKEditor( &$editorObj, $basePath = CKFINDER_DEFAULT_BASEPATH, $imageType = null, $flashType = null ) |
||
196 | { |
||
197 | if ( empty( $basePath ) ) |
||
198 | $basePath = CKFINDER_DEFAULT_BASEPATH ; |
||
199 | |||
200 | $ckfinder = new CKFinder( $basePath ) ; |
||
201 | $ckfinder->SetupCKEditorObject( $editorObj, $imageType, $flashType ); |
||
202 | } |
||
203 | |||
204 | // Non-static method of attaching CKFinder to CKEditor |
||
205 | function SetupCKEditorObject( &$editorObj, $imageType = null, $flashType = null ) |
||
206 | { |
||
207 | $url = $this->BasePath ; |
||
208 | |||
209 | // If it is a path relative to the current page. |
||
210 | if ( isset($url[0]) && $url[0] != '/' ) |
||
211 | { |
||
212 | $url = substr( $_SERVER[ 'REQUEST_URI' ], 0, strrpos( $_SERVER[ 'REQUEST_URI' ], '/' ) + 1 ) . $url ; |
||
213 | } |
||
214 | |||
215 | $url = $this->_BuildUrl( $url ) ; |
||
216 | $qs = ( strpos($url, "?") !== false ) ? "&" : "?" ; |
||
217 | |||
218 | if ( $this->Width !== '100%' && is_numeric( str_ireplace( "px", "", $this->Width ) ) ) |
||
219 | { |
||
220 | $width = intval( $this->Width ); |
||
221 | $editorObj->config['filebrowserWindowWidth'] = $width ; |
||
222 | } |
||
223 | if ( $this->Height !== 400 && is_numeric( str_ireplace( "px", "", $this->Height ) ) ) |
||
224 | { |
||
225 | $height = intval( $this->Height ); |
||
226 | $editorObj->config['filebrowserWindowHeight'] = $height ; |
||
227 | } |
||
228 | |||
229 | $editorObj->config['filebrowserBrowseUrl'] = $url ; |
||
230 | $editorObj->config['filebrowserImageBrowseUrl'] = $url . $qs . 'type=' . ( empty( $imageType ) ? 'Images' : $imageType ) ; |
||
231 | $editorObj->config['filebrowserFlashBrowseUrl'] = $url . $qs . 'type=' . ( empty( $flashType ) ? 'Flash' : $flashType ) ; |
||
232 | |||
233 | $dir = substr( $url, 0, strrpos( $url, "/" ) + 1 ) ; |
||
234 | $editorObj->config['filebrowserUploadUrl'] = $dir . 'core/connector/php/connector.php?command=QuickUpload&type=Files' ; |
||
235 | $editorObj->config['filebrowserImageUploadUrl'] = $dir . 'core/connector/php/connector.php?command=QuickUpload&type=' . ( empty( $imageType ) ? 'Images' : $imageType ) ; |
||
236 | $editorObj->config['filebrowserFlashUploadUrl'] = $dir . 'core/connector/php/connector.php?command=QuickUpload&type=' . ( empty( $flashType ) ? 'Flash' : $flashType ) ; |
||
237 | } |
||
238 | } |
||
239 |