2
0
forked from Wavyzz/dolibarr
Files
dolibarr-fork/dev/tools/rector/src/Renaming/UserRightsToFunction.php
MDW 7b54824d49 Fix #28071 - New branch to fix bad merge (#28083)
* Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

* Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into
develop

* Qual: Introduce getDataToShowPhoto to prepare generic code

* Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

* Fix missing trans

* Fix langs

* Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

* Remove useless files in web templates

* Clean code

* Fix duplicate translation key

* Fix duplicate translation key

* Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

* Fix duplicate key

* Fix $object

* Debug v19

* WIP SMSing

* Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

* WIP EMAILINGS_SUPPORT_ALSO_SMS

* Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

* Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

* WIP SMSing

* Debug the "validate" feature

* Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

* Clean code

* Move rights->x->y into hasRight('x', 'y')

* Move rights->x->y into hasRight('x', 'y')

* Move rights->x->y into hasRight('x', 'y')

* Move rights->x->y into hasRight('x', 'y')

* Move rights->x->y into hasRight('x', 'y')

* Move rights->x->y into hasRight('x', 'y')

* Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

* Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into
develop

* Enhance rector to fix empty($user->rights->modulex->perm1)

* Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into
develop

* Fix template to use v19 dev rules

* Fix use v19 dev rules

* Fix phpunit

* Debug v19

* Clean code

* Use rector to convert user->rights into user->hasRight

* Clean code

* Use rector to convert user->rights into user->hasRight

* Use rector to convert user->rights into user->hasRight

* Clean code

* Fix phpcs

* add editorconfig for sql files (#27999)

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>

* add model_pdf field in llx_ticket-ticket.sql (#27996)

* add model_pdf field in llx_ticket-ticket.sql

* Update 19.0.0-20.0.0.sql

* Update 19.0.0-20.0.0.sql

* Improve wording in README (#27994)

* fix phpstan (#27989)

* fix phpstan

* Update UserRightsToFunction.php

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>

* Qual: Fix spelling/working in datapolicy translations (#28006)

# Qual: Fix spelling/wording in datapolicy translations

Fixed some spelling and wording in datapolicy translations.

* qual: phpstan for htdocs/ticket/class/ticketstats.class.php (#27986)

htdocs/ticket/class/ticketstats.class.php	98	Parameter #1 $year (string) of method TicketStats::getNbByMonth() should be compatible with parameter $year (int) of method Stats::getNbByMonth()

* Merge branch '19.0' of git@github.com:Dolibarr/dolibarr.git into develop

* Fix user with readonly perm on email template must be able to read.

* Fix doc

* Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

* Better message

* Add missing fields in merge of thirdparty

* Debug v19 selection of ticket printer per terminal

* Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

* Use constant

* NEW: Adding a recipient on emails sent, change status to sent partialy.

* fix travis (#28052)

* fix travis

* Update partnership.class.php

* fix php doc (#28047)

* fix undefined array key (#28048)

* Add region and departament for Cuba (#28046)

* Update llx_10_c_regions.sql

Add Cuba Regions (id_country=77)

* Update llx_20_c_departements.sql

Add Provinces Cuba (id country=77)

* Find the typo (#28050)

* Find the typo

* clean code

* add last_main_doc field to product (#28045)

* add las_main_doc field to product

* add field fetch

* NEW Add Categorie filter for ActionComm (#28041)

* New Add Categorie filter for ActionComm

New Add Categorie filter for ActionComm

* Fix space errors

Fix space errors

* Fix space errors 2

Fix space errors 2

* Update cunits.class.php (#28056)

FIX: error SQL when creating a Cunit

* Update codespell-lines-ignore.txt to avoid PR merge conflict

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
Co-authored-by: Frédéric FRANCE <frederic34@users.noreply.github.com>
Co-authored-by: thibdrev <thibault.drevet@gmail.com>
Co-authored-by: sonikf <93765174+sonikf@users.noreply.github.com>
Co-authored-by: Ikarus <44511582+LeKarSol@users.noreply.github.com>
Co-authored-by: Anthony Damhet <73399671+EchoLoGeek@users.noreply.github.com>
Co-authored-by: Quentin-Seekness <72733832+Quentin-Seekness@users.noreply.github.com>
2024-02-09 15:58:49 +01:00

261 lines
7.1 KiB
PHP

<?php
namespace Dolibarr\Rector\Renaming;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Scalar\String_;
use PhpParser\NodeTraverser;
use Rector\Core\PhpParser\Node\NodeFactory;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
use PhpParser\Node\Expr\BinaryOp\Concat;
use PhpParser\Node\Expr\BinaryOp\Equal;
/**
* Class to refactor User rights
*/
class UserRightsToFunction extends AbstractRector
{
/**
* @param \Rector\Core\PhpParser\Node\NodeFactory $nodeFactory node factory
*/
public function __construct(NodeFactory $nodeFactory)
{
$this->nodeFactory = $nodeFactory;
}
/**
* @throws \Symplify\RuleDocGenerator\Exception\PoorDocumentationException
* @return RuleDefinition
*/
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Change \$user->rights->module->permission to \$user->hasRight(\'module\', \'permission\')',
[new CodeSample(
'$user->rights->module->permission',
'$user->hasRight(\'module\', \'permission\')'
)]
);
}
/**
* Return a node type from https://github.com/rectorphp/php-parser-nodes-docs/
*
* @return string[]
*/
public function getNodeTypes(): array
{
return [
Node\Expr\Assign::class,
Node\Expr\PropertyFetch::class,
Node\Expr\BooleanNot::class,
Node\Expr\BinaryOp\BooleanAnd::class,
Node\Expr\Empty_::class,
Node\Expr\Isset_::class,
Node\Stmt\ClassMethod::class
];
}
/**
* @param \PhpParser\Node $node node to be changed
* @return \PhpParser\Node|\PhpParser\Node[]|\PhpParser\Node\Expr\MethodCall|void|null| int
*/
public function refactor(Node $node)
{
if ($node instanceof Node\Stmt\ClassMethod) {
$excludeMethods = ['getrights', 'hasRight'];
/** @var \PHPStan\Analyser\MutatingScope $scope */
$scope = $node->getAttribute('scope');
$class = $scope->getClassReflection();
$classes = ['UserGroup', 'User'];
if (isset($class) && in_array($class->getName(), $classes)) {
if (in_array($this->getName($node), $excludeMethods)) {
return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
}
}
}
if ($node instanceof Node\Expr\Assign) {
// var is left of = and expr is right of =
if (!isset($node->var)) {
return;
}
if (!$node->expr instanceof Node\Expr\PropertyFetch) {
return;
}
$data = $this->getRights($node->expr);
if (!isset($data)) {
return;
}
$args = [new Arg($data['module']), new Arg($data['perm1'])];
if (!empty($data['perm2'])) {
$args[] = new Arg($data['perm2']);
}
$node->expr = $this->nodeFactory->createMethodCall($data['user'], 'hasRight', $args);
return $node;
}
if ($node instanceof Node\Expr\BinaryOp\BooleanAnd) {
/*$nodes = $this->resolveTwoNodeMatch($node);
if (!isset($nodes)) {
return;
}
$node = $nodes->getFirstExpr();
*/
$mustprocesstheleft = false;
$mustprocesstheright = false;
if ($node->left instanceof Node\Expr\PropertyFetch) {
$data = $this->getRights($node->left);
if (isset($data)) {
$mustprocesstheleft = true;
}
}
if (empty($mustprocesstheleft) && $node->right instanceof Node\Expr\PropertyFetch) {
$data = $this->getRights($node->right);
if (isset($data)) {
$mustprocesstheright = true;
}
}
if (isset($data)) {
$args = [new Arg($data['module']), new Arg($data['perm1'])];
if (!empty($data['perm2'])) {
$args[] = new Arg($data['perm2']);
}
if ($mustprocesstheleft && !empty($data['module'])) {
$node->left = $this->nodeFactory->createMethodCall($data['user'], 'hasRight', $args);
}
if ($mustprocesstheright && !empty($data['module'])) {
$node->right = $this->nodeFactory->createMethodCall($data['user'], 'hasRight', $args);
}
}
return $node;
}
$caseok = false; // Will be true if we can make the replacement. We must not do it for assignment like when $user->right->aaa->bbb = ...
$isInverse = false;
if ($node instanceof Node\Expr\BooleanNot) {
if (!$node->expr instanceof Node\Expr\Empty_) {
return null;
}
$node = $node->expr->expr;
$caseok = true;
}
if ($node instanceof Node\Expr\Empty_) {
$node = $node->expr;
$isInverse = true;
$caseok = true;
}
if ($node instanceof Node\Expr\Isset_) {
// Take first arg for isset (No code found with multiple isset).
$node = $node->vars[0];
$caseok = true;
}
if (!$node instanceof Node\Expr\PropertyFetch) {
return null;
}
if ($caseok) {
$data = $this->getRights($node);
if (!isset($data)) {
return;
}
$args = [new Arg($data['module']), new Arg($data['perm1'])];
if (!empty($data['perm2'])) {
$args[] = new Arg($data['perm2']);
}
$method = $this->nodeFactory->createMethodCall($data['user'], 'hasRight', $args);
if ($isInverse) {
return new Node\Expr\BooleanNot($method);
}
return $method;
} else {
return null;
}
}
/**
* @param \PhpParser\Node\Expr\PropertyFetch $node node
* @return array|null
*/
private function getRights(Node\Expr\PropertyFetch $node)
{
$perm2 = '';
if (!$node->var instanceof Node\Expr\PropertyFetch) {
return null;
}
// Add a test to avoid rector error on html.formsetup.class.php
if (!$node->name instanceof Node\Expr\Variable && is_null($this->getName($node))) {
//var_dump($node);
return null;
//exit;
}
$perm1 = $node->name instanceof Node\Expr\Variable ? $node->name : new String_($this->getName($node));
$moduleNode = $node->var;
if (!$moduleNode instanceof Node\Expr\PropertyFetch) {
return null;
}
if (!$moduleNode->var instanceof Node\Expr\PropertyFetch) {
return null;
}
if (!$this->isName($moduleNode->var, 'rights')) {
$perm2 = $perm1;
$perm1 = $moduleNode->name instanceof Node\Expr\Variable ? $moduleNode->name : new String_($this->getName($moduleNode));
$moduleNode = $moduleNode->var;
}
$module = $moduleNode->name instanceof Node\Expr\Variable ? $moduleNode->name : new String_($this->getName($moduleNode));
$rights = $moduleNode->var;
if (!$this->isName($rights, 'rights') || !isset($perm1) || !isset($module)) {
return null;
}
if (!$rights->var instanceof Node\Expr\Variable) {
return null;
}
$user = $rights->var;
return compact('user', 'module', 'perm1', 'perm2');
}
/**
* Get nodes with check empty
*
* @param BooleanAnd $booleanAnd A BooleandAnd
* @return TwoNodeMatch|null
*/
private function resolveTwoNodeMatch(BooleanAnd $booleanAnd): ?TwoNodeMatch
{
return $this->binaryOpManipulator->matchFirstAndSecondConditionNode(
$booleanAnd,
// Function to check if we are in the case $conf->global->... == $value
function (Node $node): bool {
if (!$node instanceof Equal) {
return \false;
}
return $this->isGlobalVar($node->left);
},
// !empty(...) || isset(...)
function (Node $node): bool {
if ($node instanceof BooleanNot && $node->expr instanceof Empty_) {
return $this->isGlobalVar($node->expr->expr);
}
if (!$node instanceof Isset_) {
return $this->isGlobalVar($node);
}
return \true;
}
);
}
}