Files
kupshop/bundles/KupShop/FeedGeneratorBundle/Utils/ObjectInfoTrait.php
2025-08-02 16:30:27 +02:00

127 lines
4.1 KiB
PHP

<?php
namespace KupShop\FeedGeneratorBundle\Utils;
use phpDocumentor\Reflection\DocBlock;
use phpDocumentor\Reflection\DocBlockFactory;
trait ObjectInfoTrait
{
/**
* @throws \ReflectionException
*
* @private
*/
public function getFieldsAndMethods(): array
{
$introspection = [];
$f = new \ReflectionClass($this);
$docBlockFactory = DocBlockFactory::createInstance();
$ignoredClasses = [
\KupShop\FeedsBundle\Wrapper\BaseWrapper::class,
\KupShop\FeedsBundle\Wrapper\MultiWrapper::class,
\KupShop\FeedsBundle\Wrapper\ObjectMultiWrapper::class,
];
foreach ($f->getMethods() as $method) {
if (array_search($method->class, $ignoredClasses) !== false || !$method->isPublic() || $method->isConstructor()) {
continue;
}
$description = '';
$help = '';
if ($method->getDocComment()) {
$docBlock = $docBlockFactory->create($method);
if ($docBlock->getTagsByName('private') || $docBlock->getTagsByName('deprecated') || $this->requiredModuleIsDisabled($docBlock)) {
continue;
}
$description = $docBlock->getSummary();
$help = $docBlock->getDescription()->render();
}
if (substr($method->name, 0, 6) == 'field_') {
$name = substr($method->name, 6);
$rawName = $name;
$isMethod = false;
} else {
$name = $this->printMethodPrototype($method);
$rawName = $method->name.'()';
$isMethod = true;
}
$return = $method->getReturnType();
if ($return) {
$return = strval($return->getName());
}
$tmpArr = [
'name' => $name,
'rawName' => $rawName,
'description' => $description,
'help' => $help,
'method' => $isMethod,
'return' => $return,
'value' => !$isMethod && (!isset($docBlock) || !$docBlock->getTagsByName('implementedInJS')) ? call_user_func([$this, $method->name]) : '',
];
// TODO: remove clone once non shared wrappers are used
if ($tmpArr['value'] instanceof IObjectInfo) {
$tmpArr['value'] = clone $tmpArr['value'];
}
$introspection[] = $tmpArr;
}
usort($introspection, function ($a, $b) {
return strcmp($a['name'], $b['name']);
});
return $introspection;
}
protected function printMethodPrototype(\ReflectionMethod $method)
{
$args = [];
foreach ($method->getParameters() as $p) {
$args[] = ($this->declaresArray($p) ? 'array ' : ($p->getType() !== null && $p->getType()->__toString() ? $p->getType()->__toString().' ' : ''))
.($p->isPassedByReference() ? '&' : '').'$'.$p->name
.($p->isOptional() ? ' = '.var_export($p->getDefaultValue(), true) : '');
}
return "{$method->name} (".implode(', ', $args).')';
}
protected function declaresArray(\ReflectionParameter $reflectionParameter): bool
{
$reflectionType = $reflectionParameter->getType();
if (!$reflectionType) {
return false;
}
$types = $reflectionType instanceof \ReflectionUnionType
? $reflectionType->getTypes()
: [$reflectionType];
return in_array('array', array_map(fn (\ReflectionNamedType $t) => $t->getName(), $types));
}
protected function requiredModuleIsDisabled(DocBlock $docBlock): bool
{
$moduleRaw = $docBlock->getTagsByName('module');
if (!empty($moduleRaw)) {
$key = trim((string) ($moduleRaw[0] ?? ''), "\"'");
$parts = explode('__', $key);
$module = $parts[0];
$submodule = getVal(1, $parts);
if (!\Modules::check($module, $submodule)) {
return true; // disabled module
}
}
return false;
}
}