Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationDI
      • ApplicationLatte
      • ApplicationTracy
      • CacheDI
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsDI
      • FormsLatte
      • Framework
      • HttpDI
      • HttpTracy
      • MailDI
      • ReflectionDI
      • SecurityDI
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Conventions
      • Drivers
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Tokenizer
    • Utils
  • Tracy
    • Bridges
      • Nette
  • none

Classes

  • ClassType
  • Closure
  • Constant
  • Factory
  • GlobalFunction
  • Helpers
  • Method
  • Parameter
  • PhpFile
  • PhpLiteral
  • PhpNamespace
  • Property
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  6:  */
  7: 
  8: namespace Nette\PhpGenerator;
  9: 
 10: use Nette;
 11: 
 12: 
 13: /**
 14:  * PHP code generator utils.
 15:  */
 16: class Helpers
 17: {
 18:     use Nette\StaticClass;
 19: 
 20:     const PHP_IDENT = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*';
 21:     const MAX_DEPTH = 50;
 22:     const WRAP_LENGTH = 70;
 23: 
 24: 
 25:     /**
 26:      * Returns a PHP representation of a variable.
 27:      * @return string
 28:      */
 29:     public static function dump($var)
 30:     {
 31:         return self::_dump($var);
 32:     }
 33: 
 34: 
 35:     private static function _dump(&$var, $level = 0)
 36:     {
 37:         if ($var instanceof PhpLiteral) {
 38:             return (string) $var;
 39: 
 40:         } elseif (is_float($var)) {
 41:             if (is_finite($var)) {
 42:                 $var = var_export($var, true);
 43:                 return strpos($var, '.') === false ? $var . '.0' : $var; // workaround for PHP < 7.0.2
 44:             }
 45:             return str_replace('.0', '', var_export($var, true)); // workaround for PHP 7.0.2
 46: 
 47:         } elseif ($var === null) {
 48:             return 'null';
 49: 
 50:         } elseif (is_string($var) && (preg_match('#[^\x09\x20-\x7E\xA0-\x{10FFFF}]#u', $var) || preg_last_error())) {
 51:             static $table;
 52:             if ($table === null) {
 53:                 foreach (array_merge(range("\x00", "\x1F"), range("\x7F", "\xFF")) as $ch) {
 54:                     $table[$ch] = '\x' . str_pad(dechex(ord($ch)), 2, '0', STR_PAD_LEFT);
 55:                 }
 56:                 $table['\\'] = '\\\\';
 57:                 $table["\r"] = '\r';
 58:                 $table["\n"] = '\n';
 59:                 $table["\t"] = '\t';
 60:                 $table['$'] = '\$';
 61:                 $table['"'] = '\"';
 62:             }
 63:             return '"' . strtr($var, $table) . '"';
 64: 
 65:         } elseif (is_string($var)) {
 66:             return "'" . preg_replace('#\'|\\\\(?=[\'\\\\]|\z)#', '\\\\$0', $var) . "'";
 67: 
 68:         } elseif (is_array($var)) {
 69:             $space = str_repeat("\t", $level);
 70: 
 71:             static $marker;
 72:             if ($marker === null) {
 73:                 $marker = uniqid("\x00", true);
 74:             }
 75:             if (empty($var)) {
 76:                 $out = '';
 77: 
 78:             } elseif ($level > self::MAX_DEPTH || isset($var[$marker])) {
 79:                 throw new Nette\InvalidArgumentException('Nesting level too deep or recursive dependency.');
 80: 
 81:             } else {
 82:                 $out = '';
 83:                 $outAlt = "\n$space";
 84:                 $var[$marker] = true;
 85:                 $counter = 0;
 86:                 foreach ($var as $k => &$v) {
 87:                     if ($k !== $marker) {
 88:                         $item = ($k === $counter ? '' : self::_dump($k, $level + 1) . ' => ') . self::_dump($v, $level + 1);
 89:                         $counter = is_int($k) ? max($k + 1, $counter) : $counter;
 90:                         $out .= ($out === '' ? '' : ', ') . $item;
 91:                         $outAlt .= "\t$item,\n$space";
 92:                     }
 93:                 }
 94:                 unset($var[$marker]);
 95:             }
 96:             return '[' . (strpos($out, "\n") === false && strlen($out) < self::WRAP_LENGTH ? $out : $outAlt) . ']';
 97: 
 98:         } elseif ($var instanceof \Serializable) {
 99:             $var = serialize($var);
100:             return 'unserialize(' . self::_dump($var, $level) . ')';
101: 
102:         } elseif ($var instanceof \Closure) {
103:             throw new Nette\InvalidArgumentException('Cannot dump closure.');
104: 
105:         } elseif (is_object($var)) {
106:             $class = get_class($var);
107:             if (PHP_VERSION_ID >= 70000 && (new \ReflectionObject($var))->isAnonymous()) {
108:                 throw new Nette\InvalidArgumentException('Cannot dump anonymous class.');
109: 
110:             } elseif (in_array($class, ['DateTime', 'DateTimeImmutable'], true)) {
111:                 return self::formatArgs("new $class(?, new DateTimeZone(?))", [$var->format('Y-m-d H:i:s.u'), $var->getTimeZone()->getName()]);
112:             }
113: 
114:             $arr = (array) $var;
115:             $space = str_repeat("\t", $level);
116: 
117:             static $list = [];
118:             if ($level > self::MAX_DEPTH || in_array($var, $list, true)) {
119:                 throw new Nette\InvalidArgumentException('Nesting level too deep or recursive dependency.');
120: 
121:             } else {
122:                 $out = "\n";
123:                 $list[] = $var;
124:                 if (method_exists($var, '__sleep')) {
125:                     foreach ($var->__sleep() as $v) {
126:                         $props[$v] = $props["\x00*\x00$v"] = $props["\x00$class\x00$v"] = true;
127:                     }
128:                 }
129:                 foreach ($arr as $k => &$v) {
130:                     if (!isset($props) || isset($props[$k])) {
131:                         $out .= "$space\t" . self::_dump($k, $level + 1) . ' => ' . self::_dump($v, $level + 1) . ",\n";
132:                     }
133:                 }
134:                 array_pop($list);
135:                 $out .= $space;
136:             }
137:             return $class === 'stdClass'
138:                 ? "(object) [$out]"
139:                 : __CLASS__ . "::createObject('$class', [$out])";
140: 
141:         } elseif (is_resource($var)) {
142:             throw new Nette\InvalidArgumentException('Cannot dump resource.');
143: 
144:         } else {
145:             return var_export($var, true);
146:         }
147:     }
148: 
149: 
150:     /**
151:      * Generates PHP statement.
152:      * @param  string
153:      * @return string
154:      */
155:     public static function format($statement, ...$args)
156:     {
157:         return self::formatArgs($statement, $args);
158:     }
159: 
160: 
161:     /**
162:      * Generates PHP statement.
163:      * @param  string
164:      * @return string
165:      */
166:     public static function formatArgs($statement, array $args)
167:     {
168:         $tokens = preg_split('#(\.\.\.\?|\$\?|->\?|::\?|\\\\\?|\?\*|\?)#', $statement, -1, PREG_SPLIT_DELIM_CAPTURE);
169:         $res = '';
170:         foreach ($tokens as $n => $token) {
171:             if ($n % 2 === 0) {
172:                 $res .= $token;
173:             } elseif ($token === '\\?') {
174:                 $res .= '?';
175:             } elseif (!$args) {
176:                 throw new Nette\InvalidArgumentException('Insufficient number of arguments.');
177:             } elseif ($token === '?') {
178:                 $res .= self::dump(array_shift($args));
179:             } elseif ($token === '...?' || $token === '?*') {
180:                 $arg = array_shift($args);
181:                 if (!is_array($arg)) {
182:                     throw new Nette\InvalidArgumentException('Argument must be an array.');
183:                 }
184:                 $sep = '';
185:                 foreach ($arg as $tmp) {
186:                     $res .= $sep . self::dump($tmp);
187:                     $sep = strlen($res) - strrpos($res, "\n") > self::WRAP_LENGTH ? ",\n\t" : ', ';
188:                 }
189:             } else { // $  ->  ::
190:                 $res .= substr($token, 0, -1) . self::formatMember(array_shift($args));
191:             }
192:         }
193:         return $res;
194:     }
195: 
196: 
197:     /**
198:      * Returns a PHP representation of a object member.
199:      * @return string
200:      */
201:     public static function formatMember($name)
202:     {
203:         return $name instanceof PhpLiteral || !self::isIdentifier($name)
204:             ? '{' . self::_dump($name) . '}'
205:             : $name;
206:     }
207: 
208: 
209:     /**
210:      * @param  string
211:      * @return string
212:      */
213:     public static function formatDocComment($content)
214:     {
215:         if (($s = trim($content)) === '') {
216:             return '';
217:         } elseif (strpos($content, "\n") === false) {
218:             return "/** $s */\n";
219:         } else {
220:             return str_replace("\n", "\n * ", "/**\n$s") . "\n */\n";
221:         }
222:     }
223: 
224: 
225:     /**
226:      * @param  string
227:      * @return string
228:      */
229:     public static function unformatDocComment($comment)
230:     {
231:         return preg_replace('#^\s*\* ?#m', '', trim(trim(trim($comment), '/*')));
232:     }
233: 
234: 
235:     /**
236:      * @return bool
237:      */
238:     public static function isIdentifier($value)
239:     {
240:         return is_string($value) && preg_match('#^' . self::PHP_IDENT . '\z#', $value);
241:     }
242: 
243: 
244:     /**
245:      * @return bool
246:      */
247:     public static function isNamespaceIdentifier($value, $allowLeadingSlash = false)
248:     {
249:         $re = '#^' . ($allowLeadingSlash ? '\\\\?' : '') . self::PHP_IDENT . '(\\\\' . self::PHP_IDENT . ')*\z#';
250:         return is_string($value) && preg_match($re, $value);
251:     }
252: 
253: 
254:     /**
255:      * @param  string
256:      * @return object
257:      * @internal
258:      */
259:     public static function createObject($class, array $props)
260:     {
261:         return unserialize('O' . substr(serialize((string) $class), 1, -1) . substr(serialize($props), 1));
262:     }
263: 
264: 
265:     /**
266:      * @param  string
267:      * @return string
268:      */
269:     public static function extractNamespace($name)
270:     {
271:         return ($pos = strrpos($name, '\\')) ? substr($name, 0, $pos) : '';
272:     }
273: 
274: 
275:     /**
276:      * @param  string
277:      * @return string
278:      */
279:     public static function extractShortName($name)
280:     {
281:         return ($pos = strrpos($name, '\\')) === false ? $name : substr($name, $pos + 1);
282:     }
283: }
284: 
Nette 2.4-20170829 API API documentation generated by ApiGen 2.8.0