...
 
Commits (265)
# Ignorer certains fichiers
~*
/.DS_Store
/conf/db.php
/web/js/compile.bat
/web/design/compile.bat
/doc/first_user.sql
# Ignorer certains dossiers
/private
/web/img/mava/cache
/inc/models/orm
/web/img/icons/old
/unshared
# PhpStorm
/.idea
......
image: registry.git.bitmycode.com:443/bmc/docker/debiancurl:latest
stages:
- deploy
deploy:
stage: deploy
script:
- eval wget --quiet --content-on-error -O - --post-data='token=$AUTODEPLOY_TOKEN' https://autodeploy.bitmycode.com
......@@ -4,3 +4,55 @@ RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
# Cacher la signature du serveur
ServerSignature Off
# Encodage
AddCharset UTF-8 .txt
# Cache
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 7200 seconds"
ExpiresByType image/jpg "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
AddType image/x-icon .ico
ExpiresByType image/ico "access plus 2592000 seconds"
ExpiresByType image/icon "access plus 2592000 seconds"
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType text/css "access plus 2592000 seconds"
ExpiresByType text/javascript "access plus 2592000 seconds"
ExpiresByType text/html "access plus 7200 seconds"
ExpiresByType application/xhtml+xml "access plus 7200 seconds"
ExpiresByType application/javascript A2592000
ExpiresByType application/x-javascript "access plus 2592000 seconds"
ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
</IfModule>
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
Header set X-Content-Security-Policy "allow 'self';"
Header set X-Frame-Options DENY
Header set X-Content-Type-Options "nosniff"
Header set X-XSS-Protection "1; mode=block"
<FilesMatch "\\.(ico|jpe?g|png|gif|swf)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
<FilesMatch "\\.(css)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
<FilesMatch "\\.(js)$">
Header set Cache-Control "max-age=216000, private"
</FilesMatch>
<FilesMatch "\\.(x?html?|php)$">
Header set Cache-Control "max-age=600, private, must-revalidate"
</FilesMatch>
</IfModule>
module.exports = function(grunt) {
// Configuration du projet
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
stylus: {
compile: {
src: [ 'web/stylus/style.styl' ],
dest: 'dist/css/style.css'
}
},
concat: {
compile: {
src: [ 'web/js/use/*.js', '!web/js/use/chat.js' ],
dest: 'dist/js/main.min.js'
}
},
uglify: {
main: {
src: [ 'dist/js/main.min.js' ],
dest: 'dist/js/main.min.js'
},
chat: {
src: [ 'web/js/use/chat.js' ],
dest: 'dist/js/chat.min.js'
}
},
jshint: {
beforeconcat: [ 'web/js/use/*.js' ]
},
watch: {
stylus: {
files: [ 'web/stylus/*.styl' ],
tasks: [ 'stylus' ],
options: {
// Lance un serveur de rechargement en direct par défaut sur le port 35729
livereload: true
}
},
concat: {
files: [ 'web/js/use/*.js' ],
tasks: [ 'concat' ]
},
uglify: {
files: [ 'dist/js/main.min.js' ],
tasks: [ 'uglify' ]
}
/*
jshint: {
files: [ 'web/js/use/*.js' ],
tasks: [ 'jshint' ]
}
*/
}
});
// Charge les modules dont les tâches ont besoin
grunt.loadNpmTasks('grunt-contrib-stylus');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
// Tâches par défaut
grunt.registerTask('default', [ 'stylus', 'concat', 'uglify', 'jshint', 'watch' ]);
grunt.registerTask('ugly:main', [ 'uglify:main' ]);
grunt.registerTask('ugly:chat', [ 'uglify:chat' ]);
};
<?php
session_start();
/**
CHAT_INFO :
id (INT)
uid (INT)
writing (BOOL)
heartbeat (INT)
sound_enabled (BOOL)
banned (B00L)
/*
chat_info :
id (int)
uid (int)
writing (bool)
heartbeat (int)
sound_enabled (bool)
banned (bool)
A faire :
* petit son pour prévenir
......@@ -19,18 +20,20 @@ session_start();
* BBCode & smileys
* Interpreteur de commandes
* Ajout du token CSRF
**/
*/
require 'inc/models/Db.php';
require '../app/models/Db.php';
require '../core/Format.php';
$db_infos = require 'conf/db.php';
$db_infos = require '../conf/db.php';
$db = DB::init($db_infos['db.host'], $db_infos['db.dbname'], $db_infos['db.username'], $db_infos['db.passwd']);
DB::init($db_infos['host'], $db_infos['dbname'], $db_infos['username'], $db_infos['passwd']);
/* Indique si un message commence par $str et retourne les options
------------------------------------------------------------------ */
/// Indique si un message commence par $str et retourne les options
function beginby($msg, $str) {
return (substr($msg->message, 0, strlen($str)) == $str) ? substr($msg->message, strlen($str)) : null;
return (substr($msg->content, 0, strlen($str)) == $str)
? substr($msg->content, strlen($str))
: null;
}
function follow($path) {
......@@ -39,33 +42,27 @@ function follow($path) {
}
class Chat {
/* Poste sur le chat à partir des données en POST
------------------------------------------------- */
/// Poste sur le chat à partir des données en POST
public static function post() {
global $db; // penser à faire passer la variable en paramètre
$time = time();
$id = (isset($_SESSION['id'])) ? $_SESSION['id'] : follow('index.php');
$id = isset($_SESSION['id']) ? $_SESSION['id'] : 0;
$msg = htmlentities($_POST['msg']);
if (empty($msg)) exit();
if (empty($msg))
exit();
DB::insert('chat_message', [
'date_message' => $time,
'id_author' => $id,
'message' => $msg
'date_add' => $time,
'id_author' => $id,
'content' => $msg
]);
}
/* Récupère les messages & les utilisateurs connectés
----------------------------------------------------- */
/// Récupère les messages & les utilisateurs connectés
public static function get() {
global $db; // penser à faire passer la variable en paramètre
$lmid = is_numeric(@$_GET['new']) ? $_GET['new'] : 0;
/* On récupère les 90 dernier messages
-------------------------------------- */
// On récupère les 90 dernier messages
$messages = DB::select('
msg.*, user.username username
from chat_message msg
......@@ -86,28 +83,27 @@ class Chat {
$cur_date = '00/00/0000';
foreach ($messages as $message) {
$last_date = date('d/m/Y', $message->date_message);
$last_date = date('d/m/Y', $message->date_add);
if ($cur_date != $last_date && $last_date != date('d/m/Y', time())) {
$msg .= '<div class="chat-date">' . $last_date . '</div>';
$cur_date = $last_date;
}
$msg .= self::format($message);
$msg .= static::format($message);
}
/* On récupère la liste des connectés
------------------------------------- */
// On récupère la liste des connectés
$logd = '';
$connectes = DB::select('
nickname
username
from user_info
where chat_heartbeat >= ' . (time() - 60) . '
')->all();
foreach ($connectes as $c) {
$logd .= $c->nickname . ", ";
$logd .= $c->username . ", ";
}
$logd = trim($logd, ', ');
......@@ -122,16 +118,14 @@ class Chat {
print json_encode($json);
// update du heartbeat
self::heartbeat();
// Mise à jour du heartbeat
static::heartbeat();
}
/* Met à jour le dernier timestamp d'update dans la db
------------------------------------------------------ */
/// Met à jour le dernier timestamp d'update dans la db
public static function heartbeat() {
global $db;
$now = time();
DB::update('
user_info
set chat_heartbeat = :timestamp
......@@ -142,42 +136,32 @@ class Chat {
]);
}
/* Formate un message
--------------------- */
/// Formate un message
public static function format($msg) {
// pas de commande, on renvoie un affichage "classique" du message
if ($msg->message[0] != '/') {
return '<strong>[' . date('H:i', $msg->date_message) . '] ' . $msg->username . '</strong> : ' . $msg->message . '<br />';
}
if ($msg->content[0] != '/')
return '<strong>[' . date('H:i', $msg->date_add) . '] ' . $msg->username . '</strong> : ' . $msg->content . '<br />';
if ($opt = beginby($msg, '/me ')) {
return '<strong>' . Format::nickname($msg->nickname) . '</strong>' . ' ' . $opt . '<br />';
}
if ($opt = beginby($msg, '/me '))
return '<strong>' . Format::username($msg->username) . '</strong>' . ' ' . $opt . '<br />';
if ($opt = beginby($msg, '/afk ')) {
// todo
}
if ($opt = beginby($msg, '/afk '))
// à faire
if ($opt = beginby($msg, '/ban ')) {
// todo
}
if ($opt = beginby($msg, '/ban '))
// à faire
if ($opt = beginby($msg, '/clear ')) {
// todo
}
if ($opt = beginby($msg, '/clear '))
// à faire
return '';
}
}
/* Pour avoir tous les messages, users connectés, ...
----------------------------------------------------- */
if (isset($_GET['new']) or !count($_GET)) {
/// Pour avoir tous les messages, users connectés, ...
if (isset($_GET['new']) or !count($_GET))
Chat::get();
}
/* Post d'un nouveau message
---------------------------- */
if (isset($_GET['post'])) {
/// Poste d'un nouveau message
if (isset($_GET['post']))
Chat::post();
}
......@@ -5,7 +5,7 @@
class Category {
/* Récupère une catégorie avec son titre ou son slug
---------------------------------------------------- */
public static function one_category($slug_category) {
public static function oneCategory($slug_category) {
$category = ForumCategory::getBySlug($slug_category);
if ($category->id)
......@@ -14,73 +14,50 @@ class Category {
return $category;
}
/* Liste des membres
-------------------- */
public static function list_categories() {
public static function listCategories() {
return DB::select('
id, title, description, slug, order_list, visible
id, title, description, slug, position, visible
from forum_category
where visible = 1
order by order_list;
order by position;
')->all();
}
/* Création d'une nouvelle catégorie
------------------------------------ */
public static function add_category($data) {
$slug_category = self::gen_slug($data['title']);
public static function addCategory($data) {
$slug_category = self::genSlug($data['title']);
DB::insert('forum_category', [
'title' => $data['title'],
'description' => $data['description'],
'slug' => $slug_category,
'order_list' => 0,
'position' => 0,
'visible' => (int) true
]);
return $slug_category;
}
/* Mise à jour d'un catégorie
----------------------------- */
public static function update_category($category, $data) {
return DB::update('
forum_category
set title = :title,
description = :description,
slug = :slug,
order_list = :order_list,
visible = :visible,
where id = :id
', [
'title' => $data['title'],
'description' => $data['description'],
'slug' => self::gen_slug($data['title']),
'order_list' => $data['order_list'],
'visible' => $data['visible'],
'id' => $category->id
]);
}
public static function updateCategory($category, $data) {
$category = ForumCategory::getById($category->id);
$category->title = $data['title'];
$category->description = $data['description'];
$category->slug = static::genSlug($data['title']);
$category->position = $data['position'];
$category->visible = $data['visible'];
return $category->save();
}
/* Supprimer une catégorie
-------------------------- */
public static function remove_category($category) {
public static function removeCategory($category) {
return DB::delete('
forum_category
where id = :id;
......@@ -89,13 +66,9 @@ class Category {
]);
}
/* Génère un slug pour les catégories
------------------------------------- */
public static function gen_slug($title) {
return Format::gen_slug_table($title, __CLASS__ . '::one_category');
public static function genSlug($title) {
return Format::genSlugTable($title, __CLASS__ . '::oneCategory');
}
}
......@@ -3,68 +3,84 @@
class DB {
const ARR = false;
const OBJ = true;
private static $connection;
protected static $connection;
public static $nbQueries = 0;
private static $lastInsertSuccess = false;
public static function init($host, $dbname, $username, $passwd, $driver = 'mysql', $driver_options = []) {
try {
$pdo_options = array_merge([
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_EMULATE_PREPARES => false
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false
], $driver_options);
self::$connection = new \PDO($driver . ':host=' . $host . ';dbname=' . $dbname, $username, $passwd, $pdo_options);
static::$connection = new PDO($driver . ':host=' . $host . ';dbname=' . $dbname, $username, $passwd, $pdo_options);
} catch (Exception $e) {
exit('<strong>Problem with the database:</strong><br />' . $e->getMessage());
exit('<strong>Problème avec la base de données :</strong><br />' . $e->getMessage());
}
}
public static function insert($table, $values = []) {
$req = self::$connection->prepare('INSERT INTO ' . $table .
static::$nbQueries++;
$req = static::$connection->prepare('insert into ' . $table .
'(' . implode(', ', array_keys($values)) . ') ' .
'VALUES(:' . implode(', :', array_keys($values)) . ');');
$req->execute($values);
static::$lastInsertSuccess = $req->execute($values);
return static::lastInsertId();
}
return self::last_insert_id();
public static function isLastInsertSuccess() {
return static::$lastInsertSuccess;
}
public static function update($query, $values = []) {
return self::$connection->prepare('UPDATE ' . $query)->execute($values);
static::$nbQueries++;
return static::$connection->prepare('update ' . $query)->execute($values);
}
public static function delete($query, $values = []) {
return self::$connection->prepare('DELETE FROM ' . $query)->execute($values);
static::$nbQueries++;
return static::$connection->prepare('delete from ' . $query)->execute($values);
}
public static function select($query, $values = []) {
return new DBStatement($query, $values, self::$connection);
return new DBStatement($query, $values, static::$connection);
}
public static function query($query) {
return self::$connection->prepare($query);
static::$nbQueries++;
return static::$connection->prepare($query);
}
public static function last_insert_id($name = NULL) {
return self::$connection->lastInsertId($name);
public static function lastInsertId($name = null) {
return static::$connection->lastInsertId($name);
}
public static function begin() {
return self::$connection->beginTransaction();
return static::$connection->beginTransaction();
}
public static function send() {
return self::$connection->commit();
return static::$connection->commit();
}
public static function back() {
return self::$connection->rollBack();
return static::$connection->rollBack();
}
}
class DBStatement {
private $query;
private $values;
private $connection;
protected $query;
protected $values;
protected $connection;
public function __construct($query, $values, $connection) {
$this->query = $query;
......@@ -84,10 +100,16 @@ class DBStatement {
return $this->select()->fetchAll(($obj) ? \PDO::FETCH_CLASS : \PDO::FETCH_ASSOC);
}
private function select() {
protected function select() {
DB::$nbQueries++;
$return = $this->connection->prepare('SELECT ' . $this->query);
$return->execute($this->values);
//echo '<pre>';
//var_dump('SELECT ' . $this->query);
//echo '</pre>';
return $return;
}
......
......@@ -3,7 +3,7 @@
/* Gestion des sujets
--------------------- */
class Mail {
public static function one_topic($slug_topic, $user = null) {
public static function oneTopic($slug_topic, $user = null) {
$fields = [
'slug' => $slug_topic
];
......@@ -12,12 +12,11 @@ class Mail {
$fields['id_user'] = $user->id;
$topic = DB::select('
ft.id, ft.title, ft.slug, ft.pinned, ft.locked, ft.archived
ft.id, ft.title, ft.slug
from mail_topic ft
inner join mail_participant fp on fp.id_topic = ft.id
where ft.slug = :slug
' . ($user ? 'and fp.id_user = :id_user' : '') . '
and archived = 0;
' . ($user ? 'and fp.id_user = :id_user' : '') . ';
', $fields)->one();
if ($topic)
......@@ -26,39 +25,35 @@ class Mail {
return $topic;
}
public static function nb_topics($user) {
public static function nbTopics($user) {
$fields = [];
if ($user)
$fields['id_user'] = $user->id;
return DB::select('
ft.id, ft.title, ft.slug, ft.pinned, ft.locked, ft.archived,
ui.username author_begin, fm.date_message date_begin,
lui.username author_last, lfm.date_message date_last,
ft.id, ft.title, ft.slug,
ui.username author_begin, fm.date_add date_begin,
lui.username author_last, lfm.date_add date_last,
sqrt(count(*)) nb_messages
from mail_topic ft
inner join mail_message fm on fm.id_topic = ft.id
inner join user_info ui on ui.id = fm.id_author
inner join (select * from mail_message order by date_message desc) lfm on lfm.id_topic = ft.id
inner join (select * from mail_message order by date_add desc) lfm on lfm.id_topic = ft.id
inner join user_info lui on lui.id = lfm.id_author
inner join mail_participant fp on fp.id_topic = ft.id
where archived = 0
' . ($user ? 'and fp.id_user = :id_user' : '') . '
' . ($user ? 'where fp.id_user = :id_user' : '') . '
group by ft.id
order by pinned desc, date_last desc;
order by date_last desc;
', $fields)->count();
}
public static function list_topics($user = null, $p = null) {
/**
* @param null $user
* @param null $p
* @return mixed
*/
public static function listTopics($user = null, $p = null) {
if ($p != null) {
$begin = ($p->actual - 1) * $p->nb_by_page;
$size = $p->nb_by_page;
......@@ -68,105 +63,100 @@ class Mail {
}
return DB::select('
ft.id, ft.title, ft.slug, ft.pinned, ft.locked, ft.archived,
ui.username author_begin, fm.date_message date_begin,
lui.username author_last, lfm.date_message date_last,
sqrt(count(*)) nb_messages,
ft.id, ft.title, ft.slug,
ui.username author_begin, fm.date_add date_begin,
lui.username author_last, lfm.date_add date_last,
count(cfm.id) nb_messages,
fr.date_last_read, fr.participate, fr.creator
from mail_topic ft
inner join mail_message fm on fm.id_topic = ft.id
inner join (
select fm.* from (
select fm.id_topic, fm.id_author, fm.date_add
from mail_message fm
order by fm.date_add asc
) fm
group by fm.id_topic
) fm on fm.id_topic = ft.id
inner join (
select fm.* from (
select fm.id_topic, fm.id_author, fm.date_add
from mail_message fm
order by fm.date_add desc
) fm
group by fm.id_topic
) lfm on lfm.id_topic = ft.id
inner join mail_message cfm on cfm.id_topic = ft.id
inner join user_info ui on ui.id = fm.id_author
inner join (select * from mail_message fm2 order by fm2.date_message desc) lfm on lfm.id_topic = ft.id
inner join user_info lui on lui.id = lfm.id_author
inner join mail_participant fp on fp.id_topic = ft.id
left join mail_read fr on fr.id_topic = ft.id and fr.id_user = :id_user
where archived = 0
' . ($user ? 'and fp.id_user = :id_user' : '') . '
where (
select id
from user_info lui
where lui.id = :id_user
and (lui.permissions & :flag_admin) = :flag_admin
) is not null
and fp.id_user = :id_user
group by ft.id
order by pinned desc, date_last desc
order by date_last desc
limit ' . $begin . ', ' . $size . ';
', [
'id_user' => $user->id
'id_user' => $user->id,
'flag_admin' => P::ADMINISTRATOR
])->all();
}
public static function add_topic($user, $data) {
public static function addTopic($user, $data) {
DB::begin();
$slug_topic = self::gen_slug($data['title']);
$slugTopic = static::genSlug($data['title']);
$id_topic = DB::insert('mail_topic', [
'id_category' => 0,
'title' => $data['title'],
'slug' => $slug_topic,
'pinned' => (int) false,
'locked' => (int) false
$idTopic = DB::insert('mail_topic', [
'title' => $data['title'],
'slug' => $slugTopic
]);
$id_message = DB::insert('mail_message', [
'id_topic' => $id_topic,
'id_author' => $user->id,
'content' => $data['content'],
'date_message' => time()
$idMessage = DB::insert('mail_message', [
'id_topic' => $idTopic,
'id_author' => $user->id,
'content' => $data['content'],
'date_add' => time()
]);
$id_read = DB::insert('mail_read', [
'id_topic' => $id_topic,
$idRead = DB::insert('mail_read', [
'id_topic' => $idTopic,
'id_user' => $user->id,
'date_last_read' => time(),
'participate' => (int) true,
'creator' => (int) true
]);
$id_participants = [];
$idParticipants = [];
foreach ($data['participants'] as $participant) {
array_push($id_participants, DB::insert('mail_participant', [
'id_topic' => $id_topic,
array_push($idParticipants, DB::insert('mail_participant', [
'id_topic' => $idTopic,
'id_user' => $participant->id,
'deleted' => (int) false
]));
}
if ($id_topic && $id_message && $id_read == '0' &&
array_map(function($val) { return $val; }, $id_participants) && DB::send())
return $slug_topic;
$success = (bool) $idTopic;
$success &= (bool) $idMessage;
$success &= (bool) $idRead;
$success &= count($idParticipants) == count($data['participants']);
if ($success && DB::send())
return $slugTopic;
else
return '';
}
public static function lock_topic($topic, $user) {
return DB::update('
mail_topic
set locked = 1 - locked
where slug = :slug
', [
'slug' => $topic->slug
]);
}
public static function remove_topic($topic, $user) {
public static function removeTopic($topic, $user) {
return false;
}
public static function nb_messages_topic($topic) {
public static function nbMessagesTopic($topic) {
return DB::select('
fm.*, ui.username
from mail_message fm
......@@ -178,13 +168,9 @@ class Mail {
])->count();
}
/* Récupérer les messages d'un sujet
------------------------------------ */
public static function list_messages_topic($topic, $p) {
public static function listMessagesTopic($topic, $p) {
$begin = ($p->actual - 1) * $p->nb_by_page;
$size = $p->nb_by_page;
......@@ -201,20 +187,16 @@ class Mail {
])->all();
}
/* Ajouter une réponse à un sujet
--------------------------------- */
public static function add_reply($topic, $user, $data) {
public static function addReply($topic, $user, $data) {
DB::begin();
$insert_reply = DB::insert('mail_message', [
'id_topic' => $topic->id,
'id_author' => $user->id,
'content' => $data['content'],
'date_message' => time()
'id_topic' => $topic->id,
'id_author' => $user->id,
'content' => $data['content'],
'date_add' => time()
]);
$update_participate = DB::update('
......@@ -234,13 +216,9 @@ class Mail {
return false;
}
public static function one_message($message_id, $user) {
public static function oneMessage($message_id, $user) {
$message = DB::select('
fm.id, fm.id_topic, fm.id_author, fm.content, fm.date_message,
fm.id, fm.id_topic, fm.id_author, fm.content, fm.date_add,
ft.slug
from mail_message fm
inner join mail_topic ft on ft.id = fm.id_topic
......@@ -255,11 +233,7 @@ class Mail {
return false;
}
public static function participants_topic($topic) {
public static function participantsTopic($topic) {
return DB::select('
ui.username
from mail_participant fp
......@@ -269,14 +243,10 @@ class Mail {
'id_topic' => $topic->id
])->all();
}
/* Génère un slug pour les sujets
--------------------------------- */
public static function gen_slug($title) {
return Format::gen_slug_table($title, __CLASS__ . '::one_topic');
public static function genSlug($title) {
return Format::genSlugTable($title, __CLASS__ . '::oneTopic');
}
}
......@@ -11,43 +11,32 @@ class Notif {
$date = time();
$notif = new NotifInfo();
$notif->numType = $type;
$notif->idRef = $id_ref;
$notif->message = $message;
$notif->dateNotif = $date;
$notif->numType = $type;
$notif->idRef = $id_ref;
$notif->message = $message;
$notif->dateAdd = $date;
$notif->save();
return $notif;
}
public static function get_all_notifs($user) {
return self::get_notifs($user)->all();
public static function getAllNotifs($user) {
return static::getNotifs($user)->all();
}
public static function get_nb_notifs($user) {
return self::get_notifs($user)->count();
public static function getNbNotifs($user) {
return static::getNotifs($user)->count();
}
private static function get_notifs($user) {
return DB::select('ft.id, ft.title, ft.slug
protected static function getNotifs($user) {
return DB::select('
ft.id, ft.title, ft.slug, ni.id_ref
from notif_info ni
inner join forum_message fm on fm.id = ni.id_ref
inner join forum_topic ft on ft.id = fm.id_topic
where fm.id_author <> :id_user
order by ni.date_notif desc;
order by ni.date_add desc;
', [
'id_user' => $user->id
]);
......
<?php
class Tuto {
/// Permissions
const CAN_CHANGE_INFORMATIONS = 1; // peut changer l'avancement et les étiquettes
const CAN_CHANGE_VISIBILITY = 2; // peut changer la visibilité du tutoriel
const CAN_MANAGE_CONTRIBUTORS = 4; // peut inviter, supprimer et changer les permessions des contributeurs
const IS_CREATOR = 8; // peut changer le titre du tutoriel et le supprimer
/// Visibilité
const VISIBILITY_CLOSED = 0; // accessible seulement aux contributeurs
const VISIBILITY_SHARED = 1; // accessible par le lien partagé (introuvable sinon)
const VISIBILITY_BETA = 2; // bêta : classé dans une catégorie spécifique
const VISIBILITY_PUBLIC = 3; // totalement public, visible par tous
public static function listTutos() {
return DB::select('
ti.id, ti.title, ti.slug, ti.progression, ti.visibility, ti.date_add,
ti.date_upd, ti.content, tc.permissions, ui.username
from tutorial_info ti
inner join tutorial_contributor tc on tc.id_tutorial = ti.id
inner join user_info ui on ui.id = tc.id_user
where visibility = :visibility
group by ti.id
order by date_upd desc;
', [
'visibility' => Tuto::VISIBILITY_PUBLIC
])->all();
}
public static function userTutos($user) {
return DB::select('
ti.id, ti.title, ti.slug, ti.progression, ti.visibility, ti.date_add,
ti.date_upd, ti.content, tc.permissions, ui.username
from tutorial_info ti
inner join tutorial_contributor tc on tc.id_tutorial = ti.id
inner join user_info ui on ui.id = tc.id_user
where ui.id = :id_user
order by date_upd desc;
', [
'id_user' => $user->id
])->all();
}
public static function addTuto($user, $data) {
Db::begin();
$slugTuto = static::genSlug($data['title']);
$date = time();
$tuto = new TutorialInfo();
$tuto->title = $data['title'];
$tuto->slug = $slugTuto;
$tuto->progression = 0;
$tuto->visibility = static::VISIBILITY_CLOSED;
$tuto->dateAdd = $date;
$tuto->dateUpd = $date;
$tuto->content = '';
$tuto->tags = '';
$tuto->save();
$author = new TutorialContributor();
$author->idTutorial = $tuto->id;
$author->idUser = $user->id;
$author->permissions = static::creator();
$author->save();
$success = (bool) $tuto->id;
$success &= (bool) $author->idTutorial;
$success &= (bool) $author->idUser;
if ($success && Db::send())
return $slugTuto;
else
return '';
}
public static function creator() {
return
static::CAN_CHANGE_INFORMATIONS |
static::CAN_CHANGE_VISIBILITY |
static::CAN_MANAGE_CONTRIBUTORS |
static::IS_CREATOR;
}
public static function remove($tuto) {
return DB::delete('
tutorial_info
where id = :id;
', [
'id' => $tuto->id
]);
}
public static function toStr($name) {
switch ($name) {
case 'VISIBILITY_CLOSED':
case static::VISIBILITY_CLOSED:
return 'Fermée';
break;
case 'VISIBILITY_SHARED':
case static::VISIBILITY_SHARED:
return 'Partagée';
break;
case 'VISIBILITY_BETA':
case static::VISIBILITY_BETA:
return 'Bêta';
break;
case 'VISIBILITY_PUBLIC':
case static::VISIBILITY_PUBLIC:
return 'Publique';
break;
default:
return '-';
}
}
/// Génère un slug pour les sujets
public static function genSlug($title) {
return Format::genSlugTable($title, function($slug) {
return isset(TutorialInfo::getBySlug($slug)->id);
});
}
}
<?php
class User {
public static function cleanUsername($username) {
return preg_replace('/[^a-zA-Z0-9_-]/', '', $username);
}
public static function listUsers() {
$users = DB::select('
id, username, passwd, signature, site, permissions, chat_heartbeat,
date_register, date_last_activity, deleted
from user_info
where deleted = 0
order by username;
')->all();
$usersArray = [];
foreach ($users as $user) {
$an_user = new UserInfo();
foreach ($user as $key => $value)
$an_user->{$key} = $value;
array_push($usersArray, $an_user);
}
return $usersArray;
}
}
<?php
class UserInfo extends Model {
public $id = 0;
public $username = '';
public $passwd = '';
public $signature = '';
public $site = '';
public $permissions = 0;
public $chatHeartbeat = 0;
public $dateRegister = 0;
public $dateLastActivity = 0;
public $notes = '';
public $deleted = false;
public $sid = '';
public $token = '';
protected $_banned;
/** @return static */
public static function getByUsername($username) {
$self = new static();
$self->_isNew = false;