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