phonetworks/pho-compiler

View on GitHub
src/Pho/Compiler/Transcoders/EdgeTranscoder.php

Summary

Maintainability
C
7 hrs
Test Coverage
<?php

/*
 * This file is part of the Pho package.
 *
 * (c) Emre Sokullu <emre@phonetworks.org>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Pho\Compiler\Transcoders;

use Pho\Compiler\Compiler;

class EdgeTranscoder extends AbstractTranscoder
{

    const SUBTYPES = [
            "read" => "Foundation\ActorOut\Read",
            "write" => "Foundation\ActorOut\Write",
            "subscribe" => "Foundation\ActorOut\Subscribe",
            "mention" => "Foundation\ObjectOut\Mention"
    ];


    protected function mapPrototypeVars(): array
    {
        $prototype_vars = $this->prototype->toArray();
        $new_array = [];
        $may_be_persistent = true;
        $new_array["formative"] = null;
        $new_array["fields_exists"] = false;
        $new_array["multiple_tails"] = false;

        foreach($prototype_vars as $key=>$val) {
            // "type" determines whether it's  node or edge in the first place.
            switch($key) {
            case "name":
                $new_array["class_name"] = $val;
                break;
            case "subtype":
                $new_array["extends"] = self::SUBTYPES[$val];
                if(in_array($val, ["mention", "write", "subscribe"])) {
                    $new_array["with_notification"] = true;
                }
                else {
                     $new_array["with_notification"] = false;
                }
                break;
            case "binding":
            case "multiplicable":
            case "formative":
            case "persistent":
            case "subscriber":
            case "notifier":
            case "consumer":
                $new_array["is_".$key] = $val ? "true" : "false";
                if($key=="formative" && $val)
                    $new_array[$key] = true;
                break;
            case "tail_node":
                $new_array[$key] = trim($val);
                if(strpos($val, ",")!==false)
                    $new_array["multiple_tails"] = true;
                break;
            case "head_nodes":
                $new_array[$key] = implode(
                    ",", 
                    array_map(function(string $x) {
                        return "\\PhoNetworksAutogenerated\\" . trim($x)."::class";
                    }, explode(",", $val))
                );
                break;
            case "head_nodes_only":
                if(empty($val))
                    break;
                $new_array[$key] = implode(
                    ",", 
                    array_map(function(string $x) {
                        return "\\".str_replace(":", "\\", trim($x))."::class";
                    }, explode(",", $val))
                );
                break;
                // 
            case "fields":
                $new_array["fields"] = [];
                if(count($val)<=1)
                    break;
                foreach($val as $v) {
                    if($v["name"]!="id") {
                        $new_array["fields"][$v["name"]] = [
                            "constraints" => $v["constraints"],
                            "directives" => $v["directives"],
                        ];
                    }
                }
                $new_array["fields_exists"] = true;
                $new_array["fields"] = addslashes(json_encode($new_array["fields"]));
                break;
            default:
                $new_array[$key] = $val;
                break;
            }
        }
        $this->completeMap($new_array);
        return $new_array;
    }

    protected function completeMap(&$array): void
    {
        $check_for_must_have = function(string $key) use($array)
        {
            if(!isset($array[$key])) {
                throw new Exceptions\MissingValueException($key);
            }
        };

        $check_with_fallback = function(string $key, /* mixed */ $fallback) use(&$array)
        {
            if(!isset($array[$key])) {
                $array[$key] = $fallback;
            }
        };

        $check_for_must_have("class_name");
        $check_for_must_have("extends");
        $check_for_must_have("tail_node");

        $check_with_fallback("is_binding", "false");
        $check_with_fallback("is_multiplicable", "true");
        $check_with_fallback("is_formative", "false");
        $check_with_fallback("is_persistent", "true");
        $check_with_fallback("is_notifier", "false");
        $check_with_fallback("is_subscriber", "false");
        $check_with_fallback("is_consumer", "false");


        $check_with_fallback("expiration", 0);
        $check_with_fallback("with_notification", false);
        
    }
}