public function addServer($host = 'localhost', $port = 11211, $timeout = 1) { Nette\Diagnostics\Debugger::tryError(); $this->memcache->addServer($host, $port, TRUE, 1, $timeout); if (Nette\Diagnostics\Debugger::catchError($e)) { throw new Nette\InvalidStateException('Memcache::addServer(): ' . $e->getMessage(), 0, $e); } }
/** * Reads configuration from INI file. * * @param string file name * * @return array * @throws Nette\InvalidStateException */ public function load($file) { Nette\Diagnostics\Debugger::tryError(); $ini = parse_ini_file($file, true); if (Nette\Diagnostics\Debugger::catchError($e)) { throw new Nette\InvalidStateException('parse_ini_file(): ' . $e->getMessage(), 0, $e); } $data = array(); foreach ($ini as $secName => $secData) { if (is_array($secData)) { // is section? if (substr($secName, -1) === self::RAW_SECTION) { $secName = substr($secName, 0, -1); } else { // process key nesting separator (key1.key2.key3) $tmp = array(); foreach ($secData as $key => $val) { $cursor =& $tmp; $key = str_replace(self::ESCAPED_KEY_SEPARATOR, "ÿ", $key); foreach (explode(self::KEY_SEPARATOR, $key) as $part) { $part = str_replace("ÿ", self::KEY_SEPARATOR, $part); if (!isset($cursor[$part]) || is_array($cursor[$part])) { $cursor =& $cursor[$part]; } else { throw new Nette\InvalidStateException("Invalid key '{$key}' in section [{$secName}] in file '{$file}'."); } } $cursor = $val; } $secData = $tmp; } $parts = explode(self::INHERITING_SEPARATOR, $secName); if (count($parts) > 1) { $secName = trim($parts[0]); $secData[Helpers::EXTENDS_KEY] = trim($parts[1]); } } $cursor =& $data; // nesting separator in section name foreach (explode(self::KEY_SEPARATOR, $secName) as $part) { if (!isset($cursor[$part]) || is_array($cursor[$part])) { $cursor =& $cursor[$part]; } else { throw new Nette\InvalidStateException("Invalid section [{$secName}] in file '{$file}'."); } } if (is_array($secData) && is_array($cursor)) { $secData = Helpers::merge($secData, $cursor); } $cursor = $secData; } return $data; }
public function __construct($host = 'localhost', $port = 11211, $prefix = '', IJournal $journal = NULL) { if (!self::isAvailable()) { throw new Nette\NotSupportedException("PHP extension 'memcache' is not loaded."); } $this->prefix = $prefix; $this->journal = $journal; $this->memcache = new \Memcache(); Nette\Diagnostics\Debugger::tryError(); $this->memcache->connect($host, $port); if (Nette\Diagnostics\Debugger::catchError($e)) { throw new Nette\InvalidStateException('Memcache::connect(): ' . $e->getMessage(), 0, $e); } }
/** * Sends email. * @param Message * @return void */ public function send(Message $mail) { $tmp = clone $mail; $tmp->setHeader('Subject', NULL); $tmp->setHeader('To', NULL); $parts = explode(Message::EOL . Message::EOL, $tmp->generateMessage(), 2); Nette\Diagnostics\Debugger::tryError(); $res = mail(str_replace(Message::EOL, PHP_EOL, $mail->getEncodedHeader('To')), str_replace(Message::EOL, PHP_EOL, $mail->getEncodedHeader('Subject')), str_replace(Message::EOL, PHP_EOL, $parts[1]), str_replace(Message::EOL, PHP_EOL, $parts[0]), (string) $this->commandArgs); if (Nette\Diagnostics\Debugger::catchError($e)) { throw new Nette\InvalidStateException('mail(): ' . $e->getMessage(), 0, $e); } elseif (!$res) { throw new Nette\InvalidStateException('Unable to send email.'); } }
/** * Returns the JSON representation of a value. * @param mixed * @return string */ public static function encode($value) { Nette\Diagnostics\Debugger::tryError(); if (function_exists('ini_set')) { $old = ini_set('display_errors', 0); // needed to receive 'Invalid UTF-8 sequence' error $json = json_encode($value); ini_set('display_errors', $old); } else { $json = json_encode($value); } if (Nette\Diagnostics\Debugger::catchError($e)) { // needed to receive 'recursion detected' error throw new JsonException($e->getMessage()); } return $json; }
/** * Reads configuration from INI file. * @param string file name * @return array * @throws Nette\InvalidStateException */ public static function load($file) { if (!is_file($file) || !is_readable($file)) { throw new Nette\FileNotFoundException("File '{$file}' is missing or is not readable."); } Nette\Diagnostics\Debugger::tryError(); $ini = parse_ini_file($file, TRUE); if (Nette\Diagnostics\Debugger::catchError($e)) { throw new Nette\InvalidStateException('parse_ini_file(): ' . $e->getMessage(), 0, $e); } $separator = trim(self::$sectionSeparator); $data = array(); foreach ($ini as $secName => $secData) { // is section? if (is_array($secData)) { if (substr($secName, -1) === self::$rawSection) { $secName = substr($secName, 0, -1); } elseif (self::$keySeparator) { // process key separators (key1> key2> key3) $tmp = array(); foreach ($secData as $key => $val) { $cursor =& $tmp; foreach (explode(self::$keySeparator, $key) as $part) { if (!isset($cursor[$part]) || is_array($cursor[$part])) { $cursor =& $cursor[$part]; } else { throw new Nette\InvalidStateException("Invalid key '{$key}' in section [{$secName}] in file '{$file}'."); } } $cursor = $val; } $secData = $tmp; } // process extends sections like [staging < production] (with special support for separator ':') $parts = $separator ? explode($separator, strtr($secName, ':', $separator)) : array($secName); if (count($parts) > 1) { $parent = trim($parts[1]); if (!isset($data[$parent]) || !is_array($data[$parent])) { throw new Nette\InvalidStateException("Missing parent section [{$parent}] in file '{$file}'."); } $secData = array_reverse(Nette\Utils\Arrays::mergeTree(array_reverse($secData, TRUE), array_reverse($data[$parent], TRUE)), TRUE); $secName = trim($parts[0]); if ($secName === '') { throw new Nette\InvalidStateException("Invalid empty section name in file '{$file}'."); } } } if (self::$keySeparator) { $cursor =& $data; foreach (explode(self::$keySeparator, $secName) as $part) { if (!isset($cursor[$part]) || is_array($cursor[$part])) { $cursor =& $cursor[$part]; } else { throw new Nette\InvalidStateException("Invalid section [{$secName}] in file '{$file}'."); } } } else { $cursor =& $data[$secName]; } if (is_array($secData) && is_array($cursor)) { $secData = Nette\Utils\Arrays::mergeTree($secData, $cursor); } $cursor = $secData; } return $data; }
/** @internal */ public static function catchPregError($pattern) { if (Nette\Diagnostics\Debugger::catchError($e)) { // compile error throw new RegexpException($e->getMessage() . " in pattern: {$pattern}"); } elseif (preg_last_error()) { // run-time error static $messages = array(PREG_INTERNAL_ERROR => 'Internal error', PREG_BACKTRACK_LIMIT_ERROR => 'Backtrack limit was exhausted', PREG_RECURSION_LIMIT_ERROR => 'Recursion limit was exhausted', PREG_BAD_UTF8_ERROR => 'Malformed UTF-8 data', 5 => 'Offset didn\'t correspond to the begin of a valid UTF-8 code point'); $code = preg_last_error(); throw new RegexpException((isset($messages[$code]) ? $messages[$code] : 'Unknown error') . " (pattern: {$pattern})", $code); } }
/** * Starts and initializes session data. * * @throws Nette\InvalidStateException * @return void */ public function start() { if (self::$started) { return; } $this->configure($this->options); Nette\Diagnostics\Debugger::tryError(); session_start(); if (Nette\Diagnostics\Debugger::catchError($e) && !session_id()) { @session_write_close(); // this is needed throw new Nette\InvalidStateException('session_start(): ' . $e->getMessage(), 0, $e); } self::$started = true; /* structure: __NF: Counter, BrowserKey, Data, Meta, Time DATA: section->variable = data META: section->variable = Timestamp, Browser, Version */ unset($_SESSION['__NT'], $_SESSION['__NS'], $_SESSION['__NM']); // old unused structures // initialize structures $nf =& $_SESSION['__NF']; if (empty($nf)) { // new session $nf = array('C' => 0); } else { $nf['C']++; } // session regenerate every 30 minutes $nfTime =& $nf['Time']; $time = time(); if ($time - $nfTime > self::REGENERATE_INTERVAL) { $this->regenerated = $this->regenerated || isset($nfTime); $nfTime = $time; } // browser closing detection $browserKey = $this->request->getCookie('nette-browser'); if (!$browserKey) { $browserKey = Nette\Utils\Strings::random(); } $browserClosed = !isset($nf['B']) || $nf['B'] !== $browserKey; $nf['B'] = $browserKey; // resend cookie $this->sendCookie(); // process meta metadata if (isset($nf['META'])) { $now = time(); // expire section variables foreach ($nf['META'] as $section => $metadata) { if (is_array($metadata)) { foreach ($metadata as $variable => $value) { if (!empty($value['B']) && $browserClosed || !empty($value['T']) && $now > $value['T'] || isset($nf['DATA'][$section][$variable]) && is_object($nf['DATA'][$section][$variable]) && (isset($value['V']) ? $value['V'] : null) != Nette\Reflection\ClassType::from($nf['DATA'][$section][$variable])->getAnnotation('serializationVersion')) { if ($variable === '') { // expire whole section unset($nf['META'][$section], $nf['DATA'][$section]); continue 2; } unset($nf['META'][$section][$variable], $nf['DATA'][$section][$variable]); } } } } } if ($this->regenerated) { $this->regenerated = false; $this->regenerateId(); } register_shutdown_function(array($this, 'clean')); }
/** * Starts and initializes session data. * @throws Nette\InvalidStateException * @return void */ public function start() { if (self::$started) { return; } elseif (self::$started === NULL && defined('SID')) { throw new Nette\InvalidStateException('A session had already been started by session.auto-start or session_start().'); } $this->configure($this->options); Nette\Diagnostics\Debugger::tryError(); session_start(); if (Nette\Diagnostics\Debugger::catchError($e)) { @session_write_close(); // this is needed throw new Nette\InvalidStateException('session_start(): ' . $e->getMessage(), 0, $e); } self::$started = TRUE; if ($this->regenerationNeeded) { session_regenerate_id(TRUE); $this->regenerationNeeded = FALSE; } /* structure: __NF: Counter, BrowserKey, Data, Meta DATA: namespace->variable = data META: namespace->variable = Timestamp, Browser, Version */ unset($_SESSION['__NT'], $_SESSION['__NS'], $_SESSION['__NM']); // old unused structures // initialize structures $nf =& $_SESSION['__NF']; if (empty($nf)) { // new session $nf = array('C' => 0); } else { $nf['C']++; } // browser closing detection $browserKey = $this->request->getCookie('nette-browser'); if (!$browserKey) { $browserKey = Nette\Utils\Strings::random(); } $browserClosed = !isset($nf['B']) || $nf['B'] !== $browserKey; $nf['B'] = $browserKey; // resend cookie $this->sendCookie(); // process meta metadata if (isset($nf['META'])) { $now = time(); // expire namespace variables foreach ($nf['META'] as $namespace => $metadata) { if (is_array($metadata)) { foreach ($metadata as $variable => $value) { if (!empty($value['B']) && $browserClosed || !empty($value['T']) && $now > $value['T'] || $variable !== '' && is_object($nf['DATA'][$namespace][$variable]) && (isset($value['V']) ? $value['V'] : NULL) !== Nette\Reflection\ClassType::from($nf['DATA'][$namespace][$variable])->getAnnotation('serializationVersion')) { if ($variable === '') { // expire whole namespace unset($nf['META'][$namespace], $nf['DATA'][$namespace]); continue 2; } unset($nf['META'][$namespace][$variable], $nf['DATA'][$namespace][$variable]); } } } } } register_shutdown_function(array($this, 'clean')); }
/** * Performs a global regular expression match. * * @param string * @param string * @param int can be PREG_OFFSET_CAPTURE (returned in bytes); PREG_SET_ORDER is default * @param int offset in bytes * * @return array */ public static function matchAll($subject, $pattern, $flags = 0, $offset = 0) { if ($offset > strlen($subject)) { return array(); } Debugger::tryError(); $res = preg_match_all($pattern, $subject, $m, $flags & PREG_PATTERN_ORDER ? $flags : $flags | PREG_SET_ORDER, $offset); if (Debugger::catchError($e) || preg_last_error()) { // compile error XOR run-time error throw new RegexpException($e ? $e->getMessage() : null, $e ? null : preg_last_error(), $pattern); } return $m; }
/** * Returns array entries that match the pattern. * * @param array * @param string * @param int * * @return array */ public static function grep(array $arr, $pattern, $flags = 0) { Nette\Diagnostics\Debugger::tryError(); $res = preg_grep($pattern, $arr, $flags); if (Nette\Diagnostics\Debugger::catchError($e) || preg_last_error()) { // compile error XOR run-time error throw new RegexpException($e ? $e->getMessage() : null, $e ? null : preg_last_error(), $pattern); } return $res; }
/** * Perform a regular expression search and replace. * @param string * @param string|array * @param string|callable * @param int * @return string */ public static function replace($subject, $pattern, $replacement = NULL, $limit = -1) { if (is_object($replacement) || is_array($replacement)) { if ($replacement instanceof Nette\Callback) { $replacement = $replacement->getNative(); } if (!is_callable($replacement, FALSE, $textual)) { throw new Nette\InvalidStateException("Callback '{$textual}' is not callable."); } foreach ((array) $pattern as $tmp) { Debugger::tryError(); preg_match($tmp, ''); if (Debugger::catchError($e)) { // compile error throw new RegexpException($e->getMessage(), NULL, $tmp); } } $res = preg_replace_callback($pattern, $replacement, $subject, $limit); if ($res === NULL && preg_last_error()) { // run-time error throw new RegexpException(NULL, preg_last_error(), $pattern); } return $res; } elseif ($replacement === NULL && is_array($pattern)) { $replacement = array_values($pattern); $pattern = array_keys($pattern); } Debugger::tryError(); $res = preg_replace($pattern, $replacement, $subject, $limit); if (Debugger::catchError($e) || preg_last_error()) { // compile error XOR run-time error throw new RegexpException($e ? $e->getMessage() : NULL, $e ? NULL : preg_last_error(), $pattern); } return $res; }
INHERITING_SEPARATOR='<',KEY_SEPARATOR='.',ESCAPED_KEY_SEPARATOR='..',RAW_SECTION='!';function load($file){Nette\Diagnostics\Debugger::tryError();$ini=parse_ini_file($file,TRUE);if(Nette\Diagnostics\Debugger::catchError($e)){throw new Nette\InvalidStateException('parse_ini_file(): '.$e->getMessage(),0,$e);}$data=array();foreach($ini as$secName=>$secData){if(is_array($secData)){if(substr($secName,-1)===self::RAW_SECTION){$secName=substr($secName,0,-1);}else{$tmp=array();foreach($secData as$key=>$val){$cursor=&$tmp;$key=str_replace(self::ESCAPED_KEY_SEPARATOR,"\xFF",$key);foreach(explode(self::KEY_SEPARATOR,$key)as$part){$part=str_replace("\xFF",self::KEY_SEPARATOR,$part);if(!isset($cursor[$part])||is_array($cursor[$part])){$cursor=&$cursor[$part];}else{throw new Nette\InvalidStateException("Invalid key '$key' in section [$secName] in file '$file'.");}}$cursor=$val;}$secData=$tmp;}$parts=explode(self::INHERITING_SEPARATOR,$secName);if(count($parts)>1){$secName=trim($parts[0]);$secData[Helpers::EXTENDS_KEY]=trim($parts[1]);}}$cursor=&$data;foreach(explode(self::KEY_SEPARATOR,$secName)as$part){if(!isset($cursor[$part])||is_array($cursor[$part])){$cursor=&$cursor[$part];}else{throw new Nette\InvalidStateException("Invalid section [$secName] in file '$file'.");}}if(is_array($secData)&&is_array($cursor)){$secData=Helpers::merge($secData,$cursor);}$cursor=$secData;}return$data;}function