// Purchase code
$purchase_code = ""; // Your purchase code, don't give it to anyone.
$siteEncryptKey = "468b120cc8e8a78333c8cee1d067fa86749ff92d"; // Your site encrypt key, don't give it to anyone.
// =============== Redis: connection info ============== //
$redis_host = "127.0.0.1";
$redis_port = 6379;
$redis_pass = "331396517"; // nếu Redis có requirepass thì điền
$redis_timeout= 1.5; // giây
// ============== Optional: PHP sessions =============== //
if (!headers_sent()) {
ini_set('session.save_handler', 'redis');
$sess_path = "tcp://{$redis_host}:{$redis_port}";
if (!empty($redis_pass)) $sess_path .= "?auth=" . rawurlencode($redis_pass);
ini_set('session.save_path', $sess_path);
}
// ================== Redis bootstrap ================== //
/** @var Redis|null $REDIS */
$REDIS = null;
if (class_exists('Redis')) {
try {
$REDIS = new Redis();
$REDIS->connect($redis_host, $redis_port, $redis_timeout);
if (!empty($redis_pass)) {
$REDIS->auth($redis_pass);
}
// Chọn DB 0 (có thể thay đổi nếu muốn tách session/cache/log)
$REDIS->select(0);
} catch (Throwable $e) {
error_log("Redis connect error: " . $e->getMessage());
$REDIS = null;
}
}
// ================== Cache primitives ================= //
function _json_enc($v) { return json_encode($v, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); }
function _json_dec($s){ $x=json_decode($s, true); return (json_last_error()===JSON_ERROR_NONE)?$x:false; }
function cache_get($key) {
global $REDIS;
if (!$REDIS) return false;
try {
$val = $REDIS->get($key);
return $val ? _json_dec($val) : false;
} catch (Throwable $e) { return false; }
}
function cache_set($key, $data, $ttl = 300) {
global $REDIS;
if (!$REDIS) return false;
try { return $REDIS->setEx($key, (int)$ttl, _json_enc($data)); }
catch (Throwable $e) { return false; }
}
function cache_del($key) {
global $REDIS;
if (!$REDIS) return false;
try { $REDIS->del($key); } catch (Throwable $e) {}
}
// ================= Versioned key system =============== //
function _ver_key($ns, $id = null) {
return is_null($id) ? "v:{$ns}" : "v:{$ns}:{$id}";
}
function cache_ver_get($ns, $id = null) {
global $REDIS;
if (!$REDIS) return 1;
$k = _ver_key($ns, $id);
try {
$v = $REDIS->get($k);
if ($v === false) { $REDIS->set($k, 1); return 1; }
return (int)$v ?: 1;
} catch (Throwable $e) { return 1; }
}
function cache_ver_bump($ns, $id = null) {
global $REDIS;
if (!$REDIS) return true;
$k = _ver_key($ns, $id);
try { $REDIS->incr($k); } catch (Throwable $e) {}
return true;
}
function vkey($parts = []) { return implode(':', $parts); }
// ================== Logging (Streams) ================= //
function log_event($event, $data = []) {
global $REDIS;
if (!$REDIS) return false;
$fields = array_merge($data, ['event'=>$event, 'ts'=>time()]);
try { $REDIS->xAdd("logs:web", '*', array_map('strval', $fields)); } catch (Throwable $e) {}
return true;
}
// =================== Pub/Sub notify =================== //
function notify_user($user_id, $type, $payload = []) {
global $REDIS;
if (!$REDIS) return false;
$message = _json_enc(['type'=>$type, 'uid'=>(int)$user_id, 'data'=>$payload, 'ts'=>time()]);
try { $REDIS->publish("notifications:user:{$user_id}", $message); } catch (Throwable $e) {}
return true;
}
// =================== MySQL helpers ==================== //
function db_row($sql) {
global $sqlConnect;
$q = mysqli_query($sqlConnect, $sql);
return $q ? mysqli_fetch_assoc($q) : null;
}
function db_all($sql) {
global $sqlConnect;
$q = mysqli_query($sqlConnect, $sql);
$rows = [];
if ($q) while ($r = mysqli_fetch_assoc($q)) $rows[] = $r;
return $rows;
}
// ================== SETTINGS cache ==================== //
function get_site_settings() {
$ns = 'settings';
$ver = cache_ver_get($ns);
$ck = vkey([$ns, "v{$ver}"]);
if (($settings = cache_get($ck)) !== false) return $settings;
$rows = db_all("SELECT * FROM config");
$settings = [];
foreach ($rows as $row) $settings[$row['name']] = $row['value'];
cache_set($ck, $settings, 3600);
return $settings;
}
function invalidate_site_settings() { cache_ver_bump('settings'); }
// ================= USER PROFILE cache ================= //
function get_user_profile($user_id) {
$user_id = (int)$user_id;
$ns = 'user:profile';
$ver = cache_ver_get($ns, $user_id);
$ck = vkey(['user','profile',$user_id,"v{$ver}"]);
if (($user = cache_get($ck)) !== false) return $user;
$user = db_row("SELECT * FROM users WHERE user_id={$user_id} LIMIT 1");
if ($user) cache_set($ck, $user, 600);
return $user;
}
function invalidate_user_profile($user_id) { cache_ver_bump('user:profile', (int)$user_id); }
// ==================== POST cache ====================== //
function get_post($post_id) {
$post_id = (int)$post_id;
$ns = 'post';
$ver = cache_ver_get($ns, $post_id);
$ck = vkey(['post',$post_id,"v{$ver}"]);
if (($post = cache_get($ck)) !== false) return $post;
$post = db_row("SELECT * FROM posts WHERE id={$post_id} LIMIT 1");
if ($post) cache_set($ck, $post, 300);
return $post;
}
function invalidate_post($post_id) { cache_ver_bump('post', (int)$post_id); }
// ============== TIMELINE cache ================= //
function get_timeline($user_id, $page = 1, $limit = 20) {
$user_id = (int)$user_id;
$page = max(1, (int)$page);
$limit = max(1, (int)$limit);
$ns = 'timeline';
$ver = cache_ver_get($ns, $user_id);
$ck = vkey([$ns,'home',$user_id,"v{$ver}",'page',$page]);
if (($posts = cache_get($ck)) !== false) return $posts;
if (function_exists('GetPosts')) {
$posts = GetPosts([
'limit' => $limit,
'publisher_id' => 0,
'page' => $page
]);
} else {
$offset = ($page - 1) * $limit;
$posts = db_all("SELECT * FROM posts ORDER BY id DESC LIMIT {$limit} OFFSET {$offset}");
}
cache_set($ck, $posts, 60);
return $posts;
}
function invalidate_timeline_for_user($user_id) { cache_ver_bump('timeline', (int)$user_id); }
// ============== COUNTS cache ================= //
function get_user_followers_count($user_id) {
$user_id = (int)$user_id;
$ns = 'user:followers';
$ver = cache_ver_get($ns, $user_id);
$ck = vkey(['user','followers',$user_id,"v{$ver}"]);
if (($cnt = cache_get($ck)) !== false) return (int)$cnt;
$row = db_row("SELECT COUNT(*) AS c FROM followers WHERE user_id={$user_id}");
$cnt = $row ? (int)$row['c'] : 0;
cache_set($ck, $cnt, 120);
return $cnt;
}
function invalidate_user_followers($user_id) { cache_ver_bump('user:followers', (int)$user_id); }
// ================== LIKE/COMMENT COUNTS ================== //
function get_post_stats($post_id) {
$post_id = (int)$post_id;
$ns = 'post:stats';
$ver = cache_ver_get($ns, $post_id);
$ck = vkey(['post','stats',$post_id,"v{$ver}"]);
if (($stats = cache_get($ck)) !== false) return $stats;
$likes = db_row("SELECT COUNT(*) AS c FROM post_likes WHERE post_id={$post_id}");
$cmts = db_row("SELECT COUNT(*) AS c FROM comments WHERE post_id={$post_id}");
$stats = [
'likes' => $likes ? (int)$likes['c'] : 0,
'comments' => $cmts ? (int)$cmts['c'] : 0,
];
cache_set($ck, $stats, 60);
return $stats;
}
function invalidate_post_stats($post_id) { cache_ver_bump('post:stats', (int)$post_id); }
// ================== NOTIFY (pub/sub hook) ================= //
function notify_new_post($author_id, $post_id) {
notify_user($author_id, 'new_post', ['post_id'=>(int)$post_id]);
}
?>
Du Học Kanata
Are you sure you want to delete this tier?
In order to sell your content and posts, start by creating a few packages.
Monetization
You are about to purchase the items, do you want to proceed?