<file_sep><?php

namespace App\Http\Controllers;

use Request;
use App\Tournament;
use App\Equipe;
use App\Match;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Input;

class PlanningController extends Controller
{

    /**
    *   Affichage du planning
    *
    *   paramètre : id du tournoi
    *   return : tournoi
    **/
    public function showPlanning($id)
    {
        $tournament = Tournament::with('equipes')->find($id);

        // Si c'est un tournoi à élimination direct
        if($tournament->typeTournoi == 1) 
        {
            $qualifiedTeam = $this->completeTable($tournament, $tournament->equipes->pluck('nom'));
            return view('Pages.treeTournament')->with('qualifiedTeam', $qualifiedTeam);
        }

        $groupes = $this->createGroups($tournament->equipes, $tournament);
        $games = $this->generateMatchs($groupes, $tournament);
        $newGames = array();
        
        foreach($games as $game)
        {
            $match = Match::firstOrCreate($game);
            $game['score1'] = $match->score1;
            $game['score2'] = $match->score2;
            array_push($newGames, $game);
        }
        
        return view('Pages.showPlanning')->with('games', $newGames)->with('tournament', $tournament);
    }

    /* Sauvegarde du résultat du match */
    public function saveGameData(Request $request)
    {
        if(Request::ajax())
        {
            $data = Input::all();

            unset($data['_token']);
            unset($data['score1']);
            unset($data['score2']);
            unset($data['heureMatchDebut']);
            unset($data['heureMatchFin']);

            $match = Match::firstOrNew($data);

            $match->fill(Input::all());
            $match->save();
        }
        return 'Score enregistré';
    }

    /* Création des groupes */
    private function createGroups($teams, $tournament)
    {
        // create an array of teams
        $members = array();
        $i = 0;
        foreach ($teams as $team) {
            $members[$i] =  $team['nom'];
            $i++;
        }

        // Split our array of team on a array of groupes of teams
        $groupes = array_chunk($members, ceil($tournament->nbEquipe / $tournament->nbGroupe));

        return $groupes;
    }

    /* Génération des matchs à jouer */
    private function generateMatchs($groupes, $tournament)
    {
        $nbOfGroupes = count($groupes);
        $matchs = array();
        $table = array();

        /* Add a fictive team for having a even number of team */
        if($tournament->nbEquipe % 2 != 0)
        {
            for($i=0; $i < $nbOfGroupes; $i++)
            {
                if (count($groupes[$i])%2 == 0)
                {
                    array_push($groupes[$i],"forfait");
                    break;
                }
            }
        }

        /* Count the number of matchs */
        $nbOfMatchs = 0;

        for($i=0; $i < $nbOfGroupes; $i++)
        {
            $nbOfMatchs += (count($groupes[$i]) * (count($groupes[$i]) - 1)) / 2;
        }

        /* Count the number of rounds */
        $nbOfRound = ceil($nbOfMatchs / $tournament->nbTerrain);

        $games = $this->createCombinaison($groupes);
        $hours = $this->generateHours($tournament, $nbOfRound);

        $indiceMatch = 0;
        $assocMatch = array();

        for($i=0; $i < $nbOfRound; $i++)
        {
            $hourEndNextGame = strtotime($hours[$i]) + (60 * $tournament->tempsMatch);
            $table[$i][0] = $hours[$i] . " - " . date("H:i", $hourEndNextGame);

            for($j = 0 ; $j < $tournament->nbTerrain; $j++)
            {
                if(in_array("forfait", $games[$indiceMatch]))
                {
                    $indiceMatch++;
                    if($indiceMatch >= count($games))
                    {
                        break 2;
                    }
                }

                $game = $games[$indiceMatch]; 

                array_push($assocMatch, array('equipe1' => $game[0], 'equipe2' => $game[1], 'tournament_id' => $tournament->id, 
                                              'groupe' => $game[2],
                                              'heureMatchDebut' => $hours[$i],
                                              'heureMatchFin' => date("H:i", $hourEndNextGame)));

                $indiceMatch++;
                if($indiceMatch >= count($games))
                {
                    break 2;
                }

            }
        }
        return $assocMatch;
    }

    /* Génération des heures de matchs */
    private function generateHours($tournament, $nbOfRound)
    {
        $hours = array();

        $hours[0] = $tournament->heureDebutTournoi;

        for($i=1; $i < $nbOfRound; $i++)
        {  
            $totalMinutes = 60 * ($tournament->tempsMatch + $tournament->tempsEntreMatch);
            $hourNextGame = strtotime($hours[$i-1]) + $totalMinutes;

            if($hourNextGame >= $tournament->pauseDebut && $hourNextGame < $tournament->pauseFin)
            {
                $hourNextGame = strtotime($tournament->pauseFin);
            }

            $hours[$i] = date("H:i", $hourNextGame);        
        }

        return $hours;
    }

    /* Trouver les combinaison possible pour les matchs de groupes */
    private function createCombinaison($groups)
    {
        if(count($groups) == 0)
            return;

        $sizeGroup = count($groups[0]);

        $arrayCombin = array();

        for($i = 0; $i < $sizeGroup; $i++)
        {
            for($j = 0; $j < $sizeGroup; $j++)
            {
                if($i != $j)
                {
                    if(!in_array($j . ';' . $i, $arrayCombin))
                        array_push($arrayCombin, $i . ';' . $j);
                }
            }
        }
        return $this->generateMatchsCalendar($groups, $arrayCombin);
    }

    /* Génération du calendrier des matchs */
    private function generateMatchsCalendar($groups, $arrayCombin)
    {
        $matchs = array();

        $newArrayCombin = $this->sortOrderGame($arrayCombin);
        
        foreach($newArrayCombin as $combin)
        {
            $c = explode(";", $combin);

            foreach ($groups as $group) 
            {
                $numGroupe = array_search($group, $groups) + 1;
                array_push($matchs, array($group[$c[0]], $group[$c[1]], $numGroupe));
            }
        }

        return $matchs;
    }

    /* Combinaison des matchs */
    private function sortOrderGame($arrayCombin)
    {
        $newArrayCombin = array();
        for($i = 0; $i < count($arrayCombin) / 2; $i++)
        {
            $lastIndice = count($arrayCombin) - $i - 1;

            array_push($newArrayCombin, $arrayCombin[$i]);

            if(isset($arrayCombin[$lastIndice]))
                array_push($newArrayCombin, $arrayCombin[$lastIndice]);
        }
        return $newArrayCombin;
    }

    private function completeTable($tournament, $equipes)
    {
        $arrayNbTeamQualif = array('0' => 32, '1' => 16, '2' => 8, '3' => 4, '4' => 2); // Type de final
        $nbEquipe = $arrayNbTeamQualif[$tournament->typeFinales];
        $nbEquipeActuel = count($equipes);
        $qualifiedTeam = array();

        foreach ($equipes as $equipe) 
        {
            array_push($qualifiedTeam, $equipe);
        }

        return $qualifiedTeam;
    }
}
<file_sep><?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateMatchTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('match', function(Blueprint $table)
        {
            $table->increments('id');
            $table->string('equipe1', 100);
            $table->string('equipe2', 100);
            $table->integer('score1');
            $table->integer('score2');
            $table->string('heureMatchDebut');
            $table->string('heureMatchFin');
            $table->integer('groupe');
            $table->integer('tournament_id')->unsigned();

            $table->foreign('tournament_id')
                  ->references('id')
                  ->on('tournament')
                  ->onDelete('cascade');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('match');
    }
}
<file_sep><?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTeamTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('team', function(Blueprint $table)
        {
            $table->increments('id');
            $table->string('nom', 100);
            $table->string('capitaine', 100);
            $table->string('ville', 100);
            $table->string('npa', 100);
            $table->string('adresse', 100);
            $table->string('email', 150);
            $table->string('telephone', 12);
            $table->integer('numGroupe');
            $table->integer('nbPoint');
            $table->integer('butFait');
            $table->integer('butSubi');
            $table->integer('tournament_id')->unsigned();

            $table->foreign('tournament_id')
                  ->references('id')
                  ->on('tournament')
                  ->onDelete('cascade');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('team');
    }
}
<file_sep><?php

namespace App;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;

class Tournament extends Model
{
    protected $table = 'tournament';

    protected $fillable = [
    		'nom',
            'lieu',
            'adresse',
            'nbEquipe',
            'nbTerrain',
            'nbGroupe',
            'tempsMatch',
            'tempsEntreMatch',
            'typeTournoi',
            'typeFinales',
            'date',
            'heureDebutTournoi',
            'pauseDebut',
            'pauseFin'
    ];

    /* Heure de début du tournoi */
    public function setDebutTournoi($date)
    {
        $this->attributes['heureDebutTournoi'] = Carbon::createFromFormat('H:i', $date);
    }

    /* Heure début pause de midi */
    public function setPauseDebut($date)
    {
    	$this->attributes['pauseDebut'] = Carbon::createFromFormat('H:i', $date);
    }

    /* Heure fin pause de midi */
    public function setPauseFin($date)
    {
    	$this->attributes['pauseFin'] = Carbon::createFromFormat('H:i', $date);
    }

    /* Liaison table équipe */
    public function equipes()
    {
    	return $this->hasMany('App\Equipe');
    }

    public function showAllTournament()
    {
        return Tournament::all();
    }
}
<file_sep><?php

namespace App\Http\Controllers;

use Request;
use App\Tournament;
use App\Equipe;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;

class PagesController extends Controller
{
    /**
    *   Affichage de la page d'accueil
    **/
    public function index()
    {
    	return view('Pages.index');
    }

    /**
    *   Affichage formulaire de création de tournoi
    *
    *   return : nom du tournoi
    **/
    public function showForm()
    {
    	$nom = Request::get('nom');

        return redirect('createTournament')->with('nom', $nom);
    }

    /**
    *   Affichage de tous les tournois
    *
    *   return : tous les tournois
    **/
    public function showListAllTournament()
    {
        $tournaments = Tournament::all();
        return view('Pages.listAllTournament')->with('tournaments', $tournaments);
    }


    /**
    *   Affichage du tournoi à modifier
    *
    *   paramètre : id tu tournoi
    *   return : tournoi
    **/
    public function showActualTournament($id)
    {
        $tournament = Tournament::find($id);
        return view('Pages.manageTournament')->with('tournament', $tournament);
    }


    /**
    *   Affichage des équipes du tournoi
    *
    *   paramètre : id du tournoi
    *   return : toutes les équipes du tournoi et l'id du tournoi
    **/
    public function showListAllTeams($id)
    {
        $tournament = Tournament::with('equipes')->find($id);
        return view('Pages.listAllTeams')->with('equipes', $tournament->equipes)->with('tournamentId', $id);
    }


    /**
    *   Affichage de l'arbre du tournoi
    *
    *   paramètre : id du tournoi
    *   return : les équipes et id tournoi
    **/
    public function showTreeTournament($id)
    {
        $tournament = Tournament::with('equipes')->find($id);
        return view('Pages.treeTournament')->with('equipes', $tournament->equipes)->with('tournamentId', $id);
    }
}
<file_sep><?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTournamentTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tournament', function(Blueprint $table)
        {
            $table->increments('id');
            $table->string('nom', 100);
            $table->string('lieu', 100);
            $table->string('adresse', 100);
            $table->integer('nbEquipe');
            $table->integer('nbTerrain');
            $table->integer('nbGroupe');
            $table->integer('tempsMatch');
            $table->integer('tempsEntreMatch');
            $table->integer('typeTournoi');
            $table->integer('typeFinales');
            $table->date('date');
            $table->string('heureDebutTournoi');
            $table->string('pauseDebut');
            $table->string('pauseFin');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('tournament');
    }
}
<file_sep><?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Tournament;
use App\Equipe;
use App\Http\Requests\TournamentRequest;
use Validator;
use Input;

class CreateTournamentController extends Controller
{
    
    /* Affichage formulaire création de tournoi */
    public function getTournament(Request $request)
    {
        $titleTournament = session('nom');
        $data = array(
                'nom' => $titleTournament,
                'lieu' => "",
                'adresse' => "",
                'date' =>  date('Y-m-d'),
                'nbEquipe' => 2,
                'typeTournoi' => 0,
                'typeFinales' => 0,
                'nbGroupe' => 2,
                'nbTerrain' => 1,
                'tempsMatch' => 1,
                'tempsEntreMatch' => 1,
                'heureDebutTournoi' => "",
                'pauseDebut' => "",
                'pauseFin' => ""
            );
        if($titleTournament == "") return redirect('/');
        return view('Pages.formCreateTournament')->with($data);
    }

    /* Ajout ou update du tournoi */
    public function postTournament(Request $request)
    {
        $input = $request->all();

        if(isset($input['id']))
        {
            $tournoi = Tournament::find($input['id']);
            $tournoi->fill($input);
            $tournoi->save();
            return redirect('listAllTournaments');
        }

       $validator = Validator::make($request->all(), [
            'nom' => 'required',
            'lieu' => 'required',
            'adresse' => 'required',
            'nbEquipe' => 'required',
            'nbTerrain' => 'required',
            'nbGroupe' => 'required',
            'heureDebutTournoi' => 'required|date_format:H:i',
            'tempsMatch' => 'required',
            'tempsEntreMatch' => 'required',
            'typeTournoi' => 'required',
            'date' => 'required|date',
            'pauseDebut' => 'required|date_format:H:i|after:heureDebutTournoi',
            'pauseFin' => 'required|date_format:H:i|after:pauseDebut'
        ]);       

        if ($validator->fails()) 
        {
            return view('Pages.formCreateTournament')->withErrors($validator)->withInput(Input::all());
        }

        $tournament = Tournament::create($input);
        $equipe = new Equipe;
        foreach ($input['equipe'] as $value) 
        {
            Equipe::updateEquipe($value, $tournament->id);
        }

        $page = 'manageTournament/'.$tournament->id;
        return redirect($page)->with('tournament', $tournament);
    }

    /* Affichage information tournoi pour la modification */
    public function updateTournament($id)
    {
        return view('Pages.formCreateTournament')->with(Tournament::find($id)->toArray());
    }

    /* Suppression tournoi */
    public function deleteTournament($id)
    {
        $tournament = Tournament::find($id);
        $tournament->delete();
        return redirect('/listAllTournaments');
    }
}
<file_sep><?php

/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/

Route::get('/', 'PagesController@index');
Route::post('/', 'PagesController@showForm');

Route::get('/createTournament', 'CreateTournamentController@getTournament');
Route::post('/createTournament', 'CreateTournamentController@postTournament');

Route::get('/updateTournament/{n}', 'CreateTournamentController@updateTournament');
Route::get('/deleteTournament/{n}', 'CreateTournamentController@deleteTournament');

Route::get('/manageTournament/{n}', 'PagesController@showActualTournament');

Route::get('/treeTournament/{n}', 'TreeTournamentController@showTreeTournament');

Route::get('/listAllTournaments', 'PagesController@showListAllTournament');
Route::get('/createGroup/{n}', 'PagesController@creationGroupsTournament');

Route::get('/listAllTeams/{n}', 'PagesController@showListAllTeams');

Route::get('/createTeam/{n}', 'CreateTeamController@createTeam');
Route::post('/createTeam', 'CreateTeamController@postTeam');

Route::get('/updateTeam/{n}', 'CreateTeamController@getTeam');
Route::post('/updateTeam', 'CreateTeamController@postTeam');
Route::get('/deleteTeam/{n}', 'CreateTeamController@deleteTeam');

Route::get('/showPlanning/{n}', 'PlanningController@showPlanning');
Route::post('/saveScoreTeam', 'PlanningController@saveGameData');<file_sep><?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Tournament;
use App\Equipe;
use App\Http\Requests\TournamentRequest;
use Validator;
use Input;

class CreateTeamController extends Controller
{
    /* Formulaire de création d'équipe */
    public function getTeam($id)
    {
        return view('Pages.formCreateTeam')->with(Equipe::find($id)->toArray());
    }

    /* Création ou update de l'équipe */
    public function postTeam(Request $request)
    {
        $input = $request->all();

        if(isset($input['id']))
        {
            $team = Equipe::find($input['id']);
            $team->fill($input);
            $team->save();

            return redirect('/listAllTeams/'. $team->tournament_id);
        }

        $validator = Validator::make($input, [
            'nom' => 'required'
        ]);

        if ($validator->fails()) 
        {
            return view('Pages.formCreateTeam')->withErrors($validator)->withInput($input);
        }

        $equipe = new Equipe();
        $equipe->fill($input);
        $equipe->save();

        return redirect('/listAllTeams/'.$input['tournament_id']);
    }

    /* Suppression de l'équipe */
    public function deleteTeam($id)
    {
        $team = Equipe::find($id);
        $idTournament = $team->tournament_id;
        $team->delete();
        return redirect('/listAllTeams/'.$idTournament);
    }

    public function createTeam($id)
    {
        $data = array(
                'nom' => "",
                'capitaine' => "",
                'ville' => "",
                'adresse' => "",
                'npa' => "",
                'email' => "",
                'telephone' => "",
                'tournament_id' => $id
            );

        return view('Pages.formCreateTeam')->with($data);
    }
}
<file_sep><?php

namespace App\Http\Controllers;

use Request;
use App\Tournament;
use App\Equipe;
use App\Match;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;

class TreeTournamentController extends Controller
{
    /**
    *   Affichage de l'arbre du tournoi
    *
    *   paramètre : id du tournoi
    *   return : les équipes et id tournoi
    **/
    public function showTreeTournament($id)
    {
        $tournament = Tournament::with('equipes')->find($id);

        $qualifiedTeam = $this->searchTeamQualified($tournament);

        return view('Pages.treeTournament')->with('qualifiedTeam', $qualifiedTeam)->with('tournamentId', $id);
    }

    /* Attribution des points dans chaque groupe */
    private function searchTeamQualified($tournament)
    {
        $games = Match::where('tournament_id', '=', $tournament->id)->get();
        $nbGroup = count($this->createGroups($tournament->equipes, $tournament));

        $classement = array();

        for($i = 0; $i < $nbGroup; $i++)
        {
            array_push($classement, array());
        }

        foreach($games as $game)
        {
            $pointWonTeam1 = $this->pointWon($game['score1'], $game['score2']);
            $pointWonTeam2 = $this->pointWon($game['score2'], $game['score1']);
            $groupe = $game['groupe']-1;

            $classement = $this->createPointTeam($game['equipe1'], $classement, $groupe, $pointWonTeam1);
            $classement = $this->createPointTeam($game['equipe2'], $classement, $groupe, $pointWonTeam2);
        }

        $classementSorted = array();

        foreach ($classement as $group) 
        {
            arsort($group);
            array_push($classementSorted, $group);
        }

        return $this->takeTeamQualified($tournament, $classementSorted, $nbGroup);
    }

    /* Récupération des équipes qualifiés pour le tour suivant */
    private function takeTeamQualified($tournament, $classement, $nbGroupe)
    {
        $qualifiedTeam = array();
        $arrayNbTeamQualif = array('0' => 32, '1' => 16, '2' => 8, '3' => 4, '4' => 2); // Type de final
        $nbTeamQualif = $arrayNbTeamQualif[$tournament->typeFinales];

        $nbTeamQualifPerGroup = $nbTeamQualif / $nbGroupe;

        if($nbTeamQualifPerGroup > 0)
        {
            foreach ($classement as $groupe) 
            {
                $i = 0;
                foreach($groupe as $team => $point)
                {
                    array_push($qualifiedTeam, $team);
                    $i++;
                    if($i >= $nbTeamQualifPerGroup) break;
                }
            }
        }

        /* 
            Inversion des matchs, les équipes du même groupe 
            ne joue pas l'une contre l'autre
        */
        if(count($qualifiedTeam) >= 4)
        {
            for($i = 0; $i < count($qualifiedTeam); $i+=4)
            {
                $tmp = $qualifiedTeam[$i];
                $qualifiedTeam[$i] = $qualifiedTeam[$i+2];
                $qualifiedTeam[$i+2] = $tmp;
            }
        }

        return $qualifiedTeam;
    }

    /* Points par match gagné, perdu et égalité */
    private function createPointTeam($team, $classement, $groupe, $pointWon)
    {
        if(!array_key_exists($team, $classement[$groupe]))
        {
            $classement[$groupe][$team] = $pointWon;
        }
        else
        {
            $classement[$groupe][$team] += $pointWon;
        }

        return $classement;
    }

    private function pointWon($score1, $score2)
    {
        if($score1 > $score2) return 3;
        else if($score1 < $score2) return 0;
        else return 1;
    }

    /* Création des groupes */
    private function createGroups($teams, $tournament)
    {
        // create an array of teams
        $members = array();
        $i = 0;
        foreach ($teams as $team) {
            $members[$i] =  $team['nom'];
            $i++;
        }

        // Split our array of team on a array of groupes of teams
        $groupes = array_chunk($members, ceil($tournament->nbEquipe / $tournament->nbGroupe));

        return $groupes;
    }
}
<file_sep><?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Equipe extends Model
{
    protected $table = 'team';

    protected $fillable = [
            'nom',
            'capitaine',
            'ville',
            'npa',
            'adresse',
            'email',
            'telephone',
            'tournament_id'
    ];

    public $timestamps = false;

    public function tournament()
    {
    	return $this->belongsTo('App\Tournament');
    }

    /* Création équipe */
    public static function updateEquipe($nom, $tournamentId)
    {
    	$equipe = new Equipe;

		$equipe['nom'] = $nom;
		$equipe['tournament_id'] = $tournamentId;

		$equipe->save();
    }
}
<file_sep><?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Match extends Model
{
    protected $table = 'match';

    protected $fillable = [
            'equipe1',
            'equipe2',
            'score1',
            'score2',
            'heureMatchDebut',
            'heureMatchFin',
            'tournament_id',
            'groupe'
    ];

    public $timestamps = false;
}
