/** * Magic method (do not call directly). * @param string method name * @param array arguments * @return mixed * @throws \MemberAccessException * @throws FtpException */ public function __call($name, $args) { $name = strtolower($name); $silent = strncmp($name, 'try', 3) === 0; $func = $silent ? substr($name, 3) : $name; static $aliases = array('sslconnect' => 'ssl_connect', 'getoption' => 'get_option', 'setoption' => 'set_option', 'nbcontinue' => 'nb_continue', 'nbfget' => 'nb_fget', 'nbfput' => 'nb_fput', 'nbget' => 'nb_get', 'nbput' => 'nb_put'); $func = 'ftp_' . (isset($aliases[$func]) ? $aliases[$func] : $func); if (!function_exists($func)) { return parent::__call($name, $args); } /*Nette\*/ Tools::tryError(); if ($func === 'ftp_connect' || $func === 'ftp_ssl_connect') { $this->state = array($name => $args); $this->resource = call_user_func_array($func, $args); $res = NULL; } elseif (!is_resource($this->resource)) { /*Nette\*/ Tools::catchError($msg); throw new FtpException("Not connected to FTP server. Call connect() or ssl_connect() first."); } else { if ($func === 'ftp_login' || $func === 'ftp_pasv') { $this->state[$name] = $args; } array_unshift($args, $this->resource); $res = call_user_func_array($func, $args); if ($func === 'ftp_chdir' || $func === 'ftp_cdup') { $this->state['chdir'] = array(ftp_pwd($this->resource)); } } if (Tools::catchError($msg) && !$silent) { throw new FtpException($msg); } return $res; }
/** * Sends e-mail. * @param Mail * @return void */ public function send(Mail $mail) { $tmp = clone $mail; $tmp->setHeader('Subject', NULL); $tmp->setHeader('To', NULL); $parts = explode(Mail::EOL . Mail::EOL, $tmp->generateMessage(), 2); Tools::tryError(); $res = mail(str_replace(Mail::EOL, PHP_EOL, $mail->getEncodedHeader('To')), str_replace(Mail::EOL, PHP_EOL, $mail->getEncodedHeader('Subject')), str_replace(Mail::EOL, PHP_EOL, $parts[1]), str_replace(Mail::EOL, PHP_EOL, $parts[0])); if (Tools::catchError($msg)) { throw new InvalidStateException($msg); } elseif (!$res) { throw new InvalidStateException('Unable to send email.'); } }
/** * Sends e-mail. * @param Mail * @return void */ public function send(Mail $mail) { $tmp = clone $mail; $tmp->setHeader('Subject', NULL); $tmp->setHeader('To', NULL); $parts = explode(Mail::EOL . Mail::EOL, $tmp->generateMessage(), 2); $linux = strncasecmp(PHP_OS, 'win', 3); /*Nette\*/ Tools::tryError(); $res = mail($mail->getEncodedHeader('To'), $mail->getEncodedHeader('Subject'), $linux ? str_replace(Mail::EOL, "\n", $parts[1]) : $parts[1], $linux ? str_replace(Mail::EOL, "\n", $parts[0]) : $parts[0]); if (Tools::catchError($msg)) { throw new InvalidStateException($msg); } elseif (!$res) { throw new InvalidStateException('Unable to send email.'); } }
/** * Starts and initializes session data. * @throws InvalidStateException * @return void */ public function start() { if (self::$started) { return; } elseif (self::$started === NULL && defined('SID')) { throw new InvalidStateException('A session had already been started by session.auto-start or session_start().'); } // start session try { $this->configure($this->options); } catch (NotSupportedException $e) { // ignore? } Tools::tryError(); session_start(); if (Tools::catchError($msg)) { @session_write_close(); // this is needed throw new InvalidStateException($msg); } 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->getHttpRequest()->getCookie('nette-browser'); if (!$browserKey) { $browserKey = (string) lcg_value(); } $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) !== ClassReflection::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')); }
/** * Reads configuration from INI file. * @param string file name * @param string section to load * @return array * @throws InvalidStateException */ public static function load($file, $section = NULL) { if (!is_file($file) || !is_readable($file)) { throw new FileNotFoundException("File '{$file}' is missing or is not readable."); } Tools::tryError(); $ini = parse_ini_file($file, TRUE); if (Tools::catchError($msg)) { throw new Exception($msg); } $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 InvalidStateException("Invalid key '{$key}' in section [{$secName}] in '{$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]); $cursor =& $data; foreach (self::$keySeparator ? explode(self::$keySeparator, $parent) : array($parent) as $part) { if (isset($cursor[$part]) && is_array($cursor[$part])) { $cursor =& $cursor[$part]; } else { throw new InvalidStateException("Missing parent section [{$parent}] in '{$file}'."); } } $secData = ArrayTools::mergeTree($secData, $cursor); } $secName = trim($parts[0]); if ($secName === '') { throw new InvalidStateException("Invalid empty section name in '{$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 InvalidStateException("Invalid section [{$secName}] in '{$file}'."); } } } else { $cursor =& $data[$secName]; } if (is_array($secData) && is_array($cursor)) { $secData = ArrayTools::mergeTree($secData, $cursor); } $cursor = $secData; } if ($section === NULL) { return $data; } elseif (!isset($data[$section]) || !is_array($data[$section])) { throw new InvalidStateException("There is not section [{$section}] in '{$file}'."); } else { return $data[$section]; } }
/** * Starts and initializes session data. * @throws \InvalidStateException * @return void */ public function start() { if (self::$started) { throw new InvalidStateException('Session has already been started.'); } elseif (self::$started === NULL && defined('SID')) { throw new InvalidStateException('A session had already been started by session.auto-start or session_start().'); } // additional protection against Session Hijacking & Fixation if ($this->verificationKeyGenerator) { /**/ fixCallback($this->verificationKeyGenerator); /**/ if (!is_callable($this->verificationKeyGenerator)) { $able = is_callable($this->verificationKeyGenerator, TRUE, $textual); throw new InvalidStateException("Verification key generator '{$textual}' is not " . ($able ? 'callable.' : 'valid PHP callback.')); } } // start session $this->configure(self::$defaultConfig, FALSE); /*Nette\*/ Tools::tryError(); session_start(); if (Tools::catchError($msg)) { @session_write_close(); // this is needed throw new InvalidStateException($msg); } self::$started = TRUE; if ($this->regenerationNeeded) { session_regenerate_id(TRUE); $this->regenerationNeeded = FALSE; } /* structure: nette: __NT data: __NS->namespace->variable = data meta: __NM->namespace->EXP->variable = timestamp */ // initialize structures $verKey = $this->verificationKeyGenerator ? (string) call_user_func($this->verificationKeyGenerator) : ''; if (!isset($_SESSION['__NT']['V'])) { // new session $_SESSION['__NT'] = array(); $_SESSION['__NT']['C'] = 0; $_SESSION['__NT']['V'] = $verKey; } else { $saved =& $_SESSION['__NT']['V']; if ($saved === $verKey) { // verified $_SESSION['__NT']['C']++; } else { // session attack? session_regenerate_id(TRUE); $_SESSION = array(); $_SESSION['__NT']['C'] = 0; $_SESSION['__NT']['V'] = $verKey; } } // browser closing detection $browserKey = $this->getHttpRequest()->getCookie('nette-browser'); if (!$browserKey) { $browserKey = (string) lcg_value(); } $browserClosed = !isset($_SESSION['__NT']['B']) || $_SESSION['__NT']['B'] !== $browserKey; $_SESSION['__NT']['B'] = $browserKey; // resend cookie $this->sendCookie(); // process meta metadata if (isset($_SESSION['__NM'])) { $now = time(); // expire namespace variables foreach ($_SESSION['__NM'] as $namespace => $metadata) { if (isset($metadata['EXP'])) { foreach ($metadata['EXP'] as $variable => $value) { if (!is_array($value)) { $value = array($value, !$value); } // back compatibility list($time, $whenBrowserIsClosed) = $value; if ($whenBrowserIsClosed && $browserClosed || $time && $now > $time) { if ($variable === '') { // expire whole namespace unset($_SESSION['__NM'][$namespace], $_SESSION['__NS'][$namespace]); continue 2; } unset($_SESSION['__NS'][$namespace][$variable], $_SESSION['__NM'][$namespace]['EXP'][$variable]); } } } } } register_shutdown_function(array($this, 'clean')); }
function start() { if (self::$started) { throw new InvalidStateException('Session has already been started.'); } elseif (self::$started === NULL && defined('SID')) { throw new InvalidStateException('A session had already been started by session.auto-start or session_start().'); } $verKey = NULL; if ($this->verificationKeyGenerator) { $verKey = (string) callback($this->verificationKeyGenerator)->invoke(); } try { $this->configure($this->options); } catch (NotSupportedException $e) { } Tools::tryError(); session_start(); if (Tools::catchError($msg)) { @session_write_close(); throw new InvalidStateException($msg); } self::$started = TRUE; if ($this->regenerationNeeded) { session_regenerate_id(TRUE); $this->regenerationNeeded = FALSE; } if (!isset($_SESSION['__NF']['V'])) { $_SESSION['__NF'] = array(); $_SESSION['__NF']['C'] = 0; $_SESSION['__NF']['V'] = $verKey; } else { $saved =& $_SESSION['__NF']['V']; if (!$this->verificationKeyGenerator || $verKey === $saved) { $_SESSION['__NF']['C']++; } else { session_regenerate_id(TRUE); $_SESSION = array(); $_SESSION['__NF']['C'] = 0; $_SESSION['__NF']['V'] = $verKey; } } $nf =& $_SESSION['__NF']; unset($_SESSION['__NT'], $_SESSION['__NS'], $_SESSION['__NM']); $browserKey = $this->getHttpRequest()->getCookie('nette-browser'); if (!$browserKey) { $browserKey = (string) lcg_value(); } $browserClosed = !isset($nf['B']) || $nf['B'] !== $browserKey; $nf['B'] = $browserKey; $this->sendCookie(); if (isset($nf['META'])) { $now = time(); 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) !== ClassReflection::from($nf['DATA'][$namespace][$variable])->getAnnotation('serializationVersion')) { if ($variable === '') { unset($nf['META'][$namespace], $nf['DATA'][$namespace]); continue 2; } unset($nf['META'][$namespace][$variable], $nf['DATA'][$namespace][$variable]); } } } } } register_shutdown_function(array($this, 'clean')); }
/** * Starts and initializes session data. * @throws InvalidStateException * @return void */ public function start() { if (self::$started) { throw new InvalidStateException('Session has already been started.'); } elseif (self::$started === NULL && defined('SID')) { throw new InvalidStateException('A session had already been started by session.auto-start or session_start().'); } // additional protection against Session Hijacking & Fixation if ($this->verificationKeyGenerator) { fixCallback($this->verificationKeyGenerator); if (!is_callable($this->verificationKeyGenerator)) { $able = is_callable($this->verificationKeyGenerator, TRUE, $textual); throw new InvalidStateException("Verification key generator '{$textual}' is not " . ($able ? 'callable.' : 'valid PHP callback.')); } } // start session try { $this->configure($this->options); } catch (NotSupportedException $e) { // ignore? } Tools::tryError(); session_start(); if (Tools::catchError($msg)) { @session_write_close(); // this is needed throw new InvalidStateException($msg); } self::$started = TRUE; if ($this->regenerationNeeded) { session_regenerate_id(TRUE); $this->regenerationNeeded = FALSE; } /* structure: __NF: VerificationKey, Counter, BrowserKey, Data, Meta DATA: namespace->variable = data META: namespace->variable = Timestamp, Browser, Version */ // initialize structures $verKey = $this->verificationKeyGenerator ? (string) call_user_func($this->verificationKeyGenerator) : NULL; if (!isset($_SESSION['__NF']['V'])) { // new session $_SESSION['__NF'] = array(); $_SESSION['__NF']['C'] = 0; $_SESSION['__NF']['V'] = $verKey; } else { $saved =& $_SESSION['__NF']['V']; if (!$this->verificationKeyGenerator || $verKey === $saved) { // ignored or verified $_SESSION['__NF']['C']++; } else { // session attack? session_regenerate_id(TRUE); $_SESSION = array(); $_SESSION['__NF']['C'] = 0; $_SESSION['__NF']['V'] = $verKey; } } $nf =& $_SESSION['__NF']; unset($_SESSION['__NT'], $_SESSION['__NS'], $_SESSION['__NM']); // old structures // browser closing detection $browserKey = $this->getHttpRequest()->getCookie('nette-browser'); if (!$browserKey) { $browserKey = (string) lcg_value(); } $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) !== ClassReflection::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')); }