Project

General

Profile

Feature #16887 » irre_RC1_stress_3.patch

Administrator Admin, 2007-02-03 12:05

View differences:

t3lib/class.t3lib_tceforms.php (Arbeitskopie)
'thumbnails' => $thumbsnail,
'readOnly' => $disabled
);
$item.= $this->dbFileIcons($PA['itemFormElName'],'db',implode(',',$tempFT),$itemArray,'',$params,$PA['onFocus']);
$item.= $this->dbFileIcons($PA['itemFormElName'],'db',implode(',',$tempFT),$itemArray,'',$params,$PA['onFocus'],$table,$field,$row['uid']);
break;
}
......
* @param string Alternative selector box.
* @param array An array of additional parameters, eg: "size", "info", "headers" (array with "selector" and "items"), "noBrowser", "thumbnails"
* @param string On focus attribute string
* @param string $table: (optional) Table name processing for
* @param string $field: (optional) Field of table name processing for
* @param string $uid: (optional) uid of table record processing for
* @return string The form fields for the selection.
*/
function dbFileIcons($fName,$mode,$allowed,$itemArray,$selector='',$params=array(),$onFocus='') {
function dbFileIcons($fName,$mode,$allowed,$itemArray,$selector='',$params=array(),$onFocus='',$table='',$field='',$uid='') {
$disabled = '';
......
);
if (!$params['readOnly']) {
if (!$params['noBrowser']) {
$aOnClick='setFormValueOpenBrowser(\''.$mode.'\',\''.($fName.'|||'.$allowed.'|').'\'); return false;';
// check against inline uniqueness
$inlineParent = $this->inline->getStructureLevel(-1);
if(is_array($inlineParent) && $inlineParent['uid']) {
if ($inlineParent['config']['foreign_table'] == $table && $inlineParent['config']['foreign_unique'] == $field) {
$objectPrefix = $this->inline->inlineNames['object'].'['.$table.']';
$aOnClickInline = $objectPrefix.'|inline.checkUniqueElement|inline.setUniqueElement';
$rOnClickInline = 'inline.revertUnique(\''.$objectPrefix.'\',null,\''.$uid.'\');';
}
}
$aOnClick='setFormValueOpenBrowser(\''.$mode.'\',\''.($fName.'|||'.$allowed.'|'.$aOnClickInline).'\'); return false;';
$icons['R'][]='<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
'<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/insert3.gif','width="14" height="14"').' border="0" '.t3lib_BEfunc::titleAltAttrib($this->getLL('l_browse_'.($mode=='file'?'file':'db'))).' />'.
'</a>';
......
'<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/insert5.png','width="14" height="14"').' border="0" '.t3lib_BEfunc::titleAltAttrib(sprintf($this->getLL('l_clipInsert_'.($mode=='file'?'file':'db')),count($clipElements))).' />'.
'</a>';
}
$icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$fName.'\',\'Remove\'); return false;">'.
$rOnClick = $rOnClickInline.'setFormValueManipulate(\''.$fName.'\',\'Remove\'); return false';
$icons['L'][]='<a href="#" onclick="'.htmlspecialchars($rOnClick).'">'.
'<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/group_clear.gif','width="14" height="14"').' border="0" '.t3lib_BEfunc::titleAltAttrib($this->getLL('l_remove_selected')).' />'.
'</a>';
}
t3lib/jsfunc.inline.js (Arbeitskopie)
prependFormFieldNames: 'data',
noTitleString: '[No title]',
data: {},
addToDataArray: function(object) {
for (var i in object) {
this.data[i] = $H(this.data[i]).merge(object[i]);
}
},
setPrependFormFieldNames: function(value) {
this.prependFormFieldNames = value;
},
setNoTitleString: function(value) {
this.noTitleString = value;
},
addToDataArray: function(object) { for (var i in object) { this.data[i] = $H(this.data[i]).merge(object[i]); } },
setPrependFormFieldNames: function(value) { this.prependFormFieldNames = value; },
setNoTitleString: function(value) { this.noTitleString = value; },
expandCollapseRecord: function(objectId, expandSingle) {
var currentUid = this.parseFormElementName('none', objectId, 1);
var objectPrefix = this.parseFormElementName('full', objectId, 0, 1);
var currentState = '';
var collapse = new Array();
var expand = new Array();
......
Element.toggle(objectId+'_fields');
currentState = Element.visible(objectId+'_fields') ? 1 : 0
if (this.isNewRecord(objectId))
this.updateExpandedCollapsedStateLocally(objectId, currentState);
else if (currentState)
......
collapse.push(currentUid);
this.setExpandedCollapsedState(objectId, expand.join(','), collapse.join(','));
return false;
},
......
}
}
}
return collapse;
},
updateExpandedCollapsedStateLocally: function(objectId, value) {
var ucName = 'uc'+this.parseFormElementName('parts', objectId, 3, 2);
var ucFormObj = document.getElementsByName(ucName);
if (ucFormObj.length) ucFormObj[0].value = value;
},
createNewRecord: function(objectId,prevRecordUid) {
if (this.isBelowMax(objectId)) this.makeAjaxCall('createNewRecord', objectId+(prevRecordUid ? '['+prevRecordUid+']' : ''));
else alert('There are no more relations possible at this moment!');
......
},
setExpandedCollapsedState: function(objectId, expand, collapse) {
// alert(objectId+': '+expand+', '+collapse);
this.makeAjaxCall('setExpandedCollapsedState', objectId, expand, collapse);
},
makeAjaxCall: function() {
if (arguments.length > 1) {
var params = '';
......
onSuccess: inline.processAjaxResponse,
onFailure: inline.showAjaxFailure
};
new Ajax.Request(url, options);
}
},
processAjaxResponse: function(xhr) {
var json = eval('('+xhr.responseText+')');
for (var i in json.scriptCall) eval(json.scriptCall[i]);
......
showAjaxFailure: function(xhr) {
alert('Error: '+xhr.status+"\n"+xhr.statusText);
},
// foreign_selector: used by selector box (type='select')
importNewRecord: function(objectId) {
var selector = $(objectId+'_selector');
if (selector.selectedIndex != -1) {
......
}
return false;
},
// foreign_selector: used by element browser (type='group/db')
importElement: function(objectId, table, uid, type) {
window.setTimeout(
function() {
inline.makeAjaxCall('createNewRecord', objectId, uid);
},
10
);
},
// Check uniqueness for element browser:
checkUniqueElement: function(objectId, table, uid, type) {
if (this.checkUniqueUsed(objectId, uid, table)) {
return {passed: false,message: 'There is already a relation to the selected element!'};
} else {
return {passed: true};
}
},
// Checks if a record was used and should be unique:
checkUniqueUsed: function(objectId, uid, table) {
if (this.data.unique && this.data.unique[objectId]) {
var unique = this.data.unique[objectId];
var values = $H(unique.used).values();
// for select: only the uid is stored
if (unique['type'] == 'select') {
if (values.indexOf(uid) != -1) return true;
// for group/db: table and uid is stored in a assoc array
} else if (unique.type == 'groupdb') {
for (var i=values.length-1; i>=0; i--) {
// if the pair table:uid is already used:
if (values[i].table==table && values[i].uid==uid) return true;
}
}
}
return false;
},
setUniqueElement: function(objectId, table, uid, type, elName) {
var recordUid = this.parseFormElementName('none', elName, 1, 1);
// alert(objectId+'/'+table+'/'+uid+'/'+recordUid);
this.setUnique(objectId, recordUid, uid);
},
// this function is applied to a newly inserted record by AJAX
// it removes the used select items, that should be unique
setUnique: function(objectId, recordUid, selectedValue) {
if (this.data.unique && this.data.unique[objectId]) {
var unique = this.data.unique[objectId];
// remove used items from each select-field of the child records
if (!(unique.selector && unique.max == -1)) {
var elName = this.parseFormElementName('full', objectId, 1)+'['+recordUid+']['+unique.field+']';
var formName = this.prependFormFieldNames+this.parseFormElementName('parts', objectId, 3, 1);
if (unique.type == 'select') {
// remove used items from each select-field of the child records
if (!(unique.selector && unique.max == -1)) {
var elName = this.parseFormElementName('full', objectId, 1)+'['+recordUid+']['+unique.field+']';
var formName = this.prependFormFieldNames+this.parseFormElementName('parts', objectId, 3, 1);
var fieldObj = document.getElementsByName(elName);
var values = $H(unique.used).values();
if (fieldObj.length) {
// remove all before used items from the new select-item
for (var i=0; i<values.length; i++) this.removeSelectOption(fieldObj[0], values[i]);
// set the selected item automatically to the first of the remaining items
selectedValue = fieldObj[0].options[0].value;
fieldObj[0].options[0].selected = true;
this.updateUnique(fieldObj[0], objectId, formName, recordUid);
this.handleChangedField(fieldObj[0], objectId+'['+recordUid+']');
if (typeof this.data.unique[objectId]['used'].length != 'undefined')
this.data.unique[objectId]['used'] = {};
this.data.unique[objectId]['used'][recordUid] = selectedValue;
var fieldObj = document.getElementsByName(elName);
var values = $H(unique.used).values();
if (fieldObj.length) {
// remove all before used items from the new select-item
for (var i=0; i<values.length; i++) this.removeSelectOption(fieldObj[0], values[i]);
// set the selected item automatically to the first of the remaining items
selectedValue = fieldObj[0].options[0].value;
fieldObj[0].options[0].selected = true;
this.updateUnique(fieldObj[0], objectId, formName, recordUid);
this.handleChangedField(fieldObj[0], objectId+'['+recordUid+']');
if (typeof this.data.unique[objectId].used.length != 'undefined') {
this.data.unique[objectId].used = {};
}
this.data.unique[objectId].used[recordUid] = selectedValue;
}
}
} else if (unique.type == 'groupdb') {
// add the new record to the used items:
this.data.unique[objectId].used[recordUid] = {'table':unique.elTable, 'uid':selectedValue};
}
// remove used items from a selector-box
if (unique.selector && selectedValue) {
if (unique.selector == 'select' && selectedValue) {
var selector = $(objectId+'_selector');
this.removeSelectOption(selector, selectedValue);
this.data.unique[objectId]['used'][recordUid] = selectedValue;
}
}
},
domAddNewRecord: function(method, insertObject, objectPrefix, htmlData) {
if (this.isBelowMax(objectPrefix)) {
if (method == 'bottom')
......
new Insertion.After(insertObject, htmlData);
}
},
changeSorting: function(objectId, direction) {
var objectName = this.prependFormFieldNames+this.parseFormElementName('parts', objectId, 3, 2);
var objectPrefix = this.parseFormElementName('full', objectId, 0, 1);
var formObj = document.getElementsByName(objectName);
if (formObj.length) {
// the uid of the calling object (last part in objectId)
var callingUid = this.parseFormElementName('none', objectId, 1);
var records = formObj[0].value.split(',');
var current = records.indexOf(callingUid);
var changed = false;
// move up
if (direction > 0 && current > 0) {
records[current] = records[current-1];
records[current-1] = callingUid;
changed = true;
// move down
} else if (direction < 0 && current < records.length-1) {
records[current] = records[current+1];
records[current+1] = callingUid;
changed = true;
}
if (changed) {
formObj[0].value = records.join(',');
var cAdj = direction > 0 ? 1 : 0; // adjustment
......
this.redrawSortingButtons(objectPrefix, records);
}
}
return false;
},
dragAndDropSorting: function(element) {
var objectId = element.getAttribute('id').replace(/_records$/, '');
var objectName = inline.prependFormFieldNames+inline.parseFormElementName('parts', objectId, 3);
......
}
}
},
createDragAndDropSorting: function(objectId) {
Sortable.create(
objectId,
......
}
);
},
destroyDragAndDropSorting: function(objectId) {
Sortable.destroy(objectId);
},
redrawSortingButtons: function(objectPrefix, records) {
var i;
var headerObj;
var sortingObj = new Array();
// if no records were passed, fetch them from form field
if (typeof records == 'undefined') {
records = new Array();
......
var formObj = document.getElementsByName(objectName);
if (formObj.length) records = formObj[0].value.split(',');
}
for (i=0; i<records.length; i++) {
if (!records[i].length) continue;
headerObj = $(objectPrefix+'['+records[i]+']_header');
sortingObj[0] = headerObj.getElementsByClassName('sortingUp');
sortingObj[1] = headerObj.getElementsByClassName('sortingDown');
if (sortingObj[0].length)
sortingObj[0][0].style.visibility = i == 0 ? 'hidden' : 'visible';
if (sortingObj[1].length)
sortingObj[1][0].style.visibility = i == records.length-1 ? 'hidden' : 'visible';
}
},
memorizeAddRecord: function(objectPrefix, newUid, afterUid, selectedValue) {
if (this.isBelowMax(objectPrefix)) {
var objectName = this.prependFormFieldNames+this.parseFormElementName('parts', objectPrefix, 3, 1);
var formObj = document.getElementsByName(objectName);
if (formObj.length) {
var records = new Array();
if (formObj[0].value.length) records = formObj[0].value.split(',');
if (afterUid) {
var newRecords = new Array();
for (var i=0; i<records.length; i++) {
......
}
formObj[0].value = records.join(',');
}
this.redrawSortingButtons(objectPrefix, records);
if (this.data.unique && this.data.unique[objectPrefix]) {
var unique = this.data.unique[objectPrefix];
this.setUnique(objectPrefix, newUid, selectedValue);
}
}
// if we reached the maximum off possible records after this action, hide the new buttons
if (!this.isBelowMax(objectPrefix))
if (!this.isBelowMax(objectPrefix)) {
this.hideElementsWithClassName('inlineNewButton', this.parseFormElementName('full', objectPrefix, 0 , 1));
}
if (TBE_EDITOR) TBE_EDITOR.fieldChanged_fName(objectName, formObj);
},
memorizeRemoveRecord: function(objectName, removeUid) {
var formObj = document.getElementsByName(objectName);
if (formObj.length) {
......
}
return false;
},
updateUnique: function(srcElement, objectPrefix, formName, recordUid) {
if (this.data.unique && this.data.unique[objectPrefix]) {
var unique = this.data.unique[objectPrefix];
var oldValue = unique.used[recordUid];
if (unique.selector) {
if (unique.selector == 'select') {
var selector = $(objectPrefix+'_selector');
this.removeSelectOption(selector, srcElement.value);
if (typeof oldValue != 'undefined') this.readdSelectOption(selector, oldValue, unique);
}
if (!(unique.selector && unique.max == -1)) {
var formObj = document.getElementsByName(formName);
if (unique && formObj.length) {
......
}
}
},
revertUnique: function(objectPrefix, elName, recordUid) {
var unique = this.data.unique[objectPrefix];
var fieldObj = document.getElementsByName(elName+'['+unique.field+']');
var fieldObj = elName ? document.getElementsByName(elName+'['+unique.field+']') : null;
if (fieldObj.length) {
delete(this.data.unique[objectPrefix].used[recordUid])
if (unique.selector) {
if (!isNaN(fieldObj[0].value)) {
var selector = $(objectPrefix+'_selector');
this.readdSelectOption(selector, fieldObj[0].value, unique);
if (unique.type == 'select') {
if (fieldObj && fieldObj.length) {
delete(this.data.unique[objectPrefix].used[recordUid])
if (unique.selector == 'select') {
if (!isNaN(fieldObj[0].value)) {
var selector = $(objectPrefix+'_selector');
this.readdSelectOption(selector, fieldObj[0].value, unique);
}
}
}
if (!(unique.selector && unique.max == -1)) {
var formName = this.prependFormFieldNames+this.parseFormElementName('parts', objectPrefix, 3, 1);
var formObj = document.getElementsByName(formName);
if (formObj.length) {
var records = formObj[0].value.split(',');
var recordObj;
// walk through all inline records on that level and get the select field
for (var i=0; i<records.length; i++) {
recordObj = document.getElementsByName(this.prependFormFieldNames+'['+unique.table+']['+records[i]+']['+unique.field+']');
if (recordObj.length) this.readdSelectOption(recordObj[0], fieldObj[0].value, unique);
if (!(unique.selector && unique.max == -1)) {
var formName = this.prependFormFieldNames+this.parseFormElementName('parts', objectPrefix, 3, 1);
var formObj = document.getElementsByName(formName);
if (formObj.length) {
var records = formObj[0].value.split(',');
var recordObj;
// walk through all inline records on that level and get the select field
for (var i=0; i<records.length; i++) {
recordObj = document.getElementsByName(this.prependFormFieldNames+'['+unique.table+']['+records[i]+']['+unique.field+']');
if (recordObj.length) this.readdSelectOption(recordObj[0], fieldObj[0].value, unique);
}
}
}
}
} else if (unique.type == 'groupdb') {
// alert(objectPrefix+'/'+recordUid);
delete(this.data.unique[objectPrefix].used[recordUid])
}
},
enableDisableRecord: function(objectId) {
var elName = this.parseFormElementName('full', objectId, 2);
var imageObj = $(objectId+'_disabled');
var valueObj = document.getElementsByName(elName+'[hidden]');
var formObj = document.getElementsByName(elName+'[hidden]_0');
var imagePath = '';
if (valueObj && formObj) {
formObj[0].click();
imagePath = this.parsePath(imageObj.src);
imageObj.src = imagePath+(valueObj[0].value > 0 ? 'button_unhide.gif' : 'button_hide.gif');
}
return false;
},
deleteRecord: function(objectId) {
var i, j, inlineRecords, records, childObjectId, childTable;
var objectPrefix = this.parseFormElementName('full', objectId, 0 , 1);
var elName = this.parseFormElementName('full', objectId, 2);
var shortName = this.parseFormElementName('parts', objectId, 2);
var recordUid = this.parseFormElementName('none', objectId, 1);
var beforeDeleteIsBelowMax = this.isBelowMax(objectPrefix);
// revert the unique settings if available
if (this.data.unique && this.data.unique[objectPrefix]) this.revertUnique(objectPrefix, elName, recordUid);
......
new Effect.Fade(objectId+'_div');
}
// remove from TBE_EDITOR (required fields, required range, etc.):
// Remove from TBE_EDITOR (required fields, required range, etc.):
if (TBE_EDITOR && TBE_EDITOR.removeElement) {
inlineRecords = document.getElementsByClassName('inlineRecord', objectId+'_div');
// Remove nested child records from TBE_EDITOR required/range checks:
for (i=inlineRecords.length-1; i>=0; i--) {
if (inlineRecords[i].value.length) {
records = inlineRecords[i].value.split(',');
childObjectId = this.data.map[inlineRecords[i].name];
childTable = this.data.config[childObjectId].table;
for (j=records.length-1; j>=0; j--) {
TBE_EDITOR.removeElement(this.prependFormFieldNames+'['+childTable+']['+records[j]+']');
}
}
}
TBE_EDITOR.removeElement(this.prependFormFieldNames+shortName);
}
......
this.destroyDragAndDropSorting(this.parseFormElementName('full', objectId, 0 , 2)+'_records');
}
this.redrawSortingButtons(objectPrefix);
// if the NEW-button was hidden and now we can add again new children, show the button
if (!beforeDeleteIsBelowMax && this.isBelowMax(objectPrefix))
this.showElementsWithClassName('inlineNewButton', this.parseFormElementName('full', objectPrefix, 0 , 1));
return false;
},
parsePath: function(path) {
var backSlash = path.lastIndexOf('\\');
var normalSlash = path.lastIndexOf('/');
if (backSlash > 0)
path = path.substring(0,backSlash+1);
else if (normalSlash > 0)
path = path.substring(0,normalSlash+1);
else
path = '';
return path;
},
parseFormElementName: function(wrap, objectId, rightCount, skipRight) {
// remove left and right side "data[...|...]" -> '...|...'
objectId = objectId.substr(0, objectId.lastIndexOf(']')).substr(objectId.indexOf('[')+1);
if (!wrap) wrap = 'full';
if (!skipRight) skipRight = 0;
var elReturn;
var elParts = new Array();
var idParts = objectId.split('][');
......
for (var i=0; i<-rightCount; i++) idParts.shift();
elParts = idParts;
}
if (wrap == 'full') {
elReturn = this.prependFormFieldNames+'['+elParts.join('][')+']';
} else if (wrap == 'parts') {
......
return elReturn;
},
handleChangedField: function(formField, objectId) {
var formObj;
if (typeof formField == 'object') {
......
formObj = document.getElementsByName(formField);
if (formObj.length) formObj = formObj[0];
}
if (formObj != undefined) {
var value;
if (formObj.nodeName == 'SELECT') value = formObj.options[formObj.selectedIndex].text;
......
}
return true;
},
arrayAssocCount: function(object) {
var count = 0;
if (typeof object.length != 'undefined') {
......
}
return count;
},
isBelowMax: function(objectPrefix) {
var isBelowMax = true;
var objectName = this.prependFormFieldNames+this.parseFormElementName('parts', objectPrefix, 3, 1);
......
}
return isBelowMax;
},
getOptionsHash: function(selectObj) {
var optionsHash = {};
for (var i=0; i<selectObj.options.length; i++) optionsHash[selectObj.options[i].value] = i;
return optionsHash;
},
removeSelectOption: function(selectObj, value) {
var optionsHash = this.getOptionsHash(selectObj);
if (optionsHash[value] != undefined) selectObj.options[optionsHash[value]] = null;
},
readdSelectOption: function(selectObj, value, unique) {
var index = null;
var optionsHash = this.getOptionsHash(selectObj);
......
if (possibleValue == value) break;
if (optionsHash[possibleValue] != undefined) index = optionsHash[possibleValue];
}
if (index == null) index = 0;
else if (index < selectObj.options.length) index++;
// recreate the <option> tag
......
// add the <option> at the right position
selectObj.add(readdOption, document.all ? index : selectObj.options[index]);
},
hideElementsWithClassName: function(className, parentElement) {
this.setVisibilityOfElementsWithClassName('hide', className, parentElement);
},
showElementsWithClassName: function(className, parentElement) {
this.setVisibilityOfElementsWithClassName('show', className, parentElement);
},
setVisibilityOfElementsWithClassName: function(action, className, parentElement) {
var domObjects = document.getElementsByClassName(className, parentElement);
for (var i=0; i<domObjects.length; i++) {
......
new Effect.Appear(domObjects[i]);
}
},
fadeOutFadeIn: function(objectId) {
var optIn = { duration:0.5, transition:Effect.Transitions.linear, from:0.50, to:1.00 };
var optOut = { duration:0.5, transition:Effect.Transitions.linear, from:1.00, to:0.50 };
optOut.afterFinish = function() { new Effect.Opacity(objectId, optIn); };
new Effect.Opacity(objectId, optOut);
},
isNewRecord: function(objectId) {
return $(objectId+'_div') && $(objectId+'_div').hasClassName('inlineIsNewRecord')
? true
t3lib/class.t3lib_tceforms_inline.php (Arbeitskopie)
// Init:
$config = $PA['fieldConf']['config'];
$foreign_table = $config['foreign_table'];
t3lib_div::loadTCA($foreign_table);
$minitems = t3lib_div::intInRange($config['minitems'],0);
$maxitems = t3lib_div::intInRange($config['maxitems'],0);
......
// if relations are required to be unique, get the uids that have already been used on the foreign side of the relation
if ($config['foreign_unique']) {
$uniqueIds = $this->getUniqueIds($recordList, $config);
// If unique *and* selector, the should both be the same - get config:
$selConfig = $this->getPossibleRecordsSelectorConfig($config, $config['foreign_unique']);
// Get the used unique ids:
$uniqueIds = $this->getUniqueIds($recordList, $config, $selConfig['type']=='groupdb');
$possibleRecords = $this->getPossibleRecords($table,$field,$row,$config,'foreign_unique');
$uniqueMax = $config['appearance']['useCombination'] ? -1 : count($possibleRecords);
$uniqueMax = $config['appearance']['useCombination'] || $possibleRecords === false ? -1 : count($possibleRecords);
$this->inlineData['unique'][$nameObject.'['.$foreign_table.']'] = array(
'max' => $uniqueMax,
'used' => $uniqueIds,
'type' => $selConfig['type'],
'table' => $config['foreign_table'],
'elTable' => $selConfig['table'], // element/record table (one step down in hierarchy)
'field' => $config['foreign_unique'],
'selector' => $config['foreign_selector'] ? true : false,
'selector' => $selConfig['PA'] && $selConfig['type'] ? $selConfig['type'] : false,
'possible' => $this->getPossibleRecordsFlat($possibleRecords),
);
}
......
$config['inline']['inlineNewButtonStyle'] = 'display: none;';
}
// add the "Create new record" link before all child records
if ($config['appearance']['newRecordLinkPosition'] != 'bottom') {
if (in_array($config['appearance']['newRecordLinkPosition'], array('both', 'top'))) {
$item .= $this->getNewRecordLink($nameObject.'['.$foreign_table.']', $config);
}
......
$item .= '</div>';
// add the "Create new record" link after all child records
if ($config['appearance']['newRecordLinkPosition'] != 'top') {
if (in_array($config['appearance']['newRecordLinkPosition'], array('both', 'bottom'))) {
$item .= $this->getNewRecordLink($nameObject.'['.$foreign_table.']', $config);
}
......
$foreign_table = $config['foreign_table'];
$foreign_field = $config['foreign_field'];
$foreign_selector = $config['foreign_selector'];
$selConfig = $this->getPossibleRecordsSelectorConfig($config, $foreign_selector);
// record comes from storage (e.g. database)
// Send a mapping information to the browser via JSON:
// e.g. data[<curTable>][<curId>][<curField>] => data[<pid>][<parentTable>][<parentId>][<parentField>][<curTable>][<curId>][<curField>]
$this->inlineData['map'][$this->inlineNames['form']] = $this->inlineNames['object'];
// Set this variable if we handle a brand new unsaved record:
$isNewRecord = t3lib_div::testInt($rec['uid']) ? false : true;
// if there is a selector field, normalize it
// If there is a selector field, normalize it:
if ($foreign_selector) {
$rec[$foreign_selector] = $this->normalizeUid($rec[$foreign_selector]);
}
......
if(!$hasAccess) return false;
// get the current prependObjectId
// Get the current naming scheme for DOM name/id attributes:
$nameObject = $this->inlineNames['object'];
$appendFormFieldNames = '['.$foreign_table.']['.$rec['uid'].']';
$formFieldNames = $nameObject.$appendFormFieldNames;
......
// set additional field for processing for saving
$fields .= '<input type="hidden" name="'.$this->prependCmdFieldNames.$appendFormFieldNames.'[delete]" value="1" disabled="disabled" />';
}
// if this record should be shown collapsed
if (!$isExpanded) $appearanceStyleFields = ' style="display: none;"';
......
// render the special alternative title
} elseif ($hasForeignLabel || $hasSymmetricLabel) {
$titleCol = $hasForeignLabel ? $config['foreign_label'] : $config['symmetric_label'];
$recTitle = t3lib_BEfunc::getProcessedValueExtra($foreign_table, $titleCol, $rec[$titleCol], 0, 0, false);
$foreignConfig = $this->getPossibleRecordsSelectorConfig($config, $titleCol);
// Render title for everything else than group/db:
if ($foreignConfig['type'] != 'groupdb') {
$recTitle = t3lib_BEfunc::getProcessedValueExtra($foreign_table, $titleCol, $rec[$titleCol], 0, 0, false);
// Render title for group/db:
} else {
// $recTitle would be something like: "tx_table_123",
$itemParts = $this->rightExplode('_', $rec[$titleCol], 2);
$recTemp = t3lib_befunc::getRecordWSOL($itemParts[0], $itemParts[1]);
$recTitle = t3lib_BEfunc::getRecordTitle($itemParts[0], $recTemp, true);
}
$recTitle = t3lib_BEfunc::getRecordTitlePrep($recTitle);
if (!strcmp(trim($recTitle),'')) {
$recTitle = t3lib_BEfunc::getNoRecordTitle(true);
......
($isPagesTable && ($localCalcPerms&4)) || (!$isPagesTable && ($calcPerms&16))
) {
$onClick = "inline.deleteRecord('".$nameObjectFtId."');";
$cells[]='<a href="#" onclick="'.htmlspecialchars('if (confirm('.$GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->getLL('deleteWarning').t3lib_BEfunc::referenceCount($foreign_table,$rec['uid'],' (There are %s reference(s) to this record!)')).')) { '.$onClick.' } return false;').'">'.
$cells[]='<a href="#" onclick="'.htmlspecialchars('if (confirm('.$GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->getLL('deleteWarning')).')) { '.$onClick.' } return false;').'">'.
'<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/garbage.gif','width="11" height="12"').' title="'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_web_list.xml:delete',1).'" alt="" />'.
'</a>';
}
......
return $out;
}
/**
* Determine the configuration and the type of a record selector.
*
* @param array $conf: TCA configuration of the parent(!) field
* @return array Associative array with the keys 'PA' and 'type', both are false if the selector was not valid.
*/
function getPossibleRecordsSelectorConfig($conf, $field = '') {
$foreign_table = $conf['foreign_table'];
$foreign_selector = $conf['foreign_selector'];
$PA = false;
$type = false;
$table = false;
if ($field) {
$PA = array();
$PA['fieldConf'] = $GLOBALS['TCA'][$foreign_table]['columns'][$field];
$PA['fieldConf']['config']['form_type'] = $PA['fieldConf']['config']['form_type'] ? $PA['fieldConf']['config']['form_type'] : $PA['fieldConf']['config']['type']; // Using "form_type" locally in this script
$PA['fieldTSConfig'] = $this->fObj->setTSconfig($foreign_table,array(),$field);
$config = $PA['fieldConf']['config'];
// Determine type of Selector:
$type = $this->getPossibleRecordsSelectorType($config);
// Return table on this level:
$table = $type == 'select' ? $config['foreign_table'] : $config['allowed'];
}
return array(
'PA' => $PA,
'type' => $type,
'table' => $table
);
}
/**
* Determine the type of a record selector, e.g. select or group/db.
*
* @param array $config: TCE configuration of the selector
* @return mixed The type of the selector, 'select' or 'groupdb' - false not valid
*/
function getPossibleRecordsSelectorType($config) {
$type = false;
if ($config['type'] == 'select') {
$type = 'select';
} elseif ($config['type'] == 'group' && $config['internal_type'] == 'db') {
$type = 'groupdb';
}
return $type;
}
/**
* Get a selector as used for the select type, to select from all available
* records and to create a relation to the embedding record (e.g. like MM).
*
......
$foreign_table = $conf['foreign_table'];
$foreign_selector = $conf['foreign_selector'];
$selConfig = $this->getPossibleRecordsSelectorConfig($conf, $foreign_selector);
$config = $selConfig['PA']['fieldConf']['config'];
if ($selConfig['type'] == 'select') {
$item = $this->renderPossibleRecordsSelectorTypeSelect($selItems, $conf, $selConfig['PA'], $uniqueIds);
} elseif ($selConfig['type'] == 'groupdb') {
$item = $this->renderPossibleRecordsSelectorTypeGroupDB($conf, $selConfig['PA']);
}
return $item;
}
/**
* Get a selector as used for the select type, to select from all available
* records and to create a relation to the embedding record (e.g. like MM).
*
* @param array $selItems: Array of all possible records
* @param array $conf: TCA configuration of the parent(!) field
* @param array $PA: An array with additional configuration options
* @param array $uniqueIds: The uids that have already been used and should be unique
* @return string A HTML <select> box with all possible records
*/
function renderPossibleRecordsSelectorTypeSelect($selItems, $conf, &$PA, $uniqueIds=array()) {
$foreign_table = $conf['foreign_table'];
$foreign_selector = $conf['foreign_selector'];
$PA = array();
$PA['fieldConf'] = $GLOBALS['TCA'][$foreign_table]['columns'][$foreign_selector];
$PA['fieldConf']['config']['form_type'] = $PA['fieldConf']['config']['form_type'] ? $PA['fieldConf']['config']['form_type'] : $PA['fieldConf']['config']['type']; // Using "form_type" locally in this script
......
// Put together the selector box:
$selector_itemListStyle = isset($config['itemListStyle']) ? ' style="'.htmlspecialchars($config['itemListStyle']).'"' : ' style="'.$this->fObj->defaultMultipleSelectorStyle.'"';
$size = intval($config['size']);
$size = $config['autoSizeMax'] ? t3lib_div::intInRange(count($itemArray)+1,t3lib_div::intInRange($size,1),$config['autoSizeMax']) : $size;
$sOnChange = "return inline.importNewRecord('".$this->inlineNames['object']."[".$conf['foreign_table']."]')";
$itemsToSelect = '
$size = intval($conf['size']);
$size = $conf['autoSizeMax'] ? t3lib_div::intInRange(count($itemArray)+1,t3lib_div::intInRange($size,1),$conf['autoSizeMax']) : $size;
$onChange = "return inline.importNewRecord('".$this->inlineNames['object']."[".$conf['foreign_table']."]')";
$item = '
<select id="'.$this->inlineNames['object'].'['.$conf['foreign_table'].']_selector"'.
$this->fObj->insertDefStyle('select').
($size ? ' size="'.$size.'"' : '').
' onchange="'.htmlspecialchars($sOnChange).'"'.
' onchange="'.htmlspecialchars($onChange).'"'.
$PA['onFocus'].
$selector_itemListStyle.
($conf['foreign_unique'] ? ' isunique="isunique"' : '').'>
......
// there is only one record item in the select-box, that is selected by default
// the selector-box creates a new relation on using a onChange event (see some line above)
$createNewRelationText = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:cm.createNewRelation',1);
$itemsToSelect .=
'<a href="#" onclick="'.htmlspecialchars($sOnChange).'" align="abstop">'.
'<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/edit2.gif','width="11" height="12"').' title="'.$createNewRelationText.'" alt="" /> '.$createNewRelationText.
$item .=
'<a href="#" onclick="'.htmlspecialchars($onChange).'" align="abstop">'.
'<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/edit2.gif','width="11" height="12"').' align="absmiddle" '.t3lib_BEfunc::titleAltAttrib($createNewRelationText).' /> '.$createNewRelationText.
'</a>';
// wrap the selector and add a spacer to the bottom
$itemsToSelect = '<div style="margin-bottom: 20px;">'.$itemsToSelect.'</div>';
$item = '<div style="margin-bottom: 20px;">'.$item.'</div>';
}
return $itemsToSelect;
return $item;
}
/**
* Generate a link that ipens an element browser in a new window.
*
* @param array $conf: TCA configuration of the parent(!) field
* @param array $PA: An array with additional configuration options
* @return string A HTML link that opens an element browser in a new window
*/
function renderPossibleRecordsSelectorTypeGroupDB($conf, &$PA) {
$foreign_table = $conf['foreign_table'];
$config = $PA['fieldConf']['config'];
$allowed = $config['allowed'];
$objectPrefix = $this->inlineNames['object'].'['.$foreign_table.']';
$createNewRelationText = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:cm.createNewRelation',1);
$onClick = "setFormValueOpenBrowser('db','".('|||'.$allowed.'|'.$objectPrefix.'|inline.checkUniqueElement||inline.importElement')."'); return false;";
$item =
'<a href="#" onclick="'.htmlspecialchars($onClick).'">'.
'<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/insert3.gif','width="14" height="14"').' align="absmiddle" '.t3lib_BEfunc::titleAltAttrib($createNewRelationText).' /> '.$createNewRelationText.
'</a>';
return $item;
}
/**
* Creates a link/button to create new records
*
......
$parent = $this->getStructureLevel(-1);
// get TCA 'config' of the parent table
$config = $parent['config'];
// dynamically create a new record using t3lib_transferData
if (!$foreignUid || !t3lib_div::testInt($foreignUid) || $config['foreign_selector']) {
$record = $this->getNewRecord($this->inlineFirstPid, $current['table']);
......
// this intermediate table holds a field, which is responsible for the foreign_selector, so
// we have to set this field to the uid we get - or if none, to a new uid
if ($config['foreign_selector'] && $foreignUid) {
$record[$config['foreign_selector']] = $foreignUid;
$selConfig = $this->getPossibleRecordsSelectorConfig($config, $config['foreign_selector']);
// For a selector of type group/db, prepend the tablename (<tablename>_<uid>):
$record[$config['foreign_selector']] = $selConfig['type'] != 'groupdb' ? '' : $selConfig['table'].'_';
$record[$config['foreign_selector']] .= $foreignUid;
}
// the HTML-object-id's prefix of the dynamically created record
......
* @param array The record data array where the value(s) for the field can be found
* @param array An array with additional configuration options.
* @param string $checkForConfField: For which field in the foreign_table the possible records should be fetched
* @return array Array of possible record items
* @return mixed Array of possible record items; false if type is "group/db", then everything could be "possible"
*/
function getPossibleRecords($table,$field,$row,$conf,$checkForConfField='foreign_selector') {
// ctrl configuration from TCA:
......
$foreign_table = $conf['foreign_table'];
$foreign_check = $conf[$checkForConfField];
$PA = array();
$PA['fieldConf'] = $GLOBALS['TCA'][$foreign_table]['columns'][$foreign_check];
$PA['fieldConf']['config']['form_type'] = $PA['fieldConf']['config']['form_type'] ? $PA['fieldConf']['config']['form_type'] : $PA['fieldConf']['config']['type']; // Using "form_type" locally in this script
$PA['fieldTSConfig'] = $this->fObj->setTSconfig($foreign_table,array(),$foreign_check);
$foreignConfig = $this->getPossibleRecordsSelectorConfig($conf, $foreign_check);
$PA = $foreignConfig['PA'];
$config = $PA['fieldConf']['config'];
// Getting the selector box items from the system
$selItems = $this->fObj->addSelectOptionsToItemArray($this->fObj->initItemArray($PA['fieldConf']),$PA['fieldConf'],$this->fObj->setTSconfig($table,$row),$field);
if ($config['itemsProcFunc']) $selItems = $this->fObj->procItems($selItems,$PA['fieldTSConfig']['itemsProcFunc.'],$config,$table,$row,$field);
// Possibly remove some items:
$removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
foreach($selItems as $tk => $p) {
// Checking languages and authMode:
$languageDeny = $tcaTableCtrl['languageField'] && !strcmp($tcaTableCtrl['languageField'], $field) && !$GLOBALS['BE_USER']->checkLanguageAccess($p[1]);
$authModeDeny = $config['form_type']=='select' && $config['authMode'] && !$GLOBALS['BE_USER']->checkAuthMode($table,$field,$p[1],$config['authMode']);
if (in_array($p[1],$removeItems) || $languageDeny || $authModeDeny) {
unset($selItems[$tk]);
} elseif (isset($PA['fieldTSConfig']['altLabels.'][$p[1]])) {
$selItems[$tk][0]=$this->fObj->sL($PA['fieldTSConfig']['altLabels.'][$p[1]]);
}
// Removing doktypes with no access:
if ($table.'.'.$field == 'pages.doktype') {
if (!($GLOBALS['BE_USER']->isAdmin() || t3lib_div::inList($GLOBALS['BE_USER']->groupData['pagetypes_select'],$p[1]))) {
if ($foreignConfig['type'] == 'select') {
// Getting the selector box items from the system
$selItems = $this->fObj->addSelectOptionsToItemArray($this->fObj->initItemArray($PA['fieldConf']),$PA['fieldConf'],$this->fObj->setTSconfig($table,$row),$field);
if ($config['itemsProcFunc']) $selItems = $this->fObj->procItems($selItems,$PA['fieldTSConfig']['itemsProcFunc.'],$config,$table,$row,$field);
// Possibly remove some items:
$removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
foreach($selItems as $tk => $p) {
// Checking languages and authMode:
$languageDeny = $tcaTableCtrl['languageField'] && !strcmp($tcaTableCtrl['languageField'], $field) && !$GLOBALS['BE_USER']->checkLanguageAccess($p[1]);
$authModeDeny = $config['form_type']=='select' && $config['authMode'] && !$GLOBALS['BE_USER']->checkAuthMode($table,$field,$p[1],$config['authMode']);
if (in_array($p[1],$removeItems) || $languageDeny || $authModeDeny) {
unset($selItems[$tk]);
} elseif (isset($PA['fieldTSConfig']['altLabels.'][$p[1]])) {
$selItems[$tk][0]=$this->fObj->sL($PA['fieldTSConfig']['altLabels.'][$p[1]]);
}
// Removing doktypes with no access:
if ($table.'.'.$field == 'pages.doktype') {
if (!($GLOBALS['BE_USER']->isAdmin() || t3lib_div::inList($GLOBALS['BE_USER']->groupData['pagetypes_select'],$p[1]))) {
unset($selItems[$tk]);
}
}
}
} else {
$selItems = false;
}
return $selItems;
......
*
* @param array $records: All inline records on this level
* @param array $conf: The TCA field configuration of the inline field to be rendered
* @param boolean $splitValue: for usage with group/db, values come like "tx_table_123|Title%20abc", but we need "tx_table" and "123"
* @return array The uids, that have been used already and should be used unique
*/
function getUniqueIds($records, $conf=array()) {
function getUniqueIds($records, $conf=array(), $splitValue=false) {
$uniqueIds = array();
if ($conf['foreign_unique'] && count($records))
foreach ($records as $rec) $uniqueIds[$rec['uid']] = $rec[$conf['foreign_unique']];
if ($conf['foreign_unique'] && count($records)) {
foreach ($records as $rec) {
$value = $rec[$conf['foreign_unique']];
// Split the value and extract the table and uid:
if ($splitValue) {
$valueParts = t3lib_div::trimExplode('|', $value);
$itemParts = explode('_', $valueParts[0]);
$value = array(
'uid' => array_pop($itemParts),
'table' => implode('_', $itemParts)
);
}
$uniqueIds[$rec['uid']] = $value;
}
}
return $uniqueIds;
}
......
$foreign_table = $config['foreign_table'];
// an inline field must have a foreign_table, if not, stop all further inline actions for this field
if (!$foreign_table || !is_array($GLOBALS['TCA'][$foreign_table]))
if (!$foreign_table || !is_array($GLOBALS['TCA'][$foreign_table])) {
return false;
}
if (!is_array($config['appearance']))
$config['appearance'] = array();
if (!in_array($config['appearance']['newRecordLinkPosition'], array('top', 'bottom', 'both')))
if (!in_array($config['appearance']['newRecordLinkPosition'], array('top', 'bottom', 'both', 'none')))
$config['appearance']['newRecordLinkPosition'] = 'top';
return true;
......
* the value of the flat array is the label of the record.
*
* @param array $possibleRecords: The possibleRecords array (for select fields)
* @return array A flat array with key=uid, value=label
* @return mixed A flat array with key=uid, value=label; if $possibleRecords isn't an array, false is returned.
*/
function getPossibleRecordsFlat($possibleRecords) {
$flat = array();
if (is_array($possibleRecords))
$flat = false;
if (is_array($possibleRecords)) {
$flat = array();
foreach ($possibleRecords as $record) $flat[$record[1]] = $record[0];
}
return $flat;
}
......
// get the parent record from structure stack
$level = $this->getStructureLevel(-1);
// if we have symmetric fields, check on which side we are and hide fields, that are set automatically
// If we have symmetric fields, check on which side we are and hide fields, that are set automatically:
if (t3lib_loadDBGroup::isOnSymmetricSide($level['uid'], $level['config'], $row)) {
$searchArray['%OR']['config'][0]['%AND']['%OR']['symmetric_field'] = $field;
$searchArray['%OR']['config'][0]['%AND']['%OR']['symmetric_sortby'] = $field;
// hide fields, that are set automatically
// Hide fields, that are set automatically:
} else {
$searchArray['%OR']['config'][0]['%AND']['%OR']['foreign_field'] = $field;
$searchArray['%OR']['config'][0]['%AND']['%OR']['foreign_sortby'] = $field;
......
$margin = $this->inlineStyles['margin-right'];
return $margin;
}
/**
* Works like explode, but the $limit counts from the end of a string.
*
* @param string $delim
* @param string $string
* @param integer $limit
* @return array The right exploded array
*/
function rightExplode($delim, $string, $limit = null) {
$result = array();
$tokens = explode($delim, $string);
if ($limit > 0) {
if ($limit > count($tokens)) {
$limit = count($tokens);
}
for ($i=1; $i<$limit; $i++) {
array_unshift($result, array_pop($tokens));
}
if (count($tokens)) {
array_unshift($result, implode($delim, $tokens));
}
return $result;
} else {
return $tokens;
}
}
}
?>
typo3/class.browse_links.php (Arbeitskopie)
}
}
function insertElement(table, uid, type, filename,fp,filetype,imagefile,action, close) { //
if (1=='.($pArr[0]&&!$pArr[1]&&!$pArr[2] ? 1 : 0).') {
addElement(filename,table+"_"+uid,fp,close);
} else {
if (setReferences()) {
parent.window.opener.group_change("add","'.$pArr[0].'","'.$pArr[1].'","'.$pArr[2].'",elRef,targetDoc);
var checkResult = true;
// Call a check function in the opener window (e.g. for uniqueness handling):
if (1=='.($pArr[4]&&$pArr[5] ? 1 : 0).') {
if (parent.window.opener) {
var res = parent.window.opener.'.$pArr[5].'("'.addslashes($pArr[4]).'",table,uid,type);
if (!res.passed) {
if (res.message) alert(res.message);
checkResult = false;
}
} else {
alert("Error - reference to main window is not set properly!");
}
if (close) {
parent.window.opener.focus();
parent.close();
}
}
// Call performing function and finish this action:
if (checkResult) {
// Call helper function to manage data in the opener window:
if (1=='.($pArr[4]&&$pArr[6] ? 1 : 0).') {
if (parent.window.opener) {
parent.window.opener.'.$pArr[6].'("'.addslashes($pArr[4]).'",table,uid,type,"'.addslashes($pArr[0]).'");
} else {
alert("Error - reference to main window is not set properly!");
parent.close();
}
}
// Call user defined handler function:
if (1=='.($pArr[4]&&$pArr[7] ? 1 : 0).') {
if (parent.window.opener) {
parent.window.opener.'.$pArr[7].'("'.addslashes($pArr[4]).'",table,uid,type);
focusOpenerAndClose(close);
} else {
alert("Error - reference to main window is not set properly!");
parent.close();
}
} else if (1=='.($pArr[0]&&!$pArr[1]&&!$pArr[2] ? 1 : 0).') {
addElement(filename,table+"_"+uid,fp,close);
} else {
if (setReferences()) {
parent.window.opener.group_change("add","'.$pArr[0].'","'.$pArr[1].'","'.$pArr[2].'",elRef,targetDoc);
} else {
alert("Error - reference to main window is not set properly!");
}
focusOpenerAndClose(close);
}
}
return false;
}
function addElement(elName,elValue,altElValue,close) { //
if (parent.window.opener && parent.window.opener.setFormValueFromBrowseWin) {
parent.window.opener.setFormValueFromBrowseWin("'.$pArr[0].'",altElValue?altElValue:elValue,elName);
if (close) {
parent.window.opener.focus();
parent.close();
}
focusOpenerAndClose(close);
} else {
alert("Error - reference to main window is not set properly!");
parent.close();
}
}
function focusOpenerAndClose(close) { //
if (close) {
parent.window.opener.focus();
parent.close();
}
}
';
// Finally, add the accumulated JavaScript to the template object:
......
function main_db() {
// Starting content:
$content=$this->doc->startPage('TBE file selector');
$content=$this->doc->startPage('TBE record selector');
// Init variable:
$pArr = explode('|',$this->bparams);
(4-4/4)