Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. JsonManipulator.php

function JsonManipulator::removeSubNode

3 calls to JsonManipulator::removeSubNode()
JsonManipulator::removeConfigSetting in vendor/composer/composer/src/Composer/Json/JsonManipulator.php
JsonManipulator::removeProperty in vendor/composer/composer/src/Composer/Json/JsonManipulator.php
JsonManipulator::removeRepository in vendor/composer/composer/src/Composer/Json/JsonManipulator.php

File

vendor/composer/composer/src/Composer/Json/JsonManipulator.php, line 340

Class

JsonManipulator
@author Jordi Boggiano <j.boggiano@seld.be>

Namespace

Composer\Json

Code

public function removeSubNode(string $mainNode, string $name) : bool {
    $decoded = JsonFile::parseJson($this->contents);
    // no node or empty node
    if (empty($decoded[$mainNode])) {
        return true;
    }
    // no node content match-able
    $nodeRegex = '{' . self::DEFINES . '^(?P<start> \\s* \\{ \\s* (?: (?&string) \\s* : (?&json) \\s* , \\s* )*?' . preg_quote(JsonFile::encode($mainNode)) . '\\s*:\\s*)(?P<content>(?&object))(?P<end>.*)}sx';
    try {
        if (!Preg::isMatch($nodeRegex, $this->contents, $match)) {
            return false;
        }
    } catch (\RuntimeException $e) {
        if ($e->getCode() === PREG_BACKTRACK_LIMIT_ERROR) {
            return false;
        }
        throw $e;
    }
    assert(is_string($match['start']));
    assert(is_string($match['content']));
    assert(is_string($match['end']));
    $children = $match['content'];
    // invalid match due to un-regexable content, abort
    if (!@json_decode($children, true)) {
        return false;
    }
    $subName = null;
    if (in_array($mainNode, [
        'config',
        'extra',
        'scripts',
    ]) && false !== strpos($name, '.')) {
        [
            $name,
            $subName,
        ] = explode('.', $name, 2);
    }
    // no node to remove
    if (!isset($decoded[$mainNode][$name]) || $subName && !isset($decoded[$mainNode][$name][$subName])) {
        return true;
    }
    // try and find a match for the subkey
    $keyRegex = str_replace('/', '\\\\?/', preg_quote($name));
    if (Preg::isMatch('{"' . $keyRegex . '"\\s*:}i', $children)) {
        // find best match for the value of "name"
        if (Preg::isMatchAll('{' . self::DEFINES . '"' . $keyRegex . '"\\s*:\\s*(?:(?&json))}x', $children, $matches)) {
            $bestMatch = '';
            foreach ($matches[0] as $match) {
                assert(is_string($match));
                if (strlen($bestMatch) < strlen($match)) {
                    $bestMatch = $match;
                }
            }
            $childrenClean = Preg::replace('{,\\s*' . preg_quote($bestMatch) . '}i', '', $children, -1, $count);
            if (1 !== $count) {
                $childrenClean = Preg::replace('{' . preg_quote($bestMatch) . '\\s*,?\\s*}i', '', $childrenClean, -1, $count);
                if (1 !== $count) {
                    return false;
                }
            }
        }
    }
    else {
        $childrenClean = $children;
    }
    if (!isset($childrenClean)) {
        throw new \InvalidArgumentException("JsonManipulator: \$childrenClean is not defined. Please report at https://github.com/composer/composer/issues/new.");
    }
    // no child data left, $name was the only key in
    unset($match);
    Preg::match('#^{ \\s*? (?P<content>\\S+.*?)? (?P<trailingspace>\\s*) }$#sx', $childrenClean, $match);
    if (empty($match['content'])) {
        $newline = $this->newline;
        $indent = $this->indent;
        $this->contents = Preg::replaceCallback($nodeRegex, static function ($matches) use ($indent, $newline) : string {
            return $matches['start'] . '{' . $newline . $indent . '}' . $matches['end'];
        }, $this->contents);
        // we have a subname, so we restore the rest of $name
        if ($subName !== null) {
            $curVal = json_decode($children, true);
            unset($curVal[$name][$subName]);
            if ($curVal[$name] === []) {
                $curVal[$name] = new \ArrayObject();
            }
            $this->addSubNode($mainNode, $name, $curVal[$name]);
        }
        return true;
    }
    $this->contents = Preg::replaceCallback($nodeRegex, function ($matches) use ($name, $subName, $childrenClean) : string {
        assert(is_string($matches['content']));
        if ($subName !== null) {
            $curVal = json_decode($matches['content'], true);
            unset($curVal[$name][$subName]);
            if ($curVal[$name] === []) {
                $curVal[$name] = new \ArrayObject();
            }
            $childrenClean = $this->format($curVal, 0, true);
        }
        return $matches['start'] . $childrenClean . $matches['end'];
    }, $this->contents);
    return true;
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal