Example #1
0
 /**
  * Send mails.
  *
  * @api
  *
  * @param string $email
  * @param string $title email subject
  * @param string $message email content
  * @param array $header (optional)
  *
  * @return bool
  */
 public static function send($email, $title, $message, array $header = [])
 {
     // Mime version header
     if (empty($header['MIME-Version'])) {
         $header['MIME-Version'] = '1.0';
     }
     // content type header
     if (empty($header['Content-type'])) {
         $header['Content-type'] = 'text/plain; charset=UTF-8';
     }
     // Message Id header
     if (empty($header['Message-ID'])) {
         $header['Message-ID'] = '<' . time() . rand(1, 1000) . '@' . $_SERVER['SERVER_NAME'] . '>';
     }
     // concatenate prefix string with the subject
     $config = Config::get('email', self::$defaultConfig);
     $title = $config['subject_prefix'] . $title;
     // From header
     if (empty($header['From']) && isset($config['support'])) {
         $header['From'] = $config['support'];
     }
     // trim line length and remove spaces around line breaks
     $message = wordwrap($message, 76);
     $msgs = explode("\n", $message);
     foreach ($msgs as &$msg) {
         $msg = trim($msg);
     }
     $message = implode("\n", $msgs);
     array_walk($header, function (&$value, $key) {
         $value = $key . ': ' . ($key != 'Content-type' ? self::encodeMailAdress($value) : $value);
     });
     Logger::getInstance()->info('email an: "' . $email . '" mit titel: "' . $title . '" und nachricht "' . $message . '" wurde mit "' . var_export($header, true) . '" als headern gesendet');
     return mail(self::encodeMailAdress($email), mb_encode_mimeheader($title), $message, implode("\n", $header));
     //return true;
 }
Example #2
0
 /**
  * @internal
  *
  * @todo get rid of registerClass
  */
 public function __construct()
 {
     parent::__construct();
     self::$defaultConfig['compile_dir'] = Application::$FILE_ROOT . 'tmp/smarty_compile';
     self::$defaultConfig['cache_dir'] = Application::$FILE_ROOT . 'tmp/smarty_cache';
     $config = Config::get('smarty', self::$defaultConfig);
     $this->setTemplateDir(dirname(dirname(__DIR__)) . '/template/html');
     $this->addTemplateDir(dirname(Application::$WEB_ROOT) . '/template');
     $this->addPluginsDir(__DIR__ . '/smarty_plugins/');
     $this->error_reporting = E_ALL & ~E_NOTICE;
     $this->_file_perms = $config['file_perms'];
     $this->_dir_perms = $config['dir_perms'];
     // cache dir
     FileUtil::makedir($config['cache_dir'], $config['dir_perms']);
     $this->setCacheDir($config['cache_dir']);
     // compile dir
     FileUtil::makedir($config['compile_dir'], $config['dir_perms']);
     $this->setCompileDir($config['compile_dir']);
     // add classes for usage in templates
     $this->registerClass('Session', 'FeM\\sPof\\Session');
     $this->registerClass('Group', 'FeM\\sPof\\model\\Group');
     $this->registerClass('DBConnection', 'FeM\\sPof\\model\\DBConnection');
     $this->registerClass('SessionRegister', 'FeM\\sPof\\model\\SessionRegister');
     $this->registerClass('Config', 'FeM\\sPof\\Config');
     $this->registerClass('Authorization', 'FeM\\sPof\\Authorization');
     $this->registerClass('Auth', 'FeM\\sPof\\Authorization');
 }
Example #3
0
 /**
  * Remove all outdated entries from list.
  *
  * @internal
  */
 private static function cleanup()
 {
     $config = Config::get('whoisonline', self::$defaultConfig);
     // check if we have to update again
     $updated = Cache::fetch(self::PREFIX . 'users_updated');
     if ($updated !== false && $updated < strtotime('-' . $config['min_update'] . ' seconds')) {
         return;
     }
     $users = Cache::fetch(self::PREFIX . 'users');
     if (empty($users)) {
         return;
     }
     // remove old entries
     foreach ($users as $user_id => $time) {
         if ($time < strtotime('-' . $config['max_inactive'] . ' minutes')) {
             unset($users[$user_id]);
         }
     }
     Cache::store(self::PREFIX . 'users', $users);
     Cache::store(self::PREFIX . 'users_updated', time(), $config['min_update']);
 }
Example #4
0
File: Cookie.php Project: fem/spof
 /**
  * Get the path where to store the cookie on the current domain.
  *
  * @internal
  *
  * @return string
  */
 private static function getCookiePath()
 {
     return Config::getDetail('server', 'path');
 }
Example #5
0
 /**
  * Download a file.
  *
  * @internal
  */
 public function download()
 {
     // get and check sid
     if (empty($this->sid) || strlen($this->sid) > 32) {
         self::sendNotFound();
     }
     $db = DBConnection::getInstance();
     $db->beginTransaction();
     // get file details
     $stmt = $db->prepare("\n            SELECT\n                id,\n                content_oid,\n                mimetype,\n                size,\n                name,\n                to_char(modify,'Dy, DD Mon YYYY HH24:MI:SS TZ') AS modify\n            FROM tbl_file\n            WHERE\n                sid=:sid\n                AND visible IS TRUE\n                AND disabled IS FALSE\n            ");
     $stmt->bindParam('sid', $this->sid, \PDO::PARAM_INT);
     $stmt->execute();
     if ($stmt->rowCount() == 0) {
         self::sendNotFound();
     }
     $file = $stmt->fetch(\PDO::FETCH_ASSOC);
     // set path to unprocessed cache file
     $path_cachefile = sprintf(Application::$CACHE_ROOT . 'files/%s/%s.file', $this->sid[0], $this->sid);
     // load file from database if cache file doesn't exist
     $handle = false;
     if (file_exists($path_cachefile) === false) {
         // open db handle if no cached file available
         $handle = $db->pgsqlLOBOpen($file['content_oid'], 'r');
         if (feof($handle)) {
             self::sendNotFound();
         }
         // try to create cache
         if (!FileUtil::makedir(dirname($path_cachefile))) {
             error_log('cache' . $path_cachefile . ' not writeable');
         } else {
             // create cache file
             $fcache = fopen($path_cachefile, 'w');
             stream_copy_to_stream($handle, $fcache);
             fclose($fcache);
             // close db handle
             fclose($handle);
             $handle = false;
         }
     }
     // check wether path_sendfile is set explicitly
     if (!empty($this->path_sendfile)) {
         // update stat data if exists
         if (is_readable($this->path_sendfile)) {
             $stat = stat($this->path_sendfile);
             $file['modify'] = $stat['mtime'];
             $file['size'] = $stat['size'];
         } elseif (isset($this->processing) && method_exists($this, 'processCachefile')) {
             // check for processing
             $file['cachefile'] = $path_cachefile;
             $this->processCachefile($file);
         } else {
             self::sendNotFound();
         }
     } else {
         $this->path_sendfile = $path_cachefile;
     }
     if (!is_readable($this->path_sendfile) && !is_resource($handle)) {
         self::sendNotFound();
     }
     // check wether stats_disable is set
     if ($this->stats_disable === false) {
         // insert statistics
         $stmt = $db->prepare("\n                    INSERT INTO tbl_statistic_file (user_id, ip, file_id)\n                    VALUES (:user_id, :ip, :file_id)\n                ");
         if (is_null(Session::getUserId())) {
             $stmt->bindValue('user_id', null, \PDO::PARAM_NULL);
         } else {
             $stmt->bindValue('user_id', Session::getUserId(), \PDO::PARAM_INT);
         }
         $stmt->bindValue('ip', Request::getIp(), \PDO::PARAM_STR);
         $stmt->bindValue('file_id', $file['id'], \PDO::PARAM_INT);
         $stmt->execute();
     }
     $db->commit();
     // there is nothing to write, tell the session it is no longer needed (and thus no longer blocking output
     // flushing)
     session_write_close();
     // check if http_range is sent by browser
     if (isset($_SERVER['HTTP_RANGE'])) {
         $unit = explode('=', $_SERVER['HTTP_RANGE'])[0];
         if ($unit == 'bytes') {
             $range_list = explode('=', $_SERVER['HTTP_RANGE'], 2)[1];
             // multiple ranges could be specified at the same time, but for simplicity only serve the first range
             // http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
             $ranges = explode(',', $range_list);
             foreach ($ranges as $range) {
                 $seek_start = explode('-', $range)[0];
                 $seek_end = explode('-', $range)[1];
                 // set valid and in range for seek end
                 if (empty($seek_end)) {
                     $seek_end = $file['size'] - 1;
                 } else {
                     $seek_end = min(abs($seek_end), $file['size'] - 1);
                 }
                 // set valid and in range for seek start
                 if (empty($seek_start) || $seek_end < abs($seek_start)) {
                     $seek_start = 0;
                 } else {
                     $seek_start = max(abs($seek_start), 0);
                 }
                 if (!is_resource($handle)) {
                     $handle = fopen($path_cachefile, 'rb');
                 }
                 // seek to start of missing part
                 if (($seek_start > 0 || $seek_end < $file['size'] - 1) && fseek($handle, $seek_start) !== -1) {
                     $length = $seek_end - $seek_start + 1;
                     header('HTTP/1.1 206 Partial Content');
                     header('Accept-Ranges: bytes');
                     header('Content-Range: bytes ' . $seek_start . '-' . $seek_end . '/' . $file['size']);
                     header('Content-Type: ' . $file['mimetype']);
                     header('Content-Disposition: attachment; filename="' . $file['name'] . '"');
                     header('Content-Length: ' . $length);
                     // start buffered download of 8 KB chunks while the connection is alive
                     $transfered = 0;
                     while (!feof($handle) && connection_status() == CONNECTION_NORMAL && $transfered < $length) {
                         // reset time limit for big files
                         set_time_limit(0);
                         // @codingStandardsIgnoreStart
                         echo fread($handle, 8192);
                         // @codingStandardsIgnoreEnd
                         $transfered += 8192;
                         flush();
                         ob_flush();
                     }
                     // while
                     fclose($handle);
                     exit;
                 }
                 // if fseek
             }
             // foreach ranges
         }
         // if unit bytes
     }
     // if http_range
     // prepare headers
     header('Last-Modified: ' . $file['modify']);
     header('Accept-Ranges: bytes');
     header('Content-Type: ' . $file['mimetype']);
     header('Content-Length: ' . $file['size']);
     header('Content-Transfer-Encoding: binary');
     session_cache_limiter(false);
     if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= strtotime($file['modify'])) {
         header('HTTP/1.0 304 Not Modified');
         exit;
     }
     if (is_resource($handle)) {
         // write to output buffer in small chunks to bypass memory limit of large files (which fpassthru would
         // exceed)
         while (!feof($handle) && connection_status() == CONNECTION_NORMAL) {
             // reset time limit for big files
             set_time_limit(0);
             // @codingStandardsIgnoreStart
             echo fread($handle, 8192);
             // @codingStandardsIgnoreEnd
             flush();
             ob_flush();
         }
         // while
         fclose($handle);
     } elseif (Config::get('use_sendfile') && in_array('mod_xsendfile', apache_get_modules())) {
         header('X-Sendfile: ' . $this->path_sendfile);
     } else {
         readfile($this->path_sendfile);
         exit;
     }
 }
Example #6
0
 /**
  * Create a new database connection.
  *
  * @internal
  */
 public function __construct()
 {
     try {
         $config = array_merge(self::$defaultConfig, Config::get('database'));
         parent::__construct('pgsql:host=' . $config['host'] . ';' . 'dbname=' . $config['name'] . ';' . 'port=' . $config['port'], $config['user'], $config['pass']);
         #            Config::unsetForDatabase();
         $this->setAttribute(\PDO::ATTR_STATEMENT_CLASS, [__NAMESPACE__ . '\\DBStatement', [$this]]);
         $this->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
         $this->exec("SET CLIENT_ENCODING TO 'UTF8'");
         $this->exec("SET search_path TO " . $config['namespace'] . ";");
     } catch (\PDOException $e) {
         Logger::getInstance()->exception($e);
     }
 }
Example #7
0
File: Logger.php Project: fem/spof
 /**
  * log message to the session.
  *
  * @param string $message
  * @param string $severity
  */
 private function sessionLog($message, $severity)
 {
     static $levels;
     if (!isset($levels)) {
         $levels = Config::get('log_level', self::$defaultConfig);
     }
     if (in_array($severity, $levels)) {
         Session::addErrorMsg($message);
     }
 }
Example #8
0
 /**
  * This function generates a new .js file from the existing files (if anything new happen to them or does not
  * exist). The name of the new file will be returned.
  *
  * @api
  *
  * @param array $files
  *
  * @return string|false false on error or nothing
  */
 public static function combine(array $files)
 {
     if (empty($files)) {
         return false;
     }
     $target = self::getTargetPath();
     $source = self::getSourcePath();
     // identify file combinations by hash
     $jsHash = md5(serialize($files));
     $targetfile = $target . $jsHash . '.js';
     // check if any source file was modified
     $needUpdate = false;
     if (file_exists($targetfile)) {
         $hashtime = filemtime($targetfile);
         foreach ($files as $file) {
             if (substr($file['name'], 0, 1) === '/') {
                 $filename = $file['name'];
             } elseif ($file['relative']) {
                 // relative to public/js
                 $filename = $target . $file['name'] . '.js';
             } else {
                 // use javascript folder
                 $filename = $source . $file['name'] . '.js.tpl';
             }
             if ($hashtime < filemtime($filename)) {
                 $needUpdate = true;
                 break;
             }
         }
     } else {
         // file does not exist, so we need an update anyway
         $needUpdate = true;
     }
     // we can abort if no update is required
     if ($needUpdate === false) {
         return $jsHash;
     }
     // make sure, that the target directory exists
     if (!is_dir($target)) {
         FileUtil::makedir($target);
     }
     // combine file contents
     $content = '';
     foreach ($files as $file) {
         try {
             if (substr($file['name'], 0, 1) === '/') {
                 if (strpos($file['name'], '.tpl') > 0) {
                     $nextcontent = JavascriptTemplate::getInstance()->fetch($file['name']);
                 } else {
                     $nextcontent = file_get_contents($file['name']);
                 }
             } elseif ($file['relative']) {
                 $nextcontent = file_get_contents($target . $file['name'] . '.js');
             } else {
                 $nextcontent = JavascriptTemplate::getInstance()->fetch($source . $file['name'] . '.js.tpl');
             }
             // do not double minify
             if (strpos($file['name'], '.min') > 0 || strpos($file['name'], '.pack') > 0 || !method_exists('\\JShrink\\Minifier', 'minify')) {
                 $content .= $nextcontent . "\n";
             } else {
                 $content .= \JShrink\Minifier::minify($nextcontent) . "\n";
             }
         } catch (\ErrorException $exception) {
             Logger::getInstance()->exception($exception);
         }
     }
     // foreach file
     // write minified version
     $success = file_put_contents($targetfile, $content);
     // adjust file permissions for webserver
     if ($success) {
         chmod($targetfile, Config::getDetail('smarty', 'file_perms', self::$defaultConfig));
     }
     // foreach scssFiles
     return $jsHash;
 }
Example #9
0
File: Session.php Project: fem/spof
 /**
  * Get current config setting.
  *
  * @internal
  *
  * @param $name
  * @return array
  */
 private static function getConfig($name)
 {
     static $config;
     if (!isset($config)) {
         $config = Config::get('session', self::$defaultConfig);
     }
     return $config[$name];
 }
Example #10
0
 /**
  * This function generates a new .css file from the existing files (if anything new happen to them or does not
  * exist). The name of the new file will be returned.
  *
  * @api
  *
  * @param array $files
  *
  * @return string|false false on error or nothing
  */
 public static function combine(array $files)
 {
     if (empty($files)) {
         return false;
     }
     $target = self::getTargetPath();
     $source = self::getSourcePath();
     // identify file combinations by hash
     $cssHash = md5(serialize($files));
     $targetfile = $target . $cssHash . '.css';
     // check if any source file was modified
     $needUpdate = false;
     if (file_exists($targetfile)) {
         $hashtime = filemtime($targetfile);
         foreach ($files as $file) {
             if ($hashtime < filemtime($file['name'])) {
                 $needUpdate = true;
                 break;
             }
         }
     } else {
         // file does not exist, so we need an update anyway
         $needUpdate = true;
     }
     // we can abort if no update is required
     if ($needUpdate === false) {
         return $cssHash;
     }
     // combine file contents
     $handle = fopen($targetfile, 'w+');
     foreach ($files as $file) {
         $content = file_get_contents($file['name']);
         if ($file['fixpaths']) {
             preg_match_all('/url\\(([^)]+)\\)/', $content, $matches, PREG_SET_ORDER);
             $replaces = [];
             $copy = [];
             foreach ($matches as $match) {
                 if (strpos($match[1], 'data') === 0) {
                     continue;
                 }
                 $filename = 'gen__' . md5($file['name'] . '-' . $match[1]) . preg_replace('/^[^.]+\\.(.+)$/', '.$1', $match[1]);
                 $replaces[$match[0]] = 'url(../img/' . $filename . ')';
                 $copy[dirname($file['name']) . '/' . $match[1]] = Application::$WEB_ROOT . 'img/' . $filename;
             }
             // replace usage in stylesheet and copy file to be accessible via web
             $content = str_replace(array_keys($replaces), $replaces, $content);
             foreach ($copy as $source => $target) {
                 try {
                     copy($source, $target);
                 } catch (\ErrorException $e) {
                     Logger::getInstance()->exception($e);
                 }
             }
         }
         fwrite($handle, self::minify($content));
     }
     // foreach file
     fclose($handle);
     // adjust file permissions for webserver
     chmod($targetfile, Config::getDetail('stylesheet', 'file_perms', self::$defaultConfig));
     return $cssHash;
 }
Example #11
0
File: Router.php Project: fem/spof
 /**
  * Redirect to route.
  *
  * @internal
  *
  * @param string $route
  * @param array $arguments
  */
 public static function redirect($route, array $arguments)
 {
     $server = Config::get('server');
     self::urlRedirect('//' . $_SERVER['SERVER_NAME'] . $server['path'] . self::reverse($route, $arguments));
 }