/** * Returns the MIME content type of an uploaded file. * @return string */ public function getContentType() { if ($this->isOk() && $this->type === NULL) { $this->type = Nette\Tools::detectMimeType($this->tmpName); } return $this->type; }
/** * 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); Nette\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 (Nette\Tools::catchError($msg)) { throw new \InvalidStateException($msg); } elseif (!$res) { throw new \InvalidStateException('Unable to send email.'); } }
/** * Enables log out after inactivity. * @param string|int|DateTime number of seconds or timestamp * @param bool log out when the browser is closed? * @param bool clear the identity from persistent storage? * @return User provides a fluent interface */ public function setExpiration($time, $whenBrowserIsClosed = TRUE, $clearIdentity = FALSE) { $session = $this->getSessionNamespace(TRUE); if ($time) { $time = Nette\Tools::createDateTime($time)->format('U'); $session->expireTime = $time; $session->expireDelta = $time - time(); } else { unset($session->expireTime, $session->expireDelta); } $session->expireIdentity = (bool) $clearIdentity; $session->expireBrowser = (bool) $whenBrowserIsClosed; $session->browserCheck = TRUE; $session->setExpiration(0, 'browserCheck'); return $this; }
/** * Sets the amount of time allowed between requests before the session will be terminated. * @param string|int|DateTime time, value 0 means "until the browser is closed" * @return Session provides a fluent interface */ public function setExpiration($time) { if (empty($time)) { return $this->setOptions(array('gc_maxlifetime' => self::DEFAULT_FILE_LIFETIME, 'cookie_lifetime' => 0)); } else { $time = Nette\Tools::createDateTime($time)->format('U'); return $this->setOptions(array('gc_maxlifetime' => $time, 'cookie_lifetime' => $time)); } }
/** * Restricts the search by modified time. * @param string "[operator] [date]" example: >1978-01-23 * @param mixed * @return Finder provides a fluent interface */ public function date($operator, $date = NULL) { if (func_num_args() === 1) { // in $operator is predicate if (!preg_match('#^(?:([=<>!]=?|<>)\\s*)?(.+)$#i', $operator, $matches)) { throw new \InvalidArgumentException('Invalid date predicate format.'); } list(, $operator, $date) = $matches; $operator = $operator ? $operator : '='; } $date = Tools::createDateTime($date)->format('U'); return $this->filter(function ($file) use($operator, $date) { return Tools::compare($file->getMTime(), $operator, $date); }); }
/** * Writes item into the cache. * Dependencies are: * - Cache::PRIORITY => (int) priority * - Cache::EXPIRE => (timestamp) expiration * - Cache::SLIDING => (bool) use sliding expiration? * - Cache::TAGS => (array) tags * - Cache::FILES => (array|string) file names * - Cache::ITEMS => (array|string) cache items * - Cache::CONSTS => (array|string) cache items * * @param string key * @param mixed value * @param array dependencies * @return mixed value itself * @throws \InvalidArgumentException */ public function save($key, $data, array $dp = NULL) { if (!is_string($key) && !is_int($key)) { throw new \InvalidArgumentException("Cache key name must be string or integer, " . gettype($key) . " given."); } $this->key = (string) $key; $key = $this->namespace . self::NAMESPACE_SEPARATOR . $key; // convert expire into relative amount of seconds if (!empty($dp[Cache::EXPIRE])) { $dp[Cache::EXPIRE] = Nette\Tools::createDateTime($dp[Cache::EXPIRE])->format('U') - time(); } // convert FILES into CALLBACKS if (isset($dp[self::FILES])) { //clearstatcache(); foreach ((array) $dp[self::FILES] as $item) { $dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkFile'), $item, @filemtime($item)); // @ - stat may fail } unset($dp[self::FILES]); } // add namespaces to items if (isset($dp[self::ITEMS])) { $dp[self::ITEMS] = (array) $dp[self::ITEMS]; foreach ($dp[self::ITEMS] as $k => $item) { $dp[self::ITEMS][$k] = $this->namespace . self::NAMESPACE_SEPARATOR . $item; } } // convert CONSTS into CALLBACKS if (isset($dp[self::CONSTS])) { foreach ((array) $dp[self::CONSTS] as $item) { $dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkConst'), $item, constant($item)); } unset($dp[self::CONSTS]); } if ($data instanceof Nette\Callback || $data instanceof \Closure) { Nette\Environment::enterCriticalSection('Nette\\Caching/' . $key); $data = $data->__invoke(); Nette\Environment::leaveCriticalSection('Nette\\Caching/' . $key); } if (is_object($data)) { $dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkSerializationVersion'), get_class($data), Nette\Reflection\ClassReflection::from($data)->getAnnotation('serializationVersion')); } $this->data = $data; if ($data === NULL) { $this->storage->remove($key); } else { $this->storage->write($key, $data, (array) $dp); } return $data; }
/** * Sets the CURLOPT options for the current request * @param string $url */ protected function setRequestOptions($requestResource, $method, $url, $post = array()) { $this->setRequestMethod($method); $this->setOption('url', $url); if ($post && is_array($post)) { $post = http_build_query($post, '', '&'); $this->setOption('postfields', $post); } // Prepend headers in response $this->setOption('header', TRUE); // this makes me literally cry sometimes // we shouldn't trust to all certificates but we have to! if ($this->getOption('ssl_verifypeer') === NULL) { $this->setOption('ssl_verifypeer', FALSE); } // fix:Sairon http://forum.nette.org/cs/profile.php?id=1844 thx if ($this->followRedirects === NULL && !Tools::iniFlag('safe_mode') && ini_get('open_basedir') == "") { $this->followRedirects = TRUE; } // Set all cURL options foreach ($this->Options as $option => $value) { if ($option == "FOLLOWLOCATION" && (Tools::iniFlag('safe_mode') || ini_get('open_basedir') != "")) { continue; } curl_setopt($requestResource, constant('CURLOPT_' . $option), $value); } }
/** * Sets the expiration of the namespace or specific variables. * @param string|int|DateTime time, value 0 means "until the browser is closed" * @param mixed optional list of variables / single variable to expire * @return SessionNamespace provides a fluent interface */ public function setExpiration($time, $variables = NULL) { if (empty($time)) { $time = NULL; $whenBrowserIsClosed = TRUE; } else { $time = Nette\Tools::createDateTime($time)->format('U'); $whenBrowserIsClosed = FALSE; } if ($variables === NULL) { // to entire namespace $this->meta['']['T'] = $time; $this->meta['']['B'] = $whenBrowserIsClosed; } elseif (is_array($variables)) { // to variables foreach ($variables as $variable) { $this->meta[$variable]['T'] = $time; $this->meta[$variable]['B'] = $whenBrowserIsClosed; } } else { // to variable $this->meta[$variables]['T'] = $time; $this->meta[$variables]['B'] = $whenBrowserIsClosed; } return $this; }
/** * Date/time formatting. * @param string|int|DateTime * @param string * @return string */ public static function date($time, $format = "%x") { if ($time == NULL) { // intentionally == return NULL; } $time = Nette\Tools::createDateTime($time); return strpos($format, '%') === FALSE ? $time->format($format) : strftime($format, $time->format('U')); // formats according to locales }
/** * Sends a cookie. * @param string name of the cookie * @param string value * @param string|int|DateTime expiration time, value 0 means "until the browser is closed" * @param string * @param string * @param bool * @param bool * @return HttpResponse provides a fluent interface * @throws \InvalidStateException if HTTP headers have been sent */ public function setCookie($name, $value, $time, $path = NULL, $domain = NULL, $secure = NULL, $httpOnly = NULL) { if (headers_sent($file, $line)) { throw new \InvalidStateException("Cannot set cookie after HTTP headers have been sent" . ($file ? " (output started at {$file}:{$line})." : ".")); } setcookie($name, $value, $time ? Nette\Tools::createDateTime($time)->format('U') : 0, $path === NULL ? $this->cookiePath : (string) $path, $domain === NULL ? $this->cookieDomain : (string) $domain, $secure === NULL ? $this->cookieSecure : (bool) $secure, $httpOnly === NULL ? $this->cookieHttpOnly : (bool) $httpOnly); return $this; }
/** * The data: URI generator. * @param string * @param string * @return string */ public static function dataStream($data, $type = NULL) { if ($type === NULL) { $type = Nette\Tools::detectMimeTypeFromString($data, NULL); } return 'data:' . ($type ? "$type;" : '') . 'base64,' . base64_encode($data); }
/** * Writes item into the cache. * Dependencies are: * - Cache::PRIORITY => (int) priority * - Cache::EXPIRATION => (timestamp) expiration * - Cache::SLIDING => (bool) use sliding expiration? * - Cache::TAGS => (array) tags * - Cache::FILES => (array|string) file names * - Cache::ITEMS => (array|string) cache items * - Cache::CONSTS => (array|string) cache items * * @param mixed key * @param mixed value * @param array dependencies * @return mixed value itself * @throws \InvalidArgumentException */ public function save($key, $data, array $dp = NULL) { $this->key = is_scalar($key) ? (string) $key : serialize($key); $key = $this->namespace . md5($this->key); // convert expire into relative amount of seconds if (isset($dp[Cache::EXPIRATION])) { $dp[Cache::EXPIRATION] = Nette\Tools::createDateTime($dp[Cache::EXPIRATION])->format('U') - time(); } // convert FILES into CALLBACKS if (isset($dp[self::FILES])) { //clearstatcache(); foreach ((array) $dp[self::FILES] as $item) { $dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkFile'), $item, @filemtime($item)); // @ - stat may fail } unset($dp[self::FILES]); } // add namespaces to items if (isset($dp[self::ITEMS])) { $dp[self::ITEMS] = (array) $dp[self::ITEMS]; foreach ($dp[self::ITEMS] as $k => $item) { $dp[self::ITEMS][$k] = $this->namespace . md5(is_scalar($item) ? $item : serialize($item)); } } // convert CONSTS into CALLBACKS if (isset($dp[self::CONSTS])) { foreach ((array) $dp[self::CONSTS] as $item) { $dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkConst'), $item, constant($item)); } unset($dp[self::CONSTS]); } if ($data instanceof Nette\Callback || $data instanceof \Closure) { Nette\Tools::enterCriticalSection(); $data = $data->__invoke(); Nette\Tools::leaveCriticalSection(); } if (is_object($data)) { $dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkSerializationVersion'), get_class($data), Nette\Reflection\ClassReflection::from($data)->getAnnotation('serializationVersion')); } $this->data = $data; if ($data === NULL) { $this->storage->remove($key); } else { $this->storage->write($key, $data, (array) $dp); } return $data; }
/** * 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."); } Nette\Tools::tryError(); $ini = parse_ini_file($file, TRUE); if (Nette\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 = Nette\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 = Nette\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]; } }
/** * Get format from the image stream in the string. * @param string * @return mixed detected image format */ public static function getFormatFromString($s) { $types = array('image/jpeg' => self::JPEG, 'image/gif' => self::GIF, 'image/png' => self::PNG); $type = Tools::detectMimeTypeFromString($s); return isset($types[$type]) ? $types[$type] : NULL; }
/** * Creates file MIME part. * @return MailMimePart */ private function createAttachment($file, $content, $contentType, $disposition) { $part = new MailMimePart; if ($content === NULL) { $content = file_get_contents($file); if ($content === FALSE) { throw new \FileNotFoundException("Unable to read file '$file'."); } } else { $content = (string) $content; } $part->setBody($content); $part->setContentType($contentType ? $contentType : Nette\Tools::detectMimeTypeFromString($content)); $part->setEncoding(preg_match('#(multipart|message)/#A', $contentType) ? self::ENCODING_8BIT : self::ENCODING_BASE64); $part->setHeader('Content-Disposition', $disposition . '; filename="' . String::fixEncoding(basename($file)) . '"'); return $part; }