Created
July 24, 2009 04:10
-
-
Save favrik/153831 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Note: some parts based on the Spyc YAML parser at http://code.google.com/p/spyc/ | |
*/ | |
class MorpheusParser { | |
private $Form = array(); | |
/* Pseudo Global Variables shared by several methods */ | |
private $group_cursor = 0; | |
private $field_name = ''; | |
private $CURRENT_STATE = 'START'; | |
private function getFile($input) { | |
if (!empty($input) and file_exists($input)) { | |
return file($input); | |
} | |
} | |
private function isComment ($line) { | |
if (!$line) { | |
return false; | |
} | |
if ($line[0] == '#') { | |
return true; | |
} | |
return false; | |
} | |
private function isBlankLine($line) { | |
return $line === ''; | |
} | |
private function parseAttributes($line) { | |
$result = array(); | |
$attribs = explode(' ', $line); | |
foreach ($attribs as $attrib) { | |
$current = explode('=', $attrib); | |
$result[array_shift($current)] = array_shift($current); | |
} | |
return $result; | |
} | |
private function addForm($line) { | |
$params = explode(' ', $line); | |
$params_number = count($params); | |
if ($params_number < 2) { | |
throw new Exception('"form:" directive requires, at least, one line | |
with two parameters separated by a space.'); | |
} | |
$this->Form['layout'] = array_shift($params); | |
$this->Form['method'] = array_shift($params); | |
if ($params_number === 3) { | |
$this->Form['action'] = array_shift($params); | |
} | |
} | |
private function addFormAttributes($line) { | |
if (!$this->isBlankLine($line)) { | |
$this->Form['attrib'] = $this->parseAttributes($line); | |
} | |
} | |
private function isAttributeLine($line) { | |
return strpos($line, '=') !== false; | |
} | |
private function isFieldStart($line) { | |
$pos = strpos($line, ':'); | |
if ($pos !== false and $line !== 'group:' and $line !== 'form:') { | |
return $pos; | |
} | |
return false; | |
} | |
private function addGroup($line) { | |
if (empty($line)) { | |
throw new Exception('"legend" cannot be empty when adding a group.'); | |
} | |
$this->Form['groups'] = array(); | |
$this->Form['groups'][$this->group_cursor]['legend'] = $line; | |
$this->Form['groups'][$this->group_cursor]['fields'] = array(); | |
} | |
private function addGroupAttributes($line) { | |
$return = $this->isAttributeLine($line); | |
if ($return) { | |
$this->Form['groups'][$this->group_cursor]['attrib'] = $this->parseAttributes($line); | |
} | |
return $return; | |
} | |
private function setFieldName($line) { | |
$pos = strpos($line, ':'); | |
$name = substr($line, 0, $pos); | |
$this->Form['groups'][$this->group_cursor]['fields'][$name]['name'] = $name; | |
$this->field_name = $name; | |
} | |
private function addFieldParams($line) { | |
$params = explode(' ', $line); | |
$params_number = count($params); | |
if ($params_number != 2) { | |
throw new Exception('"field:" directive requires exactly two parameters: TYPE and LABEL.'); | |
} | |
$this->Form['groups'][$this->group_cursor]['fields'][$this->field_name]['type'] = array_shift($params); | |
$this->Form['groups'][$this->group_cursor]['fields'][$this->field_name]['label'] = array_shift($params); | |
} | |
private function addFieldValidations($line) { | |
$params = explode(' ', $line); | |
$validations = array(); | |
foreach ($params as $validation) { | |
$validations[] = $validation; | |
} | |
$this->Form['groups'][$this->group_cursor]['fields'][$this->field_name]['validations'] = $validations; | |
} | |
private function addFieldAttributes($line) { | |
$return = $this->isAttributeLine($line); | |
if ($return) { | |
$this->Form['groups'][$this->group_cursor]['fields'][$this->field_name]['attrib'] = $this->parseAttributes($line); | |
} | |
return $return; | |
} | |
private function automatonStartCheck($line) { | |
if ($line == 'form:') { | |
$this->CURRENT_STATE = 'FORM'; | |
} else if ($line == 'group:') { | |
$this->CURRENT_STATE = 'GROUP'; | |
} else if ($this->isFieldStart($line)) { | |
$this->setFieldName($line); | |
$this->CURRENT_STATE = 'FIELD_PARAMS'; | |
} | |
} | |
private function automaton($line) { | |
switch ($this->CURRENT_STATE) { | |
case 'START': | |
$this->automatonStartCheck($line); | |
break; | |
case 'FORM': | |
$this->addForm($line); | |
$this->CURRENT_STATE = 'FORM_ATTRIBS'; | |
break; | |
case 'FORM_ATTRIBS': | |
$this->addFormAttributes($line); | |
$this->CURRENT_STATE = 'START'; | |
break; | |
case 'GROUP': | |
$this->addGroup($line); | |
$this->CURRENT_STATE = 'GROUP_ATTRIBS'; | |
break; | |
case 'GROUP_ATTRIBS': | |
if ($this->addGroupAttributes($line)) { | |
$this->CURRENT_STATE = 'FIELD'; | |
break; | |
} | |
case 'FIELD': | |
$this->setFieldName($line); | |
$this->CURRENT_STATE = 'FIELD_PARAMS'; | |
break; | |
case 'FIELD_PARAMS': | |
$this->addFieldParams($line); | |
$this->CURRENT_STATE = 'VALIDATIONS'; | |
break; | |
case 'VALIDATIONS': | |
$this->addFieldValidations($line); | |
$this->CURRENT_STATE = 'FIELD_ATTRIBS'; | |
break; | |
case 'FIELD_ATTRIBS': | |
if ($this->addFieldAttributes($line)) { | |
$this->CURRENT_STATE = 'START'; | |
} else { | |
$this->automatonStartCheck($line); | |
} | |
break; | |
} | |
} | |
private function isDataLine($line) { | |
return !($this->isComment($line) or $this->isBlankLine($line)); | |
} | |
private function parse($file) { | |
$lines = $this->getFile($file); | |
$lines = array_map('trim', $lines); | |
for ($i = 0; $i < count($lines); $i++) { | |
if ($this->isDataLine($lines[$i])) { | |
$this->automaton($lines[$i]); | |
} | |
} | |
return $this->Form; | |
} | |
public static function load($file) { | |
$parser = new MorpheusParser(); | |
return $parser->parse($file); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment