/**
  * Action parsing operations on records, such as hiding, adding, duplicating
  * @todo: Extract till you drop!!!!!
  * @todo: ^ Well that didn't work
  * @since 0.0.2 Parses
  * @since 0.0.1
  */
 public function actionRecord()
 {
     $em = DB::getEntityManager();
     $data = $this->parseRequest(['action' => null]);
     $action = strtolower($data['action']);
     $response['error'] = null;
     switch ($action) {
         case 'create':
             $data = $this->parseRequest(['given_name' => null, 'middle_name' => null, 'last_name' => null, 'record_name' => null, 'start_date' => null, 'end_date' => null]);
             if (!empty($data['given_name']) && !empty($data['last_name']) && !empty($data['record_name']) && !empty($data['start_date']) && !empty($data['end_date'])) {
                 $user = Apollo::getInstance()->getUser();
                 $person = new PersonEntity();
                 $person->setOrganisation($user->getOrganisation());
                 $person->setGivenName($data['given_name']);
                 $person->setMiddleName($data['middle_name']);
                 $person->setLastName($data['last_name']);
                 $em->persist($person);
                 $start_date = new DateTime($data['start_date']);
                 $end_date = new DateTime($data['end_date']);
                 $record = new RecordEntity($user->getEntity());
                 $record->setPerson($person);
                 $em->persist($record);
                 $record->setVarchar(FIELD_RECORD_NAME, $data['record_name']);
                 $record->setDateTime(FIELD_START_DATE, $start_date);
                 $record->setDateTime(FIELD_END_DATE, $end_date);
                 $em->flush();
                 $response['record_id'] = $record->getId();
             } else {
                 $response['error'] = $this->getJSONError(1, 'Some of the fields are empty!');
             }
             break;
         case 'add':
             $data = $this->parseRequest(['person_id' => 0, 'id' => 0, 'record_name' => null, 'start_date' => null, 'end_date' => null]);
             if (!empty($data['record_name'])) {
                 $record = new RecordEntity(Apollo::getInstance()->getUser()->getEntity());
                 /** @var PersonEntity $person */
                 $person = Person::find($data['person_id']);
                 if ($person != null) {
                     $em = DB::getEntityManager();
                     $record->setPerson($person);
                     $em->persist($record);
                     $em->flush();
                     $start_date = new DateTime($data['start_date']);
                     $end_date = new DateTime($data['end_date']);
                     $record->setVarchar(FIELD_RECORD_NAME, $data['record_name']);
                     $record->setDateTime(FIELD_START_DATE, $start_date);
                     $record->setDateTime(FIELD_END_DATE, $end_date);
                     if ($data['id'] > 0) {
                         if (($sourceRecord = Record::getValidRecordWithId($data['id'])) != null) {
                             $fields = Field::getValidFields();
                             /**
                              * @var FieldEntity $field
                              */
                             foreach ($fields as $field) {
                                 if (!in_array($field->getId(), [FIELD_RECORD_NAME, FIELD_START_DATE, FIELD_END_DATE])) {
                                     $sourceData = $sourceRecord->findOrCreateData($field->getId());
                                     /** @var DataEntity $data */
                                     $data = clone $sourceData;
                                     $data->setRecord($record);
                                     $em->persist($data);
                                 }
                             }
                         } else {
                             $response['error'] = $this->getJSONError(1, 'Source record ID is invalid.');
                         }
                     }
                     $em->flush();
                     $response['record_id'] = $record->getId();
                 } else {
                     $response['error'] = $this->getJSONError(1, 'Invalid person ID.');
                 }
             } else {
                 $response['error'] = $this->getJSONError(1, 'You must specify a name for the new record.');
             }
             break;
         case 'hide':
             $data = $this->parseRequest(['id' => 0]);
             if ($data['id'] < 0) {
                 Apollo::getInstance()->getRequest()->error(400, 'Invalid ID specified.');
             }
             /**
              * @var RecordEntity $record
              */
             $record = Record::getValidRecordWithId($data['id']);
             if ($record != null) {
                 $person = $record->getPerson();
                 if (!empty($person)) {
                     $records = $person->getRecords();
                     $count = 0;
                     foreach ($records as $current_record) {
                         if (!$current_record->isHidden()) {
                             $count++;
                         }
                     }
                     if ($count > 1) {
                         $record->setIsHidden(true);
                         $em->flush();
                     } else {
                         $response['error'] = ['id' => 1, 'description' => 'This is the only visible record for this person, hence cannot be hidden.'];
                     }
                 } else {
                     $response['error'] = $this->getJSONError(1, 'Record belongs to another organisation!');
                 }
             } else {
                 $response['error'] = $this->getJSONError(1, 'Selected record is either already hidden or does not exist.');
             }
             break;
         default:
             Apollo::getInstance()->getRequest()->error(400, 'Invalid action.');
     }
     echo json_encode($response);
 }
 /**
  * Returns JSON containing information used to build the edit view for a record
  * @todo: Put all of the field formatting in the field component
  * @since 0.0.9
  */
 public function actionRecordEdit()
 {
     $data = $this->parseRequest(['id' => 0]);
     $response['error'] = null;
     /**
      * @var RecordEntity $record
      */
     if ($data['id'] > 0 && ($record = Record::getValidRecordWithId($data['id']))) {
         Record::prepare($record);
         $response['essential'] = Record::getFormattedData($record);
         $fieldsEditData = [];
         /**
          * @var FieldEntity[] $fields
          */
         $fields = Field::getValidFields();
         foreach ($fields as $field) {
             $fieldEditData['id'] = $field->getId();
             $fieldEditData['name'] = $field->getName();
             $fieldEditData['type'] = $field->getType();
             $fieldEditData['has_default'] = $field->hasDefault();
             $fieldEditData['allow_other'] = $field->isAllowOther();
             $fieldEditData['is_multiple'] = $field->isMultiple();
             $defaults = $field->getDefaults();
             $defaultArray = [];
             foreach ($defaults as $default) {
                 $defaultArray[] = $default->getValue();
             }
             $fieldEditData['defaults'] = $defaultArray;
             $fieldData = $record->findOrCreateData($field->getId());
             if ($field->hasDefault()) {
                 if ($field->isMultiple()) {
                     $value = unserialize($fieldData->getLongText());
                 } else {
                     if ($fieldData->isDefault() || !$field->isAllowOther()) {
                         $value = $fieldData->getInt();
                     } else {
                         $value = $fieldData->getVarchar();
                     }
                 }
             } else {
                 if ($field->isMultiple()) {
                     $value = unserialize($fieldData->getLongText());
                 } else {
                     $value = Data::serialize($fieldData);
                 }
             }
             $fieldEditData['value'] = $value;
             $fieldsEditData[] = $fieldEditData;
         }
         $response['data'] = $fieldsEditData;
     } else {
         $response['error'] = ['id' => 1, 'description' => 'The supplied ID is invalid!'];
     }
     echo json_encode($response);
 }