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:
| 1 | <?php |
||
| 20 | class MonologConfig extends AbstractConfig |
||
| 21 | { |
||
| 22 | protected $nestedHandlers = array(); |
||
| 23 | |||
| 24 | /** |
||
| 25 | * Create and return the logger. |
||
| 26 | * |
||
| 27 | * @see https://github.com/symfony/MonologBundle/blob/master/DependencyInjection/MonologExtension.php |
||
| 28 | * |
||
| 29 | * {@inheritdoc} |
||
| 30 | */ |
||
| 31 | public function configureServiceManager(ServiceManager $serviceManager) |
||
| 32 | { |
||
| 33 | $configs = $serviceManager->get('Config'); |
||
| 34 | $configs['parameters'] = array_merge(array( |
||
| 35 | "monolog.logger.class" => "PPI\Framework\Log\Logger", |
||
| 36 | "monolog.gelf.publisher.class" => "Gelf\MessagePublisher", |
||
| 37 | "monolog.handler.stream.class" => "Monolog\Handler\StreamHandler", |
||
| 38 | "monolog.handler.group.class" => "Monolog\Handler\GroupHandler", |
||
| 39 | "monolog.handler.buffer.class" => "Monolog\Handler\BufferHandler", |
||
| 40 | "monolog.handler.rotating_file.class" => "Monolog\Handler\RotatingFileHandler", |
||
| 41 | "monolog.handler.syslog.class" => "Monolog\Handler\SyslogHandler", |
||
| 42 | "monolog.handler.null.class" => "Monolog\Handler\NullHandler", |
||
| 43 | "monolog.handler.test.class" => "Monolog\Handler\TestHandler", |
||
| 44 | "monolog.handler.gelf.class" => "Monolog\Handler\GelfHandler", |
||
| 45 | "monolog.handler.firephp.class" => "Symfony\Bridge\Monolog\Handler\FirePHPHandler", |
||
| 46 | "monolog.handler.chromephp.class" => "Symfony\Bridge\Monolog\Handler\ChromePhpHandler", |
||
| 47 | "monolog.handler.debug.class" => "Symfony\Bridge\Monolog\Handler\DebugHandler", |
||
| 48 | "monolog.handler.swift_mailer.class" => "Monolog\Handler\SwiftMailerHandler", |
||
| 49 | "monolog.handler.native_mailer.class" => "Monolog\Handler\NativeMailerHandler", |
||
| 50 | "monolog.handler.socket.class" => "Monolog\Handler\SocketHandler", |
||
| 51 | "monolog.handler.pushover.class" => "Monolog\Handler\PushoverHandler", |
||
| 52 | "monolog.handler.fingers_crossed.class" => "Monolog\Handler\FingersCrossedHandler", |
||
| 53 | "monolog.handler.fingers_crossed.error_level_activation_strategy.class" => "Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy", |
||
| 54 | ), $configs['parameters']); |
||
| 55 | |||
| 56 | $config = $this->processConfiguration($configs, $serviceManager); |
||
|
|
|||
| 57 | $handlersToChannels = array(); |
||
| 58 | |||
| 59 | if (isset($config['handlers'])) { |
||
| 60 | $handlers = array(); |
||
| 61 | |||
| 62 | foreach ($config['handlers'] as $name => $handler) { |
||
| 63 | $handlers[$handler['priority']][] = array( |
||
| 64 | 'id' => $this->buildHandler($serviceManager, $configs['parameters'], $name, $handler), |
||
| 65 | 'channels' => isset($handler['channels']) ? $handler['channels'] : null, |
||
| 66 | ); |
||
| 67 | } |
||
| 68 | |||
| 69 | $sortedHandlers = array(); |
||
| 70 | foreach ($handlers as $priorityHandlers) { |
||
| 71 | foreach (array_reverse($priorityHandlers) as $handler) { |
||
| 72 | $sortedHandlers[] = $handler; |
||
| 73 | } |
||
| 74 | } |
||
| 75 | |||
| 76 | foreach ($sortedHandlers as $handler) { |
||
| 77 | if (!in_array($handler['id'], $this->nestedHandlers)) { |
||
| 78 | $handlersToChannels[$handler['id']] = $handler['channels']; |
||
| 79 | } |
||
| 80 | } |
||
| 81 | } |
||
| 82 | |||
| 83 | $loggerClass = $configs['parameters']['monolog.logger.class']; |
||
| 84 | $serviceManager->setFactory('monolog.logger', function ($serviceManager) use ($loggerClass, $handlersToChannels) { |
||
| 85 | $logger = new $loggerClass('app'); |
||
| 86 | foreach ($handlersToChannels as $handler => $channels) { |
||
| 87 | $logger->pushHandler($serviceManager->get($handler)); |
||
| 88 | } |
||
| 89 | |||
| 90 | return $logger; |
||
| 91 | }); |
||
| 92 | } |
||
| 93 | |||
| 94 | /** |
||
| 95 | * {@inheritDoc} |
||
| 96 | */ |
||
| 97 | public function getConfigurationDefaults() |
||
| 101 | |||
| 102 | protected function buildHandler(ServiceManager $serviceManager, array $parameters, $name, array $handler) |
||
| 103 | { |
||
| 104 | $handlerId = $this->getHandlerId($name); |
||
| 105 | $class = $parameters[sprintf('monolog.handler.%s.class', $handler['type'])]; |
||
| 106 | $handler['level'] = is_int($handler['level']) ? $handler['level'] : constant('Monolog\Logger::' . strtoupper($handler['level'])); |
||
| 107 | |||
| 108 | $serviceManager->setFactory($handlerId, function ($serviceManager) use ($class, $handler) { |
||
| 109 | switch ($handler['type']) { |
||
| 110 | case 'stream': |
||
| 111 | return new $class($handler['path'], $handler['level'], $handler['bubble']); |
||
| 112 | } |
||
| 113 | |||
| 114 | /* |
||
| 115 | * TODO: |
||
| 116 | * <code> |
||
| 117 | if (!empty($handler['formatter'])) { |
||
| 118 | $definition->addMethodCall('setFormatter', array(new Reference($handler['formatter']))); |
||
| 119 | } |
||
| 120 | */ |
||
| 121 | }); |
||
| 122 | |||
| 123 | return $handlerId; |
||
| 124 | } |
||
| 125 | |||
| 126 | protected function getHandlerId($name) |
||
| 130 | |||
| 131 | /** |
||
| 132 | * {@inheritDoc} |
||
| 133 | */ |
||
| 134 | protected function processConfiguration(array $configs, ServiceManager $serviceManager = null) |
||
| 160 | } |
||
| 161 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.