Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
Environment.php 8.51 KiB
<?php

require_once __DIR__.'/../config.inc.php';
require_once __DIR__.'/../lang.php';
require_once 'medoo.php';
require_once 'commons.php';
require_once 'soft_protect.php';

class Environment {

    private static $__instance;

    public $database;
    public $config;
    private $dangling_form_data;

    public static function getEnv() {
        if(self::$__instance == NULL) self::$__instance = new Environment();
        return self::$__instance;
    }

    protected function __construct() {
        global $config_db, $config_studitypen, $config_essen, $config_reisearten, $invalidCharsRegEx,
               $config_reisearten_o, $config_essen_o, $config_studitypen_o;

        $this->database = new medoo(array(
            'database_type' => $config_db["type"],
            'database_name' => $config_db["name"],
            'server'        => $config_db["host"],
            'username'      => $config_db["user"],
            'password'      => $config_db["pass"]
        ));

        $this->config = [
            'studitypen' => $config_studitypen,
            'essen'      => $config_essen,
            'reisearten' => $config_reisearten,
            'invalidChars' => $invalidCharsRegEx
        ];

        $this->oconfig = [
            'studitypen' => $config_studitypen_o,
            'essen'      => $config_essen_o,
            'reisearten' => $config_reisearten_o
        ];
    }

    // signup method


    // only waitlist

    /**
     * @returns TRUE iff regular registration is allowed
     */
    public function isRegistrationOpen($fid) {
        $ret = $this->getRegistrationState($fid);
        return $ret === 0;
    }

    /**
     * @returns TRUE iff regular registration is allowed
     * @param $fid - fahrt id to check
     * @param $mail - email address to check
     * @param $list - list to check (bachelor or waitlist)
     */
    public function isRegistered($fid, $mail, $list = 'bachelor') {
        return $this->database->has($list, ['AND' => ['fahrt_id'=>$fid, 'mehl' => $mail]]);
    }
    /**
     * returns value depending on registration status
     * 0 = registration open (slots available)
     * 1 = all slots taken -> waitlist open
     * 2 = registration closed!
     *
     * @param $fid (optional) to pass this parameter
     * @returns int the state of the trip (see above)
     */
    public function getRegistrationState($fid = NULL) {
        if(is_null($fid)) $fid = $this->getSelectedTripId();

        comm_verbose(3,"checking if fid ". $fid . " is open");
        $open = $this->database->has('fahrten', ['AND' => ['fahrt_id'=>$fid, 'regopen'=>1]]);
        if(!$open)
            return 2;

        $cnt = $this->database->count("bachelor", ["AND"=>
            ["backstepped" => NULL,
                "fahrt_id"    => $fid]]);
        $max = $this->database->get("fahrten", "max_bachelor", ["fahrt_id" => $fid]);
        $wl = $this->database->count('waitlist', ['AND' =>
            ["transferred" => NULL,
                "fahrt_id"    => $fid]]);

        comm_verbose(3,"cnt: ".$cnt.", max: ".$max.", open: ".($open ? "yes" : "no"));

        if ( $cnt < $max && $wl == 0 )
            return 0;

        return 1;
    }

    /**
     * @return trip selected via $_REQUEST (or null)
     */
    public function getSelectedTripId() {
        if(isset($_REQUEST['fid']))
            return (int) $_REQUEST['fid'];
        else
            return null;
    }

    /**
     * @return bool true iff selected trip id is in the DB
     */
    public function isSelectedTripIdValid() {
		$fid = $this->getSelectedTripId();
		if ($fid == null) return false;
        $valid = $this->database->has('fahrten',
            ['fahrt_id'=> $fid]);
        if(!$valid) comm_verbose(1,"FID nicht vorhanden!");

        return $valid;
    }

    /**
     * @return bool true iff user confirmed to enter waitlist
     */
    public function isInWaitlistMode() {
        return isset($_REQUEST['waitlist']);
    }

    /**
     * Stash form data in this class (i.e. for edit)
     * @param $data
     */
    public function setDanglingFormData($data) {
        $this->dangling_form_data = $data;
    }

    /**
     * @return bool true iff formdata is received
     */
    public function formDataReceived() {
        return isset($_REQUEST['submit']) || isset($_REQUEST['storySubmit']);
    }

    public function getBachelor($bid = NULL) {
        if(!is_null($this->dangling_form_data))
            return $this->dangling_form_data;
        if(is_null($bid))
            return $this->getEmptyBachelor();
        else
            return $this->getBachelorFromDB($bid);
    }

    /**
     * Given a registration id, return all parameters from the db
     *
     * @param $bid
     * @return null or registration details
     */
    public function getBachelorFromDB($bid) {
        if(!is_null($bid) &&
            $this->database->has('bachelor', ['bachelor_id' => $bid])){

            $bachelor = $this->database->select('bachelor',
                ['forname','sirname','anday','abday','antyp','abtyp','pseudo',
                    'mehl','essen','public','virgin','studityp','comment'],
                ['bachelor_id'=>$bid]);
            $bachelor['id'] = $bid;
            return $bachelor[0];
        }
        return $this->getEmptyBachelor();
    }

    /**
     * Will return an empty registration field
     *
     * @return array
     */
    public function getEmptyBachelor() {
        $possible_dates = comm_get_possible_dates($this->database, $this->getSelectedTripId());

        return [
            'forname' => "", 'sirname' => "",
            'anday' => $possible_dates[0], 'abday' => $possible_dates[count($possible_dates)-1],
            'antyp' => "", 'abtyp' => "",
            'pseudo' => "", 'mehl' => "", 'essen' => "", 'public' => "",
            'studityp' => "", 'comment'=>""
        ];
    }

    /**
     * @param $data
     * @return bool
     */
    public function sendBachelorToDB($data) {

        // === prepare data to insert ===
        $data['anm_time'] = time();
        $data['anday'] = date('Y-m-d', DateTime::createFromFormat('d.m.Y',$data['anday'])->getTimestamp());
        $data['abday'] = date('Y-m-d', DateTime::createFromFormat('d.m.Y',$data['abday'])->getTimestamp());

        if($this->isInWaitlistMode()){
            if($this->getRegistrationState($data['fahrt_id'])==1){
                $this->database->exec("LOCK TABLES fahrten, waitlist WRITE"); // count should not be calculated in two scripts at once

                // === prepare data to insert ===
                $data['waitlist_id'] = comm_generate_key($this->database,
                    ["bachelor" => "bachelor_id", "waitlist" => "waitlist_id"],
                    ['fahrt_id'=>$data['fahrt_id']]);

                // === insert data ===
                $insertOk = !$this->isRegistered($data['fahrt_id'], $data['mehl'], 'waitlist');

                if($insertOk) $this->database->insert("waitlist", $data);
                $this->database->exec("UNLOCK TABLES"); // insert is done now, count may be recalculated in other threads
                if(!$insertOk) return false;

                // === notify success ===
                $this->feedbackHelper("lang_waitmail", $data['mehl'], $data['waitlist_id'], $data['fahrt_id']);
            }
            else return false;
        } else {
            $this->database->exec("LOCK TABLES fahrten, bachelor WRITE"); // count should not be calculated in two scripts at once

            // === prepare data to insert ===
            $data['version'] = 1;
            $data['bachelor_id'] = comm_generate_key($this->database,
                ["bachelor" => "bachelor_id"],
                ['fahrt_id'=>$data['fahrt_id']]);

            // === check regstration full ===
            $res = $this->database->get("fahrten",
                ["regopen", "max_bachelor"],
                ["fahrt_id" => $data['fahrt_id']]);
            if (!$res || $res['regopen'] != "1") {
                $this->database->exec("UNLOCK TABLES");
                return false;
            }

            $insertOk = $this->isRegistrationOpen($data['fahrt_id']) && !$this->isRegistered($data['fahrt_id'], $data['mehl']);

            if ($insertOk)
                $this->database->insert("bachelor", $data);
            $this->database->exec("UNLOCK TABLES"); // insert is done now, count may be recalculated in other threads
            if (!$insertOk)
                return false; // full

            // === notify success ===
            $this->feedbackHelper(["lang_regmail", "lang_payinfomail"], $data['mehl'], $data['bachelor_id'], $data['fahrt_id']);
        }

        return true;
    }


}