Php 创建具有条件的用户组

Php 创建具有条件的用户组,php,symfony,Php,Symfony,我有一个集团实体。此组实体有一个“nombre”字段,该字段是组的所需大小,“jour1”和“horaire1”是组检查的第一个日期时间,“jour2”和“horaire2”是组检查的第二个日期时间 大约有40个小组,只有4对不同的约会时间(周一17:30-周三18:30,周一18:30-周三17:30,周二17:30-周四18:30,周二18:30-周四17:30) 我有另一个实体,DemandeGroup。此实体允许用户请求特定的考试日期和/或与组中的其他特定用户在一起。用户可以请求多个用户

我有一个集团实体。此组实体有一个“nombre”字段,该字段是组的所需大小,“jour1”和“horaire1”是组检查的第一个日期时间,“jour2”和“horaire2”是组检查的第二个日期时间

大约有40个小组,只有4对不同的约会时间(周一17:30-周三18:30,周一18:30-周三17:30,周二17:30-周四18:30,周二18:30-周四17:30)

我有另一个实体,DemandeGroup。此实体允许用户请求特定的考试日期和/或与组中的其他特定用户在一起。用户可以请求多个用户

我希望所有用户在满足以下条件的情况下分为以下几组:

1) 请求与另一用户在一起并请求特定日期时间的用户必须位于请求的日期时间的同一组中

2) 仅询问特定用户的用户必须与此用户位于同一组中

3) 仅询问特定日期时间的用户必须位于此日期时间的组中

4) 没有问任何问题的用户必须随机分组

5) 组的大小不一样,因此所有组都必须符合“nombre”字段中定义的大小,因此每个组中的用户数必须低于或等于“nombre”,并且所有组都必须在同一时间填充(如果组中的用户数少于空格,我不希望最后一个组填充的用户数少于空格)

我无法找到一种方法同时满足所有这些条件

GroupeComposition实体:

/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @ORM\Column(name="nom", type="string")
 */
private $nom;

/**
 * @ORM\Column(name="salle_composition", type="string")
 */
private $salleComposition;

/**
 * @ORM\Column(name="salle_correction", type="string")
 */
private $salleCorrection;

/**
 * @ORM\Column(name="nombre", type="integer")
 */
private $nombre;

/**
 * @ORM\Column(name="jour1", type="string")
 */
private $jour1;

/**
 * @ORM\Column(name="horaire_jour1", type="string")
 */
private $horaireJour1;

/**
 * @ORM\Column(name="jour2", type="string")
 */
private $jour2;

/**
 * @ORM\Column(name="horaire_jour2", type="string")
 */
private $horaireJour2;

/**
 * @ORM\Column(name="type_tutore", type="string")
 */
private $typeTutore;

/**
 * @ORM\Column(name="specialite", type="string", nullable=true)
 */
private $specialite;

/**
 * @ORM\OneToMany(targetEntity="\PACES\UserBundle\Entity\Tutore", mappedBy="groupeComposition")
 */
protected $tutores;
**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @ORM\ManyToOne(targetEntity="PACES\UserBundle\Entity\Tutore", cascade={"persist"})
 */
protected $tutoreSource;

/**
 * @ORM\ManyToOne(targetEntity="PACES\UserBundle\Entity\Tutore", cascade={"persist"})
 */
protected $tutoreDemande;

/**
 * @ORM\Column(name="jour", type="string", nullable=true)
 */
private $jour;

/**
 * @ORM\Column(name="horaire", type="string", nullable=true)
 */
private $horaire;

/**
 * @ORM\Column(name="raison", type="string")
 */
private $raison;

/**
 * @ORM\Column(name="acceptee", type="boolean", nullable=true, options={"default":null})
 */
private $acceptee;
DemandeGroup实体:

/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @ORM\Column(name="nom", type="string")
 */
private $nom;

/**
 * @ORM\Column(name="salle_composition", type="string")
 */
private $salleComposition;

/**
 * @ORM\Column(name="salle_correction", type="string")
 */
private $salleCorrection;

/**
 * @ORM\Column(name="nombre", type="integer")
 */
private $nombre;

/**
 * @ORM\Column(name="jour1", type="string")
 */
private $jour1;

/**
 * @ORM\Column(name="horaire_jour1", type="string")
 */
private $horaireJour1;

/**
 * @ORM\Column(name="jour2", type="string")
 */
private $jour2;

/**
 * @ORM\Column(name="horaire_jour2", type="string")
 */
private $horaireJour2;

/**
 * @ORM\Column(name="type_tutore", type="string")
 */
private $typeTutore;

/**
 * @ORM\Column(name="specialite", type="string", nullable=true)
 */
private $specialite;

/**
 * @ORM\OneToMany(targetEntity="\PACES\UserBundle\Entity\Tutore", mappedBy="groupeComposition")
 */
protected $tutores;
**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @ORM\ManyToOne(targetEntity="PACES\UserBundle\Entity\Tutore", cascade={"persist"})
 */
protected $tutoreSource;

/**
 * @ORM\ManyToOne(targetEntity="PACES\UserBundle\Entity\Tutore", cascade={"persist"})
 */
protected $tutoreDemande;

/**
 * @ORM\Column(name="jour", type="string", nullable=true)
 */
private $jour;

/**
 * @ORM\Column(name="horaire", type="string", nullable=true)
 */
private $horaire;

/**
 * @ORM\Column(name="raison", type="string")
 */
private $raison;

/**
 * @ORM\Column(name="acceptee", type="boolean", nullable=true, options={"default":null})
 */
private $acceptee;

我用这段代码解决了这个问题:

$demandes = $em->getRepository(DemandeGroupe::class)->findBy(['acceptee' => true, 'semestre' => $semestre]);
    $groupes = $em->getRepository(GroupeComposition::class)->findAll();

    $groupesOfCompo = [];
    foreach ($groupes as $groupe) {
        $groupesOfCompo[] = ['objet' => $groupe,
                        'nombre' => $groupe->getNombre(),
                        'jour1' => $groupe->getJour1(). ' '. $groupe->getHoraireJour1(),
                        'jour2' => $groupe->getJour2(). ' '. $groupe->getHoraireJour2()];
    }

    // Array to exclude these users afterwards
    $tutoresWithDemande = [];

    shuffle($demandes);

    foreach ($demandes as $demande) {
        $tutore1 = $demande->getTutoreSource();
        $tutoresWithDemande[] = $tutore1->getId();
        $tutore2 = null;
        if ($demande->getTutoreDemande()) {
            $tutore2 = $demande->getTutoreDemande();
            $tutoresWithDemande[] = $tutore2->getId();
        }

        $dateDemande = null;
        if ($demande->getJour() && $demande->getHoraire()) {
            $dateDemande = $demande->getJour() . ' ' . $demande->getHoraire();
        }

        if ($dateDemande) {

            // Array of possible groups for current user
            $groupes = [];

            foreach ($groupesOfCompo as $groupe) {
                if ($groupe['jour1'] == $dateDemande || $groupe['jour2'] == $dateDemande) {
                    // Check if there's enough space left in group && if group is possible for this user
                    if ((($tutore2 && 0 <= $groupe['nombre'] - 2) ||
                            (!$tutore2 && 0 <= $groupe['nombre'] - 1))
                        && $tutore1->getSituation() === $groupe['objet']->getTypeTutore()
                    ) {
                        $groupes[] = $groupe;
                    }
                }
            }

            // Get size of each group
            $effectifs = array_column($groupes, 'nombre');
            // Get max group size
            $max = max($effectifs);
            // Get group with max group size
            $max_array = $groupes[array_search($max, $effectifs)];

            $tutore1->setGroupeComposition($max_array['objet']);
            $em->persist($tutore1);

            if ($tutore2) {
                $tutore2->setGroupeComposition($max_array['objet']);
                $em->persist($tutore2);
            }

            // Get back group from initial array to decrease space left in group
            foreach ($groupesOfCompo as &$a) {
                if ($a['objet'] === $max_array['objet']) {
                    if ($tutore2) {
                        $a['nombre'] -= 2;
                    }
                    else {
                        $a['nombre']--;
                    }
                }
            }
        }
        else {
            $groupes = [];
            foreach ($groupesOfCompo as $groupe) {
                if ((($tutore2 && 0 <= $groupe['nombre'] - 2) ||
                        (!$tutore2 && 0 <= $groupe['nombre'] - 1))
                    && $tutore1->getSituation() === $groupe['objet']->getTypeTutore())
                {
                    $groupes[] = $groupe;
                }
            }
            $effectifs = array_column($groupes, 'nombre');
            $max = max($effectifs);
            $max_array = $groupes[array_search($max, $effectifs)];

            $tutore1->setGroupeComposition($max_array['objet']);
            $em->persist($tutore1);

            if ($tutore2) {
                $tutore2->setGroupeComposition($max_array['objet']);
                $em->persist($tutore2);
            }

            foreach ($groupesOfCompo as &$a) {
                if ($a['objet'] === $max_array['objet']) {
                    if ($tutore2) {
                        $a['nombre'] -= 2;
                    }
                    else {
                        $a['nombre']--;
                    }
                }
            }
        }
    }

    // Get users without DemandeGroupe
    $groupeSalle = $em->getRepository(Groupe::class)->findOneBy(['nom' => 'Salle']);
    $tutoresWithoutDemande = $em->getRepository(Tutore::class)->findAllExceptExcluded($groupeSalle, $tutoresWithDemande);

    shuffle($tutoresWithoutDemande);

    foreach ($tutoresWithoutDemande as $tutore) {
        // Pour chaque groupe de composition
        foreach ($groupesOfCompo as $groupe) {

            if (0 <= $groupe['nombre'] - 1 && $tutore->getSituation() === $groupe['objet']->getTypeTutore()) {
                $groupes[] = $groupe;
            }
        }

        $effectifs = array_column($groupes, 'nombre');
        $max = max($effectifs);
        $max_array = $groupes[array_search($max, $effectifs)];

        $tutore->setGroupeComposition($max_array['objet']);
        $em->persist($tutore);

        foreach ($groupesOfCompo as &$a) {
            if ($a['objet'] === $max_array['objet']) {
                $a['nombre']--;
            }
        }
    }
$em->flush();
$demandes=$em->getRepository(demandegroup::class)->findBy(['acceptee'=>true,'semestre'=>$semestre]);
$groupes=$em->getRepository(GroupeComposition::class)->findAll();
$groupesOfCompo=[];
foreach($groupes作为$groupe){
$groupesOfCompo[]=['objet'=>$groupe,
'nombre'=>$groupe->getNombre(),
“jour1'=>$groupe->getJour1().”.$groupe->getHoraireJour1(),
“jour2'=>$groupe->getJour2().”.$groupe->getHoraireJour2()];
}
//数组来排除这些用户
$tutoresWithDemande=[];
洗牌($demandes);
foreach($demandes作为$demande){
$tutore1=$demande->getTutoreSource();
$tutoresWithDemande[]=$tutore1->getId();
$tutore2=null;
如果($demande->getturedemande()){
$tutore2=$demande->gettutoredmande();
$tutoresWithDemande[]=$tutore2->getId();
}
$dateDemande=null;
如果($demande->getJour()&&&$demande->getHoraire()){
$dateDemande=$demande->getJour().'。$demande->getHoraire();
}
如果($dateDemande){
//当前用户的可能组数组
$groupes=[];
foreach($groupesOfCompo作为$groupe){
如果($groupe['jour1']=$dateDemande | |$groupe['jour2']=$dateDemande){
//检查组中是否有足够的空间&&组是否可供此用户使用
if(($tutore2&0 getTypeTutore()
) {
$groupes[]=$groupe;
}
}
}
//获取每个组的大小
$effectifs=array_column($groupes,'nombre');
//获取最大组大小
$max=max($effectifs);
//获取具有最大组大小的组
$max_数组=$groupes[数组搜索($max,$effectifs)];
$tutore1->setGroupeComposition($max_数组['objet']);
$em->persist($tutore1);
如果($2){
$tutore2->setGroupeComposition($max_数组['objet']);
$em->persist($tutore2);
}
//从初始数组取回组以减少组中剩余的空间
foreach($groupesOfCompo as&$a){
如果($a['objet']=$max_数组['objet']){
如果($2){
$a['nombre']-=2;
}
否则{
$a['nombre']--;
}
}
}
}
否则{
$groupes=[];
foreach($groupesOfCompo作为$groupe){
if(($tutore2&0 getTypeTutore())
{
$groupes[]=$groupe;
}
}
$effectifs=array_column($groupes,'nombre');
$max=max($effectifs);
$max_数组=$groupes[数组搜索($max,$effectifs)];
$tutore1->setGroupeComposition($max_数组['objet']);
$em->persist($tutore1);
如果($2){
$tutore2->setGroupeComposition($max_数组['objet']);
$em->persist($tutore2);
}
foreach($groupesOfCompo as&$a){
如果($a['objet']=$max_数组['objet']){
如果($2){
$a['nombre']-=2;
}
否则{
$a['nombre']--;
}
}
}
}
}
//获取没有DemandeGroup的用户
$groupeSalle=$em->getRepository(Groupe::class)->findOneBy(['nom'=>'Salle']);
$tutoresWithoutDemande=$em->getRepository(Tutore::class)->findAllExceptExcluded($groupeSalle,$tutoresWithDemande);
洗牌($tutoresWithoutDemande);
foreach($tutoresWithoutDemande为$tutore){
//倒茶组分
foreach($groupesOfCompo作为$groupe){
如果(0 get情境()==$groupe['objet']->getTypeTutore()){
$groupes[]=$groupe;
}
}
$effectifs=array_column($groupes,'nombre');
$max=max($effectifs);