| Total Complexity | 40 |
| Total Lines | 262 |
| Duplicated Lines | 0 % |
| Changes | 2 | ||
| Bugs | 0 | Features | 0 |
Complex classes like ModuleManager 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 ModuleManager, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 21 | abstract class ModuleManager |
||
| 22 | { |
||
| 23 | /** |
||
| 24 | * Regenerate menus and actions. |
||
| 25 | * This is temporary, everything will be cached by user or role. |
||
| 26 | * |
||
| 27 | * @return void |
||
| 28 | */ |
||
| 29 | public static function regenerate() |
||
| 30 | { |
||
| 31 | dump([ |
||
| 32 | 'acciones' => self::getActions(), |
||
| 33 | 'menú refactorizado' => self::getArrayMenu(), |
||
| 34 | 'menú lateral' => self::getArraySidebarMenu() |
||
| 35 | ]); |
||
| 36 | } |
||
| 37 | |||
| 38 | /** |
||
| 39 | * Returns an associative array with the actions of each controller, |
||
| 40 | * the index being the namespace of the controller. |
||
| 41 | * |
||
| 42 | * @return array |
||
| 43 | */ |
||
| 44 | private static function getActions() |
||
| 45 | { |
||
| 46 | $result = []; |
||
| 47 | $menuOptions = self::iterateFunction('getActions'); |
||
| 48 | foreach ($menuOptions as $option) { |
||
| 49 | if ($option === false) { |
||
| 50 | continue; |
||
| 51 | } |
||
| 52 | $result = array_merge($result, $option); |
||
| 53 | } |
||
| 54 | return $result; |
||
| 55 | } |
||
| 56 | |||
| 57 | /** |
||
| 58 | * Generates an array in which each element is the result of calling the |
||
| 59 | * $function function for each controller in the application. |
||
| 60 | * |
||
| 61 | * @param $function |
||
| 62 | * @return array |
||
| 63 | */ |
||
| 64 | private static function iterateFunction($function) |
||
| 65 | { |
||
| 66 | $iterate = static::iterate(); |
||
| 67 | $result = []; |
||
| 68 | foreach ($iterate as $module) { |
||
| 69 | $namespace = $module['namespace']; |
||
| 70 | if (!method_exists($namespace, $function)) { |
||
| 71 | continue; |
||
| 72 | } |
||
| 73 | $result[$namespace] = $namespace::$function(); |
||
| 74 | } |
||
| 75 | return $result; |
||
| 76 | } |
||
| 77 | |||
| 78 | private static function iterate() |
||
| 79 | { |
||
| 80 | $routes = self::routes(); |
||
| 81 | $data = []; |
||
| 82 | foreach ($routes as $route) { |
||
| 83 | $data = array_merge($data, self::getModuleControllers($route['namespace'], $route['path'])); |
||
| 84 | } |
||
| 85 | return $data; |
||
| 86 | } |
||
| 87 | |||
| 88 | /** |
||
| 89 | * Returns the paths that can contain modules. |
||
| 90 | * |
||
| 91 | * @return string[] |
||
| 92 | */ |
||
| 93 | private static function routes(): array |
||
| 106 | } |
||
| 107 | |||
| 108 | /** |
||
| 109 | * Returns an array with the module drivers included in the $path folder. |
||
| 110 | * The array contains the name, namespace and path of those controllers. |
||
| 111 | * |
||
| 112 | * @param string $namespace |
||
| 113 | * @param string $path |
||
| 114 | * @return array |
||
| 115 | */ |
||
| 116 | private static function getModuleControllers(string $namespace, string $path): array |
||
| 117 | { |
||
| 118 | $result = []; |
||
| 119 | if (!is_dir($path)) { |
||
| 120 | return []; |
||
| 121 | } |
||
| 122 | $directories = scandir($path); |
||
| 123 | foreach ($directories as $directory) { |
||
| 124 | if ($directory === '.' || $directory === '..' || !is_dir($path . '/' . $directory)) { |
||
| 125 | continue; |
||
| 126 | } |
||
| 127 | $result = array_merge($result, self::getControllers($namespace . '\\' . $directory, $path, $directory)); |
||
| 128 | } |
||
| 129 | return $result; |
||
| 130 | } |
||
| 131 | |||
| 132 | /** |
||
| 133 | * Returns an array with the specified $path and $directory controllers. |
||
| 134 | * The array contains the name, namespace and path of those controllers. |
||
| 135 | * |
||
| 136 | * @param string $namespace |
||
| 137 | * @param string $path |
||
| 138 | * @param string $directory |
||
| 139 | * @return array |
||
| 140 | */ |
||
| 141 | private static function getControllers(string $namespace, string $path, string $directory): array |
||
| 142 | { |
||
| 143 | $result = []; |
||
| 144 | $files = scandir($path . '/' . $directory . '/Controller'); |
||
| 145 | foreach ($files as $file) { |
||
| 146 | if ($file === '.' || $file === '..' || !str_ends_with($file, '.php')) { |
||
| 147 | continue; |
||
| 148 | } |
||
| 149 | $name = substr($file, 0, -4); |
||
| 150 | $result[] = [ |
||
| 151 | 'name' => $name, |
||
| 152 | 'namespace' => $namespace . '\\Controller\\' . $name, |
||
| 153 | 'path' => $path . '/' . $directory . '/Controller/' . $file, |
||
| 154 | ]; |
||
| 155 | } |
||
| 156 | return $result; |
||
| 157 | } |
||
| 158 | |||
| 159 | /** |
||
| 160 | * Regenerate the top menu. |
||
| 161 | * This is temporary. |
||
| 162 | * The menus to be displayed will be cached by user or role. |
||
| 163 | * |
||
| 164 | * @return array|mixed |
||
| 165 | */ |
||
| 166 | public static function getArrayMenu() |
||
| 167 | { |
||
| 168 | return self::buildMultiLevelMenu(self::getMenu()); |
||
| 169 | } |
||
| 170 | |||
| 171 | /** |
||
| 172 | * Converts an array where the index is a menu path with the |
||
| 173 | * hierarchy separated by pipelines, to a nested array. |
||
| 174 | * |
||
| 175 | * @param $menuOptions |
||
| 176 | * @return array|mixed |
||
| 177 | */ |
||
| 178 | private static function buildMultiLevelMenu($menuOptions) |
||
| 179 | { |
||
| 180 | $result = []; |
||
| 181 | |||
| 182 | foreach ($menuOptions as $option => $value) { |
||
| 183 | $levels = explode('|', $option); |
||
| 184 | $numberOfLevels = count($levels); |
||
| 185 | $currentLevel = &$result; |
||
| 186 | |||
| 187 | foreach ($levels as $level) { |
||
| 188 | $numberOfLevels--; |
||
| 189 | if ($numberOfLevels === 0) { |
||
| 190 | $currentLevel[$level] = $value; |
||
| 191 | continue; |
||
| 192 | } |
||
| 193 | if (!isset($currentLevel[$level])) { |
||
| 194 | $currentLevel[$level] = []; |
||
| 195 | } |
||
| 196 | $currentLevel = &$currentLevel[$level]; |
||
| 197 | } |
||
| 198 | } |
||
| 199 | |||
| 200 | return $result; |
||
| 201 | } |
||
| 202 | |||
| 203 | /** |
||
| 204 | * Obtains an array with all the menu options where the index is the |
||
| 205 | * option and the value is the url of the controller to be executed. |
||
| 206 | * |
||
| 207 | * Example: ['admin|auth'] = "index.php?module=Admin&controller=Auth" |
||
| 208 | * |
||
| 209 | * @return array |
||
| 210 | */ |
||
| 211 | private static function getMenu() |
||
| 226 | } |
||
| 227 | |||
| 228 | /** |
||
| 229 | * Returns the URL that runs the controller with the given namespace. |
||
| 230 | * |
||
| 231 | * The namespace can be: |
||
| 232 | * - CoreModules\\<module>\\Controller\\<controller>Controller |
||
| 233 | * - Modules\\<module>\\Controller\\<controller>Controller |
||
| 234 | * |
||
| 235 | * @param $namespace |
||
| 236 | * @return false|string |
||
| 237 | */ |
||
| 238 | public static function getUrl($namespace) |
||
| 239 | { |
||
| 240 | $explode = explode('\\', $namespace); |
||
| 241 | if (count($explode) < 4) { |
||
| 242 | return false; |
||
| 243 | } |
||
| 244 | $name = $explode[3]; |
||
| 245 | if (!str_ends_with($name, 'Controller')) { |
||
| 246 | return false; |
||
| 247 | } |
||
| 248 | $controller = substr($name, 0, -10); |
||
| 249 | $module = $explode[1]; |
||
| 250 | |||
| 251 | return 'index.php?module=' . $module . '&controller=' . $controller; |
||
| 252 | } |
||
| 253 | |||
| 254 | /** |
||
| 255 | * Regenerate the sidebar menu. |
||
| 256 | * This is temporary. |
||
| 257 | * The menus to be displayed will be cached by user or role. |
||
| 258 | * |
||
| 259 | * @return array|mixed |
||
| 260 | */ |
||
| 261 | public static function getArraySidebarMenu() |
||
| 262 | { |
||
| 263 | return self::buildMultiLevelMenu(self::getSidebarMenu()); |
||
| 264 | } |
||
| 265 | |||
| 266 | private static function getSidebarMenu() |
||
| 283 | } |
||
| 284 | } |
||
| 285 |