AOEpeople/StackFormation

View on GitHub
src/StackFormation/PrefixedTemplate.php

Summary

Maintainability
A
2 hrs
Test Coverage
<?php
namespace StackFormation;

class PrefixedTemplate extends Template
{
    protected $prefix;

    /**
     * presudo parameters which should not be prefixed
     *
     * @var array
     */
    protected $pseudoParameters = [
            'AWS::AccountId',
            'AWS::NotificationARNs',
            'AWS::NoValue',
            'AWS::Region',
            'AWS::StackId',
            'AWS::StackName'];

    /**
     * PrefixedTemplate constructor.
     *
     * @param string            $prefix
     * @param string            $filePath
     * @param Preprocessor|null $preprocessor
     */
    public function __construct($prefix, $filePath, Preprocessor $preprocessor = null)
    {
        parent::__construct($filePath, $preprocessor);

        $this->prefix = trim($prefix);
    }

    public function getProcessedTemplate()
    {
        if ($this->prefix) {
            if (!$this->cache->has(__METHOD__)) {
                $content = parent::getProcessedTemplate();
                $content = $this->updateRef($this->prefix, $content);
                $content = $this->updateDependsOn($this->prefix, $content);
                $content = $this->updateDependsOnMultiple($this->prefix, $content);
                $content = $this->updateFnGetAtt($this->prefix, $content);
                $content = $this->updateFnFindInMap($this->prefix, $content);
                $this->cache->set(__METHOD__, $content);
            }

            return $this->cache->get(__METHOD__);
        } else {
            return parent::getProcessedTemplate();
        }
    }

    public function getDecodedJson()
    {
        if ($this->prefix) {
            if (!$this->cache->has(__METHOD__)) {
                $array = parent::getDecodedJson();

                foreach ($array as $topLevelKey => $topLevelData) {
                    if (is_array($topLevelData)) {
                        $prefixedData = [];
                        foreach ($topLevelData as $key => $value) {
                            $prefixedData[$this->prefix . $key] = $value;
                        }
                        $array[$topLevelKey] = $prefixedData;
                    }
                }
                $this->cache->set(__METHOD__, $array);
            }

            return $this->cache->get(__METHOD__);
        } else {
            return parent::getDecodedJson();
        }
    }

    /**
     * @param $prefix
     * @param $template
     *
     * @return mixed
     */
    protected function updateRef($prefix, $template)
    {
        // Update all { "Ref": "..." }
        $template = preg_replace_callback(
            '/\{\s*"Ref"\s*:\s*"([a-zA-Z0-9:]+?)"\s*\}/',
            function ($matches) use ($prefix) {
                if(true === in_array($matches[1], $this->pseudoParameters)){
                    return '{"Ref":"' . $matches[1] . '"}';
                }{
                    return '{"Ref":"' . $prefix . $matches[1] . '"}';
                }

            },
            $template
        );

        return $template;
    }

    /**
     * @param $prefix
     * @param $template
     *
     * @return mixed
     */
    protected function updateDependsOn($prefix, $template)
    {
        // Update all { "DependsOn": "..." }
        $template = preg_replace_callback(
            '/\"DependsOn"\s*:\s*"([a-zA-Z0-9:]+?)"/',
            function ($matches) use ($prefix) {
                return '"DependsOn":"' . $prefix . $matches[1] . '"';
            },
            $template
        );

        return $template;
    }

    /**
     * @param $prefix
     * @param $template
     *
     * @return mixed
     */
    protected function updateDependsOnMultiple($prefix, $template)
    {
        // Update all { "DependsOn": ["...", "...", ...] }
        $template = preg_replace_callback(
            '/"DependsOn"\s*:\s*\[(.*)\]/s',
            function ($matches) use ($prefix) {
                $dependencies = $matches[1];
                $dependencies = preg_replace_callback(
                    '/"([a-zA-Z0-9:]+?)"/',
                    function ($matches) use ($prefix) {
                        return '"' . $prefix . $matches[1] . '"';
                    },
                    $dependencies
                );

                return '"DependsOn":[' . $dependencies . ']';
            },
            $template
        );

        return $template;
    }

    /**
     * @param $prefix
     * @param $template
     *
     * @return mixed
     */
    protected function updateFnGetAtt($prefix, $template)
    {
        //  Update all "Fn::GetAtt": ["...", "..."] }
        $template = preg_replace_callback(
            '/"Fn::GetAtt"\s*:\s*\[\s*"([a-zA-Z0-9:]+?)"/',
            function ($matches) use ($prefix) {
                return '"Fn::GetAtt": ["' . $prefix . $matches[1] . '"';
            },
            $template
        );

        return $template;
    }

    /**
     * @param $prefix
     * @param $template
     *
     * @return mixed
     */
    protected function updateFnFindInMap($prefix, $template)
    {
        //  Update all "Fn::FindInMap": ["...", "..."] }
        $template = preg_replace_callback(
            '/"Fn::FindInMap"\s*:\s*\[\s*"([a-zA-Z0-9:]+?)"/',
            function ($matches) use ($prefix) {
                return '"Fn::FindInMap": ["' . $prefix . $matches[1] . '"';
            },
            $template
        );

        return $template;
    }
}