Compiler.js

{
    "type": "file",
    "namespace": {
        "type": "namespace",
        "name": "Taeluf\\PHTML",
        "declaration": "namespace Taeluf\\PHTML;",
        "class": [
            {
                "type": "class",
                "namespace": "Taeluf\\PHTML",
                "fqn": "Taeluf\\PHTML\\Compiler",
                "name": "Compiler",
                "declaration": "class Compiler",
                "properties": [
                    {
                        "type": "property",
                        "modifiers": [
                            "protected"
                        ],
                        "docblock": {
                            "type": "docblock",
                            "description": "An array of code to output.\nLikely contains placeholder which will be replaced. \nMay contain objects which implement __toString"
                        },
                        "name": "code",
                        "value": "[]",
                        "declaration": "protected $code = [];"
                    },
                    {
                        "type": "property",
                        "modifiers": [
                            "protected"
                        ],
                        "docblock": {
                            "type": "docblock",
                            "description": "The content of a PHP file for compilation"
                        },
                        "name": "src",
                        "declaration": "protected $src;"
                    },
                    {
                        "type": "property",
                        "modifiers": [
                            "protected"
                        ],
                        "docblock": {
                            "type": "docblock",
                            "description": "An array of placeholder code with codeId => [prependedCode, code, appendedCode]... there can be any number of entries for each codeId\nCode may be string or an object which implements __toString\ncodeIds are either sha sums (alpha-numeric, i think) or randmoized alpha"
                        },
                        "name": "placeholder",
                        "value": "[]",
                        "declaration": "protected $placeholder = [];"
                    },
                    {
                        "type": "property",
                        "modifiers": [
                            "protected"
                        ],
                        "docblock": {
                            "type": "docblock",
                            "description": "The parsed source code, with the PHP code replaced by placeholders"
                        },
                        "name": "htmlSource",
                        "declaration": "protected $htmlSource;"
                    }
                ],
                "methods": [
                    {
                        "type": "method",
                        "args": [],
                        "modifiers": [
                            "public"
                        ],
                        "name": "__construct",
                        "body": "",
                        "declaration": "public function __construct()"
                    },
                    {
                        "type": "method",
                        "args": [
                            {
                                "type": "arg",
                                "name": "srcCode",
                                "declaration": "$srcCode"
                            }
                        ],
                        "docblock": {
                            "type": "docblock",
                            "description": "Replaces inline PHP code with placeholder, indexes the placeholder, and returns the modified code\n",
                            "attribute": [
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "mixed $srcCode - The source code"
                                },
                                {
                                    "type": "attribute",
                                    "name": "return",
                                    "description": "string - source code with all PHP replaced by codeIds"
                                }
                            ]
                        },
                        "modifiers": [
                            "public"
                        ],
                        "name": "cleanSource",
                        "return_types": [
                            "string"
                        ],
                        "body": "$parser = new PHPParser($srcCode);\n$parsed = $parser->pieces();\nforeach ($parsed->php as $id=>$code){\n    $this->placeholder[$id] = [$code];\n}\nreturn $parsed->html;",
                        "declaration": "public function cleanSource($srcCode): string"
                    },
                    {
                        "type": "method",
                        "args": [
                            {
                                "type": "arg",
                                "name": "phpCodeWithOpenCloseTags",
                                "declaration": "$phpCodeWithOpenCloseTags"
                            }
                        ],
                        "docblock": {
                            "type": "docblock",
                            "description": "1. Generates an id\n2. indexes the passed-in-code with that id\n3. Returns the id.\n",
                            "attribute": [
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "mixed $phpCodeWithOpenCloseTags - Code, as it would be found in a PHP file. AKA PHP code MUST include open\/close tags"
                                },
                                {
                                    "type": "attribute",
                                    "name": "return",
                                    "description": "string the codeId. Either a random alpha-string OR an sha_sum, which I think is alpha-numeric"
                                }
                            ]
                        },
                        "modifiers": [
                            "public"
                        ],
                        "name": "placeholderFor",
                        "return_types": [
                            "string"
                        ],
                        "body": "$code = $phpCodeWithOpenCloseTags;\n$id = $this->freshId();\n$this->placeholder[$id] = [$code];\nreturn $id;",
                        "declaration": "public function placeholderFor($phpCodeWithOpenCloseTags): string"
                    },
                    {
                        "type": "method",
                        "args": [
                            {
                                "type": "arg",
                                "name": "code",
                                "declaration": "$code"
                            }
                        ],
                        "docblock": {
                            "type": "docblock",
                            "description": "Appends code to the output-to-be\n",
                            "attribute": [
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "mixed $code - Code to append. PHP code must be wrapped in open\/close tags"
                                },
                                {
                                    "type": "attribute",
                                    "name": "return",
                                    "description": "void"
                                }
                            ]
                        },
                        "modifiers": [
                            "public"
                        ],
                        "name": "appendCode",
                        "body": "$this->code[] = $code;",
                        "declaration": "public function appendCode($code)"
                    },
                    {
                        "type": "method",
                        "args": [
                            {
                                "type": "arg",
                                "name": "code",
                                "declaration": "$code"
                            }
                        ],
                        "docblock": {
                            "type": "docblock",
                            "description": "Prepends code to the output-to-be\n",
                            "attribute": [
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "mixed $code - Code to prepend. PHP code must be wrapped in open\/close tags"
                                },
                                {
                                    "type": "attribute",
                                    "name": "return",
                                    "description": "void"
                                }
                            ]
                        },
                        "modifiers": [
                            "public"
                        ],
                        "name": "prependCode",
                        "body": "\/\/ $this->code[] = $code;\narray_unshift($this->code,$code);",
                        "declaration": "public function prependCode($code)"
                    },
                    {
                        "type": "method",
                        "args": [
                            {
                                "type": "arg",
                                "name": "placeholder",
                                "declaration": "$placeholder"
                            },
                            {
                                "type": "arg",
                                "name": "code",
                                "declaration": "$code"
                            }
                        ],
                        "docblock": {
                            "type": "docblock",
                            "description": "Prepend code immediately prior to the given placeholder\n",
                            "attribute": [
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "mixed $placeholder - a placeholder from placeholderFor()"
                                },
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "mixed $code - a block of code. PHP must be wrapped in open\/close tags"
                                },
                                {
                                    "type": "attribute",
                                    "name": "return",
                                    "description": "void"
                                }
                            ]
                        },
                        "modifiers": [
                            "public"
                        ],
                        "name": "placeholderPrepend",
                        "body": "array_unshift($this->placeholder[$placeholder],$code);",
                        "declaration": "public function placeholderPrepend($placeholder,$code)"
                    },
                    {
                        "type": "method",
                        "args": [
                            {
                                "type": "arg",
                                "name": "placeholder",
                                "declaration": "$placeholder"
                            },
                            {
                                "type": "arg",
                                "name": "code",
                                "declaration": "$code"
                            }
                        ],
                        "docblock": {
                            "type": "docblock",
                            "description": "Append code immediately after the given placeholder\n",
                            "attribute": [
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "mixed $placeholder - a placeholder from placeholderFor()"
                                },
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "mixed $code - a block of code. PHP must be wrapped in open\/close tags"
                                },
                                {
                                    "type": "attribute",
                                    "name": "return",
                                    "description": "void"
                                }
                            ]
                        },
                        "modifiers": [
                            "public"
                        ],
                        "name": "placeholderAppend",
                        "body": "$this->placeholder[$placeholder][] = $code;",
                        "declaration": "public function placeholderAppend($placeholder,$code)"
                    },
                    {
                        "type": "method",
                        "args": [],
                        "docblock": {
                            "type": "docblock",
                            "description": "Compile the code into a string & return it. \noutput() can be called several times as it does NOT affect the state of the compiler.\n",
                            "attribute": [
                                {
                                    "type": "attribute",
                                    "name": "return",
                                    "description": "string"
                                }
                            ]
                        },
                        "modifiers": [
                            "public"
                        ],
                        "name": "output",
                        "return_types": [
                            "string"
                        ],
                        "body": "\/\/ print_r($this->code);\n\/\/ \/\/ echo $this->code[0]->;\n\/\/ exit;\n\/\/ print_r($this->placeholder);\n$code = implode(\"\\n\",$this->code);\n\/\/ return $code;\n$ph = [];\nforeach ($this->placeholder as $id=>$codeArray){\n    $ph[$id] = implode('',$codeArray);\n}\n$last = $code;\nwhile($last != $code = str_replace(array_keys($ph),$ph,$code))$last=$code;\nreturn $code;",
                        "declaration": "public function output(): string"
                    },
                    {
                        "type": "method",
                        "args": [
                            {
                                "type": "arg",
                                "arg_types": [
                                    "string"
                                ],
                                "name": "file",
                                "declaration": "string $file"
                            },
                            {
                                "type": "arg",
                                "name": "chmodTo",
                                "value": "null",
                                "declaration": "$chmodTo=null"
                            }
                        ],
                        "docblock": {
                            "type": "docblock",
                            "description": "Writes the compiled output to the given file\n",
                            "attribute": [
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "string $file - an absolute filepath"
                                },
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "$chmodTo - REMOVED DOES NOTHING\n\n         0644 or whatever. If null, chmod will not be run.\n         See https:\/\/www.php.net\/manual\/en\/function.chmod.php\n         Permissions are as follows:\n             Value    Permission Level\n              200        Owner Write\n              400        Owner Read\n              100        Owner Execute\n               40         Group Read\n               20         Group Write\n               10         Group Execute\n                4         Global Read\n                2         Global Write\n                1         Global Execute"
                                },
                                {
                                    "type": "attribute",
                                    "name": "return",
                                    "description": "boolean true if file_put_contents succeeds. False otherwise."
                                }
                            ]
                        },
                        "modifiers": [
                            "public"
                        ],
                        "name": "writeTo",
                        "return_types": [
                            "bool"
                        ],
                        "body": "$output = $this->output();\nif (!is_dir(dirname($file))){\n    mkdir(dirname($file),0771,true);\n    \/\/ chmod(dirname($file),0770);\n}\n$didPut = file_put_contents($file,$output);\nif ($chmodTo!==null){\n    \/\/ chmod($file,$chmodTo);\n}\nif ($didPut===false)return false;\nelse return true;",
                        "declaration": "public function writeTo(string $file, $chmodTo=null): bool"
                    },
                    {
                        "type": "method",
                        "args": [
                            {
                                "type": "arg",
                                "name": "compileDir",
                                "declaration": "$compileDir"
                            },
                            {
                                "type": "arg",
                                "name": "code",
                                "declaration": "$code"
                            }
                        ],
                        "docblock": {
                            "type": "docblock",
                            "description": "Get an absolute file path which can be included to execute the given code\n\n1. $codeId = sha1($code)\n2. file_put_contents(\"$compileDir\/$codeId.php\", $code)\n3. return the path of the new file\n\n- Will create the directory (non-recursive) if not exists\n",
                            "attribute": [
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "mixed $compileDir - the directory in which the file should be written"
                                },
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "mixed $code - the block of code. PHP code must be wrapped in open\/close tags to be executed"
                                },
                                {
                                    "type": "attribute",
                                    "name": "return",
                                    "description": "string an absolute file path to a php file"
                                }
                            ]
                        },
                        "modifiers": [
                            "public"
                        ],
                        "name": "fileForCode",
                        "return_types": [
                            "string"
                        ],
                        "body": "\/\/ $codeId = $this->freshId(30);\n$codeId = sha1($code);\n$file = $compileDir.'\/'.$codeId.'.php';\nif (!file_exists($compileDir))mkdir($compileDir,0770,true);\nfile_put_contents($file,$code);\nreturn $file;",
                        "declaration": "public function fileForCode($compileDir,$code): string"
                    },
                    {
                        "type": "method",
                        "args": [
                            {
                                "type": "arg",
                                "name": "length",
                                "value": "26",
                                "declaration": "$length = 26"
                            }
                        ],
                        "docblock": {
                            "type": "docblock",
                            "description": "Generate a random string of lowercase letters\n",
                            "attribute": [
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "mixed $length The desired length of the random string. Default is 26 to avoid any clashing"
                                },
                                {
                                    "type": "attribute",
                                    "name": "return",
                                    "description": "string the random string"
                                }
                            ]
                        },
                        "modifiers": [
                            "protected"
                        ],
                        "name": "freshId",
                        "return_types": [
                            "string"
                        ],
                        "body": "$characters = 'abcdefghijklmnopqrstuvwxyz';\n$charactersLength = strlen($characters);\n$randomString = '';\nfor ($i = 0; $i < $length; $i++) {\n    $randomString .= $characters[rand(0, $charactersLength - 1)];\n}\nreturn $randomString;",
                        "declaration": "protected function freshId($length = 26): string"
                    },
                    {
                        "type": "method",
                        "args": [
                            {
                                "type": "arg",
                                "arg_types": [
                                    "string"
                                ],
                                "name": "codeId",
                                "declaration": "string $codeId"
                            },
                            {
                                "type": "arg",
                                "arg_types": [
                                    "bool"
                                ],
                                "name": "asArray",
                                "value": "false",
                                "declaration": "bool $asArray=false"
                            }
                        ],
                        "docblock": {
                            "type": "docblock",
                            "description": "Get the code for the given code id.\n\nPlaceholder code is stored as an array to enable the placeholderPrepend|Append functions, so I make it available as an array if you want.\n\n",
                            "attribute": [
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "string $codeId - the id generated by placeholderFor()"
                                },
                                {
                                    "type": "attribute",
                                    "name": "param",
                                    "description": "bool $asArray - TRUE to get the code as it's array parts. FALSE to implode the array (no newlines) & return that"
                                },
                                {
                                    "type": "attribute",
                                    "name": "return",
                                    "description": "mixed an array of code pieces that make up this codeid or a string of the code"
                                }
                            ]
                        },
                        "modifiers": [
                            "public"
                        ],
                        "name": "codeForId",
                        "body": "$codeArr = $this->placeholder[$codeId];\nif ($asArray)return $codeArr;\nelse return implode('',$codeArr);",
                        "declaration": "public function codeForId(string $codeId,bool $asArray=false)"
                    }
                ]
            }
        ]
    }
}