/** * 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; }
/** * Delete the login cookie * * @api */ public static function deleteLoginCookie() { $config = self::getConfig(); if (!empty($config['login']) && isset($_COOKIE[$config['login']])) { Logger::getInstance()->info("delete cookie " . $config['login']); setcookie($config['login'], "", time() - 3600, self::getCookiePath()); unset($_COOKIE[$config['login']]); } if (!empty($config['password']) && isset($_COOKIE[$config['password']])) { Logger::getInstance()->info("delete cookie " . $config['password']); setcookie($config['password'], "", time() - 3600, self::getCookiePath()); unset($_COOKIE[$config['password']]); } }
/** * fetches a rendered Smarty template. Overrides Smarty_Internal_Compilerbase::fetch(). * * @api * * @throws \ErrorException if a error occurred in the code triggered by the template * @throws \FeM\sPof\exception\SmartyTemplateException if the error occurred in a template * * @param string $template (optional) the resource handle of the template file or template object * @param mixed $cache_id (optional) cache id to be used with this template * @param mixed $compile_id (optional) compile id to be used with this template * @param object $parent (optional) next higher level of Smarty variables * @param bool $display (optional) true: display, false: fetch * @param bool $merge_tpl_vars (optional) if true parent template variables merged in to local scope * @param bool $no_output_filter (optional) if true do not run output filter * * @return string rendered template output */ public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false) { try { if ($display) { Logger::getInstance()->addSmarty(); } return parent::fetch($template, $cache_id, $compile_id, $parent, $display, $merge_tpl_vars, $no_output_filter); } catch (\ErrorException $e) { if (strpos($e->getFile(), '.tpl.php') > 0) { $file = HtmlTemplate::getTemplateByCompilePath($e->getFile()); $error_msg = str_replace('Undefined index: ', 'Unassigned variable: $', $e->getMessage()) . ' in File: ' . $file . ' in Compiled file ' . $e->getFile() . ':' . $e->getLine(); $e = new SmartyTemplateException($error_msg, $file, $e); } throw $e; } }
/** * Stop the current transactions and rollback all changes. * * @api * * @return bool */ public function rollBack() { Logger::getInstance()->traceStop('transaction'); return parent::rollBack(); }
/** * Assigns new values to an object existing in the table with the given name. The given array must have the same * form like described in add() * * @api * * @param mixed $primary_key * @param array $input * * @return bool True if the object was updated successfully, else false. */ public static function updateByPk($primary_key, array $input) { Logger::getInstance()->info(_s('AbstractModelWithId->updateByPk to ') . static::$TABLE); static::validate($input); $sql = "\n UPDATE " . static::getTable($input) . "\n SET " . self::combineValues(array_keys($input), ' = :', ',') . "\n WHERE "; // build query and add values from all primary key columns $condition = static::buildConditionByPk($primary_key); $stmt = self::createStatement($sql . $condition['sql']); // bind where condition foreach ($condition['params'] as $key => &$value) { $stmt->assignGuessType($key, $value); } // bind update values foreach ($input as $key => &$value) { $stmt->assignGuessType($key, $value); } return $stmt->affected(); }
/** * 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; }
/** * include javascript and stylesheets for the debugbar. * * @api */ protected final function useDebugBar() { $this->useJquery(); $path = dirname(dirname(dirname(dirname(__DIR__)))) . '/maximebf/debugbar/src/DebugBar/Resources/'; $this->addJavascript($path . 'debugbar.js'); $this->addJavascript($path . 'openhandler.js'); $this->addJavascript($path . 'widgets.js'); $this->addStylesheet($path . 'debugbar.css'); $this->addStylesheet($path . 'openhandler.css'); $this->addStylesheet($path . 'widgets.css'); $this->assign('debugbar', Logger::getInstance()->getRenderer()); }
/** * Impersonate another user by using his user_id everywhere. * * @api * * @param $user_id */ public static function impersonate($user_id) { if (!self::getConfig('impersonate')) { return; } self::getInstance(); // do not allow transitional impersonization if (isset($_SESSION['thisuser']['real_id'])) { $real_id = $_SESSION['thisuser']['real_id']; } else { $real_id = self::getUserId(); } $_SESSION['thisuser'] = User::getByPk($user_id); $_SESSION['thisuser']['real_id'] = $real_id; $_SESSION['thisuser']['impersonated'] = time(); Logger::getInstance()->info("impersonate user"); }
/** * Wrap up the execution of an statement execution. Logs errors and throws exceptions. Should not be used by * external calls as fetch* or affected always call an execute. So unless you want multiple executions of a * statement don't use this function. * * @internal * * @param array $bound_input_params (ignored) * @throws \FeM\sPof\exception\ModelException if a "write" statement failed * @return bool */ public function execute($bound_input_params = null) { if ($this->invalid) { // TODO announce which id/field failed the check return false; } try { Logger::getInstance()->traceStart('execute db query', $this->queryString); $retVar = parent::execute(); Logger::getInstance()->traceStop('execute db query'); return $retVar; } catch (\PDOException $e) { $this->invalid = true; $message = $e->getMessage(); // add statemenet parameters to exception message ob_start(); $this->debugDumpParams(); $message .= "\n" . ob_get_clean(); // check for constraint voilations if ($e->getCode() >= 23000 && $e->getCode() < 24000) { $e = new UnexpectedIntegrityConstraintViolationException($message, 0, $e); } else { // nest exception, to include changed error message $e = new \PDOException($message, 0, $e); } if (strpos(ltrim($this->queryString), 'INSERT') === 0 || strpos(ltrim($this->queryString), 'UPDATE') === 0 || strpos(ltrim($this->queryString), 'DELETE') === 0) { throw new ModelException($e); } else { Logger::getInstance()->exception($e); } } return false; }
/** * 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; }
/** * Send result (was action executed as desired and the resulting message) as JSON and stop further execution. * * @internal * * @param bool $success action was executed * @param string $message */ private function sendJson($success, $message) { // close transaction, if present if ($this->atomic) { DBConnection::getInstance()->commit(); } Logger::getInstance()->stackData(); // @codingStandardsIgnoreStart echo json_encode(['success' => $success, 'message' => $message]); // @codingStandardsIgnoreEnd exit; }
/** * Redirect to URL and stop further execution. * * @internal * * @param string $url */ public static function urlRedirect($url) { Logger::getInstance()->stackData(); session_write_close(); header('Location: ' . $url); exit; }