Example #1
0
 /**
  * Check if user has reached his submission limit
  */
 public function checkIPLimit()
 {
     if ($this->ip_limit === $this::ON) {
         $startTime = TimeHelper::startTime($this->ip_limit_period);
         $ip = Yii::$app->getRequest()->getUserIP();
         if ($ip === "::1") {
             // Usefull when app run in localhost
             $ip = "81.2.69.160";
         }
         $submissions = FormSubmission::find()->select('id')->asArray()->where(['form_id' => $this->id])->andWhere(['between', 'created_at', $startTime, time()])->andWhere(['ip' => $ip])->count();
         if ($this->ip_limit_number <= $submissions) {
             /** @var \yii\web\Response $response */
             $response = Yii::$app->getResponse();
             $response->format = Response::FORMAT_JSON;
             $response->data = array('action' => 'submit', 'success' => false, 'id' => 0, 'message' => Yii::t("app", "You have reached your Submission Limit per {period}.", ['period' => TimeHelper::getPeriodByCode($this->ip_limit_period)]));
             $response->send();
             exit;
         }
     }
 }
 /**
  * Show & Save form report
  *
  * @param $id
  * @return array
  * @throws Exception
  */
 public function actionReport($id)
 {
     Yii::$app->response->format = Response::FORMAT_JSON;
     // Extract report data from post request
     $post = Yii::$app->request->post();
     // The raw data of the report
     $rawReport = isset($post) && isset($post['report']) ? $post['report'] : null;
     // Convert to charts array
     $charts = Json::decode($rawReport, true);
     if (isset($charts)) {
         // Save data in single transaction
         $transaction = FormChart::getDb()->beginTransaction();
         $success = false;
         try {
             // Delete old charts if there are
             FormChart::deleteAll(['form_id' => $id]);
             if (count($charts) > 0) {
                 // Populate each Form Chart Model and Save
                 foreach ($charts as $chart) {
                     $formChartModel = new FormChart();
                     // Add form_id to chart
                     $chart['form_id'] = $id;
                     // Prepare new model data
                     $postFormChart = ['FormChart' => $chart];
                     // Load & Save the model
                     if (!$formChartModel->load($postFormChart) || !$formChartModel->save()) {
                         throw new Exception(Yii::t("app", "Error saving the chart"));
                     }
                 }
             }
             $transaction->commit();
             // Change success flag and message
             $success = true;
             $message = Yii::t("app", "The report has been successfully updated.");
         } catch (Exception $e) {
             // Rolls back the transaction
             $transaction->rollBack();
             // Rethrow the exception
             // throw $e;
             $message = $e->getMessage();
         }
         $res = array('success' => $success, 'id' => $id, 'action' => 'update', 'message' => $message);
         return $res;
     }
     $submissions = array();
     foreach (FormSubmission::find()->select(['data', 'created_at'])->where('form_id=:form_id', [':form_id' => $id])->each(10) as $submissionModel) {
         $submission = $submissionModel->data;
         $submission['created_at'] = $submissionModel->created_at;
         array_push($submissions, $submission);
     }
     return $submissions;
 }
 /**
  * Export form submissions.
  *
  * @param integer $id
  */
 public function actionExportSubmissions($id)
 {
     $formModel = $this->findFormModel($id);
     $formDataModel = $formModel->formData;
     $query = FormSubmission::find()->select(['data', 'created_at'])->where('form_id=:form_id', [':form_id' => $id])->asArray();
     // Create the CSV into memory
     $csv = Writer::createFromFileObject(new SplTempFileObject());
     // Insert fields names as the CSV header
     $header = array_values($formDataModel->getLabels());
     array_push($header, 'Submitted at');
     $csv->insertOne($header);
     // To iterate the row one by one
     foreach ($query->each() as $submission) {
         // $submission represents one row of data from the form_submission table
         $data = Json::decode($submission['data'], true);
         foreach ($data as &$field) {
             if (is_array($field)) {
                 $field = implode(', ', $field);
             }
         }
         $data["created_at"] = Yii::$app->formatter->asDatetime($submission['created_at']);
         $csv->insertOne($data);
     }
     // Print to the output stream
     $csv->output($formModel->name . '.csv');
 }
 public function uniqueFieldsValidation()
 {
     $message = Yii::t("app", "{label} '{value}' has already been taken.");
     foreach ($this->uniqueFields as $field) {
         // Only when the input value is not empty
         if (isset($field["name"]) && trim($this->data[$field["name"]]) !== "") {
             // Strip whitespace from the beginning and end of a string
             $value = trim($this->data[$field["name"]]);
             // Search "fieldName":"fieldValue"
             $query = FormSubmission::find()->where('form_id=:form_id', [':form_id' => $this->dataModel->form_id])->andWhere(['like', 'data', '"' . $field["name"] . '":"' . $value . '"']);
             if ($query->count() > 0) {
                 $this->addError($field["name"], $field["label"], $value, $message);
             }
         }
     }
 }
 /**
  * Insert a Form Submission Model
  *
  * @param $id
  * @return array
  * @throws NotFoundHttpException
  * @throws \Exception
  * @throws \yii\db\Exception
  */
 public function actionA($id)
 {
     if (Yii::$app->request->isAjax) {
         // The HTTP post request
         $post = Yii::$app->request->post();
         if (isset($post)) {
             // If no model, throw NotFoundHttpException
             $formModel = $this->findFormModel($id);
             /**************+++++++++++++++++
                /* Spam Filter
                /*******************************/
             // Honeypot filter. If spam, throw NotFoundHttpException
             $formModel->checkHoneypot($post);
             // reCAPTCHA Validation. If error, send response to browser
             $formModel->validateRecaptcha($post);
             /**************+++++++++++++++++
                /* Submission Limit
                /*******************************/
             // If error, send response to browser
             $formModel->checkTotalLimit();
             $formModel->checkIPLimit();
             /**************+++++++++++++++++
                /* Prepare response by default
                /*******************************/
             // Response fornat
             Yii::$app->response->format = Response::FORMAT_JSON;
             // Default response
             $response = array('action' => 'submit', 'success' => true, 'id' => 0, 'message' => Yii::t('app', 'Your message has been sent. {startTag}Thank you!{endTag}', ['startTag' => '<strong>', 'endTag' => '</strong>']));
             /**************+++++++++++++++++
                /* Prepare data
                /*******************************/
             // Set public scenario of the submission
             $formSubmissionModel = new FormSubmission(['scenario' => 'public']);
             /** @var \app\models\FormData $formDataModel */
             $formDataModel = $formModel->formData;
             // Get all fields except buttons and files
             $fields = $formDataModel->getFieldsWithoutFilesAndButtons();
             // Get file fields
             $fileFields = $formDataModel->getFileFields();
             // Remove fields with null values and
             // Strip whitespace from the beginning and end of each post value
             $submissionData = $formSubmissionModel->cleanSubmission($fields, $post);
             // Get uploaded files
             $files = $formSubmissionModel->getUploadedFiles($fileFields);
             // File paths cache
             $filePaths = array();
             // Prepare Submission for validation
             $postFormSubmission = ['FormSubmission' => ['form_id' => $formModel->id, 'data' => $submissionData]];
             /**************+++++++++++++++++
                /* FormSubmission Validation
                /*******************************/
             if ($formSubmissionModel->load($postFormSubmission) && $formSubmissionModel->validate()) {
                 Yii::$app->trigger($this::EVENT_SUBMISSION_RECEIVED, new SubmissionEvent(['sender' => $this, 'form' => $formModel, 'submission' => $formSubmissionModel, 'files' => $files]));
                 if ($formModel->saveToDB()) {
                     /**************+++++++++++++++++
                        /* Save to DB
                        /*******************************/
                     // Save submission in single transaction
                     $transaction = Form::getDb()->beginTransaction();
                     try {
                         // Save submission without validation
                         if ($formSubmissionModel->save(false)) {
                             // Save files to DB and disk
                             /* @var $file \yii\web\UploadedFile */
                             foreach ($files as $file) {
                                 if (isset($file)) {
                                     // Save file to DB
                                     $fileModel = new FormSubmissionFile();
                                     $fileModel->submission_id = $formSubmissionModel->primaryKey;
                                     $fileModel->form_id = $formModel->id;
                                     // Replace special characters before the file is saved
                                     $fileModel->name = preg_replace("/[^a-zA-Z0-9]/", "", $file->baseName) . "-" . $formSubmissionModel->primaryKey;
                                     $fileModel->extension = $file->extension;
                                     $fileModel->size = $file->size;
                                     $fileModel->status = 1;
                                     $fileModel->save();
                                     // Throw exception if validation fail
                                     if (isset($fileModel->errors) && count($fileModel->errors) > 0) {
                                         throw new \Exception(Yii::t("app", "Error saving files."));
                                     }
                                     // Save file to disk
                                     $filePath = $fileModel->getFilePath();
                                     $file->saveAs($filePath);
                                     array_push($filePaths, $filePath);
                                 }
                             }
                             // Change response id
                             $response["id"] = $formSubmissionModel->primaryKey;
                         }
                         $transaction->commit();
                     } catch (\Exception $e) {
                         // Rolls back the transaction
                         $transaction->rollBack();
                         // Rethrow the exception
                         throw $e;
                     }
                 } else {
                     /**************+++++++++++++++++
                        /* Don't save to DB
                        /*******************************/
                     // Save files to disk
                     foreach ($files as $file) {
                         /* @var $file \yii\web\UploadedFile */
                         if (isset($file)) {
                             $filePath = $formModel::FILES_DIRECTORY . DIRECTORY_SEPARATOR . $formModel->id . DIRECTORY_SEPARATOR . $file->name;
                             $file->saveAs($filePath);
                             array_push($filePaths, $filePath);
                         }
                     }
                 }
                 Yii::$app->trigger($this::EVENT_SUBMISSION_ACCEPTED, new SubmissionEvent(['sender' => $this, 'form' => $formModel, 'submission' => $formSubmissionModel, 'files' => $files, 'filePaths' => $filePaths]));
             } else {
                 Yii::$app->trigger($this::EVENT_SUBMISSION_REJECTED, new SubmissionEvent(['sender' => $this, 'form' => $formModel, 'submission' => $formSubmissionModel]));
                 // Print validation errors
                 $errors = array();
                 foreach ($formSubmissionModel->errors as $field => $messages) {
                     array_push($errors, array("field" => $field, "messages" => $messages));
                 }
                 // Change response
                 $response["success"] = false;
                 $response["message"] = Yii::t('app', 'There is {startTag}an error in your submission{endTag}.', ['startTag' => '<strong>', 'endTag' => '</strong>']);
                 $response["errors"] = $errors;
             }
             return $response;
         }
     }
     return '';
 }
 public function actionDeleteall()
 {
     // Get ids param
     $request = Yii::$app->getRequest();
     $id = $request->post('id');
     $ids = $request->post('ids');
     // Default
     $success = false;
     $message = "No items matched the query";
     $itemsDeleted = 0;
     try {
         // The number of rows deleted
         $itemsDeleted = 0;
         // Delete one to one for trigger events
         foreach (FormSubmission::find()->where(['id' => $ids, 'form_id' => $id])->all() as $submissionModel) {
             $deleted = $submissionModel->delete();
             if ($deleted) {
                 $itemsDeleted++;
             }
         }
         // Set response
         if ($itemsDeleted > 0) {
             $success = true;
             $message = Yii::t("app", "Items deleted successfully");
         }
     } catch (\Exception $e) {
         // Rethrow the exception
         // throw $e;
         $message = $e->getMessage();
     }
     // Response fornat
     Yii::$app->response->format = Response::FORMAT_JSON;
     // Response to Client
     $res = array('success' => $success, 'action' => 'deleteall', 'itemsDeleted' => $itemsDeleted, 'ids' => $ids, 'message' => $message);
     return $res;
 }