Skip to content

Commit

Permalink
sonar fixes #3286
Browse files Browse the repository at this point in the history
  • Loading branch information
hmeneuvrier committed Dec 2, 2024
1 parent 005ef5c commit 2e11346
Show file tree
Hide file tree
Showing 2 changed files with 219 additions and 203 deletions.
163 changes: 88 additions & 75 deletions src/Specification/Affectation/CodeInseeSpecification.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@
use App\Specification\Context\PartnerSignalementContext;
use App\Specification\Context\SpecificationContextInterface;
use App\Specification\SpecificationInterface;
use Doctrine\Common\Collections\Collection;
use Location\Coordinate;
use Location\Polygon;
use LongitudeOne\Geo\WKT\Parser;

class CodeInseeSpecification implements SpecificationInterface
{
private const TYPE_POLYGON = 'POLYGON';
private const TYPE_MULTIPOLYGON = 'MULTIPOLYGON';
private const TYPE_GEOMETRYCOLLECTION = 'GEOMETRYCOLLECTION';

public function __construct(private array|string $inseeToInclude, private ?array $inseeToExclude)
{
if ('all' !== $inseeToInclude && 'partner_list' !== $inseeToInclude) {
Expand All @@ -24,6 +29,13 @@ public function __construct(private array|string $inseeToInclude, private ?array
$this->inseeToExclude = $inseeToExclude;
}

private function isExcludedSignalement(Signalement $signalement): bool
{
$insee = $signalement->getInseeOccupant();

return null === $insee || '' === $insee || (!empty($this->inseeToExclude) && \in_array($insee, $this->inseeToExclude));
}

public function isSatisfiedBy(SpecificationContextInterface $context): bool
{
if (!$context instanceof PartnerSignalementContext) {
Expand All @@ -36,94 +48,98 @@ public function isSatisfiedBy(SpecificationContextInterface $context): bool
/** @var Partner $partner */
$partner = $context->getPartner();

if (null === $signalement->getInseeOccupant()
|| '' === $signalement->getInseeOccupant()
|| !empty($this->inseeToExclude) && \in_array($signalement->getInseeOccupant(), $this->inseeToExclude)) {
if ($this->isExcludedSignalement($signalement)) {
return false;
}

$result = false;

switch ($this->inseeToInclude) {
case 'all':
$result = true;
break;
case 'partner_list':
$isZoneOK = true;
$isZoneExcludedOK = true;
$isInseeOK = !empty($partner->getInsee())
&& \in_array($signalement->getInseeOccupant(), $partner->getInsee());
// var_dump($isInseeOK);
if ($isInseeOK) {
if (!empty($partner->getZones()) && $partner->getZones()->count() > 0) {
$isZoneOK = false;
foreach ($partner->getZones() as $zone) {
$isZoneOK = $this->isSignalementInZone($signalement, $zone);
if ($isZoneOK) {
break;
}
}
}
// var_dump($isZoneOK);
if ($isZoneOK && !empty($partner->getExcludedZones()) && $partner->getExcludedZones()->count() > 0) {
foreach ($partner->getExcludedZones() as $zoneExcluded) {
$isZoneExcludedOK = !$this->isSignalementInZone($signalement, $zoneExcluded);
if (!$isZoneExcludedOK) {
break;
}
}
}
// var_dump($isZoneExcludedOK);
}

$result = $isInseeOK && $isZoneOK && $isZoneExcludedOK;
break;
default:
$result = !empty($this->inseeToInclude)
&& \in_array($signalement->getInseeOccupant(), $this->inseeToInclude);
break;
return match ($this->inseeToInclude) {
'all' => true,
'partner_list' => $this->isPartnerListSatisfied($signalement, $partner),
default => $this->isInseeIncluded($signalement->getInseeOccupant()),
};
}

private function isPartnerListSatisfied(Signalement $signalement, Partner $partner): bool
{
$isZoneOK = true;
$isZoneExcludedOK = true;
$isInseeOK = $this->isInseeIncludeInPartnerList($partner, $signalement->getInseeOccupant());

if ($isInseeOK) {
$isZoneOK = $this->isInZone($signalement, $partner->getZones());
if ($isZoneOK && $partner->getExcludedZones()->count() > 0) {
$isZoneExcludedOK = !$this->isInZone($signalement, $partner->getExcludedZones());
}
}

return $result;
return $isInseeOK && $isZoneOK && $isZoneExcludedOK;
}

private function isInZone(Signalement $signalement, Collection $zones): bool
{
if (0 === $zones->count()) {
return true;
}

foreach ($zones as $zone) {
if ($this->isSignalementInZone($signalement, $zone)) {
return true;
}
}

return false;
}

private function isInseeIncludeInPartnerList(Partner $partner, string $insee)
{
return !empty($partner->getInsee()) && \in_array($insee, $partner->getInsee());
}

private function isInseeIncluded(string $insee): bool
{
return !empty($this->inseeToInclude) && \in_array($insee, $this->inseeToInclude);
}

private function isSignalementInZone(Signalement $signalement, Zone $zone): bool
{
$parser = new Parser($zone->getArea());
$zoneArea = $parser->parse();
$signalementCoordinate = new Coordinate($signalement->getGeoloc()['lat'], $signalement->getGeoloc()['lng']);
// var_dump($signalement->getGeoloc());
if ('POLYGON' === $zoneArea['type']) {
$polygon = $this->buildPolygon($zoneArea['value']);
// var_dump($polygon->contains($signalementCoordinate));
if ($polygon->contains($signalementCoordinate)) {

return match ($zoneArea['type']) {
self::TYPE_POLYGON => $this->isPointInPolygon($signalementCoordinate, $zoneArea['value']),
self::TYPE_MULTIPOLYGON => $this->isPointInMultiPolygon($signalementCoordinate, $zoneArea['value']),
self::TYPE_GEOMETRYCOLLECTION => $this->isPointInGeometryCollection($signalementCoordinate, $zoneArea['value']),
default => false,
};
}

private function isPointInPolygon(Coordinate $point, array $polygonData): bool
{
$polygon = $this->buildPolygon($polygonData);

return $polygon->contains($point);
}

private function isPointInMultiPolygon(Coordinate $point, array $multiPolygonData): bool
{
foreach ($multiPolygonData as $polygonData) {
if ($this->isPointInPolygon($point, $polygonData)) {
return true;
}
}
if ('MULTIPOLYGON' === $zoneArea['type']) {
foreach ($zoneArea['value'] as $value) {
$polygon = $this->buildPolygon($value);
if ($polygon->contains($signalementCoordinate)) {
return true;
}

return false;
}

private function isPointInGeometryCollection(Coordinate $point, array $geometryCollection): bool
{
foreach ($geometryCollection as $geometry) {
if (self::TYPE_POLYGON === $geometry['type'] && $this->isPointInPolygon($point, $geometry['value'])) {
return true;
}
}
if ('GEOMETRYCOLLECTION' === $zoneArea['type']) {
foreach ($zoneArea['value'] as $value) {
if ('POLYGON' === $value['type']) {
$polygon = $this->buildPolygon($value['value']);
if ($polygon->contains($signalementCoordinate)) {
return true;
}
}
if ('MULTIPOLYGON' === $value['type']) {
foreach ($value['value'] as $val) {
$polygon = $this->buildPolygon($val);
if ($polygon->contains($signalementCoordinate)) {
return true;
}
}
}
if (self::TYPE_MULTIPOLYGON === $geometry['type'] && $this->isPointInMultiPolygon($point, $geometry['value'])) {
return true;
}
}

Expand All @@ -133,16 +149,13 @@ private function isSignalementInZone(Signalement $signalement, Zone $zone): bool
private function buildPolygon(array $points): Polygon
{
$geofence = new Polygon();
// var_dump($points);
if (1 === \count($points) && \count($points[0]) > 2) {
$points = $points[0];
}
// var_dump($points);
foreach ($points as $point) {
$geofence->addPoint(new Coordinate($point[1], $point[0]));
}

// var_dump($geofence->getPoints());
return $geofence;
}
}
Loading

0 comments on commit 2e11346

Please sign in to comment.