Initial import from aternosorg/codex-minecraft
Some checks failed
Tests / Run tests on PHP v8.4 (push) Failing after 32s
Tests / Run tests on PHP v8.5 (push) Failing after 2s

This commit is contained in:
2026-04-30 09:56:57 -05:00
commit 7c7fe5ca80
94 changed files with 7003 additions and 0 deletions

238
src/Analysis/Analysis.php Normal file
View File

@@ -0,0 +1,238 @@
<?php
namespace Aternos\Codex\Analysis;
use Aternos\Codex\Log\LogInterface;
/**
* Class Analysis
*
* @package Aternos\Codex\Analysis
*/
class Analysis implements AnalysisInterface
{
/**
* @var InsightInterface[]
*/
protected array $insights = [];
protected int $iterator = 0;
protected ?LogInterface $log = null;
/**
* Set all insights at once in an array replacing the current insights
*
* @param InsightInterface[] $insights
* @return $this
*/
public function setInsights(array $insights = []): static
{
foreach ($insights as $insight) {
$insight->setAnalysis($this);
}
$this->insights = $insights;
return $this;
}
/**
* Add an insight.
* If the insight already exists, we increase its counter.
*
* @param InsightInterface $insight
* @return $this
*/
public function addInsight(InsightInterface $insight): static
{
$insight->setAnalysis($this);
foreach ($this as $existingInsight) {
if (get_class($insight) === get_class($existingInsight) && $existingInsight->isEqual($insight)) {
$existingInsight->increaseCounter();
return $this;
}
}
$this->insights[] = $insight;
return $this;
}
/**
* Get all insights
*
* @return InsightInterface[]
*/
public function getInsights(): array
{
return $this->insights;
}
/**
* Get all insights that are extended from $extendedFrom (class name)
*
* @param class-string<InsightInterface> $extendedFrom
* @return InsightInterface[]
*/
public function getFilteredInsights(string $extendedFrom): array
{
$returnInsights = [];
foreach ($this->getInsights() as $insight) {
if ($insight instanceof $extendedFrom) {
$returnInsights[] = $insight;
}
}
return $returnInsights;
}
/**
* Get all problem insights
*
* @return ProblemInterface[]
*/
public function getProblems(): array
{
return $this->getFilteredInsights(ProblemInterface::class);
}
/**
* Get all information insights
*
* @return InformationInterface[]
*/
public function getInformation(): array
{
return $this->getFilteredInsights(InformationInterface::class);
}
/**
* Return the current element
*
* @return InsightInterface
*/
public function current(): InsightInterface
{
return $this->insights[$this->iterator];
}
/**
* Move forward to next element
*
* @return void
*/
public function next(): void
{
$this->iterator++;
}
/**
* Return the key of the current element
*
* @return int
*/
public function key(): int
{
return $this->iterator;
}
/**
* Checks if current position is valid
*
* @return boolean
*/
public function valid(): bool
{
return array_key_exists($this->iterator, $this->insights);
}
/**
* Rewind the Iterator to the first element
*
* @return void
*/
public function rewind(): void
{
$this->iterator = 0;
}
/**
* Count elements of an object
*
* @return int
*/
public function count(): int
{
return count($this->insights);
}
/**
* Whether an offset exists
*
* @param mixed $offset
* @return bool
*/
public function offsetExists(mixed $offset): bool
{
return isset($this->insights[$offset]);
}
/**
* Offset to retrieve
*
* @param mixed $offset
* @return InsightInterface
*/
public function offsetGet(mixed $offset): InsightInterface
{
return $this->insights[$offset];
}
/**
* Offset to set
*
* @param mixed $offset
* @param InsightInterface $value
*/
public function offsetSet(mixed $offset, mixed $value): void
{
$value->setAnalysis($this);
$this->insights[$offset] = $value;
}
/**
* Offset to unset
*
* @param mixed $offset
*/
public function offsetUnset(mixed $offset): void
{
unset($this->insights[$offset]);
}
/**
* @return array
*/
public function jsonSerialize(): array
{
return [
"problems" => $this->getProblems(),
"information" => $this->getInformation()
];
}
/**
* @param LogInterface $log
* @return $this
*/
public function setLog(LogInterface $log): static
{
$this->log = $log;
return $this;
}
/**
* @return LogInterface|null
*/
public function getLog(): ?LogInterface
{
return $this->log;
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace Aternos\Codex\Analysis;
use ArrayAccess;
use Aternos\Codex\Log\LogInterface;
use Countable;
use Iterator;
use JsonSerializable;
/**
* Interface AnalysisInterface
*
* @package Aternos\Codex\Analysis
*/
interface AnalysisInterface extends Iterator, Countable, ArrayAccess, JsonSerializable
{
/**
* Set the log
*
* @param LogInterface $log
* @return $this
*/
public function setLog(LogInterface $log): static;
/**
* Get the log
*
* @return LogInterface|null
*/
public function getLog(): ?LogInterface;
/**
* Set all insights at once in an array replacing the current insights
*
* @param InsightInterface[] $insights
* @return $this
*/
public function setInsights(array $insights = []): static;
/**
* Add an insight
*
* @param InsightInterface $insight
* @return $this
*/
public function addInsight(InsightInterface $insight): static;
/**
* Get all insights
*
* @return InsightInterface[]
*/
public function getInsights(): array;
/**
* Get all problem insights
*
* @return ProblemInterface[]
*/
public function getProblems(): array;
/**
* Get all information insights
*
* @return InformationInterface[]
*/
public function getInformation(): array;
/**
* Get all insights that are extended from $extendedFrom (class name)
*
* @param class-string<InsightInterface> $extendedFrom
* @return InsightInterface[]
*/
public function getFilteredInsights(string $extendedFrom): array;
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Aternos\Codex\Analysis;
/**
* Interface AutomatableSolutionInterface
*
* This interface should be used to indicate
* that a solution can be solved automatically
* e.g. deletion/creation/modification of files
*
* @package Aternos\Codex\Analysis
*/
interface AutomatableSolutionInterface extends SolutionInterface
{
}

View File

@@ -0,0 +1,90 @@
<?php
namespace Aternos\Codex\Analysis;
/**
* Class Information
*
* @package Aternos\Codex\Analysis
*/
abstract class Information extends Insight implements InformationInterface
{
protected ?string $label = null;
protected mixed $value = null;
/**
* Get the information label
*
* @return string
*/
public function getLabel(): string
{
return $this->label;
}
/**
* Set the information label
*
* @param string $label
* @return $this
*/
protected function setLabel(string $label): static
{
$this->label = $label;
return $this;
}
/**
* Get the information value
*
* @return mixed
*/
public function getValue(): mixed
{
return $this->value;
}
/**
* Set the information value
*
* @param mixed $value
* @return $this
*/
public function setValue(mixed $value): static
{
$this->value = $value;
return $this;
}
/**
* Get a human-readable message
*
* @return string
*/
public function getMessage(): string
{
return $this->getLabel() . ": " . $this->getValue();
}
/**
* Check if the $insight object is equal with the current object
*
* @param InsightInterface $insight
* @return bool
*/
public function isEqual(InsightInterface $insight): bool
{
return $insight instanceof InformationInterface && $this->getLabel() === $insight->getLabel() && $this->getValue() === $insight->getValue();
}
/**
* @return array
*/
public function jsonSerialize(): array
{
return array_merge(parent::jsonSerialize(), [
"label" => $this->getLabel(),
"value" => $this->getValue()
]);
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace Aternos\Codex\Analysis;
/**
* Interface InformationInterface
*
* @package Aternos\Codex\Analysis
*/
interface InformationInterface extends InsightInterface
{
/**
* Get the information label
*
* @return string
*/
public function getLabel(): string;
/**
* Set the information value
*
* @param mixed $value
* @return $this
*/
public function setValue(mixed $value): static;
/**
* Get the information value
*
* @return mixed
*/
public function getValue(): mixed;
}

119
src/Analysis/Insight.php Normal file
View File

@@ -0,0 +1,119 @@
<?php
namespace Aternos\Codex\Analysis;
use Aternos\Codex\Log\EntryInterface;
use Aternos\Codex\Log\LogInterface;
/**
* Class Insight
*
* @package Aternos\Codex\Analysis
*/
abstract class Insight implements InsightInterface
{
protected ?AnalysisInterface $analysis = null;
protected ?EntryInterface $entry = null;
protected int $counter = 1;
/**
* Set the related entry
*
* @param EntryInterface $entry
* @return $this
*/
public function setEntry(EntryInterface $entry): static
{
$this->entry = $entry;
return $this;
}
/**
* Get the related entry
*
* @return EntryInterface
*/
public function getEntry(): EntryInterface
{
return $this->entry;
}
/**
* Increase the counter for this insight
*
* @return $this
*/
public function increaseCounter(): static
{
$this->counter++;
return $this;
}
/**
* Get the current counter value
*
* @return int
*/
public function getCounterValue(): int
{
return $this->counter;
}
/**
* @return string
*/
public function __toString(): string
{
return $this->getMessage();
}
/**
* @return array
*/
public function jsonSerialize(): array
{
return [
'message' => $this->getMessage(),
'counter' => $this->getCounterValue(),
'entry' => $this->getEntry()
];
}
/**
* Set the related analysis
*
* @param AnalysisInterface $analysis
* @return $this
*/
public function setAnalysis(AnalysisInterface $analysis): static
{
$this->analysis = $analysis;
return $this;
}
/**
* Get the related analysis
*
* @return AnalysisInterface|null
*/
public function getAnalysis(): ?AnalysisInterface
{
return $this->analysis;
}
/**
* @return LogInterface|null
*/
protected function getLog(): ?LogInterface
{
return $this->getAnalysis()?->getLog();
}
/**
* @return string|null
*/
protected function getLogContent(): ?string
{
return $this->getLog()?->getLogFile()?->getContent();
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Aternos\Codex\Analysis;
use Aternos\Codex\Log\EntryInterface;
use JsonSerializable;
/**
* Interface InsightInterface
*
* @package Aternos\Codex\Analysis
*/
interface InsightInterface extends JsonSerializable
{
/**
* Get a human-readable message
*
* @return string
*/
public function getMessage(): string;
/**
* @return string
*/
public function __toString(): string;
/**
* Set the related entry
*
* @param EntryInterface $entry
* @return $this
*/
public function setEntry(EntryInterface $entry): static;
/**
* Get the related entry
*
* @return EntryInterface
*/
public function getEntry(): EntryInterface;
/**
* Check if the $insight object is equal with the current object
*
* @param InsightInterface $insight
* @return bool
*/
public function isEqual(InsightInterface $insight): bool;
/**
* Increase the counter for this insight
*
* @return $this
*/
public function increaseCounter(): static;
/**
* Get the current counter value
*
* @return int
*/
public function getCounterValue(): int;
/**
* Set the related analysis
*
* @param AnalysisInterface $analysis
* @return $this
*/
public function setAnalysis(AnalysisInterface $analysis): static;
/**
* Get the related analysis
*
* @return AnalysisInterface|null
*/
public function getAnalysis(): ?AnalysisInterface;
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Aternos\Codex\Analysis;
/**
* Interface PatternInsightInterface
*
* @package Aternos\Codex\Analysis
*/
interface PatternInsightInterface extends InsightInterface
{
/**
* Get an array of possible patterns
*
* The array key of the pattern will be passed to setMatches()
*
* @return string[]
*/
public static function getPatterns(): array;
/**
* Apply the matches from the pattern
*
* @param array $matches
* @param mixed $patternKey
* @return void
*/
public function setMatches(array $matches, mixed $patternKey): void;
}

168
src/Analysis/Problem.php Normal file
View File

@@ -0,0 +1,168 @@
<?php
namespace Aternos\Codex\Analysis;
/**
* Class Problem
*
* @package Aternos\Codex\Analysis
*/
abstract class Problem extends Insight implements ProblemInterface
{
/**
* @var SolutionInterface[]
*/
protected array $solutions = [];
/**
* @var int
*/
protected int $iterator = 0;
/**
* Set all solutions at once in an array replacing the current solutions
*
* @param SolutionInterface[] $solutions
* @return $this
*/
public function setSolutions(array $solutions = []): static
{
$this->solutions = $solutions;
return $this;
}
/**
* Add a solution
*
* @param SolutionInterface $solution
* @return $this
*/
public function addSolution(SolutionInterface $solution): static
{
$this->solutions[] = $solution;
return $this;
}
/**
* Get all solutions
*
* @return array
*/
public function getSolutions(): array
{
return $this->solutions;
}
/**
* Return the current element
*
* @return SolutionInterface
*/
public function current(): SolutionInterface
{
return $this->solutions[$this->iterator];
}
/**
* Move forward to next element
*
* @return void
*/
public function next(): void
{
$this->iterator++;
}
/**
* Return the key of the current element
*
* @return int
*/
public function key(): int
{
return $this->iterator;
}
/**
* Checks if current position is valid
*
* @return boolean
*/
public function valid(): bool
{
return array_key_exists($this->iterator, $this->solutions);
}
/**
* Rewind the Iterator to the first element
*
* @return void
*/
public function rewind(): void
{
$this->iterator = 0;
}
/**
* Count elements of an object
*
* @return int
*/
public function count(): int
{
return count($this->solutions);
}
/**
* Whether an offset exists
*
* @param mixed $offset
* @return bool
*/
public function offsetExists(mixed $offset): bool
{
return isset($this->solutions[$offset]);
}
/**
* Offset to retrieve
*
* @param mixed $offset
* @return SolutionInterface
*/
public function offsetGet(mixed $offset): SolutionInterface
{
return $this->solutions[$offset];
}
/**
* Offset to set
*
* @param mixed $offset
* @param SolutionInterface $value
*/
public function offsetSet(mixed $offset, mixed $value): void
{
$this->solutions[$offset] = $value;
}
/**
* Offset to unset
*
* @param mixed $offset
*/
public function offsetUnset(mixed $offset): void
{
unset($this->solutions[$offset]);
}
/**
* @return array
*/
public function jsonSerialize(): array
{
return array_merge(parent::jsonSerialize(), [
"solutions" => $this->getSolutions()
]);
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Aternos\Codex\Analysis;
use ArrayAccess;
use Countable;
use Iterator;
/**
* Interface ProblemInterface
*
* @package Aternos\Codex\Analysis
*/
interface ProblemInterface extends Iterator, Countable, ArrayAccess, InsightInterface
{
/**
* Set all solutions at once in an array replacing the current solutions
*
* @param SolutionInterface[] $solutions
* @return $this
*/
public function setSolutions(array $solutions = []): static;
/**
* Add a solution
*
* @param SolutionInterface $solution
* @return $this
*/
public function addSolution(SolutionInterface $solution): static;
/**
* Get all solutions
*
* @return SolutionInterface[]
*/
public function getSolutions(): array;
}

29
src/Analysis/Solution.php Normal file
View File

@@ -0,0 +1,29 @@
<?php
namespace Aternos\Codex\Analysis;
/**
* Class Solution
*
* @package Aternos\Codex\Analysis
*/
abstract class Solution implements SolutionInterface
{
/**
* @return string
*/
public function __toString(): string
{
return $this->getMessage();
}
/**
* @return array
*/
public function jsonSerialize(): array
{
return [
'message' => $this->getMessage()
];
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace Aternos\Codex\Analysis;
use JsonSerializable;
/**
* Interface SolutionInterface
*
* @package Aternos\Codex\Analysis
*/
interface SolutionInterface extends JsonSerializable
{
/**
* Get the solution as a human-readable message
*
* @return string
*/
public function getMessage(): string;
public function __toString(): string;
}