Merge remote-tracking branch 'origin/master'

This commit is contained in:
Unknown 2018-03-06 10:55:23 +01:00
commit c4c891f33f
23 changed files with 615 additions and 21 deletions

View File

@ -106,7 +106,7 @@
break;
case 'alphanumeric':
return $checker && is_string($value) && preg_match('/^[\w\.-]+$/ui', $value);
return $checker && is_string($value) && preg_match('/^[\w\. -]+$/ui', $value);
break;
case 'letters':
@ -124,7 +124,8 @@
// Boolean
case 'boolean':
return $checker && ( is_bool($value) || $value === 'false' || $value === 'true' );
case 'bool':
return $checker && is_bool($value);
break;
// Objet non vide
@ -138,7 +139,7 @@
break;
case 'numeric':
return $checker && (is_numeric($value) || $value == null || $value == 'null');
return $checker && (is_numeric($value) || $value == null);
break;
case "float":

View File

@ -0,0 +1,109 @@
<?php
/**
* Created by PhpStorm.
* User: lucas
* Date: 27/02/18
* Time: 16:19
*/
namespace api\module\professor;
use database\core\Repo;
use database\repo\formation;
use database\repo\ue;
use error\core\Error;
use error\core\Err;
class filterController{
/* (1) Get professor ID(s) matching a specific filter
*
* @formations<array> [OPT] Array of formation IDS
* @ues<array> [OPT] Array of UE codes
*
* @return matches<array> Array of matching professor IDs
*
---------------------------------------------------------*/
public static function post($args){
$formations = null;
$ues = null;
extract($args);
/** @var ue $ue_repo */
$ue_repo = Repo::getRepo('ue');
/* (1) If no filter -> return error
---------------------------------------------------------*/
/* (1) Exit if no filter */
if( is_null($formations) && is_null($ues) )
return ['error' => new Error(Err::MissingParam, 'You must give at least 1 parameter')];
/* (2) Init. result array (only keys used for unicity) */
$matches_uniq = [];
/* (2) Filter by formation
---------------------------------------------------------*/
if( !is_null($formations) ){
/** @var formation $form_repo */
$form_repo = Repo::getRepo('formation');
/* (1) For each formation -> get request */
foreach($formations as $form_id){
// 1. Ignore if wrong format
if( !is_numeric($form_id) || intval($form_id) !== $form_id )
continue;
// 2. Get from repo
$fetched_ids = $form_repo->getProfessors($form_id);
// 3. Add in unique set
foreach($fetched_ids as $prof_id)
$matches_uniq[ intval($prof_id) ] = null;
}
}
/* (3) Filter by ue
---------------------------------------------------------*/
if( !is_null($ues) ){
/** @var ue $ue_repo */
$ue_repo = Repo::getRepo('ue');
/* (1) For each ue -> get request */
foreach($ues as $ue_code){
// 1. Ignore if wrong format
if( !is_string($ue_code) || strlen($ue_code) < 1 )
continue;
// 2. Get from repo
$fetched_ids = $ue_repo->getProfessors($ue_code);
// 3. Add in unique set
foreach($fetched_ids as $prof_id)
$matches_uniq[ intval($prof_id) ] = null;
}
}
return ['matches' => array_keys($matches_uniq)];
}
}

View File

@ -25,7 +25,7 @@ class professorController{
---------------------------------------------------------*/
public static function get($args){
$prof_id = null;
$with_vh = '';
$with_vh = 0;
extract($args);
/* Get the professor repo */
@ -35,8 +35,7 @@ class professorController{
/* (1) If with VH data
---------------------------------------------------------*/
if( $with_vh == 1 ){
if( is_int($with_vh) && $with_vh === 1 ){
/* (1) Get All professors or 1 by its id (if set) */
$fetched = $prof_repo->getWithVH($prof_id);

View File

@ -10,7 +10,7 @@
/* Generates the API documentation
*
*/
public function get($args){
public function post($args){
extract($args);
return [ 'args' => $args ];

View File

@ -188,4 +188,44 @@ class ue extends Repo_i {
return $fetched;
}
/* (7) Gets all professors who teaches a UE by code
*
* @code<String> The UE code
*
* @return professors<array> The professors' UID matching the @code of the UE
*
---------------------------------------------------------*/
public function getProfessors(String $code) : array{
/* (1) Prepare statement */
$st = $this->pdo->prepare("SELECT p.idProfesseur
FROM Professeur p, UE u
WHERE (
p.idProfesseur IN ( SELECT p_cr.idProfesseur FROM Professeur p_cr, Cours c WHERE c.Professeur_idProfesseur = p_cr.idProfesseur AND c.UE_code = u.code )
OR p.idProfesseur IN ( SELECT p_td.idProfesseur FROM Professeur p_td, TD t WHERE t.Professeur_idProfesseur = p_td.idProfesseur AND t.UE_code = u.code )
OR p.idProfesseur IN ( SELECT p_tp.idProfesseur FROM Professeur p_tp, TP t WHERE t.Professeur_idProfesseur = p_tp.idProfesseur AND t.UE_code = u.code )
)
AND u.code = :ue_code;");
/* (2) Bind params and execute statement */
if( is_bool($st) ) return [];
$success = $st->execute([ ':ue_code' => $code ]);
/* (3) Manage error */
if( !$success )
return [];
/* (4) Get data */
$fetched = $st->fetchAll();
/* (5) Return [] on no result */
if( $fetched === false )
return [];
/* (6) Return data */
return $fetched;
}
}

View File

@ -1,9 +1,21 @@
{
"GET": {
"POST": {
"des": "Returns the API documentation",
"per": [],
"par": {
"URL0": { "des": "Method name", "typ": "varchar(1,30)", "ren": "method_name", "opt": true, "def": null }
"URL0": { "des": "Method name", "typ": "varchar(1,30)", "ren": "method_name", "opt": true, "def": null },
"mixed": { "des": "mixed type", "typ": "mixed", "opt": true },
"id": { "des": "id type", "typ": "id", "opt": true },
"text": { "des": "text type", "typ": "text", "opt": true },
"mail": { "des": "mail type", "typ": "mail", "opt": true },
"alphanumeric": { "des": "alphanumeric type", "typ": "alphanumeric", "opt": true },
"letters": { "des": "letters type", "typ": "letters", "opt": true },
"array": { "des": "array type", "typ": "array", "opt": true },
"array_id": { "des": "array<id> type", "typ": "array<id>", "opt": true },
"boolean": { "des": "boolean type", "typ": "boolean", "opt": true },
"object": { "des": "object type", "typ": "object", "opt": true },
"numeric": { "des": "numeric type", "typ": "numeric", "opt": true },
"float": { "des": "float type", "typ": "float", "opt": true }
}
},

View File

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=0.4">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Gestion des enseignants</title>
<!-- Icon -->
<link rel='shortcut icon' href='/favicon.ico'>
<!-- CSS dependencies -->
<link href="https://fonts.googleapis.com/css?family=Fira+Sans" rel="stylesheet">
<link rel='stylesheet' type='text/css' href='/css/font-loader.css'>
<link rel='stylesheet' type='text/css' href='/css/global.css'>
<link rel='stylesheet' type='text/css' href='/css/pop-up.css'>
<link rel='stylesheet' type='text/css' href='/css/layout.css'>
<link rel='stylesheet' type='text/css' href='/css/menu.css'>
<link rel='stylesheet' type='text/css' href='/css/header.css'>
<link rel='stylesheet' type='text/css' href='/css/container.css'>
<!-- JS dependencies -->
<script type='text/javascript' src='/js/_SERVER.js'></script>
</head>
<body>
<div id='main-vue'></div>
<!-- POPUP WINDOW -->
<div id='POPUP'>
<div class='header'></div>
<div class='body'></div>
<div class='footer'></div>
</div>
<div id='POPUP-BG'></div>
<!-- Main loop -->
<script type='text/javascript' src='/js/bundle@fiche.js'></script>
</body>
</html>

View File

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=0.4">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Gestion des enseignants</title>
<!-- Icon -->
<link rel='shortcut icon' href='/favicon.ico'>
<!-- CSS dependencies -->
<link href="https://fonts.googleapis.com/css?family=Fira+Sans" rel="stylesheet">
<link rel='stylesheet' type='text/css' href='/css/font-loader.css'>
<link rel='stylesheet' type='text/css' href='/css/global.css'>
<link rel='stylesheet' type='text/css' href='/css/pop-up.css'>
<link rel='stylesheet' type='text/css' href='/css/layout.css'>
<link rel='stylesheet' type='text/css' href='/css/menu.css'>
<link rel='stylesheet' type='text/css' href='/css/header.css'>
<link rel='stylesheet' type='text/css' href='/css/container.css'>
<!-- JS dependencies -->
<script type='text/javascript' src='/js/_SERVER.js'></script>
</head>
<body>
<div id='main-vue'></div>
<!-- POPUP WINDOW -->
<div id='POPUP'>
<div class='header'></div>
<div class='body'></div>
<div class='footer'></div>
</div>
<div id='POPUP-BG'></div>
<!-- Main loop -->
<script type='text/javascript' src='/js/bundle@settings.js'></script>
</body>
</html>

48
public_html/page/ue.php Normal file
View File

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=0.4">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Gestion des enseignants</title>
<!-- Icon -->
<link rel='shortcut icon' href='/favicon.ico'>
<!-- CSS dependencies -->
<link href="https://fonts.googleapis.com/css?family=Fira+Sans" rel="stylesheet">
<link rel='stylesheet' type='text/css' href='/css/font-loader.css'>
<link rel='stylesheet' type='text/css' href='/css/global.css'>
<link rel='stylesheet' type='text/css' href='/css/pop-up.css'>
<link rel='stylesheet' type='text/css' href='/css/layout.css'>
<link rel='stylesheet' type='text/css' href='/css/menu.css'>
<link rel='stylesheet' type='text/css' href='/css/header.css'>
<link rel='stylesheet' type='text/css' href='/css/container.css'>
<!-- JS dependencies -->
<script type='text/javascript' src='/js/_SERVER.js'></script>
</head>
<body>
<div id='main-vue'></div>
<!-- POPUP WINDOW -->
<div id='POPUP'>
<div class='header'></div>
<div class='body'></div>
<div class='footer'></div>
</div>
<div id='POPUP-BG'></div>
<!-- Main loop -->
<script type='text/javascript' src='/js/bundle@ue.js'></script>
</body>
</html>

View File

@ -1,5 +1,5 @@
var path = require('path')
var webpack = require('webpack')
var path = require('path');
var webpack = require('webpack');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
@ -60,6 +60,42 @@ module.exports = [ {
module: mod_common,
devtool: (process.env.NODE_ENV==='development') ? '#eval-source-map' : false
}, {
name: "ue",
entry: './webpack/page/ue.js',
output: {
path: path.resolve(__dirname, './public_html/js/bundle'),
publicPath: '/js/bundle/',
filename: 'ue@0.js'
},
module: mod_common,
devtool: (process.env.NODE_ENV==='development') ? '#eval-source-map' : false
}, {
name: "fiche",
entry: './webpack/page/fiche.js',
output: {
path: path.resolve(__dirname, './public_html/js/bundle'),
publicPath: '/js/bundle/',
filename: 'fiche@0.js'
},
module: mod_common,
devtool: (process.env.NODE_ENV==='development') ? '#eval-source-map' : false
}, {
name: "settings",
entry: './webpack/page/settings.js',
output: {
path: path.resolve(__dirname, './public_html/js/bundle'),
publicPath: '/js/bundle/',
filename: 'settings@0.js'
},
module: mod_common,
devtool: (process.env.NODE_ENV==='development') ? '#eval-source-map' : false
}, {
name: "login",

View File

@ -0,0 +1,23 @@
<template>
<div id='CONTAINER'>
<h1>Ici c'est la page Fiches</h1>
</div>
</template>
<script>
export default {
name: 'CONTAINER_VIEW',
data(){
return { gstore: gstore.get }
}
}
</script>

View File

@ -0,0 +1,23 @@
<template>
<div id='CONTAINER'>
<h1>Ici c'est la page Adiministration</h1>
</div>
</template>
<script>
export default {
name: 'CONTAINER_VIEW',
data(){
return { gstore: gstore.get }
}
}
</script>

View File

@ -0,0 +1,53 @@
<template>
<div id='CONTAINER' class='card' style="top: 0; height: 100%">
<div class="card container" style="width: 100%">
<section v-if='gstore.ues.length <= 0'>Aucun enseignant trouvé</section>
<section v-for='ue in gstore.ues' :data-id='ue.code'>
<span class='category'>{{ ue.code }}</span>
<h1>{{ ue.label }}</h1>
<div class='table'>
<div>
<span>{{ue.volumeCours}}</span>
<span>heures de cours</span>
</div>
<div>
<span>{{ue.volumeTD}}</span>
<span>heures de TD</span>
</div>
<div>
<span>{{ue.volumeTP}}</span>
<span>heures de TP</span>
</div>
</div>
<div class='sub'><strong>ZOU</strong> équivalents TD</div>
<div class='footer'>
<span :class="(ue.volumeCours == 0) ? 'course' : 'course active'">{{ ue.volumeCours }}</span><hr>
<span :class="(ue.volumeTD == 0) ? 'td' : 'td active'">{{ ue.volumeTD }}</span><hr>
<span :class="(ue.volumeTP == 0) ? 'tp' : 'tp active'">{{ ue.volumeTP }}</span>
</div>
</section>
</div>
</div>
</template>
<script>
export default {
name: 'CONTAINER_VIEW',
data(){
return { gstore: gstore.get }
}
}
</script>s

0
webpack/data/fiche.js Normal file
View File

0
webpack/data/settings.js Normal file
View File

View File

@ -69,7 +69,7 @@ gstore.add('filter_handler', function(){
element.remClass('filter-hidden');
// 3.2. Only hide if does not match filter
if( rs.professors.indexOf(local_ptr[e].idProfesseur) <= -1 )
if( rs.matches.indexOf(local_ptr[e].idProfesseur) <= -1 )
element.addClass('filter-hidden');
}

16
webpack/data/ue.js Normal file
View File

@ -0,0 +1,16 @@
/* (1) Load UEs
---------------------------------------------------------*/
/* (1) Initialize list */
gstore.add('ues', []);
/* (2) Get UEs */
api.call('GET ue', { vh: true }, function(rs) {
// {1} If error -> abort //
if(rs.error !== 0)
return console.log('No UE found, error: ' + rs.error);
// {2} Store UEs //
console.log(rs);
gstore.get.ues = rs.ues;
});

35
webpack/page/fiche.js Normal file
View File

@ -0,0 +1,35 @@
/* (1) Imports
---------------------------------------------------------*/
/* (1) NPM libs */
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from '../routes/fiche'
/* (2) Vues */
import wrapper_vue from '../vue/wrapper.vue'
/* (3) Data */
require('../data/common');
require('../data/fiche');
/* (2) Initialisation
---------------------------------------------------------*/
/* (1) Init Router */
const router = new VueRouter({
mode: 'history',
routes: routes[0]
});
/* (2) Store router in gstore */
gstore.add('router', router);
/* (3) Render view */
Vue.use(VueRouter);
new Vue({
el: '#main-vue',
router,
render: h => h(wrapper_vue)
});

35
webpack/page/settings.js Normal file
View File

@ -0,0 +1,35 @@
/* (1) Imports
---------------------------------------------------------*/
/* (1) NPM libs */
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from '../routes/settings'
/* (2) Vues */
import wrapper_vue from '../vue/wrapper.vue'
/* (3) Data */
require('../data/common');
require('../data/settings');
/* (2) Initialisation
---------------------------------------------------------*/
/* (1) Init Router */
const router = new VueRouter({
mode: 'history',
routes: routes[0]
});
/* (2) Store router in gstore */
gstore.add('router', router);
/* (3) Render view */
Vue.use(VueRouter);
new Vue({
el: '#main-vue',
router,
render: h => h(wrapper_vue)
});

35
webpack/page/ue.js Normal file
View File

@ -0,0 +1,35 @@
/* (1) Imports
---------------------------------------------------------*/
/* (1) NPM libs */
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from '../routes/ue'
/* (2) Vues */
import wrapper_vue from '../vue/wrapper.vue'
/* (3) Data */
require('../data/common');
require('../data/ue');
/* (2) Initialisation
---------------------------------------------------------*/
/* (1) Init Router */
const router = new VueRouter({
mode: 'history',
routes: routes[0]
});
/* (2) Store router in gstore */
gstore.add('router', router);
/* (3) Render view */
Vue.use(VueRouter);
new Vue({
el: '#main-vue',
router,
render: h => h(wrapper_vue)
});

11
webpack/routes/fiche.js Normal file
View File

@ -0,0 +1,11 @@
export default{ 0: [
{
path: '/fiche/view/',
component: require('../component/fiche/view.vue').default
}, {
path: '*',
redirect: '/fiche/view/'
}
]}

View File

@ -0,0 +1,11 @@
export default{ 0: [
{
path: '/settings/view/',
component: require('../component/settings/view.vue').default
}, {
path: '*',
redirect: '/settings/view/'
}
]}

11
webpack/routes/ue.js Normal file
View File

@ -0,0 +1,11 @@
export default{ 0: [
{
path: '/ue/view/',
component: require('../component/ue/view.vue').default
}, {
path: '*',
redirect: '/ue/view/'
}
]}