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 |