protected function parsePalettes(PalettesDefinitionInterface $palettesDefinition, LegacyPalettesParser $parser, array $palettesDca, array $subPalettes, array $subSelectPalettes, array $selectorFieldNames) { $palettes = array(); if (is_array($palettesDca)) { foreach ($palettesDca as $selector => $legendPropertyNames) { if (preg_match('#^(\\w+) extends (\\w+)$#', $selector, $matches)) { $parentSelector = $matches[2]; $selector = $matches[1]; if (isset($palettes[$parentSelector])) { $palette = clone $palettes[$parentSelector]; $palette->setName($selector); } else { if ($palettesDefinition->hasPaletteByName($parentSelector)) { $palette = clone $palettesDefinition->getPaletteByName($parentSelector); } else { $palette = null; } } if (!$palette) { throw new \RuntimeException('Parent palette ' . $parentSelector . ' does not exists'); } // We MUST NOT retain the DefaultPaletteCondition. $palette->setCondition($parser->createPaletteCondition($selector, $selectorFieldNames)); $extended = true; } else { $palette = new Palette(); $palette->setName($selector); $palette->setCondition($parser->createPaletteCondition($selector, $selectorFieldNames)); $extended = false; } $paletteCallbacks = array(); foreach ($legendPropertyNames as $legendName => $propertyNames) { if ($propertyNames instanceof \Closure) { $paletteCallbacks[] = $propertyNames; continue; } $additive = false; $subtractive = false; $insert = false; $refLegendName = null; if ($extended) { // add properties to existing legend if ($legendName[0] == '+') { $additive = true; $legendName = substr($legendName, 1); } else { // subtract properties from existing legend if ($legendName[0] == '-') { $subtractive = true; $legendName = substr($legendName, 1); } } if (preg_match('#^(\\w+) (before|after) (\\w+)$#', $legendName, $matches)) { $legendName = $matches[1]; $insert = $matches[2]; $refLegendName = $matches[3]; } } if ($palette->hasLegend($legendName)) { $legend = $palette->getLegend($legendName); } else { $legend = new Legend($legendName); // insert a legend before or after another one if ($insert) { $existingLegends = $palette->getLegends(); $refLegend = null; // search the referenced legend /** @var LegendInterface $existingLegend */ reset($existingLegends); while ($existingLegend = next($existingLegends)) { if ($existingLegend->getName() == $refLegendName) { if ($insert == 'after') { // if insert after, get to next $refLegend = next($existingLegends); } else { $refLegend = $existingLegend; } break; } } $palette->addLegend($legend, $refLegend); } else { // just append the legend $palette->addLegend($legend); } } // if extend a palette, but not add or remove fields, clear the legend but only when we have fields. if ($extended && !($additive || $subtractive) && count($propertyNames)) { $legend->clearProperties(); } $legendCallbacks = array(); foreach ($propertyNames as $propertyName) { if ($propertyName instanceof \Closure) { $legendCallbacks[] = $propertyName; continue; } if ($propertyName[0] == ':') { if ('hide' === substr($propertyName, 1)) { $legend->setInitialVisibility(false); } // skip other modifiers continue; } if ($additive || $subtractive) { $action = $additive ? 'add' : 'sub'; $insert = false; $refPropertyName = null; if ($propertyName[0] == '+') { $action = 'add'; $propertyName = substr($propertyName, 1); } else { if ($propertyName[0] == '-') { $action = 'sub'; $propertyName = substr($propertyName, 1); } } if (preg_match('#^(\\w+) (before|after) (\\w+)$#', $propertyName, $matches)) { $propertyName = $matches[1]; $insert = $matches[2]; $refPropertyName = $matches[3]; } if ($action == 'add') { $property = new Property($propertyName); if ($insert) { $existingProperties = $legend->getProperties(); $refProperty = null; reset($existingProperties); $existingProperty = current($existingProperties); /** @var PropertyInterface $existingProperty */ while ($existingProperty !== false) { if ($existingProperty->getName() == $refPropertyName) { if ($insert == 'after') { $refProperty = next($existingProperties); if ($refProperty === false) { $refProperty = null; } } else { $refProperty = $existingProperty; } break; } $existingProperty = next($existingProperties); } $legend->addProperty($property, $refProperty); } else { $legend->addProperty($property); } } else { /** @var PropertyInterface $property */ foreach ($legend->getProperties() as $property) { if ($property->getName() == $propertyName) { $legend->removeProperty($property); break; } } } } else { $property = new Property($propertyName); $legend->addProperty($property); } // add sub palette properties if (isset($subPalettes[$propertyName])) { $legend->addProperties($subPalettes[$propertyName]); } // add sub select properties for unspecified legend names. $this->addSubSelectProperties($legend, $subSelectPalettes, $propertyName); } foreach ($legendCallbacks as $callback) { call_user_func($callback, $legendName, $legend, $palette, $palettesDefinition); } } foreach ($paletteCallbacks as $callback) { call_user_func($callback, $palette, $palettesDefinition); } $palettes[$selector] = $palette; } } // now add sub select properties that are for specific legend names. foreach ($subSelectPalettes as $propertyName => $legendInformation) { $subpaletteCallbacks = array(); foreach ($legendInformation as $properties) { if ($properties instanceof \Closure) { $subpaletteCallbacks[] = $properties; } } foreach ($legendInformation as $fullLegendName => $properties) { if ($fullLegendName === '') { continue; } foreach ($palettes as $palette) { if (preg_match('#^(\\w+) (before|after) (\\w+)$#', $fullLegendName, $matches)) { $legendName = $matches[1]; $insert = $matches[2]; $refName = $matches[3]; } else { $legendName = $fullLegendName; $insert = ''; $refName = null; } /** @var Palette $palette */ if (!$palette->hasLegend($legendName)) { $palette->addLegend(new Legend($legendName)); } /** @var Legend $legend */ $legend = $palette->getLegend($legendName); $this->addSubSelectProperties($legend, $subSelectPalettes, $propertyName, $fullLegendName, $insert, $refName); foreach ($subpaletteCallbacks as $callback) { call_user_func($callback, $legendName, $properties, $legend, $palette, $palettesDefinition); } } } } return $palettes; }