summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authoremkael <emkael@tlen.pl>2016-10-11 14:01:29 +0200
committeremkael <emkael@tlen.pl>2016-10-11 14:01:29 +0200
commit51609351f2c4b5082b7e6f0744cd3811c325303f (patch)
tree739015e9ec69bc185ebe30db21369ae0b8b692ce /include
parent8d1b0dad63e3906efa9393ef01d08b77d83417b5 (diff)
* initial template
Diffstat (limited to 'include')
-rw-r--r--include/Convert.class.php15
-rw-r--r--include/Env.class.php113
-rw-r--r--include/Menu.class.php30
-rw-r--r--include/Minify.class.php78
-rw-r--r--include/MyCache.class.php113
-rw-r--r--include/MyLocale.class.php89
-rw-r--r--include/MySession.class.php61
-rw-r--r--include/MySmarty.class.php18
-rw-r--r--include/PgDB.class.php339
-rw-r--r--include/setup.php74
10 files changed, 930 insertions, 0 deletions
diff --git a/include/Convert.class.php b/include/Convert.class.php
new file mode 100644
index 0000000..90cc59c
--- /dev/null
+++ b/include/Convert.class.php
@@ -0,0 +1,15 @@
+<?php
+
+class Convert {
+
+ public static function decodePseudoUTF($string) {
+ $ret = str_replace(
+ ['ó','ś','ę','ą','ń','ż','ć','ź','Ó','Ś','Ę','Ą','Ń','Ż','Ć','Ź','ń','ń','e̜'],
+ ['ó','ś','ę','ą','ń','ż','ć','ź','Ó','Ś','Ę','Ą','Ń','Ż','Ź','Ć','ń','ń','ę'],
+ $string);
+ return $ret;
+ }
+
+}
+
+?> \ No newline at end of file
diff --git a/include/Env.class.php b/include/Env.class.php
new file mode 100644
index 0000000..2f7ed44
--- /dev/null
+++ b/include/Env.class.php
@@ -0,0 +1,113 @@
+<?php
+
+class Env {
+
+ private static $_variables = [];
+ private static $_lang;
+
+ private static function _fetch() {
+
+ if (empty(self::$_variables)) {
+
+ $configdir = opendir(BASEPATH.'/config');
+
+ while ($file = readdir($configdir)) {
+ if (preg_match('/.*\.json$/', $file)) {
+ self::$_variables[preg_replace('/\.json$/', '', $file)] = json_decode(file_get_contents(BASEPATH.'/config/'.$file), TRUE);
+ }
+ }
+
+ }
+
+ }
+
+ static function get() {
+
+ self::_fetch();
+
+ $default = NULL;
+ $params = func_get_args();
+ if (!is_string(end($params))) {
+ $default = array_pop($params);
+ }
+ elseif (strpos(end($params), 'default:') === 0) {
+ $default = str_replace('default:', '', array_pop($params));
+ }
+
+ $ret = self::$_variables;
+ foreach ($params as $param) {
+ if (isset($ret[$param])) {
+ $ret = $ret[$param];
+ }
+ else {
+ if ($default!==null) {
+ return $default;
+ }
+ throw new EnvNoSuchEntryException('Entry '.implode(':',$params).' not found');
+ }
+ }
+ return $ret;
+
+ }
+
+ static function remoteIP() {
+ $ip = $_SERVER['REMOTE_ADDR'];
+ $proxy_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
+ if ($proxy_ip != ""){
+ $proxy_ip = split(", ", $proxy_ip);
+ $ip = array_shift($proxy_ip);
+ array_push($proxy_ip, $_SERVER['REMOTE_ADDR']);
+ $proxy_ip = join(", ", $proxy_ip);
+ }
+ return $ip;
+ }
+
+ static public function getHostName() {
+ try {
+ $hostname = MySession::get('hostname');
+ }
+ catch (SessionVariableException $e) {
+ $hostname = MySession::set('hostname', exec('hostname'));
+ }
+ return strtolower($hostname);
+ }
+
+ static public function getDomain($default = '') {
+ return strtolower(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $default);
+ }
+
+ static public function lang() {
+ if (self::$_lang === null) {
+ try {
+ $lang = MySession::get('lang');
+ }
+ catch (SessionVariableException $e) {
+ if (class_exists('MyLocale')) {
+ $lang = MyLocale::getPreferredLang();
+ }
+ else {
+ $lang = Env::get('locale','default-language');
+ }
+ }
+ self::setLang($lang);
+ }
+ return self::$_lang;
+ }
+
+ static public function setLang($lang) {
+ if ($lang != self::$_lang) {
+ MySession::set('lang', $lang);
+ self::$_lang = $lang;
+ if (class_exists('MyLocale')) {
+ MyLocale::setLocale($lang);
+ }
+ }
+ }
+
+ static public function AJAX_setLang($params) {
+ self::setLang($params['lang']);
+ return Env::lang();
+ }
+
+
+}
diff --git a/include/Menu.class.php b/include/Menu.class.php
new file mode 100644
index 0000000..3a61595
--- /dev/null
+++ b/include/Menu.class.php
@@ -0,0 +1,30 @@
+<?php
+
+class Menu {
+
+ public static function getItems() {
+ return Env::get('menu', 'items');
+ }
+
+ public static function getActiveLink($pageID) {
+ $activeContent = $pageID;
+ foreach (self::getItems() as $item => $link) {
+ if (is_array($link)) {
+ foreach ($link as $subitem => $sublink) {
+ if (trim($sublink, '/') === $pageID) {
+ $activeContent = $link['_'];
+ break;
+ }
+ }
+ } else {
+ if (trim($link, '/') === $pageID) {
+ $activeContent = $link;
+ }
+ }
+ }
+ return $activeContent;
+ }
+
+}
+
+?>
diff --git a/include/Minify.class.php b/include/Minify.class.php
new file mode 100644
index 0000000..ad66f32
--- /dev/null
+++ b/include/Minify.class.php
@@ -0,0 +1,78 @@
+<?php
+
+class Minify {
+
+ private static function _compileFiles($files, $directory, $compressor, $cacheFile) {
+ $lastmtime = self::_getMTime($files, $directory);
+ if (!file_exists($cacheFile) || filemtime($cacheFile) < $lastmtime) {
+ $out = '';
+ foreach ($files as $file) {
+ $fullPath = implode(
+ DIRECTORY_SEPARATOR,
+ [
+ BASEPATH, 'src', $directory, $file
+ ]
+ );
+ $content = file_get_contents($fullPath) . PHP_EOL;
+ if (!preg_match('/\.min\./', $file)) {
+ $content = call_user_func($compressor, $content);
+ }
+ $out .= $content;
+ }
+ file_put_contents($cacheFile, $out);
+ }
+ return $lastmtime;
+ }
+
+ public static function minifyJS($scripts, $cacheFile) {
+ require_once(implode(
+ DIRECTORY_SEPARATOR,
+ [BASEPATH, 'lib', 'JShrink.php']
+ ));
+ return self::_compileFiles(
+ $scripts, '_js', array('Minifier', 'minify'), $cacheFile
+ );
+ }
+
+ public static function minifyCSS($sheets, $cacheFile) {
+ require_once(implode(
+ DIRECTORY_SEPARATOR,
+ [BASEPATH, 'lib', 'CssMin.php']
+ ));
+ return self::_compileFiles(
+ $sheets, '_css', array('CssMin', 'minify'), $cacheFile
+ );
+ }
+
+ private static function _getMTime($files, $directory) {
+ $timestamp = max(
+ array_map(
+ function($file) use($directory) {
+ $path = implode(
+ DIRECTORY_SEPARATOR,
+ [BASEPATH, 'src', $directory, $file]
+ );
+ $mtime = filemtime($path);
+ return $mtime;
+ },
+ $files
+ )
+ );
+ $resourceConfig = implode(
+ DIRECTORY_SEPARATOR,
+ [BASEPATH, 'config', 'resources.json']
+ );
+ if (file_exists($resourceConfig)) {
+ return max([filemtime($resourceConfig), $timestamp]);
+ }
+ return $timestamp;
+ }
+
+ public static function getMTime($scripts, $sheets) {
+ return max(self::_getMTime($scripts, '_js'),
+ self::_getMTime($sheets, '_css'));
+ }
+
+}
+
+?>
diff --git a/include/MyCache.class.php b/include/MyCache.class.php
new file mode 100644
index 0000000..e074a3b
--- /dev/null
+++ b/include/MyCache.class.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Simple on-disk variable caching class. Implements file caching logic.
+ */
+class MyCache {
+
+ private function __construct() {}
+
+ private function __clone() {}
+
+
+ /**
+ * Sets given cache line to given value
+ *
+ * @param id string cache line name. It should follow file naming conventions.
+ * @param value object - any serializable variable
+ *
+ * @return its second argument
+ */
+ static function set($id, $value) {
+ file_put_contents(BASEPATH.'/caches/MyCache/'.$id, serialize($value));
+ return $value;
+ }
+
+
+ /**
+ * fetches cached value from disk
+ *
+ * @param id string - cache line identifier to fetch. It should follow file naming conventions.
+ * @param valid int - if exists and non zero, method throws ExceptionCacheLineExpired if cache line
+ * is older than given time in seconds
+ *
+ * @return restored variable contents
+ */
+ static function get($id, $valid=0, $callback=null, $passexception=true) {
+ $isValid = self::valid($id, $valid);
+ if ($valid != 0 && !$isValid && $callback===null) {
+ throw new CacheLineExpiredException();
+ }
+ if ($isValid) {
+ return unserialize(file_get_contents(BASEPATH.'/caches/MyCache/'.$id));
+ }
+ elseif ($callback===null) {
+ if (file_exists(BASEPATH.'/caches/MyCache/'.$id)) {
+ throw new CacheLineExpiredException();
+ }
+ else {
+ throw new CacheLineNotFoundException($id);
+ }
+ }
+ else {
+ try {
+ $value = call_user_func($callback);
+ self::set($id,$value);
+ return $value;
+ }
+ catch (Exception $e) {
+ if ($passexception) {
+ throw $e;
+ }
+ return self::get($id);
+ }
+ }
+ }
+
+
+ /**
+ * Removes given cache line from disk
+ *
+ * @param id string cache line name
+ *
+ * @return void
+ */
+ static function delete($id) {
+ if (file_exists(BASEPATH.'/caches/MyCache/'.$id)) {
+ unlink(BASEPATH.'/caches/MyCache/'.$id);
+ }
+ }
+
+ /**
+ * validates if cache line is not older than given time in seconds
+ *
+ * @param id string cache line name.
+ * @param cacheLifeTime int cache line age limit (default 300 seconds)
+ *
+ * @return true if cache is stil valid, false otherwise
+ */
+ static function valid($id, $cacheLifeTime=null) {
+
+ $cacheLifeTime = (int)$cacheLifeTime; //seconds
+
+ if ($cacheLifeTime==null) {
+ return is_readable(BASEPATH.'/caches/MyCache/'.$id);
+ }
+
+ if (!is_readable(BASEPATH.'/caches/MyCache/'.$id)) {
+ return false;
+ }
+ return (time()-filemtime(BASEPATH.'/caches/MyCache/'.$id)) <= $cacheLifeTime;
+ }
+
+
+ /**
+ * checks if cache line exists without validating its age
+ *
+ * @param id sting cache line name
+ *
+ * @return boolean true if cache line is found
+ */
+ static function exist($id) {
+ return is_readable(BASEPATH .'/caches/MyCache/'.$id);
+ }
+}
diff --git a/include/MyLocale.class.php b/include/MyLocale.class.php
new file mode 100644
index 0000000..49d6856
--- /dev/null
+++ b/include/MyLocale.class.php
@@ -0,0 +1,89 @@
+<?php
+
+class MyLocale {
+
+ static private $allowedLangs = [];
+ static private $_currentLocale = '';
+
+ static function init() {
+ date_default_timezone_set(Env::get('locale','timezone'));
+ self::setLocale();
+ }
+
+ static function getAllowedLangs() {
+ if (!count(self::$allowedLangs)) {
+ self::$allowedLangs = Env::get('locale', 'languages');
+ }
+
+ return self::$allowedLangs;
+ }
+
+ static function getPreferredLang($allowed_languages = [], $deflang = '') {
+ if (count($allowed_languages)==0) {
+ $allowed_languages = self::getAllowedLangs();
+ }
+
+ if ($deflang=='') {
+ $deflang = Env::get('locale','default-language');
+ }
+
+ if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
+ $accepted = explode(',',$_SERVER['HTTP_ACCEPT_LANGUAGE']);
+ foreach ($accepted as $usrlang) {
+ foreach ($allowed_languages as $pagelang) {
+ if ($pagelang === substr($usrlang, 0, strlen($pagelang))) {
+ return $pagelang;
+ }
+ }
+ }
+ }
+ elseif ($deflang) {
+ return $deflang;
+ }
+ return $allowed_languages[0];
+ }
+
+ /**
+ * sets current locale environment. It partially duplicates functionality of Env::lang()
+ * in regards of storing current settings.
+ *
+ * @param langid - new language code. If null or empty string, default language will be
+ * guessed by using Env::lang() method.
+ *
+ * @return void
+ */
+ static function setLocale($langid='') {
+ if ($langid=='') {
+ $langid = Env::lang();
+ }
+ if (self::$_currentLocale==$langid) {
+ return;
+ }
+ self::$_currentLocale = $langid;
+ bindtextdomain('main', BASEPATH.'/locale');
+ bind_textdomain_codeset('main','utf-8');
+ textdomain('main');
+ try {
+ $localeId = Env::get('locale', 'locale-id', $langid);
+ }
+ catch (EnvNoSuchEntryException $e) {
+ $localeId = Env::get('locale', 'locale-id', Env::get('locale', 'default-language'));
+ }
+
+ setlocale(LC_MESSAGES, $localeId);
+ setlocale(LC_CTYPE, $localeId);
+ setlocale(LC_NUMERIC, $localeId);
+ setlocale(LC_MONETARY, $localeId);
+ setlocale(LC_TIME, $localeId);
+ putenv('LANGUAGE=' . $localeId);
+ Env::setLang($langid);
+ }
+
+ static function formatCurrency($value, $currency) {
+ $locale = localeconv();
+ $f = number_format(round($value, 2), 2, null, ' ');
+ return sprintf(($locale['p_cs_precedes'] ? '%2$s %1$s' : '%s %s'),
+ $f, Currency::getCurrencySymbol($currency));
+ }
+}
+?>
diff --git a/include/MySession.class.php b/include/MySession.class.php
new file mode 100644
index 0000000..b57f7c8
--- /dev/null
+++ b/include/MySession.class.php
@@ -0,0 +1,61 @@
+<?php
+
+class MySession {
+
+ private static $_initiated = FALSE;
+ private static $_dataContainer = array();
+
+ public static function init() {
+ if (!self::$_initiated) {
+ session_start();
+ if (!isset($_SESSION['__data'])) {
+ $_SESSION['__data'] = [];
+ }
+ self::$_dataContainer = &$_SESSION['__data'];
+ }
+ self::$_initiated = TRUE;
+ }
+
+ private static function _getRealm() {
+ $backtrace = debug_backtrace();
+ while (count($backtrace) && isset($backtrace[0]['class']) && $backtrace[0]['class'] == get_class()) {
+ array_shift($backtrace);
+ }
+ if (!count($backtrace) || (!isset($backtrace[0]['class']))) {
+ throw new SessionRealmException('Session realm not provided');
+ }
+ return $backtrace[0]['class'];
+ }
+
+ public static function get($variable, $realm = NULL) {
+ if (!self::$_initiated) {
+ self::init();
+ }
+ if (!$realm) {
+ $realm = self::_getRealm();
+ }
+ if (!isset(self::$_dataContainer[$realm])) {
+ throw new SessionVariableException('Realm '.$realm.' doesn\'t exist');
+ }
+ if (!isset(self::$_dataContainer[$realm][$variable])) {
+ throw new SessionVariableException('Variable '.$realm.'::'.$variable.' not set');
+ }
+ return self::$_dataContainer[$realm][$variable];
+ }
+
+ public static function set($variable, $value, $realm = NULL) {
+ if (!self::$_initiated) {
+ self::init();
+ }
+ if (!$realm) {
+ $realm = self::_getRealm();
+ }
+ if (!isset(self::$_dataContainer[$realm])) {
+ self::$_dataContainer[$realm] = [];
+ }
+ return self::$_dataContainer[$realm][$variable] = $value;
+ }
+
+}
+
+?>
diff --git a/include/MySmarty.class.php b/include/MySmarty.class.php
new file mode 100644
index 0000000..31aa5b4
--- /dev/null
+++ b/include/MySmarty.class.php
@@ -0,0 +1,18 @@
+<?php
+
+require_once(BASEPATH.'/lib/smarty/Smarty.class.php');
+
+class MySmarty extends Smarty {
+
+ public function __construct() {
+ parent::__construct();
+ $this->caching = Smarty::CACHING_OFF;
+ $this->template_dir = BASEPATH.'/template';
+ $this->compile_dir = BASEPATH.'/caches/smarty/compile';
+ $this->cache_dir = BASEPATH.'/caches/smarty';
+ $this->addPluginsDir(BASEPATH.'/lib/smarty-plugins');
+ }
+
+}
+
+?> \ No newline at end of file
diff --git a/include/PgDB.class.php b/include/PgDB.class.php
new file mode 100644
index 0000000..b79b2ec
--- /dev/null
+++ b/include/PgDB.class.php
@@ -0,0 +1,339 @@
+<?php
+/**
+ *
+ * PgDB - future unified database access interface,
+ * currently only wrapping some global functions
+ */
+
+// temporary workaround until new configuration framework will be in place.
+class PgDB {
+ static private $_db = null;
+ static private $_master_db = null;
+ static private $_slave_db = null;
+ // counts how many times transaction has been started
+ static private $_transaction_depth = 0;
+ // states if current transaction has been rolled back at some point
+ static private $_transaction_failed = false;
+
+ static private $_config = null;
+
+ static private $_me = null;
+
+ /**
+ * Private constructor prevents multiple objects creation.
+ * Guarantees singleton pattern usage of class.
+ */
+ private function __construct() {
+ }
+
+ /**
+ * returns object providing access to master database PDO functions
+ * \return object behaving like PDO Database object
+ */
+ static function db() {
+ self::_needsMasterDB();
+ if (self::$_me == null) {
+ self::$_me = new PgDB();
+ }
+ return self::$_me;
+ }
+
+
+ /**
+ * Mapping method - thanks to it PgDB object behaves like PDO
+ *
+ * @param funcname PDO function to be mapped
+ * @param args array of PDO function arguments
+ * @return PDO function response
+ */
+ public function __call($funcname, $args) {
+ return call_user_func_array([self::$_db,$funcname],$args);
+ }
+
+ /**
+ * Declares database dependency, establishes connection if needed.
+ * Guarantees availablility of master connection.
+ */
+ static private function _needsMasterDB() {
+ self::$_db = &self::$_master_db;
+ if (self::$_db == null) {
+ self::_masterConnect();
+ }
+ }
+
+ static private function _getConfig($key, $default = '') {
+ if (self::$_config === NULL) {
+ self::$_config = Env::get('db');
+ }
+ if (isset(self::$_config[$key])) {
+ return self::$_config[$key];
+ }
+ return $default;
+ }
+
+ /**
+ * Establishes connection to master server
+ * (currently there's no multimaster support available).
+ */
+ static private function _masterConnect() {
+ self::$_master_db = new PDO('pgsql:host='.self::_getConfig('host').';port='.self::_getConfig('port', 5432).';dbname='.self::_getConfig('database').'', self::_getConfig('user'), self::_getConfig('password'));
+ self::$_master_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ self::$_db = &self::$_master_db;
+ }
+
+ /** returns value from first column of first row of query result.
+ * accepts two types of variable substitution: '?' or ':var',
+ * '?' expects variable parameter list, ':var' expects second argument
+ * to be array working as dictionary
+ * \param $query PgSQL query with optional parameter substitution
+ * \param $params (optional) array or first parameter for '?' type query
+ * \param $... - (optional) following parameters for '?' type query
+ */
+ public static function fetchValue($query, $params = []) {
+ self::_needsMasterDB();
+ $sth = self::$_db->prepare($query.';');
+ if (!is_array($params)) {
+ $params = array_slice(func_get_args(),1);
+ }
+ $sth->execute($params);
+ $result = $sth->fetch(PDO::FETCH_NUM);
+ return isset($result[0]) ? $result[0] : null;
+ }
+
+ /** returns first first row of query result as assiociative array.
+ * accepts two types of variable substitution: '?' or ':var',
+ * '?' expects variable parameter list, ':var' expects second argument
+ * to be array working as dictionary
+ * \param $query PgSQL query with optional parameter substitution
+ * \param $params (optional) array or first parameter for '?' type query
+ * \param $... - (optional) following parameters for '?' type query
+ */
+ public static function fetchRow($query, $params = []) {
+ self::_needsMasterDB();
+ $sth = self::$_db->prepare($query.';');
+ if (!is_array($params)) {
+ $params = array_slice(func_get_args(),1);
+ }
+
+ $sth->execute($params);
+ return $sth->fetch(PDO::FETCH_ASSOC);
+ }
+
+ /** returns whole query result as numbered array of assiociative arrays.
+ * accepts two types of variable substitution: '?' or ':var',
+ * '?' expects variable parameter list, ':var' expects second argument
+ * to be array working as dictionary
+ * \param $query PgSQL query with optional parameter substitution
+ * \param $params (optional) array or first parameter for '?' type query
+ * \param $... - (optional) following parameters for '?' type query
+ */
+ static public function fetchAll($query, $params = []) {
+ self::_needsMasterDB();
+ $sth = self::$_db->prepare($query.';');
+ if (!is_array($params)) {
+ $params = array_slice(func_get_args(),1);
+ }
+
+ $sth->execute($params);
+ return $sth->fetchAll(PDO::FETCH_ASSOC);
+ }
+
+
+ static public function execute($query, $params = []) {
+ self::_needsMasterDB();
+ $sth = self::$_db->prepare($query.';');
+ if (!is_array($params)) {
+ $params = array_slice(func_get_args(),1);
+ }
+ $sth->execute($params);
+ return $sth->rowCount();
+
+ }
+
+ static public function insert($table, $values, $functions = []) {
+ self::_needsMasterDB();
+ list($query,$args) = self::_insert_prepare($table,$values,$functions);
+ $sth = self::$_db->prepare($query.';');
+ $sth->execute($args);
+ return $sth->rowCount();
+ }
+
+
+ static public function update($table,$values,$whereclause,$functions="") {
+ self::_needsMasterDB();
+ $query = 'UPDATE "'. $table .'" SET ';
+ $cnt=0;
+ $where = "";
+ $args = [];
+
+ foreach ($values as $key => $val) {
+ if ($cnt) {
+ $query .=', ';
+ }
+ $query .= '"'. $key .'"=?';
+ if (is_bool($val)) {
+ $args[] = ($val) ? 'TRUE' : 'FALSE';
+ }
+ else {
+ $args[] = $val;
+ }
+ $cnt++;
+ }
+
+ if ($functions!="") {
+ foreach ($functions as $key => $val) {
+ if ($cnt) {
+ $query .=', ';
+ }
+ $query .= '"'. $key .'"'. $val;
+ $cnt++;
+ }
+ }
+
+ if (empty($values)) {
+ $query = 'SELECT * FROM '.$table;
+ }
+
+ if (is_array($whereclause)) {
+ $cnt=0;
+ foreach ($whereclause as $key => $val) {
+ if ($cnt) {
+ $where .=' AND ';
+ }
+ $where .= '("'. $key .'"=?)';
+ $args[] = $val;
+ $cnt++;
+ }
+ $query .= " WHERE ".$where .";";
+ }
+ else {
+ $query .= " WHERE ". $whereclause .";";
+ }
+
+ $sth = self::$_db->prepare($query.';');
+ $sth->execute($args);
+ return $sth->rowCount();
+ }
+
+
+ public static function set($table,$values,$wherelist,$functions = []) {
+ $rowsAffected = self::update($table,$values,$wherelist,$functions);
+ if ($rowsAffected == 0) {
+ return self::insert($table,array_merge($values,$wherelist),$functions);
+ }
+ return $rowsAffcted;
+ }
+
+
+ public static function delete($table, $values, $extrarules="") {
+ $query = 'DELETE FROM "'. $table .'" WHERE ';
+ $cnt=0;
+ $args = [];
+ foreach ($values as $key => $val) {
+ if ($cnt) {
+ $query .= 'AND';
+ }
+ $query .= ' ("'. $key .'" = ?)';
+ $args[] = $val;
+ $cnt++;
+ }
+
+ if ($extrarules !== "") {
+ $query .= ' AND '.$extrarules;
+ }
+ return self::execute($query,$args);
+ }
+
+ static private function _insert_prepare($table,$values,$functions = []) {
+ $query = 'INSERT INTO "'. $table .'"(';
+ $cnt=0;
+ $valbuf = "";
+ $args = [];
+ foreach ($values as $key => $val) {
+ if ($cnt) {
+ $query .=',';
+ $valbuf.=',';
+ }
+ $query .= '"'. $key .'"';
+ $valbuf .= '?';
+
+ if (is_bool($val)) {
+ $args[] = ($val) ? 'TRUE' : 'FALSE';
+ }
+ elseif ($val===null) {
+ $args[] = NULL;
+ }
+ else {
+ $args[] = $val;
+ }
+ $cnt++;
+ }
+
+ foreach ($functions as $key => $val) {
+ if ($cnt) {
+ $query .=',';
+ $valbuf .=',';
+ }
+ $query .= '"'. $key .'"';
+ $valbuf .= $val;
+
+ $cnt++;
+ }
+
+ $query .= ") VALUES (". $valbuf .");";
+
+ return [$query, $args];
+ }
+
+
+ public static function begin() {
+ self::_needsMasterDB();
+ if (self::$_transaction_depth == 0) {
+ self::$_db->beginTransaction();
+ self::$_transaction_depth++;
+ }
+ elseif (self::$_transaction_failed) {
+ throw new Exception("Trying to begin transaction inside of already stopped transaction!");
+ }
+ else {
+ self::$_transaction_depth++;
+ }
+ }
+
+ public static function commit() {
+ if (self::$_transaction_depth>0) {
+ if (self::$_transaction_failed) {
+ // I'm not convinced that it's good idea,
+ // but we need to be sure transaction won't go to database.
+ self::rollback();
+ throw new Exception("Transaction already stopped, couldn't be commited");
+ }
+ self::$_transaction_depth--;
+ if (self::$_transaction_depth==0) {
+ return self::$_db->commit();
+ }
+ }
+ else {
+ throw new Exception("To commit transaction it needs to be started first");
+ }
+ }
+
+ public static function rollback() {
+ self::$_transaction_failed = true;
+ self::$_transaction_depth--;
+ if (self::$_transaction_depth == 0) {
+ self::$_db->rollback();
+ self::$_transaction_failed = false;
+ }
+ }
+
+ public static function inTransaction() {
+ return (self::$_transaction_depth>0);
+ }
+
+ public static function transactionStateFailed() {
+ return self::$_transaction_failed;
+ }
+}
+
+?>
diff --git a/include/setup.php b/include/setup.php
new file mode 100644
index 0000000..f5e58f4
--- /dev/null
+++ b/include/setup.php
@@ -0,0 +1,74 @@
+<?php
+
+mb_regex_encoding("UTF-8");
+mb_internal_encoding("UTF-8");
+
+define("BASEPATH",dirname(dirname(__FILE__)));
+
+function cc_autoload($class_name) {
+
+ if (substr($class_name,strlen($class_name)-9)=='Exception') {
+ return eval("class {$class_name} extends Exception {}");
+ }
+ else if (file_exists(BASEPATH.'/include/'.$class_name.'.class.php')) {
+ include_once($class_name . '.class.php');
+ }
+ else if (file_exists(BASEPATH.'/include/admin/'.$class_name.'.class.php')) {
+ include_once('admin/'.$class_name . '.class.php');
+ }
+ else if (file_exists(BASEPATH.'/include/components/'.$class_name.'.class.php')) {
+ include_once('components/'.$class_name . '.class.php');
+ }
+ else if (file_exists(BASEPATH.'/include/controls/'.$class_name.'.class.php')) {
+ include_once('controls/'.$class_name . '.class.php');
+ }
+ else {
+ return null;
+ }
+
+}
+
+spl_autoload_register('cc_autoload');
+
+function exceptions_error_handler($severity, $message, $filename, $lineno) {
+ $fatal_severities = [
+ E_ERROR,
+ E_PARSE,
+ E_CORE_ERROR,
+ E_COMPILE_ERROR,
+ E_USER_ERROR
+ ];
+ if (!in_array($severity, $fatal_severities)) {
+ return;
+ }
+ throw new ErrorException(severity($severity).': '.$message, 0, $severity, $filename, $lineno);
+}
+
+set_error_handler('exceptions_error_handler', ini_get('error_reporting'));
+
+function severity($code) {
+ $severities = [
+ E_ERROR => 'ERROR',
+ E_WARNING => 'WARNING',
+ E_PARSE => 'PARSING ERROR',
+ E_NOTICE => 'NOTICE',
+ E_CORE_ERROR => 'CORE ERROR',
+ E_CORE_WARNING => 'CORE WARNING',
+ E_COMPILE_ERROR => 'COMPILE ERROR',
+ E_COMPILE_WARNING => 'COMPILE WARNING',
+ E_USER_ERROR => 'USER ERROR',
+ E_USER_WARNING => 'USER WARNING',
+ E_USER_NOTICE => 'USER NOTICE',
+ E_STRICT => 'STRICT NOTICE',
+ E_RECOVERABLE_ERROR => 'RECOVERABLE ERROR',
+ E_DEPRECATED => 'DEPRECATED',
+ E_USER_DEPRECATED => 'USER DEPRECATED'
+ ];
+ return $severities[$code];
+}
+
+Env::get();
+MySession::init();
+//MyLocale::init();
+
+?>