From: Andrey Kutejko Date: Fri, 26 Jul 2013 05:41:48 +0000 (+0300) Subject: cleanup. update yaml parser X-Git-Tag: 0.6~78 X-Git-Url: https://git.andy128k.dev/?a=commitdiff_plain;h=8c3aa75cfb8d8d9a4c7d42c79654d51ed4846a9f;p=ipf-legacy-orm.git cleanup. update yaml parser --- diff --git a/ipf/orm/collection.php b/ipf/orm/collection.php index 129c512..2e89bf1 100644 --- a/ipf/orm/collection.php +++ b/ipf/orm/collection.php @@ -453,24 +453,6 @@ class IPF_ORM_Collection extends IPF_ORM_Access implements Countable, IteratorAg return $this->synchronizeWithArray($array); } - public function exportTo($type, $deep = false) - { - if ($type == 'array') { - return $this->toArray($deep); - } else { - return IPF_ORM_Parser::dump($this->toArray($deep, true), $type); - } - } - - public function importFrom($type, $data) - { - if ($type == 'array') { - return $this->fromArray($data); - } else { - return $this->fromArray(IPF_ORM_Parser::load($data, $type)); - } - } - public function getDeleteDiff() { return array_udiff($this->_snapshot, $this->data, array($this, 'compareRecords')); diff --git a/ipf/orm/import/schema.php b/ipf/orm/import/schema.php index b62fe8d..163db9f 100644 --- a/ipf/orm/import/schema.php +++ b/ipf/orm/import/schema.php @@ -79,13 +79,13 @@ class IPF_ORM_Import_Schema public function importSchema($filename, $extraAllwedReferences) { - $array = $this->parseSchema($filename, 'yml'); + $array = $this->parseSchema($filename); $array = $this->_buildRelationships($array, $extraAllwedReferences); $array = $this->_processInheritance($array); return $array; } - public function parseSchema($schema, $type) + private function parseSchema($schema) { $defaults = array('abstract' => false, 'className' => null, @@ -100,7 +100,7 @@ class IPF_ORM_Import_Schema 'inheritance' => array(), 'detect_relations' => false); - $array = IPF_ORM_Parser::load($schema, $type); + $array = Spyc::YAMLLoad($schema); // Go through the schema and look for global values so we can assign them to each table/class $globals = array(); diff --git a/ipf/orm/parser.php b/ipf/orm/parser.php deleted file mode 100644 index a670b9d..0000000 --- a/ipf/orm/parser.php +++ /dev/null @@ -1,48 +0,0 @@ -loadData($path); - } - - static public function dump($array, $type = 'xml', $path = null) - { - $parser = self::getParser($type); - return $parser->dumpData($array, $path); - } - - public function doLoad($path) - { - ob_start(); - if ( ! file_exists($path)) { - $contents = $path; - $path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'dparser_' . microtime(); - - file_put_contents($path, $contents); - } - include($path); - $contents = iconv("UTF-8", "UTF-8", ob_get_clean()); - return $contents; - } - - public function doDump($data, $path = null) - { - if ($path !== null) { - return file_put_contents($path, $data); - } else { - return $data; - } - } -} \ No newline at end of file diff --git a/ipf/orm/parser/spyc.php b/ipf/orm/parser/spyc.php deleted file mode 100644 index 953d2b4..0000000 --- a/ipf/orm/parser/spyc.php +++ /dev/null @@ -1,637 +0,0 @@ -id = $nodeId; - } -} - -class IPF_ORM_Parser_Spyc { - - function YAMLLoad($input) { - $spyc = new IPF_ORM_Spyc; - return $spyc->load($input); - } - - function YAMLDump($array,$indent = false,$wordwrap = false) { - $spyc = new IPF_ORM_Spyc; - return $spyc->dump($array,$indent,$wordwrap); - } - - function load($input) { - if ( ! empty($input) && (strpos($input, "\n") === false) - && file_exists($input)) { - $yaml = file($input); - } else { - $yaml = explode("\n",$input); - } - $base = new IPF_ORM_Parser_Spyc_YamlNode (1); - $base->indent = 0; - $this->_lastIndent = 0; - $this->_lastNode = $base->id; - $this->_inBlock = false; - $this->_isInline = false; - $this->_nodeId = 2; - - foreach ($yaml as $linenum => $line) { - $ifchk = trim($line); - if (preg_match('/^(\t)+(\w+)/', $line)) { - $err = 'ERROR: Line '. ($linenum + 1) .' in your input YAML begins'. - ' with a tab. YAML only recognizes spaces. Please reformat.'; - die($err); - } - - if ($this->_inBlock === false && empty($ifchk)) { - continue; - } elseif ($this->_inBlock == true && empty($ifchk)) { - $last =& $this->_allNodes[$this->_lastNode]; - $last->data[key($last->data)] .= "\n"; - } elseif ($ifchk{0} != '#' && substr($ifchk,0,3) != '---') { - $node = new IPF_ORM_Parser_Spyc_YamlNode ($this->_nodeId); - $this->_nodeId++; - - $node->indent = $this->_getIndent($line); - - // Check where the node lies in the hierarchy - if ($this->_lastIndent == $node->indent) { - // If we're in a block, add the text to the parent's data - if ($this->_inBlock === true) { - $parent =& $this->_allNodes[$this->_lastNode]; - $parent->data[key($parent->data)] .= trim($line).$this->_blockEnd; - } else { - // The current node's parent is the same as the previous node's - if (isset($this->_allNodes[$this->_lastNode])) { - $node->parent = $this->_allNodes[$this->_lastNode]->parent; - } - } - } elseif ($this->_lastIndent < $node->indent) { - if ($this->_inBlock === true) { - $parent =& $this->_allNodes[$this->_lastNode]; - $parent->data[key($parent->data)] .= trim($line).$this->_blockEnd; - } elseif ($this->_inBlock === false) { - // The current node's parent is the previous node - $node->parent = $this->_lastNode; - - // If the value of the last node's data was > or | we need to - // start blocking i.e. taking in all lines as a text value until - // we drop our indent. - $parent =& $this->_allNodes[$node->parent]; - $this->_allNodes[$node->parent]->children = true; - if (is_array($parent->data)) { - $chk = ''; - if (isset ($parent->data[key($parent->data)])) - $chk = $parent->data[key($parent->data)]; - if ($chk === '>') { - $this->_inBlock = true; - $this->_blockEnd = ' '; - $parent->data[key($parent->data)] = - str_replace('>','',$parent->data[key($parent->data)]); - $parent->data[key($parent->data)] .= trim($line).' '; - $this->_allNodes[$node->parent]->children = false; - $this->_lastIndent = $node->indent; - } elseif ($chk === '|') { - $this->_inBlock = true; - $this->_blockEnd = "\n"; - $parent->data[key($parent->data)] = - str_replace('|','',$parent->data[key($parent->data)]); - $parent->data[key($parent->data)] .= trim($line)."\n"; - $this->_allNodes[$node->parent]->children = false; - $this->_lastIndent = $node->indent; - } - } - } - } elseif ($this->_lastIndent > $node->indent) { - // Any block we had going is dead now - if ($this->_inBlock === true) { - $this->_inBlock = false; - if ($this->_blockEnd = "\n") { - $last =& $this->_allNodes[$this->_lastNode]; - $last->data[key($last->data)] = - trim($last->data[key($last->data)]); - } - } - - // We don't know the parent of the node so we have to find it - // foreach ($this->_allNodes as $n) { - foreach ($this->_indentSort[$node->indent] as $n) { - if ($n->indent == $node->indent) { - $node->parent = $n->parent; - } - } - } - - if ($this->_inBlock === false) { - // Set these properties with information from our current node - $this->_lastIndent = $node->indent; - // Set the last node - $this->_lastNode = $node->id; - // Parse the YAML line and return its data - $node->data = $this->_parseLine($line); - // Add the node to the master list - $this->_allNodes[$node->id] = $node; - // Add a reference to the parent list - $this->_allParent[intval($node->parent)][] = $node->id; - // Add a reference to the node in an indent array - $this->_indentSort[$node->indent][] =& $this->_allNodes[$node->id]; - // Add a reference to the node in a References array if this node - // has a YAML reference in it. - if ( - ( (is_array($node->data)) && - isset($node->data[key($node->data)]) && - ( ! is_array($node->data[key($node->data)])) ) - && - ( (preg_match('/^&([^ ]+)/',$node->data[key($node->data)])) - || - (preg_match('/^\*([^ ]+)/',$node->data[key($node->data)])) ) - ) { - $this->_haveRefs[] =& $this->_allNodes[$node->id]; - } elseif ( - ( (is_array($node->data)) && - isset($node->data[key($node->data)]) && - (is_array($node->data[key($node->data)])) ) - ) { - // Incomplete reference making code. Ugly, needs cleaned up. - foreach ($node->data[key($node->data)] as $d) { - if ( !is_array($d) && - ( (preg_match('/^&([^ ]+)/',$d)) - || - (preg_match('/^\*([^ ]+)/',$d)) ) - ) { - $this->_haveRefs[] =& $this->_allNodes[$node->id]; - } - } - } - } - } - } - unset($node); - - // Here we travel through node-space and pick out references (& and *) - $this->_linkReferences(); - - // Build the PHP array out of node-space - $trunk = $this->_buildArray(); - return $trunk; - } - - function dump($array,$indent = false,$wordwrap = false) { - // Dumps to some very clean YAML. We'll have to add some more features - // and options soon. And better support for folding. - - // New features and options. - if ($indent === false or !is_numeric($indent)) { - $this->_dumpIndent = 2; - } else { - $this->_dumpIndent = $indent; - } - - if ($wordwrap === false or !is_numeric($wordwrap)) { - $this->_dumpWordWrap = 40; - } else { - $this->_dumpWordWrap = $wordwrap; - } - - // New YAML document - $string = "---\n"; - - // Start at the base of the array and move through it. - foreach ($array as $key => $value) { - $string .= $this->_yamlize($key,$value,0); - } - return $string; - } - - var $_haveRefs; - var $_allNodes; - var $_allParent; - var $_lastIndent; - var $_lastNode; - var $_inBlock; - var $_isInline; - var $_dumpIndent; - var $_dumpWordWrap; - - var $_nodeId; - - function _yamlize($key,$value,$indent) { - if (is_array($value)) { - // It has children. What to do? - // Make it the right kind of item - $string = $this->_dumpNode($key,NULL,$indent); - // Add the indent - $indent += $this->_dumpIndent; - // Yamlize the array - $string .= $this->_yamlizeArray($value,$indent); - } elseif ( ! is_array($value)) { - // It doesn't have children. Yip. - $string = $this->_dumpNode($key,$value,$indent); - } - return $string; - } - - function _yamlizeArray($array,$indent) { - if (is_array($array)) { - $string = ''; - foreach ($array as $key => $value) { - $string .= $this->_yamlize($key,$value,$indent); - } - return $string; - } else { - return false; - } - } - - function _dumpNode($key,$value,$indent) { - // do some folding here, for blocks - if (strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false) { - $value = $this->_doLiteralBlock($value,$indent); - } else { - $value = $this->_doFolding($value,$indent); - } - - if (is_bool($value)) { - $value = ($value) ? "true" : "false"; - } - - $spaces = str_repeat(' ',$indent); - - if (is_int($key)) { - // It's a sequence - $string = $spaces.'- '.$value."\n"; - } else { - // It's mapped - $string = $spaces.$key.': '.$value."\n"; - } - return $string; - } - - function _doLiteralBlock($value,$indent) { - $exploded = explode("\n",$value); - $newValue = '|'; - $indent += $this->_dumpIndent; - $spaces = str_repeat(' ',$indent); - foreach ($exploded as $line) { - $newValue .= "\n" . $spaces . trim($line); - } - return $newValue; - } - - function _doFolding($value,$indent) { - // Don't do anything if wordwrap is set to 0 - if ($this->_dumpWordWrap === 0) { - return $value; - } - - if (strlen($value) > $this->_dumpWordWrap) { - $indent += $this->_dumpIndent; - $indent = str_repeat(' ',$indent); - $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent"); - $value = ">\n".$indent.$wrapped; - } - return $value; - } - - function _getIndent($line) { - preg_match('/^\s{1,}/',$line,$match); - if ( ! empty($match[0])) { - $indent = substr_count($match[0],' '); - } else { - $indent = 0; - } - return $indent; - } - - function _parseLine($line) { - $line = trim($line); - - if(!preg_match("/\\\#/", $line)) { - $line = trim(preg_replace('/#.*$/', '', $line)); - } - - $array = array(); - - if (preg_match('/^-(.*):$/',$line)) { - // It's a mapped sequence - $key = trim(substr(substr($line,1),0,-1)); - $array[$key] = ''; - } elseif ($line[0] == '-' && substr($line,0,3) != '---') { - // It's a list item but not a new stream - if (strlen($line) > 1) { - $value = trim(substr($line,1)); - // Set the type of the value. Int, string, etc - $value = $this->_toType($value); - $array[] = $value; - } else { - $array[] = array(); - } - } elseif (preg_match('/^(.+):/',$line,$key)) { - // It's a key/value pair most likely - // If the key is in double quotes pull it out - if (preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) { - $value = trim(str_replace($matches[1],'',$line)); - $key = $matches[2]; - } else { - // Do some guesswork as to the key and the value - $explode = explode(':',$line); - $key = trim($explode[0]); - array_shift($explode); - $value = trim(implode(':',$explode)); - } - - // Set the type of the value. Int, string, etc - $value = $this->_toType($value); - if (empty($key)) { - $array[] = $value; - } else { - $array[$key] = $value; - } - } - return $array; - } - - function _toType($value) { - if (preg_match('/^("(.*)"|\'(.*)\')/',$value,$matches)) { - $value = (string)preg_replace('/(\'\'|\\\\\')/',"'",end($matches)); - $value = preg_replace('/\\\\"/','"',$value); - } elseif (preg_match('/^\\[(.*)\\]$/',$value,$matches)) { - // Inline Sequence - - // Take out strings sequences and mappings - $explode = empty($matches[1]) ? array() : $this->_inlineEscape($matches[1]); - - // Propogate value array - $value = array(); - foreach ($explode as $v) { - $value[] = $this->_toType($v); - } - } elseif (strpos($value,': ')!==false && !preg_match('/^{(.+)/',$value)) { - // It's a map - $array = explode(': ',$value); - $key = trim($array[0]); - array_shift($array); - $value = trim(implode(': ',$array)); - $value = $this->_toType($value); - $value = array($key => $value); - } elseif (preg_match("/{(.+)}$/",$value,$matches)) { - // Inline Mapping - - // Take out strings sequences and mappings - $explode = $this->_inlineEscape($matches[1]); - - // Propogate value array - $array = array(); - foreach ($explode as $v) { - $array = $array + $this->_toType($v); - } - $value = $array; - } elseif (strtolower($value) == 'null' or $value == '' or $value == '~') { - $value = NULL; - } elseif (preg_match ('/^[0-9]+$/', $value)) { - // Cheeky change for compartibility with PHP < 4.2.0 - $raw = $value; - $value = (int) $value; - - if ((string) $value != (string) $raw) { - $value = (string) $raw; - } - } elseif (in_array(strtolower($value), - array('true', 'on', '+', 'yes', 'y'))) { - $value = true; - } elseif (in_array(strtolower($value), - array('false', 'off', '-', 'no', 'n'))) { - $value = false; - } elseif (is_numeric($value)) { - $raw = $value; - $value = (float) $value; - - if ((string) $value != (string) $raw) { - $value = (string) $raw; - } - } else { - // Just a normal string, right? - $value = trim(preg_replace('/#(.+)$/','',$value)); - } - - return $value; - } - - function _inlineEscape($inline) { - // There's gotta be a cleaner way to do this... - // While pure sequences seem to be nesting just fine, - // pure mappings and mappings with sequences inside can't go very - // deep. This needs to be fixed. - - $saved_strings = array(); - - // Check for strings - $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/'; - if (preg_match_all($regex,$inline,$strings)) { - $saved_strings = $strings[0]; - $inline = preg_replace($regex,'YAMLString',$inline); - } - unset($regex); - - // Check for sequences - if (preg_match_all('/\[(.+)\]/U',$inline,$seqs)) { - $inline = preg_replace('/\[(.+)\]/U','YAMLSeq',$inline); - $seqs = $seqs[0]; - } - - // Check for mappings - if (preg_match_all('/{(.+)}/U',$inline,$maps)) { - $inline = preg_replace('/{(.+)}/U','YAMLMap',$inline); - $maps = $maps[0]; - } - - $explode = explode(', ',$inline); - - - // Re-add the sequences - if ( ! empty($seqs)) { - $i = 0; - foreach ($explode as $key => $value) { - if (strpos($value,'YAMLSeq') !== false) { - $explode[$key] = str_replace('YAMLSeq',$seqs[$i],$value); - ++$i; - } - } - } - - // Re-add the mappings - if ( ! empty($maps)) { - $i = 0; - foreach ($explode as $key => $value) { - if (strpos($value,'YAMLMap') !== false) { - $explode[$key] = str_replace('YAMLMap',$maps[$i],$value); - ++$i; - } - } - } - - // Re-add the strings - if ( ! empty($saved_strings)) { - $i = 0; - foreach ($explode as $key => $value) { - while (strpos($value,'YAMLString') !== false) { - $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$i],$value, 1); - ++$i; - $value = $explode[$key]; - } - } - } - - return $explode; - } - - function _buildArray() { - $trunk = array(); - - if ( ! isset($this->_indentSort[0])) { - return $trunk; - } - - foreach ($this->_indentSort[0] as $n) { - if (empty($n->parent)) { - $this->_nodeArrayizeData($n); - // Check for references and copy the needed data to complete them. - $this->_makeReferences($n); - // Merge our data with the big array we're building - $trunk = $this->_array_kmerge($trunk,$n->data); - } - } - - return $trunk; - } - - function _linkReferences() { - if (is_array($this->_haveRefs)) { - foreach ($this->_haveRefs as $node) { - if ( ! empty($node->data)) { - $key = key($node->data); - // If it's an array, don't check. - if (is_array($node->data[$key])) { - foreach ($node->data[$key] as $k => $v) { - $this->_linkRef($node,$key,$k,$v); - } - } else { - $this->_linkRef($node,$key); - } - } - } - } - return true; - } - - function _linkRef(&$n,$key,$k = NULL,$v = NULL) { - if (empty($k) && empty($v)) { - // Look for &refs - if (preg_match('/^&([^ ]+)/',$n->data[$key],$matches)) { - // Flag the node so we know it's a reference - $this->_allNodes[$n->id]->ref = substr($matches[0],1); - $this->_allNodes[$n->id]->data[$key] = - substr($n->data[$key],strlen($matches[0])+1); - // Look for *refs - } elseif (preg_match('/^\*([^ ]+)/',$n->data[$key],$matches)) { - $ref = substr($matches[0],1); - // Flag the node as having a reference - $this->_allNodes[$n->id]->refKey = $ref; - } - } elseif ( ! empty($k) && !empty($v)) { - if (preg_match('/^&([^ ]+)/',$v,$matches)) { - // Flag the node so we know it's a reference - $this->_allNodes[$n->id]->ref = substr($matches[0],1); - $this->_allNodes[$n->id]->data[$key][$k] = - substr($v,strlen($matches[0])+1); - // Look for *refs - } elseif (preg_match('/^\*([^ ]+)/',$v,$matches)) { - $ref = substr($matches[0],1); - // Flag the node as having a reference - $this->_allNodes[$n->id]->refKey = $ref; - } - } - } - - function _gatherChildren($nid) { - $return = array(); - $node =& $this->_allNodes[$nid]; - if (is_array ($this->_allParent[$node->id])) { - foreach ($this->_allParent[$node->id] as $nodeZ) { - $z =& $this->_allNodes[$nodeZ]; - // We found a child - $this->_nodeArrayizeData($z); - // Check for references - $this->_makeReferences($z); - // Merge with the big array we're returning - // The big array being all the data of the children of our parent node - $return = $this->_array_kmerge($return,$z->data); - } - } - return $return; - } - - function _nodeArrayizeData(&$node) { - if (is_array($node->data) && $node->children == true) { - // This node has children, so we need to find them - $childs = $this->_gatherChildren($node->id); - // We've gathered all our children's data and are ready to use it - $key = key($node->data); - $key = empty($key) ? 0 : $key; - // If it's an array, add to it of course - if (isset ($node->data[$key])) { - if (is_array($node->data[$key])) { - $node->data[$key] = $this->_array_kmerge($node->data[$key],$childs); - } else { - $node->data[$key] = $childs; - } - } else { - $node->data[$key] = $childs; - } - } elseif ( ! is_array($node->data) && $node->children == true) { - // Same as above, find the children of this node - $childs = $this->_gatherChildren($node->id); - $node->data = array(); - $node->data[] = $childs; - } - - // We edited $node by reference, so just return true - return true; - } - - function _makeReferences(&$z) { - // It is a reference - if (isset($z->ref)) { - $key = key($z->data); - // Copy the data to this object for easy retrieval later - $this->ref[$z->ref] =& $z->data[$key]; - // It has a reference - } elseif (isset($z->refKey)) { - if (isset($this->ref[$z->refKey])) { - $key = key($z->data); - // Copy the data from this object to make the node a real reference - $z->data[$key] =& $this->ref[$z->refKey]; - } - } - return true; - } - - function _array_kmerge($arr1,$arr2) { - if( ! is_array($arr1)) $arr1 = array(); - if( ! is_array($arr2)) $arr2 = array(); - - $keys = array_merge(array_keys($arr1),array_keys($arr2)); - $vals = array_merge(array_values($arr1),array_values($arr2)); - $ret = array(); - foreach($keys as $key) { - list($unused,$val) = each($vals); - if (isset($ret[$key]) and is_int($key)) $ret[] = $val; else $ret[$key] = $val; - } - return $ret; - } -} \ No newline at end of file diff --git a/ipf/orm/parser/yml.php b/ipf/orm/parser/yml.php deleted file mode 100644 index bd6e0a4..0000000 --- a/ipf/orm/parser/yml.php +++ /dev/null @@ -1,19 +0,0 @@ -dump($array, false, false); - return $this->doDump($data, $path); - } - - public function loadData($path) - { - $contents = $this->doLoad($path); - $spyc = new IPF_ORM_Parser_Spyc(); - $array = $spyc->load($contents); - return $array; - } -} diff --git a/ipf/orm/record.php b/ipf/orm/record.php index f7898a4..e618d8b 100644 --- a/ipf/orm/record.php +++ b/ipf/orm/record.php @@ -864,24 +864,6 @@ abstract class IPF_ORM_Record extends IPF_ORM_Record_Abstract implements Countab } } - public function exportTo($type, $deep = true) - { - if ($type == 'array') { - return $this->toArray($deep); - } else { - return IPF_ORM_Parser::dump($this->toArray($deep, true), $type); - } - } - - public function importFrom($type, $data) - { - if ($type == 'array') { - return $this->fromArray($data); - } else { - return $this->fromArray(IPF_ORM_Parser::load($data, $type)); - } - } - public function exists() { return ($this->_state !== IPF_ORM_Record::STATE_TCLEAN &&