protected function fixUuidToBinary($strUuid) { if (\Validator::isStringUuid($strUuid)) { $strUuid = \String::uuidToBin($strUuid); } return $strUuid; }
/** * Find a watchlist item by its pid and uuid * * @param string $intPid The watchlist id * @param string $intUuid The files uuid * @param array $arrOptions An optional options array * * @return \Model|null The model or null if there is no watchlist */ public static function findByPidAndUuid($intPid, $strUuid, array $arrOptions = array()) { $t = static::$strTable; // Convert UUIDs to binary if (\Validator::isStringUuid($strUuid)) { $strUuid = \String::uuidToBin($strUuid); } return static::findOneBy(array("{$t}.pid=?", "{$t}.uuid=UNHEX(?)"), array($intPid, bin2hex($strUuid)), $arrOptions); }
public function onCreate($strTable, $insertID, $arrSet, \DataContainer $dc) { if (($objModel = SubmissionArchiveModel::findByPk($insertID)) === null) { return; } if (($uuid = Submissions::getDefaultAttachmentSRC()) !== null && \Validator::isUuid($uuid)) { $objModel->attachmentUploadFolder = class_exists('Contao\\StringUtil') ? \StringUtil::uuidToBin($uuid) : \String::uuidToBin($uuid); } $objModel->save(); }
/** * Run the controller and parse the template */ public function run() { $this->Template = new BackendTemplate('be_picker'); $this->Template->main = ''; // Ajax request if ($_POST && Environment::get('isAjaxRequest')) { $this->objAjax = new Ajax(Input::post('action')); $this->objAjax->executePreActions(); } $strTable = Input::get('table'); $strField = Input::get('field'); // Define the current ID define('CURRENT_ID', Input::get('table') ? $this->Session->get('CURRENT_ID') : Input::get('id')); $this->loadDataContainer($strTable); $strDriver = 'DC_' . $GLOBALS['TL_DCA'][$strTable]['config']['dataContainer']; $objDca = new $strDriver($strTable); // AJAX request if ($_POST && Environment::get('isAjaxRequest')) { $this->objAjax->executePostActions($objDca); } $this->Session->set('filePickerRef', \Environment::get('request')); $arrValues = array_filter(explode(',', Input::get('value'))); // Convert UUIDs to binary foreach ($arrValues as $k => $v) { // Can be a UUID or a path if (Validator::isStringUuid($v)) { $arrValues[$k] = String::uuidToBin($v); } } // Prepare the widget $class = $GLOBALS['BE_FFL']['fileSelector']; $objFileTree = new $class($class::getAttributesFromDca($GLOBALS['TL_DCA'][$strTable]['fields'][$strField], $strField, $arrValues, $strField, $strTable, $objDca)); $this->Template->main = $objFileTree->generate(); $this->Template->theme = Backend::getTheme(); $this->Template->base = Environment::get('base'); $this->Template->language = $GLOBALS['TL_LANGUAGE']; $this->Template->title = specialchars($GLOBALS['TL_LANG']['MSC']['filepicker']); $this->Template->charset = Config::get('characterSet'); $this->Template->addSearch = false; $this->Template->search = $GLOBALS['TL_LANG']['MSC']['search']; $this->Template->action = ampersand(Environment::get('request')); $this->Template->value = $this->Session->get('file_selector_search'); $this->Template->manager = $GLOBALS['TL_LANG']['MSC']['fileManager']; $this->Template->managerHref = 'contao/main.php?do=files&popup=1'; $this->Template->breadcrumb = $GLOBALS['TL_DCA']['tl_files']['list']['sorting']['breadcrumb']; Config::set('debugMode', false); $this->Template->output(); }
/** * Import images and other media file for products * @param object * @param array * @return string */ public function generate($dc, $arrNewImages = array()) { $objTree = new \FileTree(\FileTree::getAttributesFromDca($GLOBALS['TL_DCA']['tl_iso_product']['fields']['source'], 'source', null, 'source', 'tl_iso_product')); // Import assets if (\Input::post('FORM_SUBMIT') == 'tl_iso_product_import' && \Input::post('source') != '') { $objFolder = \FilesModel::findByUuid(\String::uuidToBin(\Input::post('source'))); if (null !== $objFolder) { $this->importFromPath($objFolder->path); } } // Return form return ' <div id="tl_buttons"> <a href="' . ampersand(str_replace('&key=import', '', \Environment::get('request'))) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBT']) . '">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> <h2 class="sub_headline">' . $GLOBALS['TL_LANG']['tl_iso_product']['import'][1] . '</h2> <div class="tl_message"><div class="tl_info">' . $GLOBALS['TL_LANG']['tl_iso_product']['importAssetsDescr'] . '</div></div> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_iso_product_import" class="tl_form" method="post"> <div class="tl_formbody_edit iso_importassets"> <input type="hidden" name="FORM_SUBMIT" value="tl_iso_product_import"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <div class="tl_tbox block"> <h3><label for="source">' . $GLOBALS['TL_LANG']['tl_iso_product']['source'][0] . '</label></h3> ' . $objTree->generate() . (strlen($GLOBALS['TL_LANG']['tl_iso_product']['source'][1]) ? ' <p class="tl_help">' . $GLOBALS['TL_LANG']['tl_iso_product']['source'][1] . '</p>' : '') . ' </div> </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="save" id="save" class="tl_submit" alt="import product assets" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['tl_iso_product']['import'][0]) . '"> </div> </div> </form>'; }
protected function generateField($strName, $arrData, $skipValidation = false) { $strClass = $GLOBALS['TL_FFL'][$arrData['inputType']]; // overwrite the widget in readonly mode if ($this->viewMode == FORMHYBRID_VIEW_MODE_READONLY || $this->viewMode == FORMHYBRID_VIEW_MODE_DEFAULT && $this->addReadOnly && in_array($strName, $this->arrReadOnly)) { $strClass = 'HeimrichHannot\\FormHybrid\\FormReadonlyField'; $skipValidation = true; } $strInputMethod = $this->strInputMethod; // Continue if the class is not defined if (!class_exists($strClass)) { return false; } $arrWidgetErrors = array(); // contains the load_callback! $varDefault = $this->getDefaultFieldValue($strName, $arrData); $varValue = $varDefault; if ($this->isSubmitted && !$skipValidation) { $varValue = \Input::$strInputMethod($strName) !== null ? \Input::$strInputMethod($strName) : $varValue; $varValue = FormSubmission::prepareSpecialValueForSave($varValue, $arrData, $this->strTable, $this->intId, $varDefault, $arrWidgetErrors); } // overwrite required fields if ($this->overwriteRequired) { // set mandatory to false $arrData['eval']['mandatory'] = false; // overwrite mandatory by config if (!$arrData['eval']['mandatory'] && in_array($strName, $this->arrRequired)) { $arrData['eval']['mandatory'] = true; } } // prevent name for GET and submit widget, otherwise url will have submit name in if ($this->strMethod == FORMHYBRID_METHOD_GET && $arrData['inputType'] == 'submit') { $strName = ''; } $arrData['eval']['tagTable'] = $this->strTable; // always disable validation for filter form if ($this->isFilterForm) { $arrData['eval']['mandatory'] = false; } // to make captcha form related, add the form id without entity id if ($arrData['inputType'] == 'captcha') { $strName .= '_' . $this->getFormId(false); } $this->strField = $strName; $this->strInputName = $strName; $this->varValue = is_array($varValue) ? $varValue : \Controller::replaceInsertTags($varValue); $arrWidget = \Widget::getAttributesFromDca($arrData, $strName, is_array($varValue) ? $varValue : \Controller::replaceInsertTags($varValue), $strName, $this->strTable, $this); $this->updateWidget($arrWidget, $arrData); list($blnActive, $strSubPalette, $arrFields, $arrSubPaletteFields, $blnAutoSubmit, $blnToggleSubpalette) = $this->retrieveSubpaletteWithState($strName, array_keys($this->arrFields)); // support submitOnChange as form submission if ($arrData['eval']['submitOnChange'] && $blnToggleSubpalette) { if ($blnAutoSubmit) { $arrWidget['onchange'] = $this->async ? 'FormhybridAjaxRequest.asyncSubmit(this.form);' : "this.form.submit();"; } else { $strEvent = 'onclick'; switch ($arrData['inputType']) { case 'select': $strEvent = 'onchange'; break; } $arrWidget[$strEvent] = "FormhybridAjaxRequest.toggleSubpalette(this, 'sub_" . $strName . "', '" . $strName . "', '" . AjaxAction::generateUrl(Form::FORMHYBRID_NAME, 'toggleSubpalette') . "')"; unset($arrWidget['submitOnChange']); } } else { if ($arrWidget['submitOnChange']) { $strEvent = null; if ($arrWidget['onchange']) { $strEvent = 'onchange'; } else { if ($arrWidget['onclick']) { $strEvent = 'onclick'; } } if ($strEvent !== null) { $arrWidget[$strEvent] = "FormhybridAjaxRequest.reload('" . $this->getFormId() . "', '" . AjaxAction::generateUrl(Form::FORMHYBRID_NAME, 'reload') . "')"; unset($arrWidget['submitOnChange']); } } } $objWidget = new $strClass($arrWidget); if (isset($arrData['formHybridOptions'])) { $arrFormHybridOptions = $arrData['formHybridOptions']; $this->import($arrFormHybridOptions[0]); $objWidget->options = $this->{$arrFormHybridOptions}[0]->{$arrFormHybridOptions}[1](); } if ($objWidget instanceof \uploadable) { $this->hasUpload = true; } // always xss clean the user input (also if filter, non-model submission, ...) -> done another time // FrontendWidget::validateGetAndPost() in $objWidget->value = FormHelper::xssClean($objWidget->value, $arrData['eval']['allowHtml']); if ($this->isSubmitted) { // add filter class if filter is active if ($objWidget->value && $this->isFilterForm) { $objWidget->class = 'filtered'; } // do not validate fields if not submitted or skipvalidation issset // do not submit if ajax request and group is not formhybrid, for example multifileupload (otherwise captcha fields will be validated does not match visible one) if (!($this->isSkipValidation() || $skipValidation) && Ajax::isRelated(Form::FORMHYBRID_NAME) !== false) { FrontendWidget::validateGetAndPost($objWidget, $this->strMethod, $this->getFormId(), $arrData); if (is_array($arrWidgetErrors)) { foreach ($arrWidgetErrors as $strError) { $objWidget->addError($strError); } } // Make sure unique fields are unique if ($arrData['eval']['unique'] && $varValue != '' && !\Database::getInstance()->isUniqueValue($this->strTable, $strName, $varValue, $this->intId > 0 ? $this->intId : null)) { $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['unique'], $arrData['label'][0] ?: $strName)); } // trigger save_callbacks before assertion of the new value to objActiveRecord if (is_array($arrData['save_callback'])) { foreach ($arrData['save_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $varValue = $this->{$callback}[0]->{$callback}[1]($varValue, $this); } elseif (is_callable($callback)) { $varValue = $callback($varValue, $this); } } } if ($objWidget->hasErrors()) { $this->doNotSubmit = true; $this->arrInvalidFields[] = $strName; } elseif ($arrData['inputType'] == 'tag' && in_array('tags_plus', \ModuleLoader::getActive())) { $varValue = deserialize($objWidget->value); if (!is_array($varValue)) { $varValue = array($varValue); } if ($this->intId) { \HeimrichHannot\TagsPlus\TagsPlus::saveTags($this->strTable, $this->intId, array_map('urldecode', $varValue)); } } elseif ($objWidget->submitInput()) { // save non escaped to database if (is_array($objWidget->value)) { $this->objActiveRecord->{$strName} = array_map(function ($varVal) use($arrData) { $varVal = FormSubmission::prepareSpecialValueForSave($varVal, $arrData, $this->strTable, $this->intId); if (is_array($varVal)) { foreach ($varVal as $key => $val) { $varVal[$key] = html_entity_decode($val); } } else { $varVal = html_entity_decode($varVal); } return $varVal; }, $objWidget->value); } else { $this->objActiveRecord->{$strName} = html_entity_decode(FormSubmission::prepareSpecialValueForSave($objWidget->value, $arrData, $this->strTable, $this->intId)); } } elseif ($objWidget instanceof \uploadable && $arrData['inputType'] == 'multifileupload') { $strMethod = strtolower($this->strMethod); if (\Input::$strMethod($strName)) { $arrValue = json_decode(\Input::$strMethod($strName)); if (!empty($arrValue)) { $arrValue = array_map(function ($val) { return \String::uuidToBin($val); }, $arrValue); $this->objActiveRecord->{$strName} = serialize($arrValue); } else { $this->objActiveRecord->{$strName} = serialize($arrValue); } } // delete the files scheduled for deletion $objWidget->deleteScheduledFiles(json_decode(\Input::$strMethod('deleted_' . $strName))); } elseif ($objWidget instanceof \uploadable && isset($_SESSION['FILES'][$strName]) && \Validator::isUuid($_SESSION['FILES'][$strName]['uuid'])) { $this->objActiveRecord->{$strName} = $_SESSION['FILES'][$strName]['uuid']; } } } return $objWidget; }
/** * Save path in file, not a uuid by load dca * * @param * uuid */ public function loadFile($value) { return \String::uuidToBin($value); }
/** * Fix imageSort bug to add UUID support */ protected function updatePhotoalbums2AlbumImageSortField() { $objModel = $this->Database->prepare("SELECT id, imageSort FROM tl_photoalbums2_album")->execute(); while ($objModel->next()) { $arrItem = deserialize($objModel->imageSort); if (is_array($arrItem)) { foreach ($arrItem as $k => $v) { if (\Validator::isStringUuid($v)) { $arrItem[$k] = \String::uuidToBin($v); } } } $this->Database->prepare("UPDATE tl_photoalbums2_album %s WHERE id=?")->set(array('imageSort' => serialize($arrItem)))->execute($objModel->id); } }
/** * Adds a new item to the watchlist * @param WatchlistItemModel $objItem * @throws \Exception */ public function addItem(WatchlistItemModel $objItem) { // Throw an exception if there's no id: if (!\Validator::isStringUuid($objItem->uuid)) { throw new \Exception('The watchlist requires items with an unique file uuid.'); } $strUuid = $objItem->uuid; $objItem->uuid = \String::uuidToBin($objItem->uuid); // transform string to bin // Add or delete: if (isset($this->arrItems[$strUuid])) { \Input::setGet('act', WATCHLIST_ACT_DELETE); $this->deleteItem($strUuid); } else { $objItem = $objItem->save(); $this->arrItems[$strUuid] = $objItem; $this->arrIds[] = $strUuid; // Store the id, too! $this->addNotification(sprintf($GLOBALS['TL_LANG']['WATCHLIST']['notify_add_item'], $objItem->getTitle()), WATCHLIST_NOTIFICATION_ADD_ITEM); } }
/** * Get an image object from id/uuid and an optional size configuration * * @param int|string $id ID, UUID string or binary * @param string|array $size [width, height, mode] optionally serialized * @param int $maxSize Gets passed to addImageToTemplate as $intMaxWidth * @param string $lightboxId Gets passed to addImageToTemplate as $strLightboxId * @param array $item Gets merged and passed to addImageToTemplate as $arrItem * @return object Image object (similar as addImageToTemplate) */ public function getImageObject($id, $size = null, $maxSize = null, $lightboxId = null, $item = array()) { global $objPage; if (!$id) { return null; } if (strlen($id) === 36) { $id = \String::uuidToBin($id); } if (strlen($id) === 16) { $image = \FilesModel::findByUuid($id); } else { $image = \FilesModel::findByPk($id); } if (!$image) { return null; } try { $file = new \File($image->path, true); if (!$file->exists()) { return null; } } catch (\Exception $e) { return null; } $imageMeta = $this->getMetaData($image->meta, $objPage->language); if (is_string($size) && trim($size)) { $size = deserialize($size); } if (!is_array($size)) { $size = array(); } $size[0] = isset($size[0]) ? $size[0] : 0; $size[1] = isset($size[1]) ? $size[1] : 0; $size[2] = isset($size[2]) ? $size[2] : 'crop'; $image = array('id' => $image->id, 'uuid' => isset($image->uuid) ? $image->uuid : null, 'name' => $file->basename, 'singleSRC' => $image->path, 'size' => serialize($size), 'alt' => $imageMeta['title'], 'imageUrl' => $imageMeta['link'], 'caption' => $imageMeta['caption']); $image = array_merge($image, $item); $imageObject = new \FrontendTemplate('rsce_image_object'); $this->addImageToTemplate($imageObject, $image, $maxSize, $lightboxId); $imageObject = (object) $imageObject->getData(); if (empty($imageObject->src)) { $imageObject->src = $imageObject->singleSRC; } return $imageObject; }
/** * Dispatch an AJAX request * @param string * @param \DataContainer */ public function dispatchAjaxRequest($strAction, \DataContainer $dc) { switch ($strAction) { // Upload the file case 'fineuploader_upload': $arrData['strTable'] = $dc->table; $arrData['id'] = $this->strAjaxName ?: $dc->id; $arrData['name'] = \Input::post('name'); $objWidget = new $GLOBALS['BE_FFL']['fineUploader']($arrData, $dc); $strFile = $objWidget->validateUpload(); if ($objWidget->hasErrors()) { $arrResponse = array('success' => false, 'error' => $objWidget->getErrorAsString(), 'preventRetry' => true); } else { $arrResponse = array('success' => true, 'file' => $strFile); } echo json_encode($arrResponse); exit; break; // Reload the widget // Reload the widget case 'fineuploader_reload': $intId = \Input::get('id'); $strField = $dc->field = \Input::post('name'); $this->import('Database'); // Handle the keys in "edit multiple" mode if (\Input::get('act') == 'editAll') { $intId = preg_replace('/.*_([0-9a-zA-Z]+)$/', '$1', $strField); $strField = preg_replace('/(.*)_[0-9a-zA-Z]+$/', '$1', $strField); } // The field does not exist if (!isset($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField])) { $this->log('Field "' . $strField . '" does not exist in DCA "' . $dc->table . '"', __METHOD__, TL_ERROR); header('HTTP/1.1 400 Bad Request'); die('Bad Request'); } $objRow = null; $varValue = null; // Load the value if ($GLOBALS['TL_DCA'][$dc->table]['config']['dataContainer'] == 'File') { $varValue = $GLOBALS['TL_CONFIG'][$strField]; } elseif ($intId > 0 && $this->Database->tableExists($dc->table)) { $objRow = $this->Database->prepare("SELECT * FROM " . $dc->table . " WHERE id=?")->execute($intId); // The record does not exist if ($objRow->numRows < 1) { $this->log('A record with the ID "' . $intId . '" does not exist in table "' . $dc->table . '"', __METHOD__, TL_ERROR); header('HTTP/1.1 400 Bad Request'); die('Bad Request'); } $varValue = $objRow->{$strField}; $dc->activeRecord = $objRow; } // Call the load_callback if (is_array($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['load_callback'])) { foreach ($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['load_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $varValue = $this->{$callback}[0]->{$callback}[1]($varValue, $dc); } elseif (is_callable($callback)) { $varValue = $callback($varValue, $dc); } } } $varValue = \Input::post('value', true); // Convert the selected values if ($varValue != '') { $varValue = trimsplit(',', $varValue); foreach ($varValue as $k => $v) { if (\Validator::isUuid($v) && !is_file(TL_ROOT . '/' . $v)) { $varValue[$k] = \String::uuidToBin($v); } } $varValue = serialize($varValue); } // Build the attributes based on the "eval" array $arrAttribs = $GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['eval']; $arrAttribs['id'] = $dc->field; $arrAttribs['name'] = $dc->field; $arrAttribs['value'] = $varValue; $arrAttribs['strTable'] = $dc->table; $arrAttribs['strField'] = $strField; $arrAttribs['activeRecord'] = $dc->activeRecord; $objWidget = new $GLOBALS['BE_FFL']['fineUploader']($arrAttribs); echo $objWidget->parse(); exit; break; } }
/** * Field load callback * * Finds the current value for the field * * @param string $value Current value * @param \DataContainer $dc Data container * @return string Current value for the field */ public function loadCallback($value, $dc) { if ($value !== null) { return $value; } $value = $this->getNestedValue($dc->field); if ($value === null && isset($GLOBALS['TL_DCA'][$dc->table]['fields'][$dc->field]['default'])) { $value = $GLOBALS['TL_DCA'][$dc->table]['fields'][$dc->field]['default']; } if (version_compare(VERSION, '3.2', '>=') && $value && ($GLOBALS['TL_DCA'][$dc->table]['fields'][$dc->field]['inputType'] === 'fileTree' || $GLOBALS['TL_DCA'][$dc->table]['fields'][$dc->field]['inputType'] === 'fineUploader')) { // Multiple files if (substr($value, 0, 2) === 'a:') { $value = serialize(array_map(function ($value) { if (strlen($value) === 36) { $value = \String::uuidToBin($value); } else { if (is_numeric($value) && ($file = \FilesModel::findByPk($value))) { // Convert 3.1 format into 3.2 format $value = $file->uuid; } } return $value; }, deserialize($value))); } else { if (strlen($value) === 36) { $value = \String::uuidToBin($value); } else { if (is_numeric($value) && ($file = \FilesModel::findByPk($value))) { // Convert 3.1 format into 3.2 format $value = $file->uuid; } } } } return $value; }
/** * Move temp files. If DBAFS support is enabled add entries to the dbafs. * * @CtoCommunication Enable * * @param array $arrFileList List with files for moving. * * @param boolean $blnIsDbafs Flag if we have to change the dbafs system. * * @return array The list with some more information about the moving of the file. */ public function moveTempFile($arrFileList, $blnIsDbafs) { foreach ($arrFileList as $key => $value) { try { $blnMovedFile = false; $strTempFile = $this->objSyncCtoHelper->standardizePath($GLOBALS['SYC_PATH']['tmp'], "sync", $value["path"]); // Check if the tmp file exists. if (!file_exists(TL_ROOT . DIRECTORY_SEPARATOR . $strTempFile)) { $arrFileList[$key]['saved'] = false; $arrFileList[$key]['error'] = sprintf($GLOBALS['TL_LANG']['ERR']['unknown_file'], $strTempFile); $arrFileList[$key]['skipreasons'] = $GLOBALS['TL_LANG']['ERR']['missing_file_information']; continue; } // Generate the folder if not already there. $strFolderPath = dirname($value["path"]); if ($strFolderPath != ".") { $objFolder = new Folder($strFolderPath); unset($objFolder); } // Build folders. $strFileSource = $this->objSyncCtoHelper->standardizePath($GLOBALS['SYC_PATH']['tmp'], "sync", $value["path"]); $strFileDestination = $this->objSyncCtoHelper->standardizePath($value["path"]); // DBAFS support. Check if we have the file already in the locale dbafs system. if ($blnIsDbafs) { // Get the information from the dbafs. /** @var \Model $objLocaleData */ $objLocaleData = \FilesModel::findByPath($strFileDestination); // If we have no entry in the dbafs just overwrite the current file and add the entry to the dbafs. if ($objLocaleData == null) { // Move file. $blnMovedFile = $this->objFiles->copy($strFileSource, $strFileDestination); // If success add file to the database. if ($blnMovedFile) { // First add it to the dbafs. $objLocaleData = \Dbafs::addResource($strFileDestination); // PHP 7 compatibility // See #309 (https://github.com/contao/core-bundle/issues/309) if (version_compare(VERSION . '.' . BUILD, '3.5.5', '>=')) { $objLocaleData->uuid = \StringUtil::uuidToBin($value['tl_files']['uuid']); } else { $objLocaleData->uuid = \String::uuidToBin($value['tl_files']['uuid']); } $objLocaleData->meta = $value['tl_files']['meta']; $objLocaleData->save(); // Add a status report for debugging and co. $arrFileList[$key]['dbafs']['msg'] = 'Moved file and add to database.'; $arrFileList[$key]['dbafs']['state'] = SyncCtoEnum::DBAFS_CREATE; } } else { // PHP 7 compatibility // See #309 (https://github.com/contao/core-bundle/issues/309) if (version_compare(VERSION . '.' . BUILD, '3.5.5', '>=')) { // Get the readable UUID for the work. $strLocaleUUID = \StringUtil::binToUuid($objLocaleData->uuid); } else { // Get the readable UUID for the work. $strLocaleUUID = \String::binToUuid($objLocaleData->uuid); } // Okay it seems we have already a file with this values. if ($strLocaleUUID == $value['tl_files']['uuid']) { // Move file. $blnMovedFile = $this->objFiles->copy($strFileSource, $strFileDestination); // If success add file to the database. if ($blnMovedFile) { $objLocaleData->hash = $value['checksum']; $objLocaleData->meta = $value['tl_files']['meta']; $objLocaleData->save(); // Add a status report for debugging and co. $arrFileList[$key]['dbafs']['msg'] = 'UUID same no problem found. Update database with new hash.'; $arrFileList[$key]['dbafs']['state'] = SyncCtoEnum::DBAFS_SAME; } } elseif ($strLocaleUUID != $value['tl_files']['uuid']) { // Get information about the current file information. $arrDestinationInformation = pathinfo($strFileDestination); // Try to rename it to _1 or _2 and so on. $strNewDestinationName = null; $intFileNumber = 1; for ($i = 1; $i < 100; $i++) { $strNewDestinationName = sprintf('%s' . DIRECTORY_SEPARATOR . '%s_%s.%s', $arrDestinationInformation['dirname'], $arrDestinationInformation['filename'], $i, $arrDestinationInformation['extension']); if (!file_exists(TL_ROOT . DIRECTORY_SEPARATOR . $strNewDestinationName)) { $intFileNumber = $i; break; } } // Move the current file to another name, that we have space for the new one. $this->objFiles->copy($strFileDestination, $strNewDestinationName); $objRenamedLocaleData = \Dbafs::moveResource($strFileDestination, $strNewDestinationName); // Move the tmp file. $blnMovedFile = $this->objFiles->copy($strFileSource, $strFileDestination); // If success add file to the database. if ($blnMovedFile) { // First add it to the dbafs. $objLocaleData = \Dbafs::addResource($strFileDestination); // PHP 7 compatibility // See #309 (https://github.com/contao/core-bundle/issues/309) if (version_compare(VERSION . '.' . BUILD, '3.5.5', '>=')) { $objLocaleData->uuid = \StringUtil::uuidToBin($value['tl_files']['uuid']); } else { $objLocaleData->uuid = \String::uuidToBin($value['tl_files']['uuid']); } $objLocaleData->meta = $value['tl_files']['meta']; $objLocaleData->save(); // Add a status report for debugging and co. $arrFileList[$key]['dbafs']['msg'] = $GLOBALS['TL_LANG']['ERR']['dbafs_uuid_conflict']; $arrFileList[$key]['dbafs']['error'] = sprintf($GLOBALS['TL_LANG']['ERR']['dbafs_uuid_conflict_rename'], $intFileNumber); $arrFileList[$key]['dbafs']['rename'] = $strNewDestinationName; $arrFileList[$key]['dbafs']['state'] = SyncCtoEnum::DBAFS_CONFLICT; } } } } else { $blnMovedFile = $this->objFiles->copy($strFileSource, $strFileDestination); } // Check the state at moving and add a msg to the return array. if ($blnMovedFile) { $arrFileList[$key]['saved'] = true; $arrFileList[$key]['transmission'] = SyncCtoEnum::FILETRANS_MOVED; } else { $arrFileList[$key]['saved'] = false; $arrFileList[$key]['error'] = sprintf($GLOBALS['TL_LANG']['ERR']['cant_move_file'], $strFileSource, $strFileDestination); $arrFileList[$key]['transmission'] = SyncCtoEnum::FILETRANS_SKIPPED; $arrFileList[$key]['skipreason'] = $GLOBALS['TL_LANG']['ERR']['cant_move_files']; } } catch (Exception $e) { $arrFileList[$key]['saved'] = false; $arrFileList[$key]['error'] = sprintf('Can not move file - %s. Exception message: %s', $value["path"], $e->getMessage()); $arrFileList[$key]['transmission'] = SyncCtoEnum::FILETRANS_SKIPPED; $arrFileList[$key]['skipreason'] = $GLOBALS['TL_LANG']['ERR']['cant_move_files']; } } return $arrFileList; }
/** * Run the controller and parse the template */ public function run() { /** @var \BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_picker'); $objTemplate->main = ''; // Ajax request if ($_POST && \Environment::get('isAjaxRequest')) { $this->objAjax = new \Ajax(\Input::post('action')); $this->objAjax->executePreActions(); } $strTable = \Input::get('table'); $strField = \Input::get('field'); // Define the current ID define('CURRENT_ID', \Input::get('table') ? $this->Session->get('CURRENT_ID') : \Input::get('id')); $this->loadDataContainer($strTable); $strDriver = 'DC_' . $GLOBALS['TL_DCA'][$strTable]['config']['dataContainer']; $objDca = new $strDriver($strTable); $objDca->field = $strField; // Set the active record if ($this->Database->tableExists($strTable)) { /** @var \Model $strModel */ $strModel = \Model::getClassFromTable($strTable); if (class_exists($strModel)) { $objModel = $strModel::findByPk(\Input::get('id')); if ($objModel !== null) { $objDca->activeRecord = $objModel; } } } // AJAX request if ($_POST && \Environment::get('isAjaxRequest')) { $this->objAjax->executePostActions($objDca); } $this->Session->set('filePickerRef', \Environment::get('request')); $arrValues = array_filter(explode(',', \Input::get('value'))); // Convert UUIDs to binary foreach ($arrValues as $k => $v) { // Can be a UUID or a path if (\Validator::isStringUuid($v)) { $arrValues[$k] = \String::uuidToBin($v); } } // Call the load_callback if (is_array($GLOBALS['TL_DCA'][$strTable]['fields'][$strField]['load_callback'])) { foreach ($GLOBALS['TL_DCA'][$strTable]['fields'][$strField]['load_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $arrValues = $this->{$callback}[0]->{$callback}[1]($arrValues, $objDca); } elseif (is_callable($callback)) { $arrValues = $callback($arrValues, $objDca); } } } /** @var \FileSelector $strClass */ $strClass = $GLOBALS['BE_FFL']['fileSelector']; /** @var \FileSelector $objFileTree */ $objFileTree = new $strClass($strClass::getAttributesFromDca($GLOBALS['TL_DCA'][$strTable]['fields'][$strField], $strField, $arrValues, $strField, $strTable, $objDca)); $objTemplate->main = $objFileTree->generate(); $objTemplate->theme = \Backend::getTheme(); $objTemplate->base = \Environment::get('base'); $objTemplate->language = $GLOBALS['TL_LANGUAGE']; $objTemplate->title = specialchars($GLOBALS['TL_LANG']['MSC']['filepicker']); $objTemplate->charset = \Config::get('characterSet'); $objTemplate->addSearch = false; $objTemplate->search = $GLOBALS['TL_LANG']['MSC']['search']; $objTemplate->action = ampersand(\Environment::get('request')); $objTemplate->value = $this->Session->get('file_selector_search'); $objTemplate->manager = $GLOBALS['TL_LANG']['MSC']['fileManager']; $objTemplate->managerHref = 'contao/main.php?do=files&popup=1'; $objTemplate->breadcrumb = $GLOBALS['TL_DCA']['tl_files']['list']['sorting']['breadcrumb']; if (\Input::get('switch')) { $objTemplate->switch = $GLOBALS['TL_LANG']['MSC']['pagePicker']; $objTemplate->switchHref = str_replace('contao/file.php', 'contao/page.php', ampersand(\Environment::get('request'))); } \Config::set('debugMode', false); $objTemplate->output(); }
/** * Return an array if the "multiple" attribute is set * @param mixed * @return mixed */ protected function validator($varInput) { // Store the order value if ($this->orderField != '') { $arrNew = array_map('String::uuidToBin', explode(',', \Input::post($this->strOrderName))); // Only proceed if the value has changed if ($arrNew !== $this->{$this->orderField}) { $this->Database->prepare("UPDATE {$this->strTable} SET tstamp=?, {$this->orderField}=? WHERE id=?")->execute(time(), serialize($arrNew), $this->activeRecord->id); $this->objDca->createNewVersion = true; // see #6285 } } // Return the value as usual if ($varInput == '') { if ($this->mandatory) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['mandatory'], $this->strLabel)); } return ''; } elseif (strpos($varInput, ',') === false) { $varInput = \String::uuidToBin($varInput); return $this->multiple ? array($varInput) : $varInput; } else { $arrValue = array_filter(explode(',', $varInput)); return $this->multiple ? array_map('String::uuidToBin', $arrValue) : \String::uuidToBin($arrValue[0]); } }
/** * Find multiple files by UUID and a list of extensions * * @param array $arrUuids An array of file UUIDs * @param array $arrExtensions An array of file extensions * @param array $arrOptions An optional options array * * @return \Model\Collection|null A collection of models or null of there are no matching files */ public static function findMultipleByUuidsAndExtensions($arrUuids, $arrExtensions, array $arrOptions = array()) { if (!is_array($arrUuids) || empty($arrUuids) || !is_array($arrExtensions) || empty($arrExtensions)) { return null; } foreach ($arrExtensions as $k => $v) { if (!preg_match('/^[a-z0-9]{2,5}$/i', $v)) { unset($arrExtensions[$k]); } } $t = static::$strTable; foreach ($arrUuids as $k => $v) { // Convert UUIDs to binary if (\Validator::isStringUuid($v)) { $v = \String::uuidToBin($v); } $arrUuids[$k] = "UNHEX('" . bin2hex($v) . "')"; } if (!isset($arrOptions['order'])) { $arrOptions['order'] = "{$t}.uuid!=" . implode(", {$t}.uuid!=", $arrUuids); } return static::findBy(array("{$t}.uuid IN(" . implode(",", $arrUuids) . ") AND {$t}.extension IN('" . implode("','", $arrExtensions) . "')"), null, $arrOptions); }
/** * Validate the single file * @param mixed * @param string * @return mixed */ protected function validatorSingle($varFile, $strDestination) { $varOld = $varFile; // Move the temporary file if (!\Validator::isStringUuid($varFile) && is_file(TL_ROOT . '/' . $varFile)) { $varFile = $this->moveTemporaryFile($varFile, $strDestination); } // Convert uuid to binary format if (\Validator::isStringUuid($varFile)) { $varFile = \String::uuidToBin($varFile); } // Store in the mapper $this->arrFilesMapper[$varOld] = $varFile; return $varFile; }