-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3593 from magento-qwerty/2.3-bugfixes-020119
Fixed issues: - MAGETWO-95945: Add a code mess rule for improper session and cookies usages - MAGETWO-95928: Remove RequestAwareBlockMethod and update Technical Vision
- Loading branch information
Showing
5 changed files
with
198 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
184 changes: 184 additions & 0 deletions
184
dev/tests/static/framework/Magento/CodeMessDetector/Rule/Design/CookieAndSessionMisuse.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Magento\CodeMessDetector\Rule\Design; | ||
|
||
use PDepend\Source\AST\ASTClass; | ||
use PHPMD\AbstractNode; | ||
use PHPMD\AbstractRule; | ||
use PHPMD\Node\ClassNode; | ||
use PHPMD\Rule\ClassAware; | ||
|
||
/** | ||
* Session and Cookies must be used only in HTML Presentation layer. | ||
*/ | ||
class CookieAndSessionMisuse extends AbstractRule implements ClassAware | ||
{ | ||
/** | ||
* Is given class a controller? | ||
* | ||
* @param \ReflectionClass $class | ||
* @return bool | ||
*/ | ||
private function isController(\ReflectionClass $class): bool | ||
{ | ||
return $class->isSubclassOf(\Magento\Framework\App\ActionInterface::class); | ||
} | ||
|
||
/** | ||
* Is given class a block? | ||
* | ||
* @param \ReflectionClass $class | ||
* @return bool | ||
*/ | ||
private function isBlock(\ReflectionClass $class): bool | ||
{ | ||
return $class->isSubclassOf(\Magento\Framework\View\Element\BlockInterface::class); | ||
} | ||
|
||
/** | ||
* Is given class an HTML UI data provider? | ||
* | ||
* @param \ReflectionClass $class | ||
* @return bool | ||
*/ | ||
private function isUiDataProvider(\ReflectionClass $class): bool | ||
{ | ||
return $class->isSubclassOf( | ||
\Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface::class | ||
); | ||
} | ||
|
||
/** | ||
* Is given class an HTML UI Document? | ||
* | ||
* @param \ReflectionClass $class | ||
* @return bool | ||
*/ | ||
private function isUiDocument(\ReflectionClass $class): bool | ||
{ | ||
return $class->isSubclassOf(\Magento\Framework\View\Element\UiComponent\DataProvider\Document::class) | ||
|| $class->getName() === \Magento\Framework\View\Element\UiComponent\DataProvider\Document::class; | ||
} | ||
|
||
/** | ||
* Is given class a plugin for controllers? | ||
* | ||
* @param \ReflectionClass $class | ||
* @return bool | ||
*/ | ||
private function isControllerPlugin(\ReflectionClass $class): bool | ||
{ | ||
foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { | ||
if (preg_match('/^(after|around|before).+/i', $method->getName())) { | ||
try { | ||
$argument = $method->getParameters()[0]->getClass(); | ||
} catch (\Throwable $exception) { | ||
//Non-existing class (autogenerated perhaps) or doesn't have an argument. | ||
continue; | ||
} | ||
if ($argument) { | ||
$isAction = $argument->isSubclassOf(\Magento\Framework\App\ActionInterface::class) | ||
|| $argument->getName() === \Magento\Framework\App\ActionInterface::class; | ||
if ($isAction) { | ||
return true; | ||
} | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
* Is given class a plugin for blocks? | ||
* | ||
* @param \ReflectionClass $class | ||
* @return bool | ||
*/ | ||
private function isBlockPlugin(\ReflectionClass $class): bool | ||
{ | ||
foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { | ||
if (preg_match('/^(after|around|before).+/i', $method->getName())) { | ||
try { | ||
$argument = $method->getParameters()[0]->getClass(); | ||
} catch (\Throwable $exception) { | ||
//Non-existing class (autogenerated perhaps) or doesn't have an argument. | ||
continue; | ||
} | ||
if ($argument) { | ||
$isBlock = $argument->isSubclassOf(\Magento\Framework\View\Element\BlockInterface::class) | ||
|| $argument->getName() === \Magento\Framework\View\Element\BlockInterface::class; | ||
if ($isBlock) { | ||
return true; | ||
} | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
* Whether given class depends on classes to pay attention to. | ||
* | ||
* @param \ReflectionClass $class | ||
* @return bool | ||
*/ | ||
private function doesUseRestrictedClasses(\ReflectionClass $class): bool | ||
{ | ||
$constructor = $class->getConstructor(); | ||
if ($constructor) { | ||
foreach ($constructor->getParameters() as $argument) { | ||
try { | ||
if ($class = $argument->getClass()) { | ||
if ($class->isSubclassOf(\Magento\Framework\Session\SessionManagerInterface::class) | ||
|| $class->getName() === \Magento\Framework\Session\SessionManagerInterface::class | ||
|| $class->isSubclassOf(\Magento\Framework\Stdlib\Cookie\CookieReaderInterface::class) | ||
|| $class->getName() === \Magento\Framework\Stdlib\Cookie\CookieReaderInterface::class | ||
) { | ||
return true; | ||
} | ||
} | ||
} catch (\ReflectionException $exception) { | ||
//Failed to load the argument's class information | ||
continue; | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
* | ||
* @param ClassNode|ASTClass $node | ||
*/ | ||
public function apply(AbstractNode $node) | ||
{ | ||
try { | ||
$class = new \ReflectionClass($node->getFullQualifiedName()); | ||
} catch (\Throwable $exception) { | ||
//Failed to load class, nothing we can do | ||
return; | ||
} | ||
|
||
if ($this->doesUseRestrictedClasses($class)) { | ||
if (!$this->isController($class) | ||
&& !$this->isBlock($class) | ||
&& !$this->isUiDataProvider($class) | ||
&& !$this->isUiDocument($class) | ||
&& !$this->isControllerPlugin($class) | ||
&& !$this->isBlockPlugin($class) | ||
) { | ||
$this->addViolation($node, [$node->getFullQualifiedName()]); | ||
} | ||
} | ||
} | ||
} |
53 changes: 0 additions & 53 deletions
53
dev/tests/static/framework/Magento/CodeMessDetector/Rule/Design/RequestAwareBlockMethod.php
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters