function handleDam() { if ($this->useDam()) { $bSimulatedUser = FALSE; global $BE_USER; if (!isset($BE_USER) || !is_object($BE_USER) || intval($GLOBALS["BE_USER"]->user["uid"]) === 0) { // no be_user available // we are using the one created for formidable+dam, named _formidable+dam $rSql = $GLOBALS["TYPO3_DB"]->exec_SELECTquery("uid", "be_users", "LOWER(username)='_formidable+dam'"); if (($aRs = $GLOBALS["TYPO3_DB"]->sql_fetch_assoc($rSql)) !== FALSE) { // we found user _formidable+dam // simulating user unset($BE_USER); $BE_USER = t3lib_div::makeInstance('t3lib_beUserAuth'); $BE_USER->OS = TYPO3_OS; $BE_USER->setBeUserByUid($aRs["uid"]); $BE_USER->fetchGroupData(); $BE_USER->backendSetUC(); $GLOBALS['BE_USER'] = $BE_USER; $bSimulatedUser = TRUE; } else { $this->oForm->mayday("renderlet:UPLOAD[name=" . $this->_getName() . "] /dam/use is enabled; for DAM to operate properly, you have to create a backend-user named '_formidable+dam' with permissions on dam tables"); } } if ($this->isMultiple()) { $aFiles = t3lib_div::trimExplode(",", $this->getValue()); } else { $aFiles = array($this->getValue()); } reset($aFiles); while (list(, $sFileName) = each($aFiles)) { $sFilePath = $this->getServerPath($sFileName); tx_dam::notify_fileChanged($sFilePath); $oMedia = tx_dam::media_getForFile($sFilePath); if (($mTitle = $this->_navConf("/dam/addtitle")) !== FALSE) { if (tx_ameosformidable::isRunneable($mTitle)) { $mTitle = $this->callRunneable($mTitle, array("filename" => $sFileName, "filepath" => $sFilePath, "media" => $oMedia, "currentcats" => $aCurCats, "files" => $aFiles)); } $oMedia->meta["title"] = $mTitle; if (trim($mTitle) !== '') { $oMedia->meta["title"] = $mTitle; } } if (($mDescription = $this->_navConf("/dam/adddescription")) !== FALSE) { if (tx_ameosformidable::isRunneable($mDescription)) { $mDescription = $this->callRunneable($mDescription, array("filename" => $sFileName, "filepath" => $sFilePath, "media" => $oMedia, "currentcats" => $aCurCats, "files" => $aFiles)); } $oMedia->meta["description"] = $mDescription; if (trim($mDescription) !== '') { $oMedia->meta["description"] = $mDescription; } } if (($mCaption = $this->_navConf("/dam/addcaption")) !== FALSE) { if (tx_ameosformidable::isRunneable($mCaption)) { $mCaption = $this->callRunneable($mCaption, array("filename" => $sFileName, "filepath" => $sFilePath, "media" => $oMedia, "currentcats" => $aCurCats, "files" => $aFiles)); } if (trim($mCaption) !== '') { $oMedia->meta["caption"] = $mCaption; } } if (($mCategories = $this->_navConf("/dam/addcategories")) !== FALSE) { require_once PATH_txdam . "lib/class.tx_dam_db.php"; $aCurCats = $GLOBALS["TYPO3_DB"]->exec_SELECTgetRows("uid_foreign", "tx_dam_mm_cat", "uid_local='" . $oMedia->meta["uid"] . "'", "", "sorting ASC"); if (!is_array($aCurCats)) { $aCurCats = array(); } reset($aCurCats); while (list($sKey, ) = each($aCurCats)) { $aCurCats[$sKey] = $aCurCats[$sKey]["uid_foreign"]; } if (tx_ameosformidable::isRunneable($mCategories)) { $mCategories = $this->callRunneable($mCategories, array("filename" => $sFileName, "filepath" => $sFilePath, "media" => $oMedia, "currentcats" => $aCurCats, "files" => $aFiles)); } $aCategories = array(); if (!is_array($mCategories)) { if (trim($mCategories) !== "") { $aCategories = t3lib_div::trimExplode(",", trim($mCategories)); } } else { $aCategories = $mCategories; } if (count($aCategories) > 0) { reset($aCurCats); $aCategories = array_unique(array_merge($aCurCats, $aCategories)); if (!empty($aCategories)) { $oMedia->meta["category"] = implode(",", $aCategories); } } } tx_dam_db::insertUpdateData($oMedia->meta); } if ($bSimulatedUser === TRUE) { unset($BE_USER); unset($GLOBALS["BE_USER"]); } } }
/** * Set all records deleted that matches/begins with the given path. * * @param string $path path * @return void */ function updateFilePathSetDeleted($path) { $path = tx_dam::path_makeRelative($path); // this way db trigger will not work // $GLOBALS['TYPO3_DB']->exec_UPDATEquery('tx_dam', 'tx_dam.file_path LIKE BINARY '.$GLOBALS['TYPO3_DB']->fullQuoteStr($GLOBALS['TYPO3_DB']->escapeStrForLike($path, 'tx_dam').'%', 'tx_dam'), array('deleted'=>'1')); $where = array(); $where['enableFields'] = ''; $where['pidList'] = ''; $likeStr = $GLOBALS['TYPO3_DB']->escapeStrForLike($path, 'tx_dam'); $where['file_path'] = 'tx_dam.file_path LIKE BINARY ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($likeStr . '%', 'tx_dam'); $rows = tx_dam_db::getDataWhere('tx_dam.uid', $where); foreach ($rows as $row) { $row['deleted'] = '1'; tx_dam_db::insertUpdateData($row); } }
/** * Notifies the DAM about a deleted file or folder. * This will remove the file(s) from the index. * * @param string $filename Filename with path or a folder which have to have a trailing slash. * @param string $recyclerPath New path when item is moved to recycler. * @return void */ function notify_fileDeleted($filename, $recyclerPath = '') { if (is_array($row = tx_dam::meta_getDataForFile($filename, 'uid', true))) { $uid = $row['uid']; } if ($uid) { $fields_values = array(); $fields_values['uid'] = $uid; $fields_values['deleted'] = '1'; // file was moved to recycler if ($recyclerPath) { $org_filename = tx_dam::file_basename($filename); $path_parts = t3lib_div::split_fileref($recyclerPath); $new_filename = $path_parts['file']; $new_path = $path_parts['path']; if ($org_filename != $new_filename) { $fields_values['file_name'] = $new_filename; } if ($new_path) { $fields_values['file_path'] = tx_dam::path_makeRelative($new_path); } } else { // delete MM relations $GLOBALS['TYPO3_DB']->exec_DELETEquery('tx_dam_mm_ref', 'tx_dam_mm_ref.uid_local=' . $uid); } tx_dam_db::insertUpdateData($fields_values); // set language overlays deleted $GLOBALS['TYPO3_DB']->exec_UPDATEquery('tx_dam', 'l18n_parent=' . $uid, array('deleted' => 1)); # $GLOBALS['TYPO3_DB']->exec_DELETEquery('tx_dam', 'l18n_parent='.$uid); // todo: replace with full supported group concept -------------------- // todo: delete child elements and their MM-relation // files stay at their physical storage position (usually uploads/tx_dam/storage/_uid_/) $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'tx_dam', 'parent_id=' . intval($uid)); while ($childRow = $GLOBALS['TYPO3_DB']->sql_fetch_row($res)) { $childUid = $childRow[0]; $GLOBALS['TYPO3_DB']->exec_UPDATEquery('tx_dam', 'uid=' . $childUid, array('deleted' => 1)); $GLOBALS['TYPO3_DB']->exec_DELETEquery('tx_dam_mm_ref', 'tx_dam_mm_ref.uid_local=' . $childUid); } // ------------------------------------ } elseif (preg_match('#/$#', $filename)) { tx_dam_db::updateFilePathSetDeleted($filename); } }
/** * Indexing a single file. * Use indexUsingCurrentSetup() or indexFiles() instead. * * @param string $filepath: file path or array: array('processFile' => 'path to file that should be indexed', 'metaFile' => 'additional file that holds meta data for the file to be indexed') * @param integer $crdate: timestamp of the index run * @param integer $pid: The sysfolder to store the meta data record * @param mixed $metaCallbackFunc Will be called to process the meta data * @param mixed $filePreprocessingCallbackFunc Will be called to allow preprocessing of the file before indexing * @param array $metaPreset: Meta data preset. $meta['fields'] has the record data. * @return array Meta data array. $meta['fields'] has the record data. */ function indexFile($filepath, $crdate = 0, $pid = NULL, $metaCallbackFunc = NULL, $filePreprocessingCallbackFunc = NULL, $metaPreset = array()) { global $TYPO3_CONF_VARS; $pathname = $this->getFilePath($filepath); $pathname = tx_dam::file_absolutePath($pathname); // locks the indexing for the current file // If the file is currently indexed this will return false if (!$this->lock($pathname)) { return FALSE; } $pid = is_null($pid) ? $this->pid : $pid; if ($filePreprocessingCallbackFunc) { call_user_func($filePreprocessingCallbackFunc, 'filePreprocessing', $pathname, $this); if ($this->writeDevLog) { t3lib_div::devLog('indexFile(): call filePreprocessingCallbackFunc', 'tx_dam_indexing', 0, $filePreprocessingCallbackFunc); } } // might be possible to have $pathname call by reference and change the filename - usable for copying files before indexing??? Needs to be tested. // Answer: Note that the parameters for call_user_func() are not passed by reference. $meta = $this->getFileNodeInfo($pathname, true); if ($metaFile = $this->getMetaFilePath($filepath)) { $meta['metaFile'] = $metaFile; } if ($this->skipThisFile($meta['file'])) { unset($meta); $this->log('Skipped file: ' . $pathname, 1, 0); if ($this->writeDevLog) { t3lib_div::devLog('indexFile(): file skipped: ' . $pathname, 'tx_dam_indexing'); } } elseif (is_array($meta)) { if ($this->writeDevLog) { t3lib_div::devLog('indexFile() - got file node info: ' . $pathname, 'tx_dam_indexing', 0, $meta); } if ($this->writeDevLog and $metaPreset) { t3lib_div::devLog('indexFile: use meta preset', 'tx_dam_indexing', 0, $metaPreset); } $meta = t3lib_div::array_merge_recursive_overrule($metaPreset, $meta); $status = tx_dam::index_check($meta['fields'], $meta['fields']['file_hash']); $uid = intval($status['meta']['uid']); if ($uid) { if ($this->writeDevLog) { t3lib_div::devLog('indexFile(): file already indexed (uid:' . $uid . ')', 'tx_dam_indexing', 0, $status); } $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'tx_dam', 'uid=' . intval($uid)); $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); if ($this->writeDevLog) { t3lib_div::devLog('indexFile(): fetch index data for reindexing', 'tx_dam_indexing', 0, $row); } // this is needed for fields like group/MM require_once PATH_t3lib . 'class.t3lib_transferdata.php'; $processData = t3lib_div::makeInstance('t3lib_transferData'); $row = $processData->renderRecordRaw('tx_dam', $row['uid'], $row['pid'], $row); if ($this->writeDevLog) { t3lib_div::devLog('indexFile(): call t3lib_transferdata->renderRecordRaw() for data from index', 'tx_dam_indexing', 0, $row); } // index rule use 'row' for merging $meta['row'] = $row; $meta['indexExist'] = true; $meta['reindexed'] = $this->doReindexing; } else { $uid = 'NEW'; $meta['indexExist'] = false; $meta['reindexed'] = false; } // TODO handle TXDAM_file_missing and reconnect file to index if ($status['__status'] == TXDAM_file_unknown or $status['__status'] > TXDAM_file_unknown and $this->doReindexing) { $mimeType = array(); $mimeType['fields'] = $this->getFileMimeType($pathname); $meta = t3lib_div::array_merge_recursive_overrule(array('fields' => $this->getDefaultRecord()), $meta); $meta = t3lib_div::array_merge_recursive_overrule($meta, $mimeType); $meta['fields']['uid'] = $uid; $meta['fields']['pid'] = $pid; $meta['fields']['index_type'] = $this->indexRunType; $meta = $this->getFileMetaInfo($pathname, $meta); if ($meta['textExtract']) { $meta['textExtract'] = $this->processTextExcerpt($meta['textExtract']); } else { $meta['textExtract'] = $this->getFileTextExcerpt($pathname, $meta['fields']['file_type']); } $meta['fields']['search_content'] = $meta['textExtract']; $meta['fields']['abstract'] = $meta['fields']['abstract'] ? $meta['fields']['abstract'] : trim($meta['fields']['search_content']); $meta['fields']['language'] = $this->getMetaLanguage($meta); $meta['fields']['file_dl_name'] = $meta['fields']['file_dl_name'] ? $meta['fields']['file_dl_name'] : $meta['fields']['file_name']; $meta['fields']['crdate'] = $crdate ? $crdate : time(); $meta['fields']['tstamp'] = time(); $meta['fields']['cruser_id'] = intval($GLOBALS['BE_USER']->user['uid']); $meta['fields']['date_cr'] = $meta['fields']['date_cr'] ? $meta['fields']['date_cr'] : time(); $meta['fields']['date_mod'] = $meta['fields']['date_mod'] ? $meta['fields']['date_mod'] : $meta['fields']['date_cr']; // TODO category handling - merging? # $fieldsUpdated = tx_dam_db::getUpdateData($meta['fields'], $this->replaceData, $this->appendData); foreach ($this->dataPreset as $field => $value) { if ($value and !$meta['fields'][$field]) { $meta['fields'][$field] = $value; } } $fieldsUpdated = tx_dam_db::getUpdateData($meta['fields'], $this->dataPostset, $this->dataAppend); $meta['fields'] = array_merge($meta['fields'], $fieldsUpdated); $meta = $this->rulesCallback('process', $meta, $pathname); if ($metaCallbackFunc) { $meta = call_user_func($metaCallbackFunc, 'process', $meta, $pathname, $this); if ($this->writeDevLog) { t3lib_div::devLog('indexFile(): call_user_func: ' . @get_class($metaCallbackFunc[0]) . '->' . $metaCallbackFunc[1] . ' (process)', 'tx_dam_indexing', 0, $meta); } } $meta['failure'] = false; if (!$this->dryRun) { if ($this->writeDevLog) { t3lib_div::devLog('indexFile(): call tx_dam_db::insertUpdateData()', 'tx_dam_indexing', 0, $meta['fields']); } $meta['fields']['uid'] = tx_dam_db::insertUpdateData($meta['fields']); if (!intval($meta['fields']['uid'])) { list($error, $errorMsg) = tx_dam_db::getLastError(); $meta['failure'] = 'Meta record could not be inserted: ' . $errorMsg; $this->log('Meta record could not be inserted: ' . $pathname . '. ' . $errorMsg, 1, 1); } else { if ($this->writeDevLog) { $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'tx_dam', 'uid=' . intval($meta['fields']['uid'])); } if ($this->writeDevLog) { $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); } if ($this->writeDevLog) { t3lib_div::devLog('indexFile(): written to index', 'tx_dam_indexing', 0, $row); } } } if (intval($meta['fields']['uid'])) { $meta['isIndexed'] = true; $this->infoList[] = array('uid' => $meta['fields']['uid'], 'title' => $meta['fields']['title'], 'file_name' => $meta['fields']['file_name'], 'file_path' => $meta['fields']['file_path'], 'reindexed' => $meta['reindexed']); $this->stat['newIndexed'] += $meta['reindexed'] ? 0 : 1; $this->stat['reIndexed'] += $meta['reindexed'] ? 1 : 0; } $meta = $this->rulesCallback('post', $meta, $pathname); if ($metaCallbackFunc) { $meta = call_user_func($metaCallbackFunc, 'post', $meta, $pathname, $this); if ($this->writeDevLog) { t3lib_div::devLog('indexFile(): call_user_func: ' . @get_class($metaCallbackFunc[0]) . '->' . $metaCallbackFunc[1] . ' (post)', 'tx_dam_indexing', 0, $meta); } } $currentUid = intval($meta['fields']['uid']) ? $meta['fields']['uid'] : '_NO_UID_' . (string) intval($this->noIdCounter++); if ($this->collectMeta) { $this->meta[$currentUid] = $meta; } // todo: indexing of childs to this file - eg. images from a OpenOffice file if (is_array($meta['childs'])) { foreach ($meta['childs'] as $fileDef) { $pathname = $fileDef['pathname']; if (file_exists($pathname)) { if ($meta['fields']['file_hash'] and $fileDef['fileStorageType'] === 'moveToInternal') { $storageFolder = PATH_site . 'uploads/tx_dam/storage/' . $meta['fields']['file_hash'] . '/'; $targetFile = $storageFolder . tx_dam::file_basename($pathname); if (!is_dir($storageFolder)) { t3lib_div::mkdir($storageFolder); } @unlink($targetFile); rename($pathname, $targetFile); $pathname = $targetFile; } $metaPreset = is_array($fileDef['metaPreset']) ? $fileDef['metaPreset'] : array(); $metaPreset['fields']['parent_id'] = $currentUid; $this->indexFile($pathname, $crdate, $pid, $metaCallbackFunc, $filePreprocessingCallbackFunc, $metaPreset); } } } $this->statMeta($meta); $this->unlock(); return $meta; } elseif (is_array($meta['row'])) { $meta['fields'] = $meta['row']; $this->statMeta($meta); $this->unlock(); return $meta; } } else { if (!@is_file($pathname)) { $this->log('Is not a file: ' . $pathname, 1, 1); } elseif (!@is_readable($pathname)) { $this->log('Is not readable: ' . $pathname, 1, 1); } } $this->unlock(); return FALSE; }