static function error($details = '') { if (!is_scalar($details)) { Debug::toss($details); } else { throw new \Exception($details); } }
static function __callStatic($name, $arguments) { if (!method_exists(__CLASS__, $name)) { Debug::toss('DbBatch method not found: ' . $name); } $class = __CLASS__; $that = new $class(); return call_user_func_array(array($that, $name), $arguments); }
function __call($fnName, $args) { if (method_exists($this, $fnName)) { return call_user_func_array(array($this, $fnName), $args); } elseif (method_exists($this->under, $fnName)) { return call_user_func_array(array($this->under, $fnName), $args); } elseif (method_exists($this->under, '__call')) { //under may have it's own __call handling return call_user_func_array(array($this->under, $fnName), $args); } Debug::toss(__CLASS__ . ' Method not found: ' . $fnName); }
static function json_encode($x, $options = 0, $depth = 512) { $json = json_encode($x, $options, $depth); if ($json === false) { if (json_last_error() == JSON_ERROR_UTF8) { self::utf8_encode($x); $json = json_encode($x, $options, $depth); } } if (json_last_error() != JSON_ERROR_NONE) { $types = [JSON_ERROR_NONE => 'JSON_ERROR_NONE', JSON_ERROR_DEPTH => 'JSON_ERROR_DEPTH', JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH', JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR', JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX', JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8', JSON_ERROR_RECURSION => 'JSON_ERROR_RECURSION', JSON_ERROR_INF_OR_NAN => 'JSON_ERROR_INF_OR_NAN', JSON_ERROR_UNSUPPORTED_TYPE => 'JSON_ERROR_UNSUPPORTED_TYPE']; Debug::toss('JSON encode error: ' . $types[json_last_error()]); } return $json; }
static function loadXml($xml, $nsPrefix = 'd') { $dom = new \DOMDocument(); @$dom->loadXML($xml); $xpath = new \DomXPath($dom); $rootNamespace = $dom->lookupNamespaceUri($dom->namespaceURI); if ($rootNamespace) { if ($dom->documentElement->getAttribute('xmlns:d')) { Debug::toss('Namespace prefix "' . $nsPrefix . '" taken'); } $xpath->registerNamespace($nsPrefix, $rootNamespace); $nsPrefix .= ':'; } else { $nsPrefix = ''; } return array($dom, $xpath, $nsPrefix); }
function resolveRoutes() { $this->unparsedTokens = array_merge([''], $this->tokens); $this->globals['route'] = $this; $i = 0; while ($this->unparsedTokens && !$this->stopRouting) { $i++; if ($i > $this->max_loops) { Debug::out('_routing rules are looping'); Debug::out($this); Debug::toss('Route appears to be looping infinitely'); } $this->currentToken = array_shift($this->unparsedTokens); if ($this->currentToken) { $this->parsedTokens[] = $this->currentToken; } $path = $this->options['folder'] . implode('/', $this->parsedTokens); if (!isset($this->ruleSets[$path])) { $this->ruleSets[$path] = (array) Files::inc($path . '/_routing.php', $this->globals, ['extract' => ['rules']])['rules']; } if (!$this->ruleSets[$path] || $this->stopRouting) { continue; } //note, on match, matehRules resets unparsedTokens (having the effect of loopiing matchRules over again) $this->matchRules($path, $this->ruleSets[$path]); } $this->parsedTokens = []; }
/** @param options { mimic:<return paths prefixes with @:dir>, prefix:<prefix returned file paths with>, filter:<function to filter returned paths>, ghost:<don't error on non-existent>} */ static function scan($dir, $options = []) { if (!$options['prefix'] && $options['mimic']) { $options['prefix'] = $dir; } if (isset($options['maxDepth']) && $options['maxDepth'] == 0) { return []; } $realPath = realpath($dir); if (!$realPath) { if ($options['ghost']) { return []; } else { Debug::toss('No such directory'); } } $realPath .= '/'; $files = array(); foreach (scandir($realPath) as $v) { if ($v != '.' && $v != '..') { if (is_dir($realPath . $v)) { $newOptions = array_merge($options, ['prefix' => $options['prefix'] . $v . '/']); if (isset($newOptions['maxDepth'])) { $newOptions['maxDepth']--; } $newFiles = self::scan($realPath . $v, $newOptions); $files = Arrays::merge($files, $newFiles); } else { if (!$options['filter'] || $options['filter']($options['prefix'] . $v)) { $files[] = $options['prefix'] . $v; } } } } return $files; }
function checkUniqueKeys($value, $table, $type, $id = null) { $indices = $this->db->indices($table); foreach ($indices as $name => $key) { if ($key['unique']) { if ($name != 'PRIMARY') { foreach ($key['columns'] as $column) { if (!isset($this->input->in[$column]) || $this->input->in[$column] === null) { //null indices can overlap continue 2; } } $where = Arrays::extract($key['columns'], $this->input->in); if ($type != 'create' && $id) { $where['id?<>'] = $id; } if ($this->db->check($table, $where)) { Debug::toss(['type' => 'record_not_unique', 'detail' => $key['columns']], 'InputException'); } } } } }
function __methodExists($fnName) { if (!method_exists($this, $fnName)) { Debug::toss(get_called_class() . ' Method not found: ' . $fnName); } }
/** @param table table to replace on @param where see self::where() function @return row count @note as a precaution, to delete all must use $where = '1 = 1' */ protected function delete($table, $where) { if (!$where) { Debug::toss('Unqualified delete is too risky. Use 1=1 to verify'); } return $this->query('DELETE FROM ' . $this->quoteIdentity($table) . $this->where($where))->rowCount(); }
function apply_rules($field, $rules) { try { $value = Arrays::got($this->input, $field); } catch (\Exception $e) { # Field wasn't found $value = null; } foreach ($rules as $rule) { # handle continuity if ($rule['flags']['continuity'] && $this->field_errors($field)) { Debug::toss(['type' => 'continuity']); } elseif ($rule['flags']['full_continuity'] && $this->errors) { Debug::toss(['type' => 'continuity']); } # resolve and try function $fn = $this->resolve_fn($rule['fn_path']); $params = array_merge([$value], $rule['params']); # including `input` and `output` as referenced arrays doubles the time of a do-nothing callback $params[] = ['field' => $field, 'instance' => $this]; try { $value = call_user_func_array($fn, $params); if ($rule['flags']['not']) { Debug::toss(['type' => 'not']); } } catch (\Exception $e) { $error = self::parse_exception($e); if ($rule['flags']['not'] && $error['type'] != 'not') { # potentially, the not flag caused the Error continue; } if (!$rule['flags']['optional']) { $error['rule'] = $rule; $this->error($error, $field); } if ($rule['flags']['break']) { $error['type'] = 'break'; Debug::toss($error); } if ($rule['flags']['break_all']) { $error['type'] = 'break_all'; Debug::toss($error); } } } return $value; }
function ruleCallable($callback) { if (is_string($callback)) { list($type, $method) = explode('.', $callback, 2); if (!$method) { $method = $type; unset($type); } } else { return $callback; } if (!$callback) { \Grithin\Debug::toss('Failed to provide callback for input handler'); } switch ($type) { case 'f': case 'filter': return [$this->filter, $method]; break; case 'v': case 'validate': return [$this->validate, $method]; break; case 'l': case 'local': list($name, $method) = explode('.', $method, 2); return [$this->localInstances[$name], $method]; break; case 'g': case 'global': return $method; break; default: if ($type) { return [$type, $method]; } return $callback; break; } }