Skip to content
Snippets Groups Projects
Select Git revision
  • 31d999ae3c8e6db35b082e4fe2e932b448b8f492
  • master default protected
2 results

pair.php

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    pair.php 20.31 KiB
    <?php
    
    /**
     * This file is part of the TandemPlugin for Stud.IP
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License as
     * published by the Free Software Foundation; either version 2 of
     * the License, or (at your option) any later version.
     *
     * @author   Moritz Strohm <strohm@data-quest.de>
     * @license  http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
     * @category Plugin
     **/
    
    
    require_once(__DIR__ . '/../models/TandemPair.class.php');
    require_once(__DIR__ . '/../classes/TandemManager.class.php');
    
    
    class PairController extends PluginController
    {
    
        public function before_filter(&$action, &$args)
        {
            parent::before_filter($action, $args);
    
            $this->user = User::findCurrent();
    
            if (!$this->plugin->userHasAccess($this->user->id)) {
                throw new AccessDeniedException(
                    dgettext('TandemPlugin', 'Sie befinden sich auf der Blockliste und dürfen daher das TandemPlugin nicht nutzen!')
                );
            }
        }
    
    
        /**
         * Checks wether the current user has matching requests for the offer
         * and if multiple requests match the offer the user can select
         * one of them.
         */
        public function select_profile_action()
        {
            $offer_profile_id = Request::get('offer_profile_id');
            if(!$offer_profile_id) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Die Anfrage zur Tandem-Bildung kann nicht erstellt werden, da das Angebot, auf das sich die Anfrage bezieht, nicht angegeben wurde!')
                );
                return;
            }
    
            $this->offer_profile = TandemProfile::find($offer_profile_id);
            if(!$this->offer_profile) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Die Anfrage zur Tandem-Bildung kann nicht erstellt werden, da das angegebene Angebot nicht in der Datenbank gefunden wurde!')
                );
                return;
            }
    
            //Ok, we have the offer. Now we must find profiles of the current user
            //that match the offer. If there is only one match we can redirect
            //to the apply-action directly. Otherwise, we must show a selection
            //dialog where the current user can select one of his requests.
    
            $one_side_matching_requests = TandemMatching::findMatches($this->offer_profile, 0, User::findCurrent()->id);
    
            $this->matching_requests = [];
            if (Config::get()->TANDEMPLUGIN_USE_LEVEL) {
                //Check if these requests match the other way around, too:
                foreach ($one_side_matching_requests as $request) {
                    if ($request->matchesSpokenLanguages($this->offer_profile->user_id)) {
                        $this->matching_requests[] = $request;
                    }
                }
            } else {
                $this->matching_requests = $one_side_matching_requests;
            }
    
            $num_matching_requests = count($this->matching_requests);
    
            if($num_matching_requests == 0) {
                PageLayout::postError(
                    sprintf(
                        dgettext('TandemPlugin', 'Sie haben keine passende Anfrage für das Angebot von %s!'),
                        (
                            $this->offer_profile->user
                            ? $this->offer_profile->user->getFullName()
                            : dgettext('TandemPlugin', 'unbekannt')
                        )
                    )
                );
    
                return;
            } elseif($num_matching_requests == 1) {
                //Only one matching request:
                //We can directly redirect to the apply action.
    
                $this->redirect(
                    PluginEngine::getURL(
                        $this->plugin,
                        [
                            'request_profile_id' => $this->matching_requests[0]->id,
                            'offer_profile_id' => $this->offer_profile->id
                        ],
                        'pair/apply'
                    )
                );
                return;
            } else {
                //More than one matching request:
                //We must display a choice dialog.
    
                PageLayout::postInfo(
                    sprintf(
                        dgettext('TandemPlugin', '%s ihrer Gesuche passen auf das gewählte Angebot. Bitte wählen Sie das Gesuch aus, welches sie mit dem Angebot von %s verknüpfen wollen.'),
                        $num_matching_requests,
                        (
                            $this->offer_profile->user
                            ? $this->offer_profile->user->getFullName()
                            : dgettext('TandemPlugin', 'unbekannt')
                        )
                    )
                );
            }
        }
    
    
        /**
         * This action creates a tandem pair. It is called when a user
         * wants to bind his profile with a matching profile of another user.
         */
        public function apply_action()
        {
            $request_profile_id = Request::get('request_profile_id');
            $offer_profile_id = Request::get('offer_profile_id');
    
            if(!$request_profile_id) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Die Anfrage zur Tandem-Bildung kann nicht erstellt werden, da keine Anfrage angegeben wurde!')
                );
                return;
            }
    
            if(!$offer_profile_id) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Die Anfrage zur Tandem-Bildung kann nicht erstellt werden, da das Angebot, auf das sich die Anfrage bezieht, nicht angegeben wurde!')
                );
                return;
            }
    
            $this->request_profile = TandemProfile::find($request_profile_id);
            $this->offer_profile = TandemProfile::find($offer_profile_id);
    
            /*
               //request_profile is determined by looking at the mother languages
               //of the target user (the user of the "offer"). There must be one
               //tandem profile of the current user that has the same language_id
               //as one mother language of the target user.
               $this->request_profile = TandemProfile::findOneBySql(
               'INNER JOIN tandem_user_mother_languages AS tuml
               ON tandem_profiles.target_language_id = tuml.language_id
               WHERE tuml.user_id = :target_user_id
               AND tandem_profiles.user_id = :current_user_id',
               [
               'target_user_id' => $this->offer_profile->user_id,
               'target_language_id' => $this->offer->language_id,
               'current_user_id' => $this->user->id
               ]
               );
             */
    
    
            if(!$this->request_profile) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Die Anfrage zur Tandem-Bildung kann nicht erstellt werden, da das angegebene Gesuch nicht in der Datenbank gefunden wurde!')
                );
                return;
            }
    
            if(!$this->offer_profile) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Die Anfrage zur Tandem-Bildung kann nicht erstellt werden, da das angegebene Angebot nicht in der Datenbank gefunden wurde!')
                );
                return;
            }
    
            if($this->request_profile->user_id != $this->user->id) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Sie sind nicht berechtigt, für einen anderen Nutzer eine Anfrage zur Tandem-Bildung zu erstellen!')
                );
                return;
            }
    
            //Check if the request's and the offer's target languages match one of
            //the mother languages of the opposite user:
    
            $request_user_mother_language = TandemUserMotherLanguage::findBySql(
                'user_id = :user_id AND language_id = :language_id',
                [
                    'user_id' => $this->request_profile->user_id,
                    'language_id' => $this->offer_profile->target_language_id
                ]
            );
    
            if(!$request_user_mother_language) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Tandem kann nicht gebildet werden!') . ' ' .
                    sprintf(
                        dgettext('TandemPlugin', 'Keine Ihrer Sprachen passt auf das Gesuch von %s!'),
                        (
                            $this->offer_profile->user
                            ? $this->offer_profile->user->getFullName()
                            : dgettext('TandemPlugin', 'unbekannt')
                        )
                    )
                );
            }
    
            $offer_user_mother_language = TandemUserMotherLanguage::findBySql(
                'user_id = :user_id AND language_id = :language_id',
                [
                    'user_id' => $this->offer_profile->user_id,
                    'language_id' => $this->request_profile->target_language_id
                ]
            );
    
            if(!$offer_user_mother_language) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Tandem kann nicht gebildet werden!') . ' ' .
                    sprintf(
                        dgettext('TandemPlugin', '%s spricht nicht die Sprache, zu der Sie ein Tandem suchen!'),
                        (
                            $this->offer_profile->user
                            ? $this->offer_profile->user->getFullName()
                            : dgettext('TandemPlugin', 'unbekannt')
                        )
                    )
                );
            }
    
            //Check, if the pairing was already initiated or established for this
            //combination of a request and offer profile:
            $pair_exists = (TandemPair::countBySql(
                "request_profile_id = :request_profile_id
                AND offer_profile_id = :offer_profile_id
                AND status > '-1'",
                [
                    'request_profile_id' => $this->request_profile->id,
                    'offer_profile_id' => $this->offer_profile->id
                ]
            ) > 0);
    
            if($pair_exists) {
                PageLayout::postError(
                    sprintf(
                        dgettext('TandemPlugin', 'Für das Angebot von %1$s in der Sprache %2$s wurde bereits eine Anfrage erstellt!'),
                        (
                            $this->offer_profile->user
                            ? $this->offer_profile->user->getFullName()
                            : dgettext('TandemPlugin', 'unbekannt')
                        ),
                        $this->offer_profile->target_language->getLocalName()
                    )
                );
    
                if(!Request::isDialog()) {
                    $this->redirect(
                        PluginEngine::getURL(
                            $this->plugin,
                            [],
                            'my_tandems/index'
                        )
                    );
                }
                return;
            }
    
            //Check, if the "offerer" (the opposite person) has made a request
            //for the current user's request.
            //This would mean the current user can simply accept or reject the offer
            //from the "offerer".
    
            $offerer_request = TandemPair::findOneBySql(
                'request_profile_id = :offer_profile_id
                AND offer_profile_id = :request_profile_id',
                [
                    'offer_profile_id' => $this->offer_profile->id,
                    'request_profile_id' => $this->request_profile->id
                ]
            );
    
            if($offerer_request) {
                //The "offerer" has made a request: redirect to the page
                //where the user can accept or reject the request of the "offerer":
                $this->redirect(
                    PluginEngine::getURL(
                        $this->plugin,
                        [],
                        'pair/decide/' . $offerer_request->id
                    )
                );
                return;
            }
    
            //Validation complete: We can apply for a new tandem pair:
    
            $result = TandemManager::applyForPair($this->request_profile, $this->offer_profile);
    
            if($result) {
                PageLayout::postSuccess(
                    sprintf(
                        dgettext('TandemPlugin', 'Sie haben %s eine Anfrage zur Tandem-Bildung geschickt!'),
                        (
                            $this->offer_profile->user
                            ? $this->offer_profile->user->getFullName()
                            : dgettext('TandemPlugin', 'unbekannt')
                        )
                    )
                );
            } else {
                PageLayout::postError(
                    sprintf(
                        dgettext('TandemPlugin', 'Beim Erstellen der Anfrage zur Tandem-Bildung an %s ist ein Fehler aufgetreten!'),
                        (
                            $this->offer_profile->user
                            ? $this->offer_profile->user->getFullName()
                            : dgettext('TandemPlugin', 'unbekannt')
                        )
                    )
                );
            }
    
            if(!Request::isDialog()) {
                $this->redirect(
                    PluginEngine::getUrl(
                        $this->plugin,
                        [],
                        'my_tandems/index'
                    )
                );
            }
        }
    
    
        /**
         * If a user has applied for a tandem pair and wants to withdraw
         * his application he calls this method.
         */
        public function withdraw_action($pair_id = null)
        {
            if(!$pair_id) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Es wurde keine Tandem-Anfrage angegeben!')
                );
                $this->redirect(
                    PluginEngine::getUrl(
                        $this->plugin,
                        [],
                        'my_tandems/index'
                    )
                );
                return;
            }
    
            $pair = TandemPair::find($pair_id);
    
            if(!$pair) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Die angegebene Tandem-Anfrage wurde nicht in der Datenbank gefunden!')
                );
                $this->redirect(
                    PluginEngine::getUrl(
                        $this->plugin,
                        [],
                        'my_tandems/index'
                    )
                );
                return;
            }
    
            if($pair->request->user_id != $this->user->id) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Sie sind nicht dazu berechtigt, die Tandem-Anfrage eines anderen Nutzers zurückzuziehen!')
                );
                $this->redirect(
                    PluginEngine::getUrl(
                        $this->plugin,
                        [],
                        'my_tandems/index'
                    )
                );
                return;
            }
    
            //Checks are done: delete the pair:
    
            //We must get the target name before deleting the pair,
            //if we want to display the target name in the next success/error message!
            $request_target_name = $pair->request->getTargetName();
    
            $result = $pair->delete();
    
            if($result) {
                PageLayout::postSuccess(
                    sprintf(
                        dgettext('TandemPlugin', 'Die Tandem-Anfrage für %s wurde zurückgezogen!'),
                        $request_target_name
                    )
                );
            } else {
                PageLayout::postError(
                    sprintf(
                        dgettext('TandemPlugin', 'Fehler beim Zurückziehen der Tandem-Anfrage für %s!'),
                        $request_target_name
                    )
                );
            }
    
            $this->redirect(
                PluginEngine::getUrl(
                    $this->plugin,
                    [],
                    'my_tandems/index'
                )
            );
        }
    
    
        /**
         * If a user got applications for one of his profiles he can decide
         * for one of the applications here.
         */
        public function decide_action($pair_id = null)
        {
            if(!$pair_id) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Es wurde kein Tandem-Paar angegeben!')
                );
            }
    
            $this->pair = TandemPair::find($pair_id);
            if(!$this->pair) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Das angegebene Tandem-Paar wurde nicht in der Datenbank gefunden!')
                );
                return;
            }
    
    
        }
    
    
        /**
         * If a user wants to accept the application for one of his profiles
         * he calls this method.
         */
        public function accept_action($pair_id = null)
        {
            if(!$pair_id) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Es wurde kein Tandem-Paar angegeben!')
                );
                return;
            }
    
            $pair = TandemPair::find($pair_id);
            if(!$pair) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Das angegebene Tandem-Paar wurde nicht in der Datenbank gefunden!')
                );
                return;
            }
    
            $user = User::findCurrent();
    
            if($pair->offer->user_id != $user->id) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Sie sind nicht berechtigt, eine Tandem-Anfrage für andere Nutzer zu akzeptieren!')
                );
                return;
            }
    
            $result = TandemManager::acceptApplication($pair);
    
            if($result) {
                PageLayout::postSuccess(
                    dgettext('TandemPlugin', 'Tandem-Anfrage wurde angenommen!')
                );
                $this->redirect(
                    PluginEngine::getUrl(
                        $this->plugin,
                        [],
                        'my_tandems/index'
                    )
                );
            } else {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Fehler beim Annehmen der Tandem-Anfrage!')
                );
                return;
            }
        }
    
    
        /**
         * If a user wants to reject the application for one of his profiles
         * he calls this method.
         */
        public function reject_action($pair_id = null)
        {
            if(!$pair_id) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Es wurde kein Tandem-Paar angegeben!')
                );
            }
    
            $pair = TandemPair::find($pair_id);
            if(!$pair) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Das angegebene Tandem-Paar wurde nicht in der Datenbank gefunden!')
                );
                return;
            }
    
            $user = User::findCurrent();
    
            if($pair->offer->user_id != $user->id) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Sie sind nicht dazu berechtigt, eine Anfrage für ein Angebot eines anderen Nutzers abzulehnen!')
                );
                return;
            }
    
            $pair->status = -1;
            if($pair->store()) {
                PageLayout::postSuccess(
                    dgettext('TandemPlugin', 'Die Tandem-Anfrage wurde abgelehnt!')
                );
            } else {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Fehler beim Ablehnen der Tandem-Anfrage!')
                );
            }
    
            $this->redirect(
                PluginEngine::getUrl(
                    $this->plugin,
                    [],
                    'my_tandems/index'
                )
            );
        }
    
    
        /**
         * If a user has an established pair he can call this method
         * to terminate it.
         */
        public function terminate_action($pair_id = null)
        {
            if(!$pair_id) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Es wurde kein Tandem-Paar angegeben!')
                );
            }
    
            $pair = TandemPair::find($pair_id);
            if(!$pair) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Das angegebene Tandem-Paar wurde nicht in der Datenbank gefunden!')
                );
                return;
            }
    
            $user = User::findCurrent();
    
            if(($pair->request->user_id != $user->id) and
                ($pair->offer->user_id != $user->id)) {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Sie sind nicht dazu berechtigt, ein Tandem eines anderen Nutzers aufzulösen!')
                );
                return;
            }
    
            //Terminate the pair and delete the user's profile which is bound
            //to that pair if the user's profile is the requesting part
            //of the pair:
            $result = TandemManager::terminatePair(
                $pair,
                $user,
                ($pair->request->user_id === $user->id)
            );
    
            if($result) {
                PageLayout::postSuccess(
                    dgettext('TandemPlugin', 'Das Tandem-Paar wurde aufgelöst!')
                );
            } else {
                PageLayout::postError(
                    dgettext('TandemPlugin', 'Fehler beim Auflösen des Tandem-Paares!')
                );
            }
    
            $this->redirect(
                PluginEngine::getUrl(
                    $this->plugin,
                    [],
                    'my_tandems/index'
                )
            );
        }
    }