├── .gitignore ├── README.md ├── composer.json ├── configs ├── phpstan │ ├── phpstan.neon.sw5 │ ├── phpstan.neon.sw6 │ └── phpstan.neon.sw_legacy └── sonarqube │ ├── javascript.xml │ └── php.xml ├── extension.neon └── src └── Shopware5 └── Rules └── InvalidUsage ├── InvalidCacheClearing.php └── PluginManagerOverwrite.php /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /vendor 3 | /composer.lock 4 | /phpstan.neon 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Store Plugin Code-Review 2 | 3 | * [PHPStan](https://github.com/phpstan/phpstan) 4 | 5 | Here can you find the current used rules for the store plugin reviews. 6 | 7 | ## Setup 8 | 9 | You can find the base `phpstan.neon` config in the `configs/phpstan` folder. 10 | The current sonarqube quality profile can be found in the `configs/sonarqube` folder. 11 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopwarelabs/phpstan-shopware", 3 | "type": "phpstan-extension", 4 | "description": "Shopware extensions and rules for PHPStan", 5 | "license": [ 6 | "MIT" 7 | ], 8 | "authors": [ 9 | { 10 | "name": "Soner Sayakci", 11 | "email": "s.sayakci@shopware.com", 12 | "homepage": "https://shyim.de" 13 | } 14 | ], 15 | "minimum-stability": "dev", 16 | "prefer-stable": true, 17 | "extra": { 18 | "phpstan": { 19 | "includes": [ 20 | "extension.neon" 21 | ] 22 | } 23 | }, 24 | "require": { 25 | "php": "^7.2", 26 | "ext-simplexml": "*", 27 | "phpstan/phpstan": "^0.11" 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "Shopware\\PhpStan\\": "src/" 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /configs/phpstan/phpstan.neon.sw5: -------------------------------------------------------------------------------- 1 | parameters: 2 | level: 0 3 | scanDirectories: 4 | - %currentWorkingDirectory%/../../../var/cache 5 | - %currentWorkingDirectory%/../../../engine/Library 6 | - %currentWorkingDirectory% 7 | bootstrapFiles: 8 | - %currentWorkingDirectory%/../../../autoload.php 9 | paths: 10 | - %currentWorkingDirectory% 11 | excludePaths: 12 | - %currentWorkingDirectory%/Components/Smarty 13 | - %currentWorkingDirectory%/vendor 14 | - %currentWorkingDirectory%/tests/Unit/config.php 15 | - %currentWorkingDirectory%/tests/Functional/config.php 16 | - %currentWorkingDirectory%/Resources/smarty 17 | ignoreErrors: 18 | - '#apcu_#' 19 | - '#ioncube_#' 20 | - '#opcache_#' 21 | - '#imagettftext#' 22 | - '#class Redis#' 23 | - '#Constant STARTTIME#' 24 | reportUnmatchedIgnoredErrors: false 25 | tipsOfTheDay: false -------------------------------------------------------------------------------- /configs/phpstan/phpstan.neon.sw6: -------------------------------------------------------------------------------- 1 | parameters: 2 | level: 0 3 | 4 | bootstrapFiles: 5 | - %currentWorkingDirectory%/vendor/autoload.php 6 | paths: 7 | - %currentWorkingDirectory% 8 | excludePaths: 9 | - %currentWorkingDirectory%/Components/Smarty 10 | - %currentWorkingDirectory%/vendor 11 | - %currentWorkingDirectory%/tests/ 12 | - %currentWorkingDirectory%/Test/ 13 | - %currentWorkingDirectory%/Resources/smarty 14 | - %currentWorkingDirectory%/platform 15 | - %currentWorkingDirectory%/autoload-dist/vendor/ 16 | 17 | ignoreErrors: 18 | - '#apcu_#' 19 | - '#ioncube_#' 20 | - '#opcache_#' 21 | - '#imagettftext#' 22 | - '#class Redis#' 23 | - '#Constant STARTTIME#' 24 | 25 | reportUnmatchedIgnoredErrors: false 26 | tipsOfTheDay: false 27 | -------------------------------------------------------------------------------- /configs/phpstan/phpstan.neon.sw_legacy: -------------------------------------------------------------------------------- 1 | parameters: 2 | level: 0 3 | 4 | scanDirectories: 5 | - %currentWorkingDirectory% 6 | bootstrapFiles: 7 | - %currentWorkingDirectory%/../../../../autoload.php 8 | 9 | paths: 10 | - %currentWorkingDirectory% 11 | excludePaths: 12 | - %currentWorkingDirectory%/Components/Smarty 13 | - %currentWorkingDirectory%/vendor 14 | - %currentWorkingDirectory%/tests/Unit/config.php 15 | - %currentWorkingDirectory%/tests/Functional/config.php 16 | - %currentWorkingDirectory%/Resources/smarty 17 | 18 | ignoreErrors: 19 | - '#apcu_#' 20 | - '#ioncube_#' 21 | - '#opcache_#' 22 | - '#imagettftext#' 23 | - '#class Redis#' 24 | - '#Constant STARTTIME#' 25 | 26 | reportUnmatchedIgnoredErrors: false 27 | tipsOfTheDay: false 28 | 29 | -------------------------------------------------------------------------------- /configs/sonarqube/javascript.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Code-Review 4 | js 5 | 6 | 7 | common-js 8 | FailedUnitTests 9 | MAJOR 10 | 11 | 12 | 13 | javascript 14 | BitwiseOperators 15 | MAJOR 16 | 17 | 18 | 19 | javascript 20 | BoundOrAssignedEvalOrArguments 21 | MAJOR 22 | 23 | 24 | 25 | javascript 26 | ConstructorFunctionsForSideEffects 27 | MAJOR 28 | 29 | 30 | 31 | javascript 32 | DebuggerStatement 33 | BLOCKER 34 | 35 | 36 | 37 | javascript 38 | DuplicateFunctionArgument 39 | MAJOR 40 | 41 | 42 | 43 | javascript 44 | DuplicatePropertyName 45 | MAJOR 46 | 47 | 48 | 49 | javascript 50 | Eval 51 | CRITICAL 52 | 53 | 54 | 55 | javascript 56 | ForIn 57 | MAJOR 58 | 59 | 60 | 61 | javascript 62 | FunctionDeclarationsWithinBlocks 63 | MINOR 64 | 65 | 66 | 67 | javascript 68 | NamedFunctionExpression 69 | MINOR 70 | 71 | 72 | 73 | javascript 74 | S1143 75 | CRITICAL 76 | 77 | 78 | 79 | javascript 80 | S1145 81 | MAJOR 82 | 83 | 84 | 85 | javascript 86 | S1154 87 | MAJOR 88 | 89 | 90 | 91 | javascript 92 | S1226 93 | MINOR 94 | 95 | 96 | 97 | javascript 98 | S1442 99 | BLOCKER 100 | 101 | 102 | 103 | javascript 104 | S1656 105 | MAJOR 106 | 107 | 108 | 109 | javascript 110 | S1697 111 | MAJOR 112 | 113 | 114 | 115 | javascript 116 | S1764 117 | MAJOR 118 | 119 | 120 | 121 | javascript 122 | S1862 123 | MAJOR 124 | 125 | 126 | 127 | javascript 128 | S2077 129 | CRITICAL 130 | 131 | 132 | 133 | javascript 134 | S2123 135 | MAJOR 136 | 137 | 138 | 139 | javascript 140 | S2137 141 | MAJOR 142 | 143 | 144 | 145 | javascript 146 | S2189 147 | BLOCKER 148 | 149 | 150 | 151 | javascript 152 | S2201 153 | MAJOR 154 | 155 | 156 | 157 | javascript 158 | S2251 159 | MAJOR 160 | 161 | 162 | 163 | javascript 164 | S2255 165 | MINOR 166 | 167 | 168 | 169 | javascript 170 | S2259 171 | MAJOR 172 | 173 | 174 | 175 | javascript 176 | S2424 177 | MAJOR 178 | 179 | 180 | 181 | javascript 182 | S2427 183 | MINOR 184 | 185 | 186 | 187 | javascript 188 | S2432 189 | MAJOR 190 | 191 | 192 | 193 | javascript 194 | S2508 195 | MINOR 196 | 197 | 198 | 199 | javascript 200 | S2549 201 | CRITICAL 202 | 203 | 204 | 205 | javascript 206 | S2550 207 | MAJOR 208 | 209 | 210 | 211 | javascript 212 | S2583 213 | MAJOR 214 | 215 | 216 | 217 | javascript 218 | S2611 219 | BLOCKER 220 | 221 | 222 | 223 | javascript 224 | S2688 225 | MAJOR 226 | 227 | 228 | 229 | javascript 230 | S2757 231 | MAJOR 232 | 233 | 234 | 235 | javascript 236 | S2769 237 | MAJOR 238 | 239 | 240 | 241 | javascript 242 | S2817 243 | BLOCKER 244 | 245 | 246 | 247 | javascript 248 | S2819 249 | BLOCKER 250 | 251 | 252 | 253 | javascript 254 | S2873 255 | MAJOR 256 | 257 | 258 | 259 | javascript 260 | S2999 261 | MAJOR 262 | 263 | 264 | considerJSDoc 265 | false 266 | 267 | 268 | 269 | 270 | javascript 271 | S3001 272 | MINOR 273 | 274 | 275 | 276 | javascript 277 | S3271 278 | BLOCKER 279 | 280 | 281 | 282 | javascript 283 | S3403 284 | MAJOR 285 | 286 | 287 | 288 | javascript 289 | S3500 290 | MAJOR 291 | 292 | 293 | 294 | javascript 295 | S3531 296 | MAJOR 297 | 298 | 299 | 300 | javascript 301 | S3616 302 | MAJOR 303 | 304 | 305 | 306 | javascript 307 | S3699 308 | MAJOR 309 | 310 | 311 | 312 | javascript 313 | S3759 314 | MAJOR 315 | 316 | 317 | 318 | javascript 319 | S3785 320 | CRITICAL 321 | 322 | 323 | 324 | javascript 325 | S3786 326 | MAJOR 327 | 328 | 329 | 330 | javascript 331 | S3796 332 | BLOCKER 333 | 334 | 335 | 336 | javascript 337 | S3799 338 | MAJOR 339 | 340 | 341 | 342 | javascript 343 | S3812 344 | CRITICAL 345 | 346 | 347 | 348 | javascript 349 | S3828 350 | BLOCKER 351 | 352 | 353 | 354 | javascript 355 | S3834 356 | CRITICAL 357 | 358 | 359 | 360 | javascript 361 | S3854 362 | CRITICAL 363 | 364 | 365 | 366 | javascript 367 | S3923 368 | MAJOR 369 | 370 | 371 | 372 | javascript 373 | S3981 374 | MAJOR 375 | 376 | 377 | 378 | javascript 379 | S3984 380 | MAJOR 381 | 382 | 383 | 384 | javascript 385 | S4043 386 | MAJOR 387 | 388 | 389 | 390 | javascript 391 | S4143 392 | MAJOR 393 | 394 | 395 | 396 | javascript 397 | S4721 398 | CRITICAL 399 | 400 | 401 | 402 | javascript 403 | S4784 404 | CRITICAL 405 | 406 | 407 | 408 | javascript 409 | S4787 410 | CRITICAL 411 | 412 | 413 | 414 | javascript 415 | S4790 416 | CRITICAL 417 | 418 | 419 | 420 | javascript 421 | S4817 422 | CRITICAL 423 | 424 | 425 | 426 | javascript 427 | S4818 428 | CRITICAL 429 | 430 | 431 | 432 | javascript 433 | S4823 434 | CRITICAL 435 | 436 | 437 | 438 | javascript 439 | S4829 440 | CRITICAL 441 | 442 | 443 | 444 | javascript 445 | S5122 446 | MINOR 447 | 448 | 449 | 450 | javascript 451 | S905 452 | MAJOR 453 | 454 | 455 | 456 | javascript 457 | S930 458 | CRITICAL 459 | 460 | 461 | 462 | javascript 463 | UnreachableCode 464 | MAJOR 465 | 466 | 467 | 468 | javascript 469 | WithStatement 470 | MINOR 471 | 472 | 473 | 474 | 475 | -------------------------------------------------------------------------------- /configs/sonarqube/php.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Code-Review 4 | php 5 | 6 | 7 | common-php 8 | FailedUnitTests 9 | MAJOR 10 | 11 | 12 | 13 | php 14 | S1145 15 | MAJOR 16 | 17 | 18 | 19 | php 20 | S1313 21 | MINOR 22 | 23 | 24 | 25 | php 26 | S1523 27 | CRITICAL 28 | 29 | 30 | 31 | php 32 | S1536 33 | MAJOR 34 | 35 | 36 | 37 | php 38 | S1656 39 | MAJOR 40 | 41 | 42 | 43 | php 44 | S1697 45 | MAJOR 46 | 47 | 48 | 49 | php 50 | S1751 51 | MAJOR 52 | 53 | 54 | 55 | php 56 | S1763 57 | MAJOR 58 | 59 | 60 | 61 | php 62 | S1764 63 | MAJOR 64 | 65 | 66 | 67 | php 68 | S1784 69 | MINOR 70 | 71 | 72 | 73 | php 74 | S1799 75 | BLOCKER 76 | 77 | 78 | 79 | php 80 | S1848 81 | MAJOR 82 | 83 | 84 | 85 | php 86 | S1862 87 | MAJOR 88 | 89 | 90 | 91 | php 92 | S2000 93 | MINOR 94 | 95 | 96 | 97 | php 98 | S2002 99 | MINOR 100 | 101 | 102 | 103 | php 104 | S2003 105 | MINOR 106 | 107 | 108 | 109 | php 110 | S2014 111 | BLOCKER 112 | 113 | 114 | 115 | php 116 | S2036 117 | MAJOR 118 | 119 | 120 | 121 | php 122 | S2037 123 | MINOR 124 | 125 | 126 | 127 | php 128 | S2053 129 | CRITICAL 130 | 131 | 132 | 133 | php 134 | S2068 135 | BLOCKER 136 | 137 | 138 | credentialWords 139 | password,passwd,pwd 140 | 141 | 142 | 143 | 144 | php 145 | S2077 146 | CRITICAL 147 | 148 | 149 | 150 | php 151 | S2092 152 | BLOCKER 153 | 154 | 155 | 156 | php 157 | S2115 158 | BLOCKER 159 | 160 | 161 | 162 | php 163 | S2123 164 | MAJOR 165 | 166 | 167 | 168 | php 169 | S2201 170 | MAJOR 171 | 172 | 173 | 174 | php 175 | S2245 176 | CRITICAL 177 | 178 | 179 | 180 | php 181 | S2251 182 | MAJOR 183 | 184 | 185 | 186 | php 187 | S2255 188 | MINOR 189 | 190 | 191 | 192 | php 193 | S2277 194 | CRITICAL 195 | 196 | 197 | 198 | php 199 | S2278 200 | BLOCKER 201 | 202 | 203 | 204 | php 205 | S2757 206 | MAJOR 207 | 208 | 209 | 210 | php 211 | S2964 212 | MINOR 213 | 214 | 215 | 216 | php 217 | S3011 218 | CRITICAL 219 | 220 | 221 | 222 | php 223 | S3330 224 | CRITICAL 225 | 226 | 227 | 228 | php 229 | S3331 230 | CRITICAL 231 | 232 | 233 | 234 | php 235 | S3332 236 | CRITICAL 237 | 238 | 239 | 240 | php 241 | S3333 242 | BLOCKER 243 | 244 | 245 | 246 | php 247 | S3334 248 | BLOCKER 249 | 250 | 251 | 252 | php 253 | S3335 254 | MAJOR 255 | 256 | 257 | 258 | php 259 | S3336 260 | BLOCKER 261 | 262 | 263 | 264 | php 265 | S3337 266 | BLOCKER 267 | 268 | 269 | 270 | php 271 | S3338 272 | BLOCKER 273 | 274 | 275 | 276 | php 277 | S3699 278 | MAJOR 279 | 280 | 281 | 282 | php 283 | S3923 284 | MAJOR 285 | 286 | 287 | 288 | php 289 | S3981 290 | MAJOR 291 | 292 | 293 | 294 | php 295 | S3984 296 | MAJOR 297 | 298 | 299 | 300 | php 301 | S4423 302 | MAJOR 303 | 304 | 305 | 306 | php 307 | S4426 308 | BLOCKER 309 | 310 | 311 | 312 | php 313 | S4433 314 | CRITICAL 315 | 316 | 317 | 318 | php 319 | S4507 320 | CRITICAL 321 | 322 | 323 | 324 | php 325 | S4508 326 | CRITICAL 327 | 328 | 329 | 330 | php 331 | S4784 332 | CRITICAL 333 | 334 | 335 | 336 | php 337 | S4787 338 | CRITICAL 339 | 340 | 341 | 342 | php 343 | S4792 344 | CRITICAL 345 | 346 | 347 | 348 | php 349 | S4818 350 | CRITICAL 351 | 352 | 353 | 354 | php 355 | S4823 356 | CRITICAL 357 | 358 | 359 | 360 | php 361 | S4828 362 | CRITICAL 363 | 364 | 365 | 366 | php 367 | S4829 368 | CRITICAL 369 | 370 | 371 | 372 | php 373 | S4830 374 | CRITICAL 375 | 376 | 377 | 378 | php 379 | S4834 380 | CRITICAL 381 | 382 | 383 | 384 | php 385 | S5328 386 | CRITICAL 387 | 388 | 389 | 390 | php 391 | S836 392 | MAJOR 393 | 394 | 395 | 396 | php 397 | S905 398 | MAJOR 399 | 400 | 401 | 402 | 403 | -------------------------------------------------------------------------------- /extension.neon: -------------------------------------------------------------------------------- 1 | rules: 2 | - Shopware\PhpStan\Shopware5\Rules\InvalidUsage\PluginManagerOverwrite 3 | - Shopware\PhpStan\Shopware5\Rules\InvalidUsage\InvalidCacheClearing 4 | -------------------------------------------------------------------------------- /src/Shopware5/Rules/InvalidUsage/InvalidCacheClearing.php: -------------------------------------------------------------------------------- 1 | name; 33 | 34 | if (!in_array($name, ['install', 'uninstall'], true)) { 35 | return []; 36 | } 37 | 38 | $errors = []; 39 | 40 | /** @var Node\Stmt\Expression $stmt */ 41 | foreach ($node->getStmts() as $stmt) { 42 | $call = $stmt->expr; 43 | if (! $call instanceof Node\Expr\MethodCall) { 44 | continue; 45 | } 46 | 47 | $callName = (string) $call->name; 48 | $varName = (string) $call->var->name; 49 | 50 | if ($callName !== 'scheduleClearCache' && $varName !== 'context') { 51 | continue; 52 | } 53 | 54 | $list = $this->convertArgToList($call->args[0]); 55 | 56 | foreach (self::NOT_ALLOWED_CACHE_ITEMS_WHILE_INSTALL as $item) { 57 | if (in_array($item, $list, true)) { 58 | $errors[] = 'Clear only the necessary caches when installing or uninstalling a plugin. For more information please look at https://docs.shopware.com/en/plugin-standard-for-community-store#clear-only-the-necessary-caches-when-installing-or-uninstalling-a-plugin'; 59 | } 60 | } 61 | } 62 | 63 | return $errors; 64 | } 65 | 66 | private function convertArgToList(Node\Arg $arg): array 67 | { 68 | if ($arg->value instanceof Node\Expr\ClassConstFetch) { 69 | return [(string) $arg->value->name]; 70 | } 71 | 72 | if($arg->value instanceof Node\Expr\Array_) { 73 | return array_map(static function (Node\Expr\ArrayItem $item) { 74 | return InvalidCacheClearing::convertValue($item->value); 75 | }, $arg->value->items); 76 | } 77 | 78 | return []; 79 | } 80 | 81 | public static function convertValue($value): ?string 82 | { 83 | if ($value instanceof Node\Expr\ClassConstFetch) { 84 | return (string) $value->name; 85 | } 86 | 87 | if ($value instanceof Node\Scalar\String_) { 88 | return (string) $value->value; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Shopware5/Rules/InvalidUsage/PluginManagerOverwrite.php: -------------------------------------------------------------------------------- 1 | value; 22 | 23 | if ( 24 | strpos($name, 'Enlight_Controller_Action_PostDispatch_Backend_PluginManager') !== false || 25 | strpos($name, 'Enlight_Controller_Action_PreDispatch_Backend_PluginManager') !== false || 26 | strpos($name, 'Enlight_Controller_Action_Backend_PluginManager') !== false 27 | ) { 28 | return [ 29 | 'It is not allowed to modifiy the plugin manager. For more information please look at https://docs.shopware.com/en/plugin-standard-for-community-store#it-is-not-allowed-to-extend-the-plugin-manager' 30 | ]; 31 | } 32 | 33 | return []; 34 | } 35 | } 36 | --------------------------------------------------------------------------------