Skip to content

Instantly share code, notes, and snippets.

@joseph-montanez
Created August 15, 2012 19:44
Show Gist options
  • Save joseph-montanez/3363000 to your computer and use it in GitHub Desktop.
Save joseph-montanez/3363000 to your computer and use it in GitHub Desktop.
Php to Javascript Transcoder
<script type="text/javascript">
var js_templates = js_templates || {};
js_templates['item-listing'] = function (data) {
var result_string = [];
result_string.push('<ul>');
var key_502cbbed82967;
for (key_502cbbed82967 in data.items) {
var item = data.items[key_502cbbed82967];
result_string.push('<li class="item');
result_string.push((data.item['sale']) ? ' sale' : '');
result_string.push('">');
result_string.push(data.item['name']);
result_string.push('</li>');
}
result_string.push('</ul>');
result_string.push('\n<ul>');
for (var i = 0; i < count(data.items); i++;) {
result_string.push('<li class="item');
result_string.push((data.items[data.i]['sale']) ? ' sale' : '');
result_string.push('">');
result_string.push(data.item[data.i]['name']);
result_string.push('</li>');
}
result_string.push('</ul>');
if (count(data.item) == 0) {
result_string.push('Has items!');
}
else if (count(data.item) <= 1) {
result_string.push('Has No items!');
}
else {
result_string.push('Has No items!');
}
i--;
var j = 1;
j = 2;
return result_string.join();
};
</script>
<ul>
<? foreach($items as $item): ?>
<li class="item<?= $item['sale'] ? ' sale' : ''?>"><?= $item['name'] ?></li>
<? endforeach ?>
</ul>
<ul>
<? for($i = 0; $i < count($items); $i++): ?>
<li class="item<?= $items[$i]['sale'] ? ' sale' : ''?>"><?= $item[$i]['name'] ?></li>
<? endfor ?>
</ul>
<? if (count($item) == 0): ?>
Has items!
<? elseif (count($item) <= 1): ?>
his would never happen!!
<? else: ?>
Has No items!
<? endif ?>
<?
$i--;
$j = 1;
$j = 2;
?>
<?php
include 'vendor/autoload.php';
class js {
public static function template($filename) {
$code = file_get_contents($filename);
$parser = new PHPParser_Parser(new PHPParser_Lexer);
$info = new SplFileInfo($filename);
$fn = $info->getBasename('.php');
try {
$stmts = $parser->parse($code);
$out = '';
$scope = array(
'level' => 0,
'vars' => array('data' => 0, 'result_string' => 0),
'innerscope' => array(),
'outterscope' => null
);
self::resolve($stmts, $out, 1, $scope);
$ln = PHP_EOL;
echo "<script type=\"text/javascript\">" . PHP_EOL .
"var js_templates = js_templates || {};" . PHP_EOL .
"js_templates['{$fn}'] = function (data) {" . PHP_EOL .
"\tvar result_string = [];" . PHP_EOL .
"{$out}" . PHP_EOL .
"\treturn result_string.join();" . PHP_EOL .
"};" . PHP_EOL .
"</script>";
} catch (PHPParser_Error $e) {
echo 'Parse Error: ', $e->getMessage();
}
}
public static function resolve($stmts, &$str, $level = 0, &$scope) {
$substr = '';
if (is_array($stmts)) {
$tab = str_repeat("\t", $level);
foreach ($stmts as $i => $stmt) {
$type = $stmt->getType();
$next = (array) $stmt->stmts;
$subs = $stmt->getIterator();
if ($type === 'Expr_Assign') {
$var_str = '';
$expression = '';
self::resolve(array($stmt->var), $var_str, 0, $scope);
self::resolve(array($stmt->expr), $expression, 0, $scope);
if ($stmt->var->getType() === 'Expr_ArrayDimFetch') {
$str .= $tab . "array_push({$var_str}, {$expression});" . PHP_EOL;
} else {
$var_key = $var_str;
if (substr($var_key, 0, 5) === 'data.') {
$var_key = substr($var_key, 5, strlen($var_key));
}
if (isset($scope['vars'][$var_key]) === false) {
$scope['vars'][$var_key] = 0;
$var_str = 'var ' . $var_key;
}
$str .= $tab . rtrim("{$var_str} = {$expression}", ';') . ';' . PHP_EOL;
}
}
else if ($type === 'Expr_Array') {
$elements = '';
self::resolve($stmt->items, $elements, 0, $scope);
$str .= '({' . $elements . '})';
//var_dump($stmt);
}
else if ($type === 'Arg') {
//var_dump($stmt);
$value_str = '';
self::resolve(array($stmt->value), $value_str, 0, $scope);
$str .= "$value_str";
}
else if ($type === 'Name') {
//var_dump($stmt);
$str .= implode('', $stmt->parts);
}
else if ($type === 'Expr_ArrayItem') {
$key = $stmt->key !== null ? $stmt->key : $i;
$value = $stmt->value->value;
$str .= "{$key}:{$value}";
if ($i < count($stmts) - 1) {
$str .= ",";
}
}
else if ($type === 'Expr_Variable') {
//var_dump($stmt);
$name = $stmt->name;
if (isset($scope['vars'][$name]) === false) {
$name = 'data.' . $name;
}
$str .= $name;
}
else if ($type === 'Expr_FuncCall') {
//var_dump($stmt);
$name_str = '';
self::resolve(array($stmt->name), $name_str, 0, $scope);
//$name = $stmt->name->name;
$args_str = '';
self::resolve($stmt->args, $args_str, 0, $scope);
$str .= "{$name_str}({$args_str})";
}
else if ($type === 'Expr_Closure') {
//var_dump($stmt);
$closure_str = '';
self::resolve($stmt->stmts, $closure_str, $level + 1, $scope);
$str .= $tab . 'function () {' . PHP_EOL . $closure_str . PHP_EOL . '}';
continue;
}
else if ($type === 'Expr_ArrayDimFetch') {
$iter = next($stmts);
$key_str = '';
self::resolve(array($stmt->var), $key_str, 0, $scope);
$dim_str = '';
if ($stmt->dim) {
self::resolve(array($stmt->dim), $dim_str, 0, $scope);
}
$str .= "{$key_str}";
if (strlen($dim_str) > 0) {
$str .= "[{$dim_str}]";
}
}
else if ($type === 'Expr_PropertyFetch') {
//var_dump($stmt);
$var_str = '';
self::resolve(array($stmt->var), $var_str, $level, $scope);
$str .= "{$var_str}.{$stmt->name}";
}
else if ($type === 'Expr_Smaller') {
$left_str = '';
$right_str = '';
//var_dump($stmt->right);
self::resolve(array($stmt->left), $left_str, 0, $scope);
self::resolve(array($stmt->right), $right_str, 0, $scope);
$str .= "{$left_str} < {$right_str}";
}
else if ($type === 'Expr_Greater') {
$left_str = '';
$right_str = '';
//var_dump($stmt->right);
self::resolve(array($stmt->left), $left_str, 0, $scope);
self::resolve(array($stmt->right), $right_str, 0, $scope);
$str .= "{$left_str} > {$right_str}";
}
else if ($type === 'Expr_Equal') {
$left_str = '';
$right_str = '';
self::resolve(array($stmt->left), $left_str, 0, $scope);
self::resolve(array($stmt->right), $right_str, 0, $scope);
$str .= "{$left_str} == {$right_str}";
}
else if ($type === 'Expr_GreaterOrEqual') {
$left_str = '';
$right_str = '';
self::resolve(array($stmt->left), $left_str, 0, $scope);
self::resolve(array($stmt->right), $right_str, 0, $scope);
$str .= "{$left_str} >= {$right_str}";
}
else if ($type === 'Expr_SmallerOrEqual') {
$left_str = '';
$right_str = '';
self::resolve(array($stmt->left), $left_str, 0, $scope);
self::resolve(array($stmt->right), $right_str, 0, $scope);
$str .= "{$left_str} <= {$right_str}";
}
else if ($type === 'Expr_Ternary') {
//var_dump($stmt);
$if_str = '';
$else_str = '';
$cond_str = '';
self::resolve(array($stmt->if), $if_str, $level, $scope);
self::resolve(array($stmt->else), $else_str, $level, $scope);
self::resolve(array($stmt->cond), $cond_str, $level, $scope);
$str .= "({$cond_str}) ? {$if_str} : {$else_str}";
}
else if ($type === 'Expr_PostInc') {
$var_str = '';
self::resolve(array($stmt->var), $var_str, 0, $scope);
$str .= $tab . "{$var_str}++;" . PHP_EOL;
}
else if ($type === 'Expr_PostDec') {
$var_str = '';
self::resolve(array($stmt->var), $var_str, 0, $scope);
$str .= $tab . "{$var_str}--;" . PHP_EOL;
}
else if ($type === 'Stmt_Foreach') {
//var_dump($stmt);
$key = 'key_' . uniqid();
if ($stmt->keyVar !== null) {
$key = $stmt->keyVar->name;
}
$expression = '';
self::resolve(array($stmt->expr), $expression, 0, $scope);
$foreach_str = '';
self::resolve($stmt->stmts, $foreach_str, $level + 1, $scope);
//-- Assign to temp of there is an expression in the loop
if ($stmt->expr->getType() !== 'Expr_Variable') {
$express_var = 'expr_' . uniqid();
$str .= $tab . "{$express_var} = {$expression};" . PHP_EOL;
$expression = $express_var;
}
$scope['vars'][$key] = 0;
$str .=
$tab . "var {$key};" . PHP_EOL .
$tab . "for ({$key} in {$expression}) {" . PHP_EOL .
$tab . "\tvar {$stmt->valueVar->name} = {$expression}[{$key}];" . PHP_EOL .
$foreach_str . PHP_EOL .
$tab . "}" . PHP_EOL;
continue;
}
else if ($type === 'Stmt_For') {
//var_dump($stmt);
$init_str = '';
$cond_str = '';
$loop_str = '';
$for_str = '';
self::resolve($stmt->stmts, $for_str, $level + 1, $scope);
self::resolve($stmt->init, $init_str, 0, $scope);
self::resolve($stmt->cond, $cond_str, 0, $scope);
self::resolve($stmt->loop, $loop_str, 0, $scope);
$loop_str = trim($loop_str);
$init_str = trim($init_str);
$str .=
$tab . "for ({$init_str} {$cond_str}; {$loop_str}) {" . PHP_EOL .
$for_str . PHP_EOL .
$tab . "}" . PHP_EOL;
continue;
}
else if ($type === 'Stmt_If') {
//var_dump($stmt);
$if_str = '';
$cond_str = '';
self::resolve($stmt->stmts, $if_str, $level + 1, $scope);
self::resolve(array($stmt->cond), $cond_str, 0, $scope);
$str .=
$tab . "if ({$cond_str}) {" . PHP_EOL .
$tab . "{$if_str}" . PHP_EOL .
$tab . "}" . PHP_EOL;
if (count($stmt->elseifs)) {
$elseifs_str = '';
self::resolve($stmt->elseifs, $elseifs_str, $level, $scope);
$str .= $elseifs_str;
}
if ($stmt->else !== null) {
$else_str = '';
self::resolve(array($stmt->else), $else_str, $level, $scope);
$str .=
$tab . "else {" . PHP_EOL .
$tab . "{$else_str}" . PHP_EOL .
$tab . "}" . PHP_EOL;
}
continue;
}
else if ($type === 'Stmt_Else') {
$else_str = '';
self::resolve($stmt->stmts, $else_str, $level + 1, $scope);
$str .= $else_str;
continue;
}
else if ($type === 'Stmt_ElseIf') {
$elseif_str = '';
$cond_str = '';
self::resolve($stmt->stmts, $elseif_str, $level + 1, $scope);
self::resolve(array($stmt->cond), $cond_str, 0, $scope);
$str .=
$tab . "else if ({$cond_str}) {" . PHP_EOL .
$tab . "{$elseif_str}" . PHP_EOL .
$tab . "}" . PHP_EOL;
continue;
}
else if ($type === 'Stmt_Function') {
//var_dump($stmt);
$function_str = '';
$params_str = '';
self::resolve($stmt->stmts, $function_str, $level + 1, $scope);
$trans_str = self::resolve($stmt->params, $params_str, $level + 1, $scope);
$function_str = $trans_str . '';
$str .=
$tab . "function $stmt->name ({$params_str}) {" . PHP_EOL .
$tab . "{$function_str}" . PHP_EOL .
$tab . "}" . PHP_EOL;
continue;
}
else if ($type === 'Param') {
$str .= "{$stmt->name}";
if ($i < count($stmts) - 1) {
$str .= ",";
}
if ($stmt->default !== null) {
$default_str = '';
self::resolve(array($stmt->default), $default_str, 0, $scope);
$substr .= $tab . "if (typeof {$stmt->name} === 'undefined') {" . PHP_EOL;
$substr .= $tab . "\t{$stmt->name} = {$default_str};" . PHP_EOL;
$substr .= $tab . "}" . PHP_EOL;
}
}
else if ($type === 'Stmt_InlineHTML') {
//var_dump($stmt);
$val = $stmt->value;
$vals = explode("\n", str_replace("\r\n", "\n", $val));
$vals = array_map('trim', $vals);
$vals = implode("');" . PHP_EOL . $tab . "result_string.push('\\n", $vals);
$vals = $tab . "result_string.push('{$vals}');" . PHP_EOL;
$vals = str_replace('result_string.push(\'\n\');', '', $vals);
$vals = str_replace('result_string.push(\'\');', '', $vals);
$vals = explode(PHP_EOL, $vals);
$vals = array_map('rtrim', $vals);
$vals = array_filter($vals);
$str .= implode(PHP_EOL, $vals) . PHP_EOL;
}
else if ($type === 'Stmt_Echo') {
//var_dump($stmt);
$exprs_str = '';
self::resolve($stmt->exprs, $exprs_str, 0, $scope);
$str .= $tab . "result_string.push({$exprs_str});" . PHP_EOL;
}
else if ($type === 'Stmt_Return') {
//var_dump($stmt);
$expr_str = '';
self::resolve(array($stmt->expr), $expr_str, 0, $scope);
$str .= $tab . "return {$expr_str};" . PHP_EOL;
}
else if ($type === 'Scalar_LNumber') {
$str .= $stmt->value;
}
else if ($type === 'Scalar_String') {
$str .= "'{$stmt->value}'";
}
self::resolve($next, $str, $level, $scope);
//echo $type, PHP_EOL;
}
}
return $substr;
}
}
js::template('item-listing.php');
?>
<? js::template('item-listing.php') ?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment