Primo Committ

This commit is contained in:
paoloar77
2024-05-07 12:17:25 +02:00
commit e73d0e5113
7204 changed files with 884387 additions and 0 deletions

View File

@@ -0,0 +1,125 @@
<?php
namespace Facade\Ignition\Support;
use Illuminate\Support\Str;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
class ComposerClassMap
{
/** @var \Composer\Autoload\ClassLoader|FakeComposer */
protected $composer;
/** @var string */
protected $basePath;
public function __construct(?string $autoloaderPath = null)
{
$autoloaderPath = $autoloaderPath ?? base_path('/vendor/autoload.php');
if (file_exists($autoloaderPath)) {
$this->composer = require $autoloaderPath;
} else {
$this->composer = new FakeComposer();
}
$this->basePath = app_path();
}
public function listClasses(): array
{
$classes = $this->composer->getClassMap();
return array_merge($classes, $this->listClassesInPsrMaps());
}
public function searchClassMap(string $missingClass): ?string
{
foreach ($this->composer->getClassMap() as $fqcn => $file) {
$basename = basename($file, '.php');
if ($basename === $missingClass) {
return $fqcn;
}
}
return null;
}
public function listClassesInPsrMaps(): array
{
// TODO: This is incorrect. Doesnt list all fqcns. Need to parse namespace? e.g. App\LoginController is wrong
$prefixes = array_merge(
$this->composer->getPrefixes(),
$this->composer->getPrefixesPsr4()
);
$classes = [];
foreach ($prefixes as $namespace => $directories) {
foreach ($directories as $directory) {
if (file_exists($directory)) {
$files = (new Finder())
->in($directory)
->files()
->name('*.php');
foreach ($files as $file) {
if ($file instanceof SplFileInfo) {
$fqcn = $this->getFullyQualifiedClassNameFromFile($namespace, $file);
$classes[$fqcn] = $file->getRelativePathname();
}
}
}
}
}
return $classes;
}
public function searchPsrMaps(string $missingClass): ?string
{
$prefixes = array_merge(
$this->composer->getPrefixes(),
$this->composer->getPrefixesPsr4()
);
foreach ($prefixes as $namespace => $directories) {
foreach ($directories as $directory) {
if (file_exists($directory)) {
$files = (new Finder())
->in($directory)
->files()
->name('*.php');
foreach ($files as $file) {
if ($file instanceof SplFileInfo) {
$basename = basename($file->getRelativePathname(), '.php');
if ($basename === $missingClass) {
return $namespace.basename($file->getRelativePathname(), '.php');
}
}
}
}
}
}
return null;
}
protected function getFullyQualifiedClassNameFromFile(string $rootNamespace, SplFileInfo $file): string
{
$class = trim(str_replace($this->basePath, '', $file->getRealPath()), DIRECTORY_SEPARATOR);
$class = str_replace(
[DIRECTORY_SEPARATOR, 'App\\'],
['\\', app()->getNamespace()],
ucfirst(Str::replaceLast('.php', '', $class))
);
return $rootNamespace.$class;
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace Facade\Ignition\Support;
class FakeComposer
{
public function getClassMap()
{
return [];
}
public function getPrefixes()
{
return [];
}
public function getPrefixesPsr4()
{
return [];
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Facade\Ignition\Support;
class LaravelVersion
{
public static function major()
{
return substr(app()->version(), 0, 1);
}
}

View File

@@ -0,0 +1,97 @@
<?php
namespace Facade\Ignition\Support;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Livewire\LivewireManager;
use ReflectionClass;
use ReflectionMethod;
use ReflectionProperty;
class LivewireComponentParser
{
/** @var string */
protected $componentAlias;
/** @var string */
protected $componentClass;
/** @var ReflectionClass */
protected $reflectionClass;
public static function create(string $componentAlias): self
{
return new self($componentAlias);
}
public function __construct(string $componentAlias)
{
$this->componentAlias = $componentAlias;
$this->componentClass = app(LivewireManager::class)->getClass($this->componentAlias);
$this->reflectionClass = new ReflectionClass($this->componentClass);
}
public function getComponentClass(): string
{
return $this->componentClass;
}
public function getPropertyNamesLike(string $similar): Collection
{
$properties = collect($this->reflectionClass->getProperties(ReflectionProperty::IS_PUBLIC))
->reject(function (ReflectionProperty $reflectionProperty) {
return $reflectionProperty->class !== $this->reflectionClass->name;
})
->map(function (ReflectionProperty $reflectionProperty) {
return $reflectionProperty->name;
});
$computedProperties = collect($this->reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC))
->reject(function (ReflectionMethod $reflectionMethod) {
return $reflectionMethod->class !== $this->reflectionClass->name;
})
->filter(function (ReflectionMethod $reflectionMethod) {
return str_starts_with($reflectionMethod->name, 'get') && str_ends_with($reflectionMethod->name, 'Property');
})
->map(function (ReflectionMethod $reflectionMethod) {
return lcfirst(Str::of($reflectionMethod->name)->after('get')->before('Property'));
});
return $this->filterItemsBySimilarity(
$properties->merge($computedProperties),
$similar
);
}
public function getMethodNamesLike(string $similar): Collection
{
$methods = collect($this->reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC))
->reject(function (ReflectionMethod $reflectionMethod) {
return $reflectionMethod->class !== $this->reflectionClass->name;
})
->map(function (ReflectionMethod $reflectionMethod) {
return $reflectionMethod->name;
});
return $this->filterItemsBySimilarity($methods, $similar);
}
protected function filterItemsBySimilarity(Collection $items, string $similar): Collection
{
return $items
->map(function (string $name) use ($similar) {
similar_text($similar, $name, $percentage);
return ['match' => $percentage, 'value' => $name];
})
->sortByDesc('match')
->filter(function (array $item) {
return $item['match'] > 40;
})
->map(function (array $item) {
return $item['value'];
})
->values();
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace Facade\Ignition\Support\Packagist;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
class Package
{
/** @var string */
public $name;
/** @var string */
public $url;
/** @var string */
public $repository;
public function __construct(array $properties)
{
$this->name = $properties['name'];
$this->url = $properties['url'];
$this->repository = $properties['repository'];
}
public function hasNamespaceThatContainsClassName(string $className): bool
{
return $this->getNamespaces()->contains(function ($namespace) use ($className) {
return Str::startsWith(strtolower($className), strtolower($namespace));
});
}
protected function getNamespaces(): Collection
{
$details = json_decode(file_get_contents("https://packagist.org/packages/{$this->name}.json"), true);
return collect($details['package']['versions'])
->map(function ($version) {
return collect($version['autoload'] ?? [])
->map(function ($autoload) {
return array_keys($autoload);
})
->flatten();
})
->flatten()
->unique();
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Facade\Ignition\Support\Packagist;
class Packagist
{
/**
* @param string $className
*
* @return \Facade\Ignition\Support\Packagist\Package[]
*/
public static function findPackagesForClassName(string $className): array
{
$parts = explode('\\', $className);
$queryParts = array_splice($parts, 0, 2);
$url = 'https://packagist.org/search.json?q='.implode(' ', $queryParts);
try {
$packages = json_decode(file_get_contents($url));
} catch (\Exception $e) {
return [];
}
return array_map(function ($packageProperties) {
return new Package((array) $packageProperties);
}, $packages->results);
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace Facade\Ignition\Support;
use Facade\FlareClient\Report;
use Illuminate\Support\Arr;
class SentReports
{
/** @var array<int, Report> */
protected $reports = [];
public function add(Report $report): self
{
$this->reports[] = $report;
return $this;
}
public function all(): array
{
return $this->reports;
}
public function uuids(): array
{
return array_map(function (Report $report) {
return $report->trackingUuid();
}, $this->reports);
}
public function urls(): array
{
return array_map(function (string $trackingUuid) {
return "https://flareapp.io/tracked-occurrence/{$trackingUuid}";
}, $this->uuids());
}
public function latestUuid(): ?string
{
if (! $latestReport = Arr::last($this->reports)) {
return null;
}
return $latestReport->trackingUuid();
}
public function latestUrl(): ?string
{
return Arr::last($this->urls());
}
public function clear()
{
$this->reports = [];
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Facade\Ignition\Support;
use Illuminate\Support\Collection;
class StringComparator
{
public static function findClosestMatch(array $strings, string $input, int $sensitivity = 4): ?string
{
$closestDistance = -1;
$closestMatch = null;
foreach ($strings as $string) {
$levenshteinDistance = levenshtein($input, $string);
if ($levenshteinDistance === 0) {
$closestMatch = $string;
$closestDistance = 0;
break;
}
if ($levenshteinDistance <= $closestDistance || $closestDistance < 0) {
$closestMatch = $string;
$closestDistance = $levenshteinDistance;
}
}
if ($closestDistance <= $sensitivity) {
return $closestMatch;
}
return null;
}
public static function findSimilarText(array $strings, string $input): ?string
{
if (empty($strings)) {
return null;
}
return Collection::make($strings)
->sortByDesc(function (string $string) use ($input) {
similar_text($input, $string, $percentage);
return $percentage;
})
->first();
}
}