/** * Outputs a stack trace based on the supplied options. * * ### Options * * - `depth` - The number of stack frames to return. Defaults to 999 * - `format` - The format you want the return. Defaults to the currently selected format. If * format is 'array' or 'points' the return will be an array. * - `args` - Should arguments for functions be shown? If true, the arguments for each method call * will be displayed. * - `start` - The stack frame to start generating a trace from. Defaults to 0 * * @param array $options Format for outputting stack trace. * * @return mixed Formatted stack trace. */ public static function trace(array $options = []) { $self = Debugger::getInstance(); $defaults = ['depth' => 999, 'format' => $self->_outputFormat, 'args' => false, 'start' => 0, 'scope' => null, 'exclude' => ['call_user_func_array', 'trigger_error']]; $options = Hash::merge($defaults, $options); $backtrace = debug_backtrace(); $count = count($backtrace); $back = []; $_trace = ['line' => '??', 'file' => '[internal]', 'class' => null, 'function' => '[main]']; for ($i = $options['start']; $i < $count && $i < $options['depth']; $i++) { $trace = $backtrace[$i] + ['file' => '[internal]', 'line' => '??']; $signature = $reference = '[main]'; if (isset($backtrace[$i + 1])) { $next = $backtrace[$i + 1] + $_trace; $signature = $reference = $next['function']; if (!empty($next['class'])) { $signature = $next['class'] . '::' . $next['function']; $reference = $signature . '('; if ($options['args'] && isset($next['args'])) { $args = []; foreach ($next['args'] as $arg) { $args[] = Debugger::exportVar($arg); } $reference .= implode(', ', $args); } $reference .= ')'; } } if (in_array($signature, $options['exclude'])) { continue; } if ($options['format'] === 'points' && $trace['file'] !== '[internal]') { $back[] = ['file' => $trace['file'], 'line' => $trace['line']]; } elseif ($options['format'] === 'array') { $back[] = $trace; } else { if (isset($self->_templates[$options['format']]['traceLine'])) { $tpl = $self->_templates[$options['format']]['traceLine']; } else { $tpl = $self->_templates['base']['traceLine']; } $trace['path'] = static::trimPath($trace['file']); $trace['reference'] = $reference; unset($trace['object'], $trace['args']); $back[] = Text::insert($tpl, $trace, ['before' => '{:', 'after' => '}']); } } if ($options['format'] === 'array' || $options['format'] === 'points') { return $back; } return implode("\n", $back); }
/** * Loads stored configuration information from a resource. You can add * config file resource engines with `Configure::config()`. * * Loaded configuration information will be merged with the current * runtime configuration. You can load configuration files from plugins * by preceding the filename with the plugin name. * * `Configure::load('Users.user')` * * Would load the 'user' config file using the default config engine. You can load * app config files by giving the name of the resource you want loaded. * * `Configure::load('setup');` * * @param string $key name of configuration resource to load. * @param bool $merge if config files should be merged instead of simply overridden * * @return bool if file not found, void if load successful. */ public static function load($key, $merge = true) { $file = static::_getFilePath($key); $return = (include $file); if (!is_array($return)) { throw new Exception(sprintf('Config file "%s" did not return an array', $key . static::EXT)); } $values = $return; if ($merge) { $values = Hash::merge(static::$_values, $values); } return static::write($values); }
/** * Write a config variable * * @param string|array $key Key to write to. * @param mixed $value Value to write. * @param bool|string $merge True to merge recursively, 'shallow' for simple merge, * false to overwrite, defaults to false. * @return void * * @throws \Mars\Configure\Configure\Exception\Exception if attempting to clobber existing config */ protected function _configWrite($key, $value, $merge = false) { if (is_string($key) && $value === null) { $this->_configDelete($key); return; } if ($merge) { if (is_array($key)) { $update = $key; } else { $update = [$key => $value]; } if ($merge === 'shallow') { $this->_config = array_merge($this->_config, Hash::expand($update)); } else { $this->_config = Hash::merge($this->_config, Hash::expand($update)); } return; } if (is_array($key)) { foreach ($key as $k => $val) { $this->_configWrite($k, $val); } return; } if (strpos($key, '.') === false) { $this->_config[$key] = $value; return; } $update =& $this->_config; $stack = explode('.', $key); foreach ($stack as $k) { if (!is_array($update)) { throw new Exception(sprintf('Cannot set %s value', $key)); } if (!isset($update[$k])) { $update[$k] = []; } $update =& $update[$k]; } $update = $value; }