yokai-php /
messenger-bundle
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | namespace Yokai\MessengerBundle\DependencyInjection; |
||
| 4 | |||
| 5 | use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; |
||
| 6 | use Symfony\Component\Config\Definition\Builder\NodeDefinition; |
||
| 7 | use Symfony\Component\Config\Definition\Builder\TreeBuilder; |
||
| 8 | use Symfony\Component\Config\Definition\ConfigurationInterface; |
||
| 9 | |||
| 10 | /** |
||
| 11 | * @author Yann Eugoné <[email protected]> |
||
| 12 | */ |
||
| 13 | class Configuration implements ConfigurationInterface |
||
| 14 | { |
||
| 15 | /** |
||
| 16 | * @inheritdoc |
||
| 17 | */ |
||
| 18 | 14 | public function getConfigTreeBuilder() |
|
| 19 | { |
||
| 20 | 14 | $builder = $this->getBuilder(); |
|
| 21 | 14 | $root = $builder->root('yokai_messenger'); |
|
| 22 | |||
| 23 | $root |
||
| 24 | 14 | ->addDefaultsIfNotSet() |
|
| 25 | 14 | ->fixXmlConfig('message') |
|
| 26 | 14 | ->children() |
|
| 27 | 14 | ->scalarNode('logging_channel')->defaultValue('app')->end() |
|
| 28 | 14 | ->append($this->getContentBuilderNode()) |
|
| 29 | 14 | ->append($this->getChannelsNode()) |
|
| 30 | 14 | ->append($this->getMessagesNode()) |
|
| 31 | 14 | ->end() |
|
| 32 | ; |
||
| 33 | |||
| 34 | 14 | return $builder; |
|
| 35 | } |
||
| 36 | |||
| 37 | /** |
||
| 38 | * @return TreeBuilder |
||
| 39 | */ |
||
| 40 | 14 | private function getBuilder() |
|
| 41 | { |
||
| 42 | 14 | return new TreeBuilder(); |
|
| 43 | } |
||
| 44 | |||
| 45 | /** |
||
| 46 | * @param string $name |
||
| 47 | * |
||
| 48 | * @return ArrayNodeDefinition |
||
| 49 | */ |
||
| 50 | 14 | private function root($name) |
|
| 51 | { |
||
| 52 | 14 | return $this->getBuilder()->root($name); |
|
| 53 | } |
||
| 54 | |||
| 55 | /** |
||
| 56 | * @return NodeDefinition |
||
| 57 | */ |
||
| 58 | 14 | private function getChannelsNode() |
|
| 59 | { |
||
| 60 | 14 | $node = $this->root('channels'); |
|
| 61 | |||
| 62 | $node |
||
| 63 | 14 | ->addDefaultsIfNotSet() |
|
| 64 | 14 | ->children() |
|
| 65 | 14 | ->append($this->getSwiftmailerChannelNode()) |
|
| 66 | 14 | ->append($this->getTwilioChannelNode()) |
|
| 67 | 14 | ->append($this->getDoctrineChannelNode()) |
|
| 68 | 14 | ->append($this->getMobileChannelNode()) |
|
| 69 | 14 | ->end() |
|
| 70 | ; |
||
| 71 | |||
| 72 | 14 | return $node; |
|
| 73 | } |
||
| 74 | |||
| 75 | /** |
||
| 76 | * @return NodeDefinition |
||
| 77 | */ |
||
| 78 | 14 | private function getMessagesNode() |
|
| 79 | { |
||
| 80 | 14 | $node = $this->root('messages'); |
|
| 81 | |||
| 82 | $node |
||
|
0 ignored issues
–
show
|
|||
| 83 | 14 | ->defaultValue([]) |
|
| 84 | 14 | ->prototype('array') |
|
| 85 | 14 | ->fixXmlConfig('channel') |
|
| 86 | 14 | ->children() |
|
| 87 | 14 | ->scalarNode('id')->isRequired()->end() |
|
| 88 | 14 | ->arrayNode('channels') |
|
| 89 | 14 | ->beforeNormalization() |
|
| 90 | 14 | ->ifString()->then($this->stringToArray()) |
|
| 91 | 14 | ->end() |
|
| 92 | 14 | ->requiresAtLeastOneElement() |
|
| 93 | 14 | ->prototype('scalar')->end() |
|
| 94 | 14 | ->end() |
|
| 95 | 14 | ->arrayNode('defaults') |
|
| 96 | 14 | ->defaultValue([]) |
|
| 97 | 14 | ->prototype('variable')->end() |
|
| 98 | 14 | ->end() |
|
| 99 | 14 | ->arrayNode('options') |
|
| 100 | 14 | ->defaultValue([]) |
|
| 101 | 14 | ->useAttributeAsKey('channel') |
|
| 102 | 14 | ->prototype('variable') |
|
| 103 | 14 | ->validate() |
|
| 104 | 14 | ->ifTrue($this->isNotHash()) |
|
| 105 | 14 | ->thenInvalid('Expected a hash for channel options, got %s.') |
|
| 106 | 14 | ->end() |
|
| 107 | 14 | ->end() |
|
| 108 | 14 | ->end() |
|
| 109 | 14 | ->end() |
|
| 110 | 14 | ->end() |
|
| 111 | ; |
||
| 112 | |||
| 113 | 14 | return $node; |
|
| 114 | } |
||
| 115 | |||
| 116 | /** |
||
| 117 | * @return NodeDefinition |
||
| 118 | */ |
||
| 119 | 14 | private function getSwiftmailerChannelNode() |
|
| 120 | { |
||
| 121 | 14 | $node = $this->root('swiftmailer'); |
|
| 122 | |||
| 123 | $node |
||
|
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Symfony\Component\Config...\Builder\NodeDefinition as the method children() does only exist in the following sub-classes of Symfony\Component\Config...\Builder\NodeDefinition: Symfony\Component\Config...der\ArrayNodeDefinition. Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
| 124 | 14 | ->canBeEnabled() |
|
| 125 | 14 | ->validate() |
|
| 126 | 14 | ->ifTrue($this->nodeRequiredIfEnabled('from')) |
|
| 127 | 14 | ->thenInvalid($this->nodeMustBeConfigured('from', 'channels.swiftmailer')) |
|
| 128 | 14 | ->end() |
|
| 129 | 14 | ->children() |
|
| 130 | 14 | ->arrayNode('from') |
|
| 131 | 14 | ->normalizeKeys(false) |
|
| 132 | 14 | ->beforeNormalization() |
|
| 133 | 14 | ->ifString()->then($this->stringToArray()) |
|
| 134 | 14 | ->end() |
|
| 135 | 14 | ->requiresAtLeastOneElement() |
|
| 136 | 14 | ->prototype('scalar')->end() |
|
| 137 | 14 | ->end() |
|
| 138 | 14 | ->scalarNode('translator_catalog')->defaultValue('notifications')->end() |
|
| 139 | 14 | ->end() |
|
| 140 | ; |
||
| 141 | |||
| 142 | 14 | return $node; |
|
| 143 | } |
||
| 144 | |||
| 145 | /** |
||
| 146 | * @return NodeDefinition |
||
| 147 | */ |
||
| 148 | 14 | private function getTwilioChannelNode() |
|
| 149 | { |
||
| 150 | 14 | $node = $this->root('twilio'); |
|
| 151 | |||
| 152 | $node |
||
|
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Symfony\Component\Config...\Builder\NodeDefinition as the method children() does only exist in the following sub-classes of Symfony\Component\Config...\Builder\NodeDefinition: Symfony\Component\Config...der\ArrayNodeDefinition. Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
| 153 | 14 | ->canBeEnabled() |
|
| 154 | 14 | ->validate() |
|
| 155 | 14 | ->ifTrue($this->nodeRequiredIfEnabled('from')) |
|
| 156 | 14 | ->thenInvalid($this->nodeMustBeConfigured('from', 'channels.twilio')) |
|
| 157 | 14 | ->ifTrue($this->nodeRequiredIfEnabled('api_id')) |
|
| 158 | 14 | ->thenInvalid($this->nodeMustBeConfigured('api_id', 'channels.twilio')) |
|
| 159 | 14 | ->ifTrue($this->nodeRequiredIfEnabled('api_token')) |
|
| 160 | 14 | ->thenInvalid($this->nodeMustBeConfigured('api_token', 'channels.twilio')) |
|
| 161 | 14 | ->end() |
|
| 162 | 14 | ->children() |
|
| 163 | 14 | ->scalarNode('from')->end() |
|
| 164 | 14 | ->scalarNode('api_id')->end() |
|
| 165 | 14 | ->scalarNode('api_token')->end() |
|
| 166 | 14 | ->end() |
|
| 167 | ; |
||
| 168 | |||
| 169 | 14 | return $node; |
|
| 170 | } |
||
| 171 | |||
| 172 | /** |
||
| 173 | * @return NodeDefinition |
||
| 174 | */ |
||
| 175 | 14 | private function getDoctrineChannelNode() |
|
| 176 | { |
||
| 177 | 14 | $node = $this->root('doctrine'); |
|
| 178 | |||
| 179 | $node |
||
| 180 | 14 | ->canBeEnabled() |
|
| 181 | 14 | ->children() |
|
| 182 | 14 | ->scalarNode('manager')->defaultValue('default')->end() |
|
| 183 | 14 | ->end() |
|
| 184 | ; |
||
| 185 | |||
| 186 | 14 | return $node; |
|
| 187 | } |
||
| 188 | |||
| 189 | /** |
||
| 190 | * @return NodeDefinition |
||
| 191 | */ |
||
| 192 | 14 | private function getMobileChannelNode() |
|
| 193 | { |
||
| 194 | 14 | $node = $this->root('mobile'); |
|
| 195 | |||
| 196 | $node |
||
| 197 | 14 | ->canBeEnabled() |
|
| 198 | 14 | ->children() |
|
| 199 | 14 | ->scalarNode('environment')->defaultValue('dev')->end() |
|
| 200 | 14 | ->arrayNode('apns') |
|
| 201 | 14 | ->canBeDisabled() |
|
| 202 | 14 | ->validate() |
|
| 203 | 14 | ->ifTrue($this->nodeRequiredIfEnabled('certificate')) |
|
| 204 | 14 | ->thenInvalid($this->nodeMustBeConfigured('certificate', 'channels.mobile.apns')) |
|
| 205 | 14 | ->ifTrue($this->nodeRequiredIfEnabled('certificate')) |
|
| 206 | 14 | ->thenInvalid($this->nodeMustBeConfigured('pass_phrase', 'channels.mobile.apns')) |
|
| 207 | 14 | ->end() |
|
| 208 | 14 | ->children() |
|
| 209 | 14 | ->scalarNode('certificate')->defaultNull()->end() |
|
| 210 | 14 | ->scalarNode('pass_phrase')->defaultNull()->end() |
|
| 211 | 14 | ->end() |
|
| 212 | 14 | ->end() |
|
| 213 | 14 | ->arrayNode('gcm') |
|
| 214 | 14 | ->canBeDisabled() |
|
| 215 | 14 | ->validate() |
|
| 216 | 14 | ->ifTrue($this->nodeRequiredIfEnabled('api_key')) |
|
| 217 | 14 | ->thenInvalid($this->nodeMustBeConfigured('api_key', 'channels.mobile.gcm')) |
|
| 218 | 14 | ->end() |
|
| 219 | 14 | ->children() |
|
| 220 | 14 | ->scalarNode('api_key')->defaultNull()->end() |
|
| 221 | 14 | ->end() |
|
| 222 | 14 | ->end() |
|
| 223 | 14 | ->end() |
|
| 224 | ; |
||
| 225 | |||
| 226 | 14 | return $node; |
|
| 227 | } |
||
| 228 | |||
| 229 | /** |
||
| 230 | * @return NodeDefinition |
||
| 231 | */ |
||
| 232 | 14 | private function getContentBuilderNode() |
|
| 233 | { |
||
| 234 | 14 | $node = $this->root('content_builder'); |
|
| 235 | |||
| 236 | $node |
||
|
0 ignored issues
–
show
The call to the method
Symfony\Component\Config...r\NodeDefinition::end() seems un-needed as the method has no side-effects.
PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left. Let’s take a look at an example: class User
{
private $email;
public function getEmail()
{
return $this->email;
}
public function setEmail($email)
{
$this->email = $email;
}
}
If we look at the $user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.
On the hand, if we look at the $user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
// instance variable).
Loading history...
|
|||
| 237 | 14 | ->defaultValue([]) |
|
| 238 | 14 | ->useAttributeAsKey('name') |
|
| 239 | 14 | ->prototype('variable') |
|
| 240 | 14 | ->end() |
|
| 241 | ; |
||
| 242 | |||
| 243 | 14 | return $node; |
|
| 244 | } |
||
| 245 | |||
| 246 | /** |
||
| 247 | * @return callable |
||
| 248 | */ |
||
| 249 | private function stringToArray() |
||
| 250 | { |
||
| 251 | 14 | return function ($value) { |
|
| 252 | 2 | return [$value]; |
|
| 253 | 14 | }; |
|
| 254 | } |
||
| 255 | |||
| 256 | /** |
||
| 257 | * @return callable |
||
| 258 | */ |
||
| 259 | private function isNotHash() |
||
| 260 | { |
||
| 261 | 14 | return function ($value) { |
|
| 262 | if (!is_array($value)) { |
||
| 263 | return true; |
||
| 264 | } |
||
| 265 | |||
| 266 | if (array_values($value) === $value) { |
||
| 267 | return true; |
||
| 268 | } |
||
| 269 | |||
| 270 | return false; |
||
| 271 | 14 | }; |
|
| 272 | } |
||
| 273 | |||
| 274 | /** |
||
| 275 | * @param string $node |
||
| 276 | * |
||
| 277 | * @return callable |
||
| 278 | */ |
||
| 279 | private function nodeRequiredIfEnabled($node) |
||
| 280 | { |
||
| 281 | 14 | return function ($value) use ($node) { |
|
| 282 | 7 | if (!$value['enabled']) { |
|
| 283 | 1 | return false; |
|
| 284 | } |
||
| 285 | |||
| 286 | 6 | if (isset($value[$node]) && !empty($value[$node])) { |
|
| 287 | 6 | return false; |
|
| 288 | } |
||
| 289 | |||
| 290 | return true; |
||
| 291 | 14 | }; |
|
| 292 | } |
||
| 293 | |||
| 294 | /** |
||
| 295 | * @param string $node |
||
| 296 | * @param string $path |
||
| 297 | * |
||
| 298 | * @return string |
||
| 299 | */ |
||
| 300 | 14 | private function nodeMustBeConfigured($node, $path) |
|
| 301 | { |
||
| 302 | 14 | return sprintf( |
|
| 303 | 14 | 'The child node "%s" at path "yokai_messenger.%s" must be configured.', |
|
| 304 | 14 | $node, |
|
| 305 | 14 | $path |
|
| 306 | ); |
||
| 307 | } |
||
| 308 | } |
||
| 309 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the parent class: