function parse($path, array $var = array(), $maxDepth = null) { $file = $this->basePath . '/' . ltrim($path, '/'); $meta = array(); foreach (array(dirname(dirname($file)), dirname($file)) as $v) { $v .= '/_meta.txt'; if (file_exists($v)) { $meta = array_merge_recursive($meta, $this->parseArr($this->getContent($v), $maxDepth)); } } $content = $this->getContent($file); // parse here doc $hereDoc = array(); $content = preg_replace_callback('/<<<(.+)>>>/sm', function (&$node) use(&$hereDoc) { $hereDoc[] = $node[1]; return '\\d' . (count($hereDoc) - 1); }, $content); $arr = $this->parseArr($content, $maxDepth); if (array_key_exists('_meta', $arr)) { if (!empty($arr['_meta'])) { $meta = array_merge_recursive($meta, $arr['_meta']); } unset($arr['_meta']); } if (!empty($meta['_unset'])) { Arrays::unsetr($meta, $meta['_unset']); unset($meta['_unset']); } foreach ($arr as $k => $v) { if (null == $v) { unset($arr[$k]); continue; } $parent = $meta; // unset if (!empty($v['_unset'])) { Arrays::unsetr($parent, $v['_unset']); unset($v['_unset']); } // default if (!empty($parent['default'])) { list($v, $temp) = array($parent['default'], $v); Arrays::merger($v, $temp); } // replace Arrays::pregReplacer('/^\\\\k$/', $k, $v); // key clean Arrays::pregReplaceKeyr('/^\\\\s(\\d+)$/', '\\1', $v); // prefix if (!empty($parent['prefix'])) { Arrays::prefixr($v, $parent['prefix']); } // suffix if (!empty($parent['suffix'])) { Arrays::suffixr($v, $parent['suffix']); } // wraper if (!empty($parent['wraper'])) { Arrays::wraperr($v, $parent['wraper']); } // var replace if (!empty($var)) { array_walk_recursive($v, function (&$v, $k, $var) { if (is_string($v)) { preg_match_all('/\\{\\$(\\w+)\\}/', $v, $matches); if (!empty($matches[1])) { foreach ($matches[1] as $v1) { if (isset($var[$v1])) { $v = str_replace('{$' . $v1 . '}', $var[$v1], $v); } } } } }, $var); } // \d recover $search = $replace = array(); for ($i = 0; $i < count($hereDoc); $i++) { $search[] = '/^\\\\d' . $i . '$/'; $replace[] = $hereDoc[$i]; } Arrays::pregReplacer($search, $replace, $v); $arr[$k] = $v; } // \h self inherit $funcH = function (array &$subject) use(&$funcH, $arr) { foreach ($subject as $k => &$v) { if ('\\h' === $k) { $key = explode(' ', $v); $value = \Arrays::current($arr, $key); $key = array_pop($key); $subject[$key] = $value; unset($subject[$k]); } elseif (is_array($v)) { call_user_func_array($funcH, array(&$v)); } } }; $funcH($arr); // \i include $dir = dirname($file) . '/_inc'; Arrays::pregReplaceCallbackr('/\\\\i(.+)/', function ($node) use($dir) { $file = $dir . '/' . trim($node[1]); if (file_exists($file)) { return file_get_contents($file); } }, $arr); return $arr; }
function indexAction() { $path = trim($this->getRequest()->getQuery('path', ''), ' /'); if ('.txt' == substr($path, -4)) { $this->forward('detail', array('path' => $path)); return false; } $out = array(); $model = DocModel::getInstance(); $out['list'] = $model->getList($path, 4); // set version list in inverted order $sort = function (&$v) { if (is_array($v)) { reset($v); $k1 = key($v); $v1 = current($v); next($v); $k2 = key($v); $v2 = current($v); $pattern = '/^v\\d\\.\\d\\.\\d/'; if (preg_match($pattern, $k1) && preg_match($pattern, $k2)) { uksort($v, function ($a, $b) { return $a < $b; }); } if (is_string($v1) && is_string($v2)) { if (preg_match($pattern, $v1) && preg_match($pattern, $v2)) { uasort($v, function ($a, $b) { return $a < $b; }); } } } }; $sort($out['list']); Arrays::walkr($out['list'], function (&$v) use($sort) { $sort($v); }); $mapKey = array(); $mapValue = array(); Arrays::pregReplaceKeyr('/.+/', function ($match) use(&$mapKey) { if (0 === strpos(PHP_OS, 'WIN')) { $enc = mb_convert_encoding($match[0], "UTF-8", "GBK"); } else { $enc = $match[0]; } $mapKey[$enc] = urlencode($match[0]); return $enc; }, $out['list']); Arrays::pregReplacer('/.+/', function ($match) use(&$mapValue) { if (0 === strpos(PHP_OS, 'WIN')) { $enc = mb_convert_encoding($match[0], "UTF-8", "GBK"); } else { $enc = $match[0]; } $mapValue[$enc] = urlencode($match[0]); return $enc; }, $out['list']); $out['map'] = $mapKey; $out['mapVal'] = $mapValue; $this->getView()->assign($out); }
/** * parse doc file and relative files * * @param string $path * @param array $var * replacement in doc * @param int $maxDepth * @return mixed */ function parse($path, array $var = array(), $maxDepth = null) { $file = $this->basePath . '/' . ltrim($path, '/'); // replace var $funcVarReplace = function ($arr, $var) { if (!empty($var)) { $flag = false; if (is_string($arr)) { $flag = true; $arr = array($arr); } array_walk_recursive($arr, function (&$v, $k, $var) { if (is_string($v)) { preg_match_all('/\\{\\$(\\w+)\\}/', $v, $matches); if (!empty($matches[1])) { foreach ($matches[1] as $v1) { if (isset($var[$v1])) { $v = str_replace('{$' . $v1 . '}', $var[$v1], $v); } } } } }, $var); } if ($flag) { $arr = $arr[0]; } return $arr; }; $i = 0; $meta = array(); // merge _meta.txt foreach (array(dirname(dirname($file)), dirname($file)) as $v) { $v .= '/_meta.txt'; if (file_exists($v)) { $metaCurrent = $this->parseArr($this->getContent($v), $maxDepth); $lastUnset = array(); if (!empty($metaCurrent['_unset'])) { $lastUnset = $metaCurrent['_unset']; unset($metaCurrent['_unset']); } // meta inherit $metaFile = $v; while (!empty($metaCurrent['inherit'])) { if ($i++ > 10) { // break; } // replace version in _meta.txt $metaFile = dirname($metaFile) . '/' . $metaCurrent['inherit']; unset($metaCurrent['inherit']); if (false !== strpos($metaFile, '{$version}')) { preg_match('/v\\d\\.\\d\\.\\d/', $metaFile, $metaFileVersion); if (!empty($metaFileVersion[0])) { $metaFile = str_replace('{$version}', $metaFileVersion[0], $metaFile); } } $metaInherit = $this->parseArr($this->getContent($metaFile), $maxDepth); $metaCurrent = Arrays::merger($metaInherit, $metaCurrent); } $meta = Arrays::merger($meta, $metaCurrent); $meta = Arrays::unsetr($meta, $lastUnset); if (!empty($meta['_unset']) || !empty($lastUnset)) { if (empty($meta['_unset'])) { $meta['_unset'] = array(); } $lastUnset = array_merge_recursive($lastUnset, $meta['_unset']); unset($meta['_unset']); } } } // merge var in doc if (!empty($meta['var'])) { $var = Arrays::merger($var, $meta['var']); unset($meta['var']); } $content = $this->getContent($file); // parse here doc $hereDoc = array(); $content = preg_replace_callback('/<<<(.+)>>>/sm', function (&$node) use(&$hereDoc) { $hereDoc[] = $node[1]; return '\\d' . (count($hereDoc) - 1); }, $content); // parse content $arr = $this->parseArr($content, $maxDepth); // inline _meta if (!empty($arr['_meta'])) { // process inherit first $fileCurrent = $file; $lastUnset = array(); if (!empty($arr['_unset'])) { $lastUnset = $arr['_unset']; unset($arr['_unset']); } while (!empty($arr['_meta']['inherit'])) { if (is_string($arr['_meta']['inherit'])) { $inheritFile = $arr['_meta']['inherit']; $inheritKeys = null; } elseif (is_array($arr['_meta']['inherit'])) { $inheritFile = $arr['_meta']['inherit'][0]; $inheritKeys = $arr['_meta']['inherit']; array_shift($inheritKeys); } else { user_error('inherit file is invalid', E_USER_ERROR); } unset($arr['_meta']['inherit']); $inheritFile = dirname($fileCurrent) . '/' . $funcVarReplace($inheritFile, $var); $fileCurrent = $inheritFile; $arrInherit = $this->parseArr($this->getContent($inheritFile), $maxDepth); if (isset($inheritKeys)) { foreach ($arrInherit as $k => $v) { if (!in_array($k, $inheritKeys)) { unset($arrInherit[$k]); } } } $arrInherit = Arrays::unsetr($arrInherit, $lastUnset); if (!empty($arrInherit['_unset']) || !empty($lastUnset)) { if (empty($arrInherit['_unset'])) { $arrInherit['_unset'] = array(); } $lastUnset = array_merge_recursive($lastUnset, $arrInherit['_unset']); unset($arrInherit['_unset']); } $arrInherit = Arrays::merger($arrInherit, $arr); $arr = $arrInherit; } if (array_key_exists('_meta', $arr)) { $meta = array_merge_recursive($meta, $arr['_meta']); } unset($arr['_meta']); } // do _meta definitions foreach ($arr as $k => $v) { if (null == $v) { unset($arr[$k]); continue; } $metaReplace = $meta; // default if (!empty($metaReplace['default'])) { list($v, $temp) = array($metaReplace['default'], $v); $v = Arrays::merger($v, $temp); } // replace Arrays::pregReplacer('/^\\\\k$/', $k, $v); // key clean Arrays::pregReplaceKeyr('/^\\\\s(\\d+)$/', '\\1', $v); // prefix if (!empty($metaReplace['prefix'])) { Arrays::prefixr($v, $metaReplace['prefix']); } // suffix if (!empty($metaReplace['suffix'])) { Arrays::suffixr($v, $metaReplace['suffix']); } // wraper if (!empty($metaReplace['wraper'])) { Arrays::wraperr($v, $metaReplace['wraper']); } // var replace $v = $funcVarReplace($v, $var); // \d recover $search = $replace = array(); for ($i = 0; $i < count($hereDoc); $i++) { $search[] = '/^\\\\d' . $i . '$/'; $replace[] = $hereDoc[$i]; } Arrays::pregReplacer($search, $replace, $v); $arr[$k] = $v; } // \h self inherit $funcInherit = function (array &$subject) use(&$funcInherit, $arr) { foreach ($subject as $k => &$v) { if ('\\h' === $k) { if (is_string($v)) { $key = array($v); } else { $key = $v; } $value = Arrays::current($arr, $key); $key = array_pop($key); $subject[$key] = $value; unset($subject[$k]); } elseif (is_array($v)) { call_user_func_array($funcInherit, array(&$v)); } } }; $funcInherit($arr); // \i include $dir = dirname($file); Arrays::pregReplacer('/\\\\i(.+)/', function ($node) use($dir) { $file = $dir . '/' . trim($node[1]); if (file_exists($file)) { return file_get_contents($file); } }, $arr); // sort param foreach ($arr as &$v) { if (!empty($v['params']['httpPost'])) { uasort($v['params']['httpPost'], function ($a, $b) { return $a[0] < $b[0]; }); } if (!empty($v['params']['httpGet'])) { uasort($v['params']['httpGet'], function ($a, $b) { return $a[0] < $b[0]; }); } } // sort value foreach ($arr as &$v) { if (!empty($v['return']['data']['value']['data']['data'])) { uksort($v['return']['data']['value']['data']['data'], function ($a, $b) { return $a > $b; }); } } return $arr; }