/**
  * HOW IT WORKS
  * 1 - If the idContent is set retrieve all the fields and values for this ID, otherwise retrieve only the fields to show
  * 2 - On save check the errors on the "normal fields"; for the attachments save everything into the tmp folder and check for errors
  * 3 - If there aren't errors save the content (insert or update), save the values and moving the attachments from the tmp folder to the content folder
  * 4 - Process the images, if any
  * 5 - Empty the TMP folder
  * 6 - Redirect to the result page
  *
  */
 public function saveContent($contentType, $content = null)
 {
     $result = array();
     $uploadData = array();
     $redirectURL = '/admin/contents/';
     $oldValues = array();
     $errors = array();
     $result['data_saved'] = FALSE;
     $contentTypeName = $contentType;
     $contentType = $this->getContentTypeByName($contentType);
     $fields = $this->getContentFieldsByIdContentType($contentType['id']);
     $categories = $this->getCategoriesByContentType($contentType['id']);
     $oldValues['title'] = '';
     $oldValues['relative_path'] = '';
     $absolutePath = '';
     $oldValues['categories'] = array();
     if ($content) {
         $idContent = $content['id'];
     } else {
         $idContent = null;
     }
     if ($contentTypeName === 'pages') {
         $menu = $this->getMenu(true);
         $flatPagesTree = $this->getFlatPagesTree($menu);
         $flatPagesTitles = array();
         foreach ($flatPagesTree as $id => $page) {
             $flatPagesTitles[$id] = ltrim(str_repeat('--', $page['level']) . ' ', ' ') . "{$page['title']}";
         }
         // TODO another day
         // if ($idContent && isset($flatPagesTitles[$idContent])) {
         // 	unset($flatPagesTitles[$idContent]);
         // }
     }
     // ================ 1 - RETRIEVING ALL THE CONTENT COMPONENTS (FIELDS, VALUES, ATTACHS, ETC.) ===============
     // Retrieve the content if the idContent is set
     if ($idContent) {
         $this->data['uploadUrl'] = '/uploads/' . $idContent . '/';
         $content = $this->getContentById($idContent);
         $contentValues = $this->getAllContentValuesByIdContent($idContent);
         $contentCategories = $this->getAllContentCategoriesByIdContent($idContent);
         $oldValues['title'] = $content['title'];
         $oldValues['relative_path'] = $content['relative_path'];
         $oldValues['categories'] = $contentCategories;
         if (count($oldValues['categories']) > 0) {
             $tmp = array();
             foreach ($oldValues['categories'] as $category) {
                 $tmp[] = $category['id_category'];
             }
             $oldValues['categories'] = $tmp;
         }
         $tmp = array();
         if (count($contentValues) > 0) {
             foreach ($contentValues as $value) {
                 $tmp[$value['id_content_field']] = $value;
             }
         }
         $contentValues = $tmp;
     } else {
         $content = array();
         $contentValues = array();
         $contentCategories = array();
     }
     $contentAttachments = array();
     // Fields transformations (options, images, etc.)
     if (count($fields) > 0) {
         foreach ($fields as $index => $field) {
             if (isset($contentValues[$field['id']]['value']) && $contentValues[$field['id']]['value'] != '') {
                 $field['value'] = $contentValues[$field['id']]['value'];
             } else {
                 $field['value'] = '';
             }
             if (in_array($field['type'], array('radio', 'select', 'multiselect', 'checkbox', 'multicheckbox'))) {
                 $field['options'] = FM_Utility::convertOptionsTextToArray($field['options']);
             }
             if (in_array($field['type'], array('multiselect', 'multicheckbox', 'multiple_linked_content')) && $field['value'] != '') {
                 $field['value'] = FM_Utility::convertMultiOptionsTextToArray($contentValues[$field['id']]['value']);
             }
             if ($field['type'] == 'file_upload') {
                 if (isset($contentValues[$field['id']])) {
                     $field['attach'] = array('id_content_value' => $contentValues[$field['id']]['id'], 'file' => $this->data['uploadUrl'] . $contentValues[$field['id']]['value']);
                 } else {
                     $field['attach'] = array();
                 }
             }
             if ($field['type'] == 'image_upload') {
                 if (isset($contentValues[$field['id']])) {
                     $field['attach'] = array('id_content_value' => $contentValues[$field['id']]['id'], 'zoom_image' => $this->data['uploadUrl'] . $contentValues[$field['id']]['value'], 'thumb_image' => $this->data['uploadUrl'] . 'thumbs/' . $contentValues[$field['id']]['value']);
                 } else {
                     $field['attach'] = array();
                 }
             }
             if ($field['type'] == 'gallery') {
                 $contentAttachments[$field['name']] = $this->getAllContentAttachmentsByIdContent($idContent);
                 $field['attachs'] = array();
                 if (count($contentAttachments[$field['name']]) > 0) {
                     foreach ($contentAttachments[$field['name']] as $att) {
                         array_push($field['attachs'], array('id_content_attachment' => $att['id'], 'zoom_image' => $this->data['uploadUrl'] . $att['filename'], 'thumb_image' => $this->data['uploadUrl'] . 'thumbs/' . $att['filename']));
                     }
                 }
             }
             if ($field['type'] == 'linked_content' || $field['type'] == 'multiple_linked_content') {
                 $ctypeToSelect = $this->getContentTypeById($field['linked_id_content_type']);
                 $contentSearch = new FM_ContentSearch();
                 $contentSearch->initialize($ctypeToSelect['content_type'])->select('*')->fullInfo(TRUE);
                 $contentList = $contentSearch->getContentList();
                 $options = array();
                 foreach ($contentList as $cont) {
                     $options[$cont['id']] = $cont['title'];
                 }
                 $field['options'] = $options;
             }
             if ($field['name'] === 'parent_page_id' && $contentTypeName === 'pages' && $field['type'] == 'select') {
                 $field['options'] = $flatPagesTitles;
             }
             // PAGE FIELD MANAGEMENT
             if ($field['name'] == 'content_types_list' && $contentTypeName == 'pages' && $field['type'] == 'select') {
                 $cTypes = $this->getContentTypes('pages');
                 $options = array();
                 if (count($cTypes) > 0) {
                     foreach ($cTypes as $ct) {
                         $options[$ct['content_type']] = $ct['content_type'];
                     }
                 }
                 $field['options'] = $options;
                 // If the value exist, I load the options for the content list
                 if ($field['value'] != '') {
                     $contentListOptions = array();
                     $contentSearch = new FM_ContentSearch();
                     $contentSearch->initialize($field['value'])->select('*')->fullInfo(TRUE);
                     $tmpContentList = $contentSearch->getContentList();
                     if (count($tmpContentList) > 0) {
                         foreach ($tmpContentList as $tmpContent) {
                             $contentListOptions[$tmpContent['id']] = $tmpContent['title'];
                         }
                     }
                 }
             }
             if ($field['name'] === 'content_list_categories' && $contentTypeName === 'pages' && in_array($field['type'], array('multiselect', 'multicheckbox'))) {
                 $field['options'] = (array) $field['value'];
                 $field['options'] = array_combine($field['options'], $field['options']);
             }
             if ($field['name'] == 'content_list' && $contentTypeName == 'pages' && ($field['type'] == 'select' || $field['type'] == 'multiselect')) {
                 // Check if the operation value exist
                 if (isset($contentListOptions) && count($contentListOptions) > 0) {
                     $field['options'] = $contentListOptions;
                 }
             }
             $fields[$index] = $field;
         }
     }
     if ($this->ci->input->post('save') || $this->ci->input->post('save_list')) {
         $redirectURL .= $this->ci->input->post('save') ? 'edit/' : 'index/' . $contentType['content_type'];
         $tmpFolder = $this->getTmpFolder();
         // Generic saving of the values
         foreach ($this->ci->input->post() as $name => $value) {
             $oldValues[$name] = $value;
         }
         if (count($fields) > 0) {
             foreach ($fields as $index => $field) {
                 if ($this->ci->input->post($field['name'])) {
                     $field['value'] = $this->ci->input->post($field['name']);
                 }
                 $fields[$index] = $field;
             }
         }
         // Basic content checking
         if ($this->ci->input->post('title') == '') {
             $errors['title'] = $this->ci->lang->line('incorrect_content_title');
         }
         if ($this->ci->input->post('relative_path') == '') {
             $errors['relative_path'] = sprintf($this->ci->lang->line('incorrect_field'), 'relative path');
         } else {
             $_POST['relative_path'] = $relativePath = url_title(convert_accented_characters($this->ci->input->post('relative_path')), '-', true);
         }
         // Check for page absolute_path uniqueness
         if ($contentTypeName === 'pages' && !isset($errors['relative_path']) && isset($flatPagesTitles)) {
             $absolutePath = "{$relativePath}/";
             $parentPageId = $this->ci->input->post('parent_page_id');
             if ($parentPageId) {
                 $absolutePath = "{$flatPagesTree[$parentPageId]['absolute_path']}{$absolutePath}";
             }
             $contentSearch = new FM_ContentSearch();
             $contentSearch->initialize($contentType['id'])->select('id')->addWhereCondition('absolute_path', '=', $absolutePath)->addWhereCondition('lang', '=', $this->ci->input->post('lang'));
             $content = current($contentSearch->getContentList());
             if ($content && (!$idContent || $content['id'] !== $idContent)) {
                 $errors['relative_path'] = $this->ci->lang->line('non_unique_absolute_path');
             }
         } else {
             $absolutePath = url_title(convert_accented_characters($oldValues['title']));
         }
         // ================ 2 - CHECKING THE ERRORS ========================
         if (count($fields) > 0) {
             foreach ($fields as $index => $field) {
                 if (!$this->isFilesystemField($field)) {
                     if ($field['mandatory'] == TRUE && $this->ci->input->post($field['name']) == '') {
                         $field['showError'] = TRUE;
                         $field['error'] = sprintf($this->ci->lang->line('incorrect_field'), $field['label']);
                     }
                     if ($field['type'] == 'date' || $field['type'] == 'datetime') {
                         $value = $this->ci->input->post($field['name']);
                         if ($value) {
                             $field['value'] = $value;
                             if ($field['type'] == 'datetime') {
                                 list($date, $time) = explode(' ', $value);
                             } else {
                                 $date = $value;
                             }
                             list($day, $month, $year) = explode('/', $date);
                             if (!checkdate($month, $day, $year)) {
                                 $field['showError'] = TRUE;
                                 $field['error'] = sprintf($this->ci->lang->line('incorrect_date_field'), $field['label']);
                             }
                         }
                     }
                 } else {
                     $hidden = $this->ci->input->post($field['name']);
                     if ($field['mandatory'] == TRUE && $_FILES[$field['name']]['error'] != 0 && !$hidden) {
                         $field['showError'] = TRUE;
                         $field['error'] = sprintf($this->ci->lang->line('incorrect_field'), $field['label']);
                     }
                     if ($_FILES[$field['name']]['error'] == 0) {
                         $temp = $this->saveTemporaryAttachments($field);
                         if (isset($temp[$field['name']]['error'])) {
                             $field['showError'] = TRUE;
                             $field['error'] = $temp[$field['name']]['error'];
                         } else {
                             $field['value'] = $temp[$field['name']]['file_name'];
                             $uploadData = array_merge($uploadData, $temp);
                         }
                     }
                 }
                 $fields[$index] = $field;
             }
         }
         $values = array();
         $checkErrors = FALSE;
         // The title and permalink are correct
         // (??)
         if (count($errors) == 0) {
             if (count($fields) > 0) {
                 foreach ($fields as $field) {
                     if (isset($field['error']) && $field['error'] != '') {
                         $checkErrors = TRUE;
                     }
                 }
             }
         }
         // ================ 3 - SAVE THE CONTENT VALUES ========================
         if (count($errors) == 0 && !$checkErrors) {
             $contentData = array('absolute_path' => $absolutePath) + array_intersect_key($this->ci->input->post(), array_flip(array('title', 'relative_path', 'lang')));
             // Save the basic content
             if (!$idContent) {
                 $contentData['id_content_type'] = $contentType['id'];
                 $contentData['id_user'] = $this->ci->fm_users_management->getLoggedUserId();
                 $idContent = $this->insertContent($contentData);
             } else {
                 $contentData['id'] = $idContent;
                 $this->updateContent($contentData);
                 if ($contentTypeName === 'pages' && isset($contentData['absolute_path']) && $contentData['absolute_path']) {
                     $this->ci->content->updateSonsPath($contentData['absolute_path'], $idContent);
                 }
             }
             $storeFolder = $this->_uploadPath . '/' . $idContent . '/';
             // I check if the directory of the content exists or not
             if (file_exists($storeFolder) == FALSE) {
                 mkdir($storeFolder, 0777);
             }
             // Create the thumb folder if image
             if (file_exists($storeFolder . 'thumbs/') == FALSE) {
                 mkdir($storeFolder . 'thumbs/', 0777);
             }
             $redirectURL .= $this->ci->input->post('save') ? $idContent : '';
             // Save the content values
             if (count($fields) > 0) {
                 // Move everything from the tmp folder to the content folder
                 $this->moveTemporaryAttachments($idContent);
                 foreach ($fields as $field) {
                     // ================ 4 - PROCESS THE IMAGES ===============
                     if ($field['type'] == 'image_upload' || $field['type'] == 'gallery') {
                         $hidden = $this->ci->input->post($field['name']);
                         if (isset($uploadData[$field['name']])) {
                             $processResult = $this->processImage($idContent, $field, $uploadData);
                             if (isset($processResult['error'])) {
                                 log_message($processResult['error']);
                             }
                         }
                     }
                     // Insert the value
                     if (!isset($contentValues[$field['id']])) {
                         if (!$this->isFilesystemField($field)) {
                             $value = $this->ci->input->post($field['name']);
                             if ($field['type'] == 'xhtml_textarea' && $tmpFolder) {
                                 $tmpFolder = $this->ci->config->item('txt_upl_img_path', 'factotum') . '/' . $tmpFolder;
                                 $value = str_replace($tmpFolder, $this->_imagesURL . '/' . $idContent, $value);
                             }
                             if ($field['type'] == 'multiselect' || $field['type'] == 'multicheckbox' || $field['type'] == 'multiple_linked_content') {
                                 $value = $value ? FM_Utility::convertMultiOptionsArrayToText($value) : '';
                             }
                             $this->insertContentValue($idContent, $field['id'], $value);
                         } else {
                             // Saving the Image/File Uploaded
                             if (($field['type'] == 'image_upload' || $field['type'] == 'file_upload') && isset($uploadData[$field['name']]['file_name'])) {
                                 if (isset($uploadData[$field['name']]['file_name'])) {
                                     $value = $uploadData[$field['name']]['file_name'];
                                 } else {
                                     // Retrieve the hidden value
                                     $value = $this->ci->input->post($field['name']);
                                 }
                                 $this->insertContentValue($idContent, $field['id'], $value);
                             }
                             // Saving the gallery
                             if ($field['type'] == 'gallery' && isset($uploadData[$field['name']])) {
                                 $idContentAttachment = $this->insertContentAttachment($idContent, $field['id'], $uploadData[$field['name']]['file_name'], $uploadData[$field['name']]['file_name']);
                                 $this->insertContentValue($idContent, $field['id'], $idContentAttachment);
                             }
                         }
                     } else {
                         // Update the existing rows
                         $cValue = $contentValues[$field['id']];
                         // Normal field type (text/textarea)
                         if (!$this->isFilesystemField($field)) {
                             $value = $this->ci->input->post($field['name']);
                             if ($field['type'] == 'xhtml_textarea' && $tmpFolder) {
                                 $tmpFolder = $this->ci->config->item('txt_upl_img_path', 'factotum') . '/' . $tmpFolder;
                                 $value = str_replace($tmpFolder, $this->_imagesURL . '/' . $idContent, $value);
                             }
                             if ($field['type'] == 'multiselect' || $field['type'] == 'multicheckbox' || $field['type'] == 'multiple_linked_content') {
                                 $value = FM_Utility::convertMultiOptionsArrayToText($value);
                             }
                             $this->updateContentValue($cValue['id'], $value);
                         } else {
                             // Saving the Image/File Uploaded
                             if (($field['type'] == 'image_upload' || $field['type'] == 'file_upload') && isset($uploadData[$field['name']]['file_name'])) {
                                 $value = $uploadData[$field['name']]['file_name'];
                                 $this->updateContentValue($cValue['id'], $value);
                             }
                             if ($field['type'] == 'gallery' && isset($uploadData[$field['name']])) {
                                 $idContentAttachment = $this->insertContentAttachment($idContent, $field['id'], $uploadData[$field['name']]['file_name'], $uploadData[$field['name']]['file_name']);
                                 $this->insertContentValue($idContent, $field['id'], $idContentAttachment);
                             }
                         }
                     }
                 }
                 // ================ 5 - EMPTY THE TMP FOLDER ===============
                 $this->deleteTmpFolder();
             }
             // 6 - SAVE THE CONTENT CATEGORIES
             $tmp = array();
             if (count($contentCategories) > 0) {
                 foreach ($contentCategories as $contentCategory) {
                     $tmp[] = $contentCategory['id_category'];
                 }
             }
             $contentCategories = $tmp;
             $postedCategories = $this->ci->input->post('categories');
             if ($postedCategories && count($postedCategories) > 0) {
                 if ($postedCategories) {
                     $tmp = array();
                     foreach ($postedCategories as $idContentCategory) {
                         $tmp[] = $idContentCategory;
                     }
                     $postedCategories = $tmp;
                 }
                 foreach ($categories as $cat) {
                     if (!in_array($cat['id'], $postedCategories)) {
                         $this->deleteContentCategoryByIdContentAndIdCategory($idContent, $cat['id']);
                     } else {
                         if (!in_array($cat['id'], $contentCategories)) {
                             $this->insertContentCategory($idContent, $cat['id']);
                         }
                     }
                 }
             } else {
                 foreach ($contentCategories as $idCategory) {
                     $this->deleteContentCategoryByIdContentAndIdCategory($idContent, $idCategory);
                 }
             }
             // ================ 7 - REDIRECT TO THE RESULT ===============
             $result['redirectURL'] = $redirectURL;
             $result['data_saved'] = TRUE;
         } else {
             $result['redirectURL'] = '';
         }
     }
     $result['fields'] = $fields;
     $result['errors'] = $errors;
     $result['oldValues'] = $oldValues;
     return $result;
 }