Compare commits
18
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
886714704b | ||
|
|
64785ea055 | ||
|
|
c6bd5707bc | ||
|
|
13ccb13a0b | ||
|
|
67aa7e513d | ||
|
|
eac8269c48 | ||
|
|
fa0430a3fc | ||
|
|
237f0a30d2 | ||
|
|
b093f53a6b | ||
|
|
dd239c63bc | ||
|
|
0db34fe228 | ||
|
|
fa4fe32277 | ||
|
|
e20157a162 | ||
|
|
63c7dc23f9 | ||
|
|
a4d99dfe08 | ||
|
|
f199cc7085 | ||
|
|
fcb332ae53 | ||
|
|
133672b347 |
No files matched your search
-129
@@ -1,129 +0,0 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
array_shift($argv);
|
||||
|
||||
$opt = getopt('c::f:v', [ 'folder:', 'confirm', 'verbose', 'clean', 'old' ]);
|
||||
|
||||
if ( ! $opt ) {
|
||||
exit("Bad arguments provided, you must specify a fullpath using the -f or --folder option\n");
|
||||
}
|
||||
|
||||
$iterator = new RecursiveIteratorIterator(new class(new RecursiveDirectoryIterator($opt['folder'] ?? $opt['f'], FilesystemIterator::SKIP_DOTS)) extends RecursiveFilterIterator {
|
||||
public function accept() : bool {
|
||||
return true;
|
||||
}
|
||||
}, RecursiveIteratorIterator::SELF_FIRST);
|
||||
|
||||
$files = array();
|
||||
|
||||
foreach ($iterator as $info) {
|
||||
if ($info->getExtension() !== "php" || $info->isDir() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
echo sprintf("\n### MIGRATING FILE %s\n", $info->getFilename());
|
||||
|
||||
$opened = false;
|
||||
|
||||
$attr = $newContent = [];
|
||||
|
||||
$content = file_get_contents($info->getPathname());
|
||||
|
||||
if ( isset($opt['clean']) ) {
|
||||
foreach (explode(PHP_EOL, $content) as $lineIdx => $line) {
|
||||
if ( $pos = strpos($line, '# migrated from: ') ) {
|
||||
$attr = true;
|
||||
|
||||
$newContent[] = $newLine = substr($line, 0, $pos);
|
||||
|
||||
echo sprintf("Changed line '%s' \n", trim($newLine));
|
||||
}
|
||||
else {
|
||||
$newContent[] = $line;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
foreach (explode(PHP_EOL, $content) as $lineIdx => $line) {
|
||||
$tline = trim($line);
|
||||
|
||||
if ($tline === "/**") {
|
||||
$opened = true;
|
||||
} elseif ($tline === '*/') {
|
||||
$opened = false;
|
||||
} elseif (substr($tline, 0, 1) === '*') {
|
||||
$annotation = trim(substr($tline, 1));
|
||||
|
||||
if (strpos($annotation, '@') === 0) {
|
||||
$argpos = strpos($annotation, '(');
|
||||
|
||||
if ($argpos !== false) {
|
||||
$name = substr($annotation, 1, $argpos - 1);
|
||||
$args = substr($annotation, $argpos + 1, strrpos($annotation, ')') - $argpos - 1);
|
||||
|
||||
try {
|
||||
$array = eval("return [{$args}];");
|
||||
|
||||
$renderedArgs = [];
|
||||
|
||||
foreach ($array as $key => $argument) {
|
||||
|
||||
if (is_array($argument)) {
|
||||
$argument = var_export($argument, true);
|
||||
} elseif (is_bool($argument)) {
|
||||
$argument = $argument ? 'true' : 'false';
|
||||
} elseif (!is_numeric($argument)) {
|
||||
$argument = "\"$argument\"";
|
||||
}
|
||||
|
||||
if (is_numeric($key)) {
|
||||
$renderedArgs[] = $argument;
|
||||
} else {
|
||||
$renderedArgs[] = "$key: $argument";
|
||||
}
|
||||
}
|
||||
|
||||
$renderedArgs = implode(', ', $renderedArgs);
|
||||
} catch (\Throwable $e) {
|
||||
echo sprintf("!!! WARNING : %s in file (%s) line %d ; using previous notation.\n", $e->getMessage(), $info->getPathname(), $lineIdx + 1);
|
||||
|
||||
$renderedArgs = str_replace(' => ', ': ', $args);
|
||||
}
|
||||
} else {
|
||||
$name = substr($annotation, 1);
|
||||
$renderedArgs = "";
|
||||
}
|
||||
|
||||
$attr[] = $attribute = sprintf("%s#[%s%s]%s", str_repeat(" ", strlen($line) - strlen(ltrim($line)) >= 4 ? 4 : 0), $name, $renderedArgs ? "($renderedArgs)" : "", $renderedArgs ? ( isset($opt['old']) ? " # migrated from: $args" : "" ) : "");
|
||||
|
||||
$newContent[] = $attribute;
|
||||
}
|
||||
} else {
|
||||
$newContent[] = $line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$newContent = implode(PHP_EOL, $newContent);
|
||||
|
||||
if ($attr) {
|
||||
if ( isset($opt['verbose']) || isset($opt['v']) ) {
|
||||
echo $newContent;
|
||||
}
|
||||
|
||||
if ( isset($opt['confirm']) || isset($opt['c']) ) {
|
||||
file_put_contents($info->getPathname(), $newContent);
|
||||
|
||||
echo sprintf("\n### FILE CONVERSION COMPLETED %s\n", $info->getFilename());
|
||||
}
|
||||
else {
|
||||
echo sprintf("\n### FILE CONVERSION ANALYZED, NOTHING WRITTEN UNTIL --confirm or -c FLAG IS PROVIDED %s\n", $info->getFilename());
|
||||
}
|
||||
}
|
||||
else {
|
||||
echo sprintf("\n### NOTHING TO DO ON FILE %s\n", $info->getFilename());
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"mcnd/kash" : "dev-master"
|
||||
"mcnd/kash" : "^1.0.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
@@ -33,8 +33,9 @@ class AttributeReader
|
||||
{
|
||||
switch(true) {
|
||||
case $reflect instanceof ReflectionMethod :
|
||||
case $reflect instanceof ReflectionProperty :
|
||||
return $reflect->class . "::" . $reflect->name;
|
||||
case $reflect instanceof ReflectionProperty :
|
||||
return $reflect->class . "::$" . $reflect->name;
|
||||
|
||||
case $reflect instanceof ReflectionClass :
|
||||
return $reflect->name;
|
||||
|
||||
@@ -21,7 +21,6 @@ abstract class Reflected
|
||||
$type = strtolower($type);
|
||||
|
||||
foreach($this->getTypes() as $item) {
|
||||
|
||||
if ($type === "null") {
|
||||
if ($item->type === "null" || $item->nullable) {
|
||||
return true;
|
||||
@@ -46,6 +45,8 @@ abstract class Reflected
|
||||
$type = $property->getType();
|
||||
|
||||
if ($type instanceof \ReflectionUnionType ) {
|
||||
$this->type = [];
|
||||
|
||||
foreach($type->getTypes() as $item) {
|
||||
$this->type[] = new ReflectedPropertyType($item->getName(), $item->isBuiltIn(), $item->allowsNull());
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@ class ReflectedClass implements ReflectedInterface
|
||||
|
||||
public function getClassName() : string
|
||||
{
|
||||
return end(explode('\\', $this->name));
|
||||
$exploded = explode('\\', $this->name);
|
||||
|
||||
return end($exploded);
|
||||
}
|
||||
|
||||
public function getProperties(bool $deep = true) : array
|
||||
@@ -173,10 +175,8 @@ class ReflectedClass implements ReflectedInterface
|
||||
public function getAttribute(string $attributeType): ?object
|
||||
{
|
||||
foreach($this->getAttributes(true, $attributeType) as $attribute) {
|
||||
if ($attribute->object instanceof $attributeType) {
|
||||
return $attribute;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -18,4 +18,14 @@ class ReflectedPropertyType
|
||||
|
||||
return $this->type === $type;
|
||||
}
|
||||
|
||||
public function isObject() : bool
|
||||
{
|
||||
return ! $this->builtIn && class_exists($this->type);
|
||||
}
|
||||
|
||||
public function isEnum() : bool
|
||||
{
|
||||
return ! $this->builtIn && enum_exists($this->type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Notes\Common;
|
||||
|
||||
class ReflectedPropertyType
|
||||
{
|
||||
public function __construct(
|
||||
public string $type,
|
||||
public bool $builtIn,
|
||||
public bool $nullable,
|
||||
) {}
|
||||
|
||||
public function isType(string $type) : bool
|
||||
{
|
||||
if ($type === "null" || $this->nullable) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->type === $type;
|
||||
}
|
||||
|
||||
public function isObject() : bool
|
||||
{
|
||||
return ! $this->builtIn && class_exists($this->type);
|
||||
}
|
||||
}
|
||||
@@ -7,5 +7,6 @@ class Cronard implements \Notes\Attribute {
|
||||
public function __construct(
|
||||
public string $cron,
|
||||
public null|string $method = null,
|
||||
public null|string $name = null,
|
||||
) {}
|
||||
}
|
||||
@@ -23,10 +23,7 @@ class ObjectReflection {
|
||||
$this->classname = ltrim($class instanceof ReflectionClass ? $class->getName() : $class, '\\');
|
||||
|
||||
$this->cache = $cache;
|
||||
|
||||
#if ( ! $this->cache || ! $this->cache->has($class) ) {
|
||||
$this->classReflection = $class instanceof ReflectionClass ? $class : new ReflectionClass($class);
|
||||
# }
|
||||
}
|
||||
|
||||
public static function fromClass(ReflectionClass|string $class, ? CacheInterface $cache = null) : self
|
||||
@@ -66,7 +63,6 @@ class ObjectReflection {
|
||||
|
||||
foreach($this->classReflection->getProperties($filter) as $property) {
|
||||
$reflected = new ReflectedProperty($property->getName());
|
||||
|
||||
$reflected->attributes = AttributeReader::reflectAttributes($property);
|
||||
|
||||
if ( $reflected->hasIgnoreAttribute() ) {
|
||||
@@ -87,18 +83,17 @@ class ObjectReflection {
|
||||
}
|
||||
|
||||
public function reflectMethods(int $filter =
|
||||
ReflectionMethod::IS_PUBLIC |
|
||||
ReflectionMethod::IS_PROTECTED |
|
||||
ReflectionMethod::IS_PRIVATE |
|
||||
ReflectionMethod::IS_STATIC |
|
||||
ReflectionMethod::IS_FINAL
|
||||
ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED |
|
||||
ReflectionMethod::IS_PRIVATE | ReflectionMethod::IS_STATIC |
|
||||
ReflectionMethod::IS_FINAL,
|
||||
bool $includeParents = false
|
||||
) : array
|
||||
{
|
||||
$list = [];
|
||||
|
||||
foreach($this->classReflection->getMethods($filter) as $method) {
|
||||
# Skipping parent's methods, we'll retrieve them in its own reflection
|
||||
if ( $method->class !== $this->classname ) {
|
||||
if ( ! $includeParents && $method->class !== $this->classname ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@ class Route implements \Notes\Attribute {
|
||||
public string $description = "",
|
||||
) {}
|
||||
|
||||
public function getBase() : ?string
|
||||
{
|
||||
return $this->base ? rtrim($this->base, '/') : null;
|
||||
}
|
||||
|
||||
public function getRoute() : string
|
||||
{
|
||||
return rtrim("/" . trim(isset($this->base) ?
|
||||
@@ -25,6 +30,11 @@ class Route implements \Notes\Attribute {
|
||||
"/" . ltrim($this->route, "/"), "/"), '/');
|
||||
}
|
||||
|
||||
public function getRegistrableRoute() : string
|
||||
{
|
||||
return preg_replace('/(\=.*)(?=\})/i', '', $this->getRoute());
|
||||
}
|
||||
|
||||
public function matchRouteName(string $name) : bool
|
||||
{
|
||||
return strtolower($this->name) === strtolower($name);
|
||||
|
||||
@@ -8,5 +8,11 @@ class Route implements \Notes\Attribute {
|
||||
public string|array $method = [ "GET", "POST" ],
|
||||
# NULL will fallback on nearest base
|
||||
public null|string $base = null,
|
||||
public null|bool $inheritRoutes = null, # true or false will skip others attribute from parents after, null = skipped for this one.
|
||||
){}
|
||||
|
||||
public function getBase() : ?string
|
||||
{
|
||||
return $this->base ? rtrim($this->base, '/') : null;
|
||||
}
|
||||
}
|
||||
@@ -81,6 +81,14 @@ class RouteFetcher {
|
||||
{
|
||||
$attributes ??= $this->attributes;
|
||||
|
||||
/*
|
||||
8.5: return $attributes
|
||||
|> serialize(...)
|
||||
|> md5(...)
|
||||
|> (fn($x) => substr($x, 0, 7))
|
||||
|> (fn($x) => $this->handleCaching())
|
||||
*/
|
||||
|
||||
return $this->handleCaching(substr(md5(serialize($attributes)), 0, 7), function() use ($attributes) : array {
|
||||
$list = [];
|
||||
|
||||
@@ -92,11 +100,13 @@ class RouteFetcher {
|
||||
$base = null;
|
||||
$class = $this->generateClassname($file->getBasename(".php"), $namespace);
|
||||
$methods = null;
|
||||
$inheritRoutes = null;
|
||||
|
||||
$objectResolver = new ObjectResolver($class, $this->cache);
|
||||
|
||||
if ( isset($attributes['object']) ) {
|
||||
|
||||
# Also loading Routes attribute from parent classes
|
||||
$objects = $objectResolver->reflectedClass->getClassAttributeListFromClassname($attributes['object'], true, false);
|
||||
|
||||
foreach($objects as $object) {
|
||||
@@ -104,12 +114,13 @@ class RouteFetcher {
|
||||
$methods ??= (array) $object->method;
|
||||
}
|
||||
|
||||
$inheritRoutes ??= $object->inheritRoutes;
|
||||
$base ??= $object->base ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset($attributes['method']) ) {
|
||||
$routeList = $objectResolver->reflectedClass->getMethodAttributeListFromClassname( $attributes['method'], false, false );
|
||||
$routeList = $objectResolver->reflectedClass->getMethodAttributeListFromClassname( $attributes['method'], (bool) $inheritRoutes, false );
|
||||
|
||||
foreach($routeList as $func => $routes) {
|
||||
if (is_array($routes)) {
|
||||
@@ -118,12 +129,10 @@ class RouteFetcher {
|
||||
if ($route instanceof \Notes\Route\Attribute\Method\Route) {
|
||||
$route->base = $route->base ?: $base;
|
||||
}
|
||||
|
||||
$route->class = $class;
|
||||
$route->classMethod = $func;
|
||||
|
||||
if (false === ($route->methods ?? false)) {
|
||||
$route->methods = $methods ?? $this->defaultMethods;
|
||||
}
|
||||
$route->method ??= $methods ?? $this->defaultMethods;
|
||||
|
||||
if (false !== ($this->callback ?? false)) {
|
||||
call_user_func_array($this->callback, [$route]);
|
||||
|
||||
@@ -14,11 +14,11 @@ class SecurityHandler {
|
||||
|
||||
protected ResponseInterface $redirectResponse;
|
||||
|
||||
protected ? \Closure $unauthorizeResponse;
|
||||
protected \Closure|ResponseInterface|null $unauthorizeResponse;
|
||||
|
||||
protected ? Taxus $taxus;
|
||||
|
||||
public function __construct(ResponseInterface $redirectResponse, ? \Closure $unauthorizeResponse = null, ? Taxus $taxus = null) {
|
||||
public function __construct(ResponseInterface $redirectResponse, \Closure|ResponseInterface|null $unauthorizeResponse = null, ? Taxus $taxus = null) {
|
||||
$this->redirectResponse = $redirectResponse;
|
||||
$this->unauthorizeResponse = $unauthorizeResponse;
|
||||
$this->taxus = $taxus;
|
||||
@@ -40,25 +40,40 @@ class SecurityHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function taxus(string $className, string $methodName, object $user = null) : ? ResponseInterface
|
||||
public function taxus(string $className, string $methodName, ... $arguments) : ? ResponseInterface
|
||||
{
|
||||
$fromObject = $this->findAttributes(Attribute\Taxus::class, $className);
|
||||
$fromMethod = $this->findAttributes(Attribute\Taxus::class, $className, $methodName);
|
||||
$granted = $this->hasGrantPermission($className , $methodName, ...$arguments);
|
||||
|
||||
if ($fromMethod || $fromObject) {
|
||||
if ( $this->taxusGrantPermission($fromMethod, $user) || $this->taxusGrantPermission($fromObject, $user) ) {
|
||||
if ($granted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
else {
|
||||
if ($this->unauthorizeResponse) {
|
||||
return call_user_func_array($this->unauthorizeResponse, [ $user, ['method' => $fromMethod, 'object' => $fromObject ], $className, $methodName ]);
|
||||
if ($this->unauthorizeResponse instanceof ResponseInterface) {
|
||||
return $this->unauthorizeResponse;
|
||||
}
|
||||
|
||||
return call_user_func_array($this->unauthorizeResponse, [ ...$arguments, ['method' => $methodName, 'object' => $className ], $className, $methodName ]);
|
||||
}
|
||||
else {
|
||||
throw new \ErrorException("Unauthorized response given.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
public function hasGrantPermission(string $className, string $methodName, ... $arguments) : bool
|
||||
{
|
||||
$fromObject = $this->findAttributes(Attribute\Taxus::class, $className);
|
||||
$fromMethod = $this->findAttributes(Attribute\Taxus::class, $className, $methodName);
|
||||
|
||||
if ($fromMethod) {
|
||||
return $this->taxusGrantPermission($fromMethod, ... $arguments);
|
||||
}
|
||||
elseif ($fromObject) {
|
||||
return $this->taxusGrantPermission($fromObject, ... $arguments);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function findAttributes(string $attribute, string $class, ? string $method = null) : array
|
||||
@@ -86,10 +101,10 @@ class SecurityHandler {
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function taxusGrantPermission(array $attributeList, object $user = null) : bool
|
||||
protected function taxusGrantPermission(array $attributeList, ...$arguments) : bool
|
||||
{
|
||||
foreach ($attributeList as $item) {
|
||||
if ( $grant = $this->taxus->granted($item->privilege, $user, $item) ) {
|
||||
if ( $grant = $this->taxus->granted($item->privilege, ... array_merge($arguments, [ $item ])) ) {
|
||||
if (is_bool($grant) ? $grant : $grant === TaxusGrantEnum::Authorized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user