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 Application 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 Application, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 40 | class Application extends ApplicationTrait |
||
|
|
|||
| 41 | { |
||
| 42 | public function __construct(array $values = array()) |
||
| 52 | |||
| 53 | 704 | public function initConfig() |
|
| 135 | |||
| 136 | 704 | public function initLogger() |
|
| 137 | { |
||
| 138 | 704 | $app = $this; |
|
| 139 | $this->register(new ServiceProvider\EccubeMonologServiceProvider($app)); |
||
| 140 | $this['monolog.logfile'] = __DIR__.'/../../app/log/site.log'; |
||
| 141 | $this['monolog.name'] = 'eccube'; |
||
| 142 | 704 | } |
|
| 143 | |||
| 144 | 689 | public function initialize() |
|
| 145 | { |
||
| 146 | // init locale |
||
| 147 | $this->initLocale(); |
||
| 148 | |||
| 149 | // init session |
||
| 150 | $this->initSession(); |
||
| 151 | |||
| 152 | // init twig |
||
| 153 | $this->initRendering(); |
||
| 154 | |||
| 155 | // init provider |
||
| 156 | $this->register(new \Silex\Provider\HttpFragmentServiceProvider()); |
||
| 157 | $this->register(new \Silex\Provider\UrlGeneratorServiceProvider()); |
||
| 158 | $this->register(new \Silex\Provider\FormServiceProvider()); |
||
| 159 | $this->register(new \Silex\Provider\SerializerServiceProvider()); |
||
| 160 | $this->register(new \Eccube\ServiceProvider\ValidatorServiceProvider()); |
||
| 161 | |||
| 162 | 689 | $app = $this; |
|
| 163 | $this->error(function(\Exception $e, $code) use ($app) { |
||
| 164 | if ($app['debug']) { |
||
| 165 | 2 | return; |
|
| 166 | } |
||
| 167 | |||
| 168 | switch ($code) { |
||
| 169 | case 403: |
||
| 170 | $title = 'アクセスできません。'; |
||
| 171 | $message = 'お探しのページはアクセスができない状況にあるか、移動もしくは削除された可能性があります。'; |
||
| 172 | break; |
||
| 173 | case 404: |
||
| 174 | $title = 'ページがみつかりません。'; |
||
| 175 | $message = 'URLに間違いがないかご確認ください。'; |
||
| 176 | break; |
||
| 177 | default: |
||
| 178 | $title = 'システムエラーが発生しました。'; |
||
| 179 | $message = '大変お手数ですが、サイト管理者までご連絡ください。'; |
||
| 180 | break; |
||
| 181 | } |
||
| 182 | |||
| 183 | return $app['twig']->render('error.twig', array( |
||
| 184 | 'error_title' => $title, |
||
| 185 | 'error_message' => $message, |
||
| 186 | )); |
||
| 187 | }); |
||
| 188 | |||
| 189 | // init mailer |
||
| 190 | $this->initMailer(); |
||
| 191 | |||
| 192 | // init doctrine orm |
||
| 193 | $this->initDoctrine(); |
||
| 194 | |||
| 195 | // init security |
||
| 196 | $this->initSecurity(); |
||
| 197 | |||
| 198 | // init ec-cube service provider |
||
| 199 | $this->register(new ServiceProvider\EccubeServiceProvider()); |
||
| 200 | |||
| 201 | // mount controllers |
||
| 202 | $this->register(new \Silex\Provider\ServiceControllerServiceProvider()); |
||
| 203 | $this->mount('', new ControllerProvider\FrontControllerProvider()); |
||
| 204 | $this->mount('/'.trim($this['config']['admin_route'], '/').'/', new ControllerProvider\AdminControllerProvider()); |
||
| 205 | Request::enableHttpMethodParameterOverride(); // PUTやDELETEできるようにする |
||
| 206 | 689 | } |
|
| 207 | |||
| 208 | 689 | public function initLocale() |
|
| 209 | { |
||
| 210 | |||
| 211 | // timezone |
||
| 212 | if (!empty($this['config']['timezone'])) { |
||
| 213 | date_default_timezone_set($this['config']['timezone']); |
||
| 214 | } |
||
| 215 | |||
| 216 | $this->register(new \Silex\Provider\TranslationServiceProvider(), array( |
||
| 217 | 689 | 'locale' => $this['config']['locale'], |
|
| 218 | )); |
||
| 219 | $this['translator'] = $this->share($this->extend('translator', function($translator, \Silex\Application $app) { |
||
| 220 | $translator->addLoader('yaml', new \Symfony\Component\Translation\Loader\YamlFileLoader()); |
||
| 221 | |||
| 222 | $r = new \ReflectionClass('Symfony\Component\Validator\Validator'); |
||
| 223 | $file = dirname($r->getFilename()).'/Resources/translations/validators.'.$app['locale'].'.xlf'; |
||
| 224 | if (file_exists($file)) { |
||
| 225 | $translator->addResource('xliff', $file, $app['locale'], 'validators'); |
||
| 226 | } |
||
| 227 | |||
| 228 | $file = __DIR__.'/Resource/locale/validator.'.$app['locale'].'.yml'; |
||
| 229 | if (file_exists($file)) { |
||
| 230 | $translator->addResource('yaml', $file, $app['locale'], 'validators'); |
||
| 231 | } |
||
| 232 | |||
| 233 | $file = __DIR__.'/Resource/locale/message.'.$app['locale'].'.yml'; |
||
| 234 | if (file_exists($file)) { |
||
| 235 | $translator->addResource('yaml', $file, $app['locale']); |
||
| 236 | } |
||
| 237 | |||
| 238 | 364 | return $translator; |
|
| 239 | })); |
||
| 240 | 689 | } |
|
| 241 | |||
| 242 | 689 | public function initSession() |
|
| 267 | |||
| 268 | 689 | public function initRendering() |
|
| 269 | { |
||
| 270 | $this->register(new \Silex\Provider\TwigServiceProvider(), array( |
||
| 271 | 'twig.form.templates' => array('Form/form_layout.twig'), |
||
| 272 | )); |
||
| 273 | $this['twig'] = $this->share($this->extend('twig', function(\Twig_Environment $twig, \Silex\Application $app) { |
||
| 274 | $twig->addExtension(new \Eccube\Twig\Extension\EccubeExtension($app)); |
||
| 275 | $twig->addExtension(new \Twig_Extension_StringLoader()); |
||
| 276 | |||
| 277 | 124 | return $twig; |
|
| 278 | })); |
||
| 279 | |||
| 280 | $this->before(function(Request $request, \Silex\Application $app) { |
||
| 281 | // フロント or 管理画面ごとにtwigの探索パスを切り替える. |
||
| 282 | $app['twig'] = $app->share($app->extend('twig', function(\Twig_Environment $twig, \Silex\Application $app) { |
||
| 283 | 95 | $paths = array(); |
|
| 284 | |||
| 285 | // 互換性がないのでprofiler とproduction 時のcacheを分離する |
||
| 286 | |||
| 287 | if (isset($app['profiler'])) { |
||
| 288 | $cacheBaseDir = __DIR__.'/../../app/cache/twig/profiler/'; |
||
| 289 | } else { |
||
| 290 | 95 | $cacheBaseDir = __DIR__.'/../../app/cache/twig/production/'; |
|
| 291 | } |
||
| 292 | if (strpos($app['request']->getPathInfo(), '/'.trim($app['config']['admin_route'], '/')) === 0) { |
||
| 293 | if (file_exists(__DIR__.'/../../app/template/admin')) { |
||
| 294 | 55 | $paths[] = __DIR__.'/../../app/template/admin'; |
|
| 295 | } |
||
| 296 | $paths[] = $app['config']['template_admin_realdir']; |
||
| 297 | 55 | $paths[] = __DIR__.'/../../app/Plugin'; |
|
| 298 | 55 | $cache = $cacheBaseDir.'admin'; |
|
| 299 | } else { |
||
| 300 | if (file_exists($app['config']['template_realdir'])) { |
||
| 301 | $paths[] = $app['config']['template_realdir']; |
||
| 302 | } |
||
| 303 | $paths[] = $app['config']['template_default_realdir']; |
||
| 304 | 40 | $paths[] = __DIR__.'/../../app/Plugin'; |
|
| 305 | $cache = $cacheBaseDir.$app['config']['template_code']; |
||
| 306 | 55 | } |
|
| 307 | $twig->setCache($cache); |
||
| 308 | $app['twig.loader']->addLoader(new \Twig_Loader_Filesystem($paths)); |
||
| 309 | |||
| 310 | 95 | return $twig; |
|
| 311 | })); |
||
| 312 | |||
| 313 | // 管理画面のIP制限チェック. |
||
| 314 | if (strpos($app['request']->getPathInfo(), '/'.trim($app['config']['admin_route'], '/')) === 0) { |
||
| 315 | // IP制限チェック |
||
| 316 | $allowHost = $app['config']['admin_allow_host']; |
||
| 317 | if (count($allowHost) > 0) { |
||
| 318 | if (array_search($app['request']->getClientIp(), $allowHost) === false) { |
||
| 319 | throw new \Exception(); |
||
| 320 | } |
||
| 321 | } |
||
| 322 | } |
||
| 323 | }, self::EARLY_EVENT); |
||
| 324 | |||
| 325 | // twigのグローバル変数を定義. |
||
| 326 | 689 | $app = $this; |
|
| 327 | $this->on(\Symfony\Component\HttpKernel\KernelEvents::CONTROLLER, function(\Symfony\Component\HttpKernel\Event\FilterControllerEvent $event) use ($app) { |
||
| 328 | // ショップ基本情報 |
||
| 329 | $BaseInfo = $app['eccube.repository.base_info']->get(); |
||
| 330 | $app['twig']->addGlobal('BaseInfo', $BaseInfo); |
||
| 331 | |||
| 332 | if (strpos($app['request']->getPathInfo(), '/'.trim($app['config']['admin_route'], '/')) === 0) { |
||
| 333 | // 管理画面 |
||
| 334 | // 管理画面メニュー |
||
| 335 | 55 | $menus = array('', '', ''); |
|
| 336 | $app['twig']->addGlobal('menus', $menus); |
||
| 337 | |||
| 338 | $Member = $app->user(); |
||
| 339 | if (is_object($Member)) { |
||
| 340 | // ログインしていれば管理者のロールを取得 |
||
| 341 | $AuthorityRoles = $app['eccube.repository.authority_role']->findBy(array('Authority' => $Member->getAuthority())); |
||
| 342 | |||
| 343 | 52 | $roles = array(); |
|
| 344 | foreach ($AuthorityRoles as $AuthorityRole) { |
||
| 345 | // 管理画面でメニュー制御するため相対パス全てをセット |
||
| 346 | $roles[] = $app['request']->getBaseUrl() . '/' . $app['config']['admin_route'] . $AuthorityRole->getDenyUrl(); |
||
| 347 | 52 | } |
|
| 348 | |||
| 349 | $app['twig']->addGlobal('AuthorityRoles', $roles); |
||
| 350 | } |
||
| 351 | |||
| 352 | } else { |
||
| 353 | // フロント画面 |
||
| 354 | $request = $event->getRequest(); |
||
| 355 | $route = $request->attributes->get('_route'); |
||
| 356 | |||
| 357 | // ユーザ作成画面 |
||
| 358 | if ($route === trim($app['config']['user_data_route'])) { |
||
| 359 | $params = $request->attributes->get('_route_params'); |
||
| 360 | $route = $params['route']; |
||
| 361 | // プレビュー画面 |
||
| 362 | } elseif ($request->get('preview')) { |
||
| 363 | $route = 'preview'; |
||
| 364 | } |
||
| 365 | |||
| 366 | try { |
||
| 367 | $DeviceType = $app['eccube.repository.master.device_type'] |
||
| 368 | ->find(\Eccube\Entity\Master\DeviceType::DEVICE_TYPE_PC); |
||
| 369 | $PageLayout = $app['eccube.repository.page_layout']->getByUrl($DeviceType, $route); |
||
| 370 | } catch (\Doctrine\ORM\NoResultException $e) { |
||
| 371 | $PageLayout = $app['eccube.repository.page_layout']->newPageLayout($DeviceType); |
||
| 372 | 19 | } |
|
| 373 | |||
| 374 | $app['twig']->addGlobal('PageLayout', $PageLayout); |
||
| 375 | $app['twig']->addGlobal('title', $PageLayout->getName()); |
||
| 376 | 55 | } |
|
| 377 | }); |
||
| 378 | 689 | } |
|
| 379 | |||
| 380 | 689 | public function initMailer() |
|
| 409 | |||
| 410 | 689 | public function initDoctrine() |
|
| 460 | |||
| 461 | 689 | public function initSecurity() |
|
| 561 | |||
| 562 | public function initializePlugin() |
||
| 570 | |||
| 571 | 449 | public function initPluginEventDispatcher() |
|
| 608 | |||
| 609 | public function loadPlugin() |
||
| 694 | } |
||
| 695 |