From e4e0be508787e4c45d60da819c35df8c41a92e8f Mon Sep 17 00:00:00 2001
From: Tim Repke <timmothey@gmx.de>
Date: Tue, 18 Aug 2015 00:05:16 +0200
Subject: [PATCH] registration via form works againgit status

---
 .../frameworks/environment.php                | 74 ++++++++++++++-
 .../frameworks/soft_protect.php               |  5 +-
 registration-system/index.php                 | 23 ++++-
 registration-system/spec/js/spec/api.spec.js  | 22 +++++
 registration-system/view/js/api.js            | 90 +++++++++----------
 .../view/signups/form/index.php               |  6 +-
 .../view/signups/form/style.css               |  2 +-
 registration-system/view/signups/index.php    | 12 ++-
 8 files changed, 174 insertions(+), 60 deletions(-)

diff --git a/registration-system/frameworks/environment.php b/registration-system/frameworks/environment.php
index 123d762..5bcefb6 100644
--- a/registration-system/frameworks/environment.php
+++ b/registration-system/frameworks/environment.php
@@ -56,8 +56,13 @@ class Environment {
      * 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) {
+    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)
@@ -84,7 +89,7 @@ class Environment {
      */
     public function getSelectedTripId() {
         if(isset($_REQUEST['fid']))
-            return $_REQUEST['fid'];
+            return (int) $_REQUEST['fid'];
         else
             return null;
     }
@@ -160,4 +165,69 @@ class Environment {
             '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){
+                // === 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 ===
+                $this->database->insert("waitlist", $data);
+
+                // === notify success ===
+                $this->feedbackHelper("lang_waitmail", $data['mehl'], $data['waitlist_id'], $data['fahrt_id']);
+            }
+            else return false;
+        } else {
+            // === 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")
+                return false;
+
+            $this->database->exec("LOCK TABLES fahrten, bachelor WRITE"); // count should not be calculated in two scripts at once
+
+            $insertOk = $this->isRegistrationOpen($data['fahrt_id']);
+
+            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", $data['mehl'], $data['bachelor_id'], $data['fahrt_id']);
+        }
+
+        return true;
+    }
+
+    private function feedbackHelper($mail_lang, $to, $hash, $fid) {
+        global $config_baseurl;
+
+        $from = $this->database->get("fahrten", ["kontakt","leiter"], ["fahrt_id"=>$fid]);
+        $mail = comm_get_lang($mail_lang, array( "{{url}}"         => $config_baseurl."status.php?hash=".$hash,
+            "{{organisator}}" => $from['leiter']));
+        comm_send_mail($this->database, $to, $mail, $from['kontakt']);
+    }
 }
\ No newline at end of file
diff --git a/registration-system/frameworks/soft_protect.php b/registration-system/frameworks/soft_protect.php
index 45db2eb..f712944 100644
--- a/registration-system/frameworks/soft_protect.php
+++ b/registration-system/frameworks/soft_protect.php
@@ -19,10 +19,9 @@ class soft_protect
 			{
 				array_push($elems, "'".addslashes($protectkey)."'");
 			}
-			array_push($lines, "soft_protect([".implode(",", $elems)."], ".$element[1].");");
+			array_push($lines, "FAPI.attachSoftProtector([".implode(",", $elems)."], ".$element[1].");");
 		}
 		array_push($lines, "</script>");
 		return implode("\r\n", $lines);
 	}
-}
-?>
+}
\ No newline at end of file
diff --git a/registration-system/index.php b/registration-system/index.php
index 43b31ad..fa182b8 100644
--- a/registration-system/index.php
+++ b/registration-system/index.php
@@ -66,6 +66,10 @@ function index_get_dependencies_helper($dependency_function_name) {
 }
 
 function index_get_additional_headers() {
+    $signup_method = SignupMethods::getInstance();
+    if($signup_method->signupMethodExists()){
+        return $signup_method->getActiveMethod()->getAdditionalHeader();
+    }
     return '';
 }
 
@@ -135,15 +139,16 @@ function index_show_signup() {
         $sub = $signup_method->validateSubmission();
 
         if ($sub['valid']) {
-            if (index_form_to_db($sub['data']))
+            if ($environment->sendBachelorToDB($sub['data']))
                 header("Location: ?fid=".$fid."&success");
             else
                 header("Location: ?fid=".$fid."&full");
             die();
         } else {
             //TODO include that behaviour:
-            // index_show_errors($errors);
-            // index_show_formular($fid, NULL, $data);
+            index_show_errors($sub['errors']);
+            $environment->setDanglingFormData($sub['data']);
+            $signup_method->getFallbackMethod()->showInlineHTML();
         }
     }
 
@@ -189,7 +194,17 @@ function index_show_signup() {
     echo '</div>'; // close signup-container
 }
 
-
+/**
+ * puts out a list of all errors
+ * @param $errors
+ */
+function index_show_errors($errors){
+    echo '<div class="message error"><ul>';
+    foreach($errors as $e){
+        echo '<li>'.$e.'</li>';
+    }
+    echo'</ul></div>';
+}
 
 
 
diff --git a/registration-system/spec/js/spec/api.spec.js b/registration-system/spec/js/spec/api.spec.js
index 08fc507..f53249f 100644
--- a/registration-system/spec/js/spec/api.spec.js
+++ b/registration-system/spec/js/spec/api.spec.js
@@ -21,9 +21,11 @@ describe("Bachelor prototype behaviour", function() {
 
     it("should handle single property setting/getting", function() {
         expect(bachelor.getValue('forname')).toBe(null);
+        expect(bachelor.isSet('forname')).toBe(false);
 
         bachelor.setValue('forname', 'Franz');
         expect(bachelor.getValue('forname')).toBe('Franz');
+        expect(bachelor.isSet('forname')).toBe(true);
 
         expect(bachelor.getProperties()).toEqual({
             'forname': 'Franz',
@@ -65,6 +67,22 @@ describe("Bachelor prototype behaviour", function() {
             'studityp':null,
             'comment': null
         });
+
+        expect(bachelor.isComplete()).toBe(false);
+
+        bachelor.setValues({
+            'anday':   'bla',
+            'abday':   'bla',
+            'antyp':   'bla',
+            'abtyp':   'bla',
+            'pseudo':  'bla',
+            'mehl':    'bla',
+            'essen':   'bla',
+            'public':  'bla',
+            'studityp':'bla',
+            'comment': 'bla'
+        });
+        expect(bachelor.isComplete()).toBe(true);
     });
 
     it("should revoke setting/getting invalid attributes", function() {
@@ -76,6 +94,10 @@ describe("Bachelor prototype behaviour", function() {
             bachelor.resetValue('illegalAttribute')
         }).toThrow();
 
+        expect(function () {
+            bachelor.isSet('illegalAttribute')
+        }).toThrow();
+
         expect(function () {
             bachelor.setValues({
                 illegalAttribute: 'bla',
diff --git a/registration-system/view/js/api.js b/registration-system/view/js/api.js
index d121ca6..3e80c7d 100644
--- a/registration-system/view/js/api.js
+++ b/registration-system/view/js/api.js
@@ -21,6 +21,10 @@ var UrlComponents = {
             })(q.split("&"));
         }
     },
+    isSet: function(param) {
+        var tmp = this.getParams();
+        return tmp && param in tmp;
+    },
     getValueOf: function(param) {
         return this.getParams()[param];
     }
@@ -53,7 +57,15 @@ function Bachelor() {
     };
 
     this.isSet = function (attribute) {
-        return !!properties[attribute];
+        if(! (attribute in properties)) throw new Error("Attribute does not exist!");
+        return properties[attribute] !== null;
+    };
+
+    this.isComplete = function () {
+        for (var key in properties) {
+            if(!this.isSet(key)) return false;
+        }
+        return true;
     };
 
     this.setValue = function (attribute, value) {
@@ -85,6 +97,8 @@ function Bachelor() {
 
 function FAPI() {
     this.data = new Bachelor();
+    this.captcha = '';
+
     this.methodBasepath = 'view/signups/' + UrlComponents.getValueOf('method') + '/';
 }
 
@@ -93,63 +107,49 @@ FAPI.prototype.resolvePath = function(file) {
 };
 
 /**
- * params to send have to be set earlier (see the Bachelor)
+ * Submit the registration send-and-pray style!
  *
- * callback is called, once the request was sent to the server.
- * It'll transmit an object containing the
- *    -> state (0 = successful, 1 = error, 2 = ?)
- *    -> main message (string)
- *    -> errors (null, if non; array of strings with messages else)
-
- * @param callback
+ * All error handling will be done by the simple form (if needed).
  */
-FAPI.prototype.submitSignup = function(callback) {
-    // TODO evaluate params and send them
-
-    callback({
-        state: 0,
-        messages: 'Successful signup',
-        errors: null
-    })
-};
-
-/**
- * Helper function for FAPI.prototype.submitSignup
- * it creates a hidden form to be submitted.
- */
-FAPI.prototype.prepareSubmission = function () {
+FAPI.prototype.submitSignup = function() {
     var formWrapper = $('<div style="display:none"/>');
     var form = $('<form name="storySubmitForm" method="POST"/>');
     formWrapper.append(form);
     $('#signup-container').append(formWrapper);
 
-    function formAppendText (name, value) {
-        form.append('<input name="' + name + '" value="' + value.replace(/[\r\n]/g, "<br/>").replace(/&/g, "&amp;").replace(/"/g, "&quot;") + '"/>');
+
+    var data = this.data.getProperties();
+
+    for (var key in data) {
+        var value = data[key];
+        var leaveOut = false;
+        switch (key) {
+            case 'public':
+                if(value === true) value = 'public';
+                else leaveOut = true;
+                break;
+            default: /* does nothing */
+        }
+
+        if(!leaveOut) {
+            value = value.replace(/[\r\n]/g, "<br/>").replace(/&/g, "&amp;").replace(/"/g, "&quot;");
+            addToForm(key, value);
+        }
     }
 
-    if(window.location.pathname.search("waitlist")>0)
-        formAppendText("waitlist", "waitlist");
-    formAppendText('forname', story.form_variables.forname);
-    formAppendText('sirname', story.form_variables.name);
-    formAppendText('pseudo', story.form_variables.anzeig);
-    formAppendText('mehl', story.form_variables.mehl);
-    formAppendText('studityp', $('#story_summary_studityp').val());
-    formAppendText('virgin', Story.ageMap[story.form_variables.age]);
-    formAppendText('essen', Story.eatMapPhp[Story.eatMap[story.form_variables.eat]]);
-    formAppendText('anday', story.form_variables.travelStartDate);
-    formAppendText('antyp', Story.travelMapPhp[Story.travelMap[story.form_variables.travelStartType]]);
-    formAppendText('abday', story.form_variables.travelEndDate);
-    formAppendText('abtyp', Story.travelMapPhp[Story.travelMap[story.form_variables.travelEndType]]);
-    formAppendText('comment', $('#story_summary_comment').val());
-    if ($('#story_summary_public').is(':checked'))
-        formAppendText('public', 'public');
-    formAppendText('captcha', $('#story_summary_captcha').val());
-    formAppendText('storySubmit', 'storySubmit');
+    addToForm('captcha', this.captcha);
+    addToForm('storySubmit', 'storySubmit');
+    if(UrlComponents.isSet('waitlist'))
+        addToForm('waitlist', 'waitlist');
 
     form.submit();
+
+    function addToForm(key, value) {
+        form.append('<input name="' + key + '" value="' + value + '"/>');
+    }
 };
 
-FAPI.prototype.attachSoftProtector = function (elementIds, regex) {
+FAPI.attachSoftProtector = function (elementIds, regex) {
     for(var i = 0; i < elementIds.length; ++i) {
         $('#'+elementIds[i]).keyup(function(event) {
             if (!event.target.value.match(regex))
diff --git a/registration-system/view/signups/form/index.php b/registration-system/view/signups/form/index.php
index 6d05227..4078de0 100644
--- a/registration-system/view/signups/form/index.php
+++ b/registration-system/view/signups/form/index.php
@@ -52,9 +52,9 @@ class FormSignupMethod extends SignupMethod {
         echo '<div id="stylized" class="myform">
                 <form id="form" name="form" method="post" action="index.php' . $link_params . '">';
 
-        $this->show_formular_helper_input("Vorname",        "forname", $bachelor["forname"], "");
-        $this->show_formular_helper_input("Nachname",       "sirname", $bachelor["sirname"], "");
-        $this->show_formular_helper_input("Anzeigename",    "pseudo",  $bachelor["pseudo"],  "");
+        $this->show_formular_helper_input("Vorname",     "forname", $bachelor["forname"], "");
+        $this->show_formular_helper_input("Nachname",    "sirname", $bachelor["sirname"], "");
+        $this->show_formular_helper_input("Anzeigename", "pseudo",  $bachelor["pseudo"],  "");
         echo $soft_prot->add(array('forname', 'sirname', 'pseudo'), $environment->config['invalidChars'])->write();
 
         $this->show_formular_helper_input("E-Mail-Adresse", "mehl",    $bachelor["mehl"],    "regelmäßig lesen!");
diff --git a/registration-system/view/signups/form/style.css b/registration-system/view/signups/form/style.css
index 6936027..cde9636 100644
--- a/registration-system/view/signups/form/style.css
+++ b/registration-system/view/signups/form/style.css
@@ -52,7 +52,7 @@
     margin-left:150px;
     width:125px;
     height:31px;
-    background:#666666 url(img/button.png) no-repeat;
+    background:#666666;
     text-align:center;
     line-height:31px;
     color:#FFFFFF;
diff --git a/registration-system/view/signups/index.php b/registration-system/view/signups/index.php
index 2d3402c..59c3f55 100644
--- a/registration-system/view/signups/index.php
+++ b/registration-system/view/signups/index.php
@@ -6,6 +6,7 @@ class SignupMethods {
 
     private static $__instance = NULL;
     private $signup_methods = [];
+    private $fallback_method = 'form';
 
     public static function getInstance() {
         if(self::$__instance == NULL) self::$__instance = new SignupMethods();
@@ -49,6 +50,11 @@ class SignupMethods {
         }
     }
 
+    public function getFallbackMethod() {
+        $method = $this->getMethodObj($this->fallback_method);
+        return new $method['class']();
+    }
+
     /**
      * @return class (instantiated) of the active signup method
      * @throws ErrorException when $_GET["method"] is missing or not available in the list
@@ -73,9 +79,11 @@ class SignupMethods {
      */
     private function getActiveMethodObj() {
         if(!isset($_REQUEST["method"])) throw new ErrorException("No signup-method selected!");
-        $mode = $_REQUEST["method"];
-        if(!isset($this->signup_methods[$mode])) throw new ErrorException("Signup-method does not exist!");
+        return $this->getMethodObj($_REQUEST["method"]);
+    }
 
+    private function getMethodObj($mode) {
+        if(!isset($this->signup_methods[$mode])) throw new ErrorException("Signup-method does not exist!");
         return [ 'id' => $mode, 'class' => $this->signup_methods[$mode]['class']];
     }
 
-- 
GitLab