Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUGFIX: Fix and make nodeTypes:show command usable #4619

Merged
merged 4 commits into from
Nov 8, 2023

Conversation

mhsdesign
Copy link
Member

@mhsdesign mhsdesign commented Oct 15, 2023

Fixes handling of invalid nodetype or invalid path.

And introduces new option level to clamp the input (previously this command was useless for bigger nodetypes):

flow nodeTypes:show Neos.Demo:Document.Homepage --path properties --level 1
NodeType configuration "Neos.Demo:Document.Homepage.properties":

_removed: ...
_creationDateTime: ...
_lastModificationDateTime: ...
_lastPublicationDateTime: ...
_path: ...
_name: ...
_nodeType: ...
_hidden: ...
_hiddenBeforeDateTime: ...
_hiddenAfterDateTime: ...
titleOverride: ...
metaDescription: ...
...

Checklist

  • Code follows the PSR-2 coding style
  • Tests have been created, run and adjusted as needed
  • The PR is created against the lowest maintained branch
  • Reviewer - PR Title is brief but complete and starts with FEATURE|TASK|BUGFIX
  • Reviewer - The first section explains the change briefly for change-logs
  • Reviewer - Breaking Changes are marked with !!! and have upgrade-instructions

…o deep input

Use it like

```
flow nodeTypes:show Neos.Demo:Document.Homepage --path properties --level 1
```

to show only the property keys
@mhsdesign mhsdesign changed the title BUGFIX: nodetypes command controller BUGFIX: nodeTypes:show command Oct 15, 2023
@mhsdesign
Copy link
Member Author

the 9.0 upmerged code should be (tested)

<?php

namespace Neos\ContentRepositoryRegistry\Command;

/*
 * This file is part of the Neos.ContentRepository package.
 *
 * (c) Contributors of the Neos Project - www.neos.io
 *
 * This package is Open Source Software. For the full copyright and license
 * information, please view the LICENSE file which was distributed with this
 * source code.
 */

use Neos\ContentRepository\Core\Factory\ContentRepositoryId;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Cli\CommandController;
use Symfony\Component\Yaml\Yaml;

#[Flow\Scope("singleton")]
class NodeTypesCommandController extends CommandController
{
    public function __construct(
        private readonly ContentRepositoryRegistry $contentRepositoryRegistry
    ) {
        parent::__construct();
    }

    /**
     * Shows the merged configuration (including supertypes) of a NodeType
     *
     * @param string $nodeTypeName The name of the NodeType to show
     * @param ?string $path Path of the NodeType-configuration which will be shown
     * @param ?int $level Truncate the configuration at this depth and show '...' (Usefully for only seeing the keys of the properties)
     * @param string $contentRepository Identifier of the Content Repository to determine the set of NodeTypes
     */
    public function showCommand(string $nodeTypeName, ?string $path = null, ?int $level = 0, string $contentRepository = 'default'): void
    {
        $contentRepositoryId = ContentRepositoryId::fromString($contentRepository);
        $nodeTypeManager = $this->contentRepositoryRegistry->get($contentRepositoryId)->getNodeTypeManager();

        if (!$nodeTypeManager->hasNodeType($nodeTypeName)) {
            $this->outputLine('<error>NodeType "%s" was not found!</error>', [$nodeTypeName]);
            $this->quit();
        }

        $nodeType = $nodeTypeManager->getNodeType($nodeTypeName);

        if ($path && !$nodeType->hasConfiguration($path)) {
            $this->outputLine('<b>NodeType "%s" does not have configuration "%s".</b>', [$nodeTypeName, $path]);
            $this->quit();
        }

        $configuration = $path
            ? self::truncateArrayAtLevel($nodeType->getConfiguration($path), $level)
            : [$nodeTypeName => self::truncateArrayAtLevel($nodeType->getFullConfiguration(), $level)];

        $yaml = Yaml::dump($configuration, 99);

        $this->outputLine('<b>NodeType configuration "%s":</b>', [$nodeTypeName . ($path ? ("." . $path) : "")]);
        $this->outputLine();
        $this->outputLine($yaml);
        $this->outputLine();
    }

    /**
     * Lists all declared NodeTypes grouped by namespace
     *
     * @param string|null $filter Only NodeType-names containing this string will be listed
     * @param bool $includeAbstract List abstract NodeTypes
     * @param string $contentRepository Identifier of the Content Repository to determine the set of NodeTypes
     */
    public function listCommand(?string $filter = null, bool $includeAbstract = true, string $contentRepository = 'default'): void
    {
        $contentRepositoryId = ContentRepositoryId::fromString($contentRepository);
        $nodeTypeManager = $this->contentRepositoryRegistry->get($contentRepositoryId)->getNodeTypeManager();

        $nodeTypesFound = 0;
        $nodeTypeNameSpacesWithNodeTypeNames = [];
        foreach ($nodeTypeManager->getNodeTypes($includeAbstract) as $nodeType) {
            $nodeTypeName = $nodeType->name->value;
            if (!$filter || str_contains($nodeTypeName, $filter)) {
                [$nameSpace] = explode(":", $nodeTypeName, 2);
                $nodeTypeNameSpacesWithNodeTypeNames[$nameSpace][] = $nodeTypeName;
                $nodeTypesFound++;
            }
        }

        $this->outputLine("<b>Found $nodeTypesFound NodeTypes</b>");

        foreach ($nodeTypeNameSpacesWithNodeTypeNames as $nameSpace => $nodeTypeNames) {
            $this->outputLine();
            $this->outputLine("<b>$nameSpace</b>");

            foreach ($nodeTypeNames as $nodeTypeName) {
                $this->output->outputFormatted($nodeTypeName, [], 2);
            }
        }
    }

    /**
     * @param int $truncateLevel 0 for no truncation and 1 to only show the first keys of the array
     * @param int $currentLevel 1 for the start and will be incremented recursively
     */
    private static function truncateArrayAtLevel(array $array, int $truncateLevel, int $currentLevel = 1): array
    {
        if ($truncateLevel <= 0) {
            return $array;
        }
        $truncatedArray = [];
        foreach ($array as $key => $value) {
            if ($currentLevel >= $truncateLevel) {
                $truncatedArray[$key] = '...'; // truncated
                continue;
            }
            if (!is_array($value)) {
                $truncatedArray[$key] = $value;
                continue;
            }
            $truncatedArray[$key] = self::truncateArrayAtLevel($value, $truncateLevel, $currentLevel + 1);
        }
        return $truncatedArray;
    }
}

Copy link
Member

@nezaniel nezaniel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine by me

@kdambekalns kdambekalns changed the title BUGFIX: nodeTypes:show command FEATURE: Improve nodeTypes:show command Nov 2, 2023
Co-authored-by: Karsten Dambekalns <[email protected]>
@mhsdesign mhsdesign changed the title FEATURE: Improve nodeTypes:show command BUGFIX: Fix and make nodeTypes:show command usable Nov 5, 2023
@mhsdesign mhsdesign merged commit 6848c6c into 8.3 Nov 8, 2023
7 checks passed
@mhsdesign mhsdesign deleted the bugfix/NodeTypesCommandController branch November 8, 2023 09:47
mhsdesign added a commit to mhsdesign/neos-development-collection that referenced this pull request Jan 16, 2024
Related: neos#4619

Primitive values cannot be shown currently:

```
flow nodetypes:show Neos.Neos:Document --path properties.title.ui.label
Neos\ContentRepository\Command\NodeTypesCommandController_Original::truncateArrayAtLevel(): Argument neos#1 ($array) must be of type array, string given
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants