00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 class t3lib_TCEforms_inline {
00093 const Structure_Separator = '-';
00094 const Disposal_AttributeName = 'Disposal_AttributeName';
00095 const Disposal_AttributeId = 'Disposal_AttributeId';
00096
00097
00098
00099
00100
00101
00102 var $fObj;
00103 var $backPath;
00104
00105 var $isAjaxCall = false;
00106 var $inlineStructure = array();
00107 var $inlineFirstPid;
00108 var $inlineNames = array();
00109 var $inlineData = array();
00110 var $inlineView = array();
00111 var $inlineCount = 0;
00112 var $inlineStyles = array();
00113
00114 var $prependNaming = 'data';
00115 var $prependFormFieldNames;
00116 var $prependCmdFieldNames;
00117
00118 protected $hookObjects = array();
00119
00120
00121
00122
00123
00124
00125
00126
00127 function init(&$tceForms) {
00128 $this->fObj = $tceForms;
00129 $this->backPath =& $tceForms->backPath;
00130 $this->prependFormFieldNames =& $this->fObj->prependFormFieldNames;
00131 $this->prependCmdFieldNames =& $this->fObj->prependCmdFieldNames;
00132 $this->inlineStyles['margin-right'] = '5';
00133 $this->initHookObjects();
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143 protected function initHookObjects() {
00144 $this->hookObjects = array();
00145 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tceforms_inline.php']['tceformsInlineHook'])) {
00146 $tceformsInlineHook =& $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tceforms_inline.php']['tceformsInlineHook'];
00147 if (is_array($tceformsInlineHook)) {
00148 foreach($tceformsInlineHook as $classData) {
00149 $processObject = t3lib_div::getUserObj($classData);
00150
00151 if(!($processObject instanceof t3lib_tceformsInlineHook)) {
00152 throw new UnexpectedValueException('$processObject must implement interface t3lib_tceformsInlineHook', 1202072000);
00153 }
00154
00155 $processObject->init($this);
00156 $this->hookObjects[] = $processObject;
00157 }
00158 }
00159 }
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 function getSingleField_typeInline($table,$field,$row,&$PA) {
00174
00175 if ($this->checkConfiguration($PA['fieldConf']['config']) === false) {
00176 return false;
00177 }
00178
00179
00180 $this->inlineCount++;
00181
00182
00183 $config = $PA['fieldConf']['config'];
00184 $foreign_table = $config['foreign_table'];
00185 t3lib_div::loadTCA($foreign_table);
00186
00187 if (t3lib_BEfunc::isTableLocalizable($table)) {
00188 $language = intval($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']]);
00189 }
00190 $minitems = t3lib_div::intInRange($config['minitems'],0);
00191 $maxitems = t3lib_div::intInRange($config['maxitems'],0);
00192 if (!$maxitems) $maxitems=100000;
00193
00194
00195 $this->fObj->requiredElements[$PA['itemFormElName']] = array($minitems,$maxitems,'imgName'=>$table.'_'.$row['uid'].'_'.$field);
00196
00197
00198
00199 if (!isset($this->inlineFirstPid)) {
00200
00201
00202 if (t3lib_div::testInt($row['uid'])) {
00203 $inlineView = unserialize($GLOBALS['BE_USER']->uc['inlineView']);
00204 $this->inlineView = $inlineView[$table][$row['uid']];
00205 }
00206
00207 if ($table == 'pages') {
00208 $this->inlineFirstPid = $row['uid'];
00209
00210 } elseif ($row['pid'] < 0) {
00211 $prevRec = t3lib_BEfunc::getRecord($table, abs($row['pid']));
00212 $this->inlineFirstPid = $prevRec['pid'];
00213
00214 } else {
00215 $this->inlineFirstPid = $row['pid'];
00216 }
00217 }
00218
00219 $this->pushStructure($table, $row['uid'], $field, $config);
00220
00221 $nameForm = $this->inlineNames['form'];
00222
00223 $nameObject = $this->inlineNames['object'];
00224
00225 $relatedRecords = $this->getRelatedRecords($table,$field,$row,$PA,$config);
00226
00227 $relatedRecordsUids = array_keys($relatedRecords['records']);
00228 $config['inline']['first'] = reset($relatedRecordsUids);
00229 $config['inline']['last'] = end($relatedRecordsUids);
00230
00231
00232 $top = $this->getStructureLevel(0);
00233 $this->inlineData['config'][$nameObject] = array(
00234 'table' => $foreign_table,
00235 'md5' => md5($nameObject),
00236 );
00237 $this->inlineData['config'][$nameObject. self::Structure_Separator . $foreign_table] = array(
00238 'min' => $minitems,
00239 'max' => $maxitems,
00240 'sortable' => $config['appearance']['useSortable'],
00241 'top' => array(
00242 'table' => $top['table'],
00243 'uid' => $top['uid'],
00244 ),
00245 );
00246
00247 $this->inlineData['nested'][$nameObject] = $this->fObj->getDynNestedStack(false, $this->isAjaxCall);
00248
00249
00250 if ($config['foreign_unique']) {
00251
00252 $selConfig = $this->getPossibleRecordsSelectorConfig($config, $config['foreign_unique']);
00253
00254 $uniqueIds = $this->getUniqueIds($relatedRecords['records'], $config, $selConfig['type']=='groupdb');
00255 $possibleRecords = $this->getPossibleRecords($table,$field,$row,$config,'foreign_unique');
00256 $uniqueMax = $config['appearance']['useCombination'] || $possibleRecords === false ? -1 : count($possibleRecords);
00257 $this->inlineData['unique'][$nameObject. self::Structure_Separator . $foreign_table] = array(
00258 'max' => $uniqueMax,
00259 'used' => $uniqueIds,
00260 'type' => $selConfig['type'],
00261 'table' => $config['foreign_table'],
00262 'elTable' => $selConfig['table'],
00263 'field' => $config['foreign_unique'],
00264 'selector' => $selConfig['selector'],
00265 'possible' => $this->getPossibleRecordsFlat($possibleRecords),
00266 );
00267 }
00268
00269
00270 if ($config['foreign_selector']) {
00271
00272 if (!$config['foreign_unique']) {
00273 $possibleRecords = $this->getPossibleRecords($table,$field,$row,$config);
00274 $uniqueIds = array();
00275 }
00276 $selectorBox = $this->renderPossibleRecordsSelector($possibleRecords,$config,$uniqueIds);
00277 $item .= $selectorBox;
00278 }
00279
00280
00281 $item .= '<div id="'.$nameObject.'">';
00282
00283
00284 if ($relatedRecords['count'] >= $maxitems || ($uniqueMax > 0 && $relatedRecords['count'] >= $uniqueMax)) {
00285 $config['inline']['inlineNewButtonStyle'] = 'display: none;';
00286 }
00287
00288
00289 if ($config['appearance']['levelLinksPosition']!='none') {
00290 $levelLinks = $this->getLevelInteractionLink('newRecord', $nameObject . self::Structure_Separator . $foreign_table, $config);
00291 if ($language>0) {
00292
00293 if (isset($config['appearance']['showAllLocalizationLink']) && $config['appearance']['showAllLocalizationLink']) {
00294 $levelLinks.= $this->getLevelInteractionLink('localize', $nameObject . self::Structure_Separator . $foreign_table, $config);
00295 }
00296
00297 if (isset($config['appearance']['showSynchronizationLink']) && $config['appearance']['showSynchronizationLink']) {
00298 $levelLinks.= $this->getLevelInteractionLink('synchronize', $nameObject . self::Structure_Separator . $foreign_table, $config);
00299 }
00300 }
00301 }
00302
00303 if (in_array($config['appearance']['levelLinksPosition'], array('both', 'top'))) {
00304 $item.= $levelLinks;
00305 }
00306
00307 $item .= '<div id="'.$nameObject.'_records">';
00308 $relationList = array();
00309 if (count($relatedRecords['records'])) {
00310 foreach ($relatedRecords['records'] as $rec) {
00311 $item .= $this->renderForeignRecord($row['uid'],$rec,$config);
00312 if (!isset($rec['__virtual']) || !$rec['__virtual']) {
00313 $relationList[] = $rec['uid'];
00314 }
00315 }
00316 }
00317 $item .= '</div>';
00318
00319
00320 if (in_array($config['appearance']['levelLinksPosition'], array('both', 'bottom'))) {
00321 $item.= $levelLinks;
00322 }
00323
00324
00325 if (count($relationList) > 1 && $config['appearance']['useSortable'])
00326 $this->addJavaScriptSortable($nameObject.'_records');
00327
00328 $item .= '<input type="hidden" name="'.$nameForm.'" value="'.implode(',', $relationList).'" class="inlineRecord" />';
00329
00330 $item .= '</div>';
00331
00332
00333 $this->popStructure();
00334
00335
00336 if (!$this->getStructureDepth()) {
00337 unset($this->inlineFirstPid);
00338 }
00339
00340 return $item;
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 function renderForeignRecord($parentUid, $rec, $config = array()) {
00360 $foreign_table = $config['foreign_table'];
00361 $foreign_field = $config['foreign_field'];
00362 $foreign_selector = $config['foreign_selector'];
00363
00364
00365 $parent = $this->getStructureLevel(-1);
00366 if (isset($parent['localizationMode']) && $parent['localizationMode']!=false) {
00367 $this->fObj->registerDefaultLanguageData($foreign_table, $rec);
00368 }
00369
00370
00371 $this->inlineData['map'][$this->inlineNames['form']] = $this->inlineNames['object'];
00372
00373
00374 $isNewRecord = t3lib_div::testInt($rec['uid']) ? false : true;
00375
00376 $isVirtualRecord = (isset($rec['__virtual']) && $rec['__virtual']);
00377
00378 if ($foreign_selector) {
00379 $rec[$foreign_selector] = $this->normalizeUid($rec[$foreign_selector]);
00380 }
00381
00382 if (!$this->checkAccess(($isNewRecord ? 'new' : 'edit'), $foreign_table, $rec['uid'])) {
00383 return false;
00384 }
00385
00386
00387 $nameObject = $this->inlineNames['object'];
00388 $appendFormFieldNames = '['.$foreign_table.']['.$rec['uid'].']';
00389 $objectId = $nameObject . self::Structure_Separator . $foreign_table . self::Structure_Separator . $rec['uid'];
00390
00391 $this->fObj->pushToDynNestedStack('inline', $objectId);
00392
00393 if (!$isVirtualRecord) {
00394
00395 $collapseAll = (isset($config['appearance']['collapseAll']) && $config['appearance']['collapseAll']);
00396 $ajaxLoad = (isset($config['appearance']['ajaxLoad']) && !$config['appearance']['ajaxLoad']) ? false : true;
00397
00398 if ($isNewRecord) {
00399
00400 $isExpanded = (!$collapseAll ? 1 : 0);
00401 } else {
00402 $isExpanded = ($config['renderFieldsOnly'] || (!$collapseAll && $this->getExpandedCollapsedState($foreign_table, $rec['uid'])));
00403 }
00404
00405 if ($isNewRecord || $isExpanded || !$ajaxLoad) {
00406 $combination = $this->renderCombinationTable($rec, $appendFormFieldNames, $config);
00407 $fields = $this->renderMainFields($foreign_table, $rec);
00408 $fields = $this->wrapFormsSection($fields);
00409
00410 $ajaxArguments = t3lib_div::_GP('ajax');
00411 if (isset($ajaxArguments[2]) && trim($ajaxArguments[2]) != '') {
00412 $fields = str_replace('P[returnUrl]=%2F' . rawurlencode(TYPO3_mainDir) . '%2Fajax.php', 'P[returnUrl]=' . rawurlencode($ajaxArguments[2]), $fields);
00413 }
00414 } else {
00415 $combination = '';
00416
00417 $fields = '<!--notloaded-->';
00418 }
00419 if ($isNewRecord) {
00420
00421 $top = $this->getStructureLevel(0);
00422 $ucFieldName = 'uc[inlineView]['.$top['table'].']['.$top['uid'].']'.$appendFormFieldNames;
00423
00424 $fields .= '<input type="hidden" name="'.$this->prependFormFieldNames.$appendFormFieldNames.'[pid]" value="'.$rec['pid'].'"/>';
00425 $fields .= '<input type="hidden" name="'.$ucFieldName.'" value="'.$isExpanded.'" />';
00426 } else {
00427
00428 $fields .= '<input type="hidden" name="'.$this->prependCmdFieldNames.$appendFormFieldNames.'[delete]" value="1" disabled="disabled" />';
00429 }
00430
00431 if (!$isExpanded) {
00432 $appearanceStyleFields = ' style="display: none;"';
00433 }
00434 }
00435
00436 if ($config['renderFieldsOnly']) {
00437 $out = $fields . $combination;
00438 } else {
00439
00440 $out = '<div class="t3-form-field-record-inline" id="' . $objectId . '_fields"' . $appearanceStyleFields . '>' . $fields . $combination . '</div>';
00441 $header = $this->renderForeignRecordHeader($parentUid, $foreign_table, $rec, $config, $isVirtualRecord);
00442 $out = '<div class="t3-form-field-header-inline" id="' . $objectId . '_header">' . $header . '</div>' . $out;
00443
00444 $classMSIE = ($this->fObj->clientInfo['BROWSER']=='msie' && $this->fObj->clientInfo['VERSION'] < 8 ? 'MSIE' : '');
00445 $class = 'inlineDiv' . $classMSIE . ($isNewRecord ? ' inlineIsNewRecord' : '');
00446 $out = '<div id="' . $objectId . '_div" class="t3-form-field-container-inline '.$class.'">' . $out . '</div>';
00447 }
00448
00449 $this->fObj->popFromDynNestedStack();
00450
00451 return $out;
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 protected function renderMainFields($table, $row) {
00463
00464 $depth = $this->fObj->renderDepth;
00465
00466 if (isset($this->fObj->palettesRendered[$depth][$table])) {
00467 $palettesRendered = $this->fObj->palettesRendered[$depth][$table];
00468 }
00469
00470 $content = $this->fObj->getMainFields($table, $row, $depth);
00471
00472 if (isset($palettesRendered)) {
00473 $this->fObj->palettesRendered[$depth][$table] = $palettesRendered;
00474 }
00475 return $content;
00476 }
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 function renderForeignRecordHeader($parentUid, $foreign_table, $rec, $config, $isVirtualRecord=false) {
00491
00492 $objectId = $this->inlineNames['object'] . self::Structure_Separator . $foreign_table . self::Structure_Separator . $rec['uid'];
00493 $expandSingle = $config['appearance']['expandSingle'] ? 1 : 0;
00494
00495 $onClick = "return inline.expandCollapseRecord('" . htmlspecialchars($objectId) . "', $expandSingle, '" . rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI')) . "')";
00496
00497
00498 $isOnSymmetricSide = t3lib_loadDBGroup::isOnSymmetricSide($parentUid, $config, $rec);
00499 $hasForeignLabel = !$isOnSymmetricSide && $config['foreign_label'] ? true : false;
00500 $hasSymmetricLabel = $isOnSymmetricSide && $config['symmetric_label'] ? true : false;
00501
00502
00503 if ($GLOBALS['TCA'][$foreign_table]['ctrl']['label_userFunc']) {
00504 $params = array(
00505 'table' => $foreign_table,
00506 'row' => $rec,
00507 'title' => '',
00508 'isOnSymmetricSide' => $isOnSymmetricSide,
00509 'parent' => array(
00510 'uid' => $parentUid,
00511 'config' => $config,
00512 ),
00513 );
00514 $null = null;
00515 t3lib_div::callUserFunction($GLOBALS['TCA'][$foreign_table]['ctrl']['label_userFunc'], $params, $null);
00516 $recTitle = $params['title'];
00517
00518 } elseif ($hasForeignLabel || $hasSymmetricLabel) {
00519 $titleCol = $hasForeignLabel ? $config['foreign_label'] : $config['symmetric_label'];
00520 $foreignConfig = $this->getPossibleRecordsSelectorConfig($config, $titleCol);
00521
00522 if ($foreignConfig['type'] != 'groupdb') {
00523 $recTitle = t3lib_BEfunc::getProcessedValueExtra($foreign_table, $titleCol, $rec[$titleCol], 0, 0, false);
00524
00525 } else {
00526
00527 $valueParts = t3lib_div::trimExplode('|', $rec[$titleCol]);
00528 $itemParts = t3lib_div::revExplode('_', $valueParts[0], 2);
00529 $recTemp = t3lib_befunc::getRecordWSOL($itemParts[0], $itemParts[1]);
00530 $recTitle = t3lib_BEfunc::getRecordTitle($itemParts[0], $recTemp, false);
00531 }
00532 $recTitle = t3lib_BEfunc::getRecordTitlePrep($recTitle);
00533 if (!strcmp(trim($recTitle),'')) {
00534 $recTitle = t3lib_BEfunc::getNoRecordTitle(true);
00535 }
00536
00537 } else {
00538 $recTitle = t3lib_BEfunc::getRecordTitle($foreign_table, $rec, true);
00539 }
00540
00541 $altText = t3lib_BEfunc::getRecordIconAltText($rec, $foreign_table);
00542 $iconImg = t3lib_iconWorks::getSpriteIconForRecord($foreign_table, $rec, array('title' => htmlspecialchars($altText), 'id' => $objectId . '_icon"'));
00543 $label = '<span id="' . $objectId . '_label">' . $recTitle . '</span>';
00544 if (!$isVirtualRecord) {
00545 $iconImg = $this->wrapWithAnchor($iconImg, '#', array('onclick' => $onClick));
00546 $label = $this->wrapWithAnchor($label, '#', array('onclick' => $onClick, 'style' => 'display: block;'));
00547 }
00548
00549 $ctrl = $this->renderForeignRecordHeaderControl($parentUid, $foreign_table, $rec, $config, $isVirtualRecord);
00550
00551 // @TODO: Check the table wrapping and the CSS definitions
00552 $header =
00553 '<table cellspacing="0" cellpadding="0" border="0" width="100%" style="margin-right: '.$this->inlineStyles['margin-right'].'px;"'.
00554 ($this->fObj->borderStyle[2] ? ' background="'.htmlspecialchars($this->backPath.$this->fObj->borderStyle[2]).'"':'').
00555 ($this->fObj->borderStyle[3] ? ' class="'.htmlspecialchars($this->fObj->borderStyle[3]).'"':'').'>' .
00556 '<tr class="class-main12"><td width="18" id="' . $objectId . '_iconcontainer">' . $iconImg . '</td><td align="left"><strong>' . $label . '</strong></td><td align="right">' . $ctrl . '</td></tr></table>';
00557
00558 return $header;
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 function renderForeignRecordHeaderControl($parentUid, $foreign_table, $rec, $config=array(), $isVirtualRecord=false) {
00573
00574 $cells = array();
00575 $isNewItem = substr($rec['uid'], 0, 3) == 'NEW';
00576
00577 $tcaTableCtrl =& $GLOBALS['TCA'][$foreign_table]['ctrl'];
00578 $tcaTableCols =& $GLOBALS['TCA'][$foreign_table]['columns'];
00579
00580 $isPagesTable = $foreign_table == 'pages' ? true : false;
00581 $isOnSymmetricSide = t3lib_loadDBGroup::isOnSymmetricSide($parentUid, $config, $rec);
00582 $enableManualSorting = $tcaTableCtrl['sortby'] || $config['MM'] || (!$isOnSymmetricSide && $config['foreign_sortby']) || ($isOnSymmetricSide && $config['symmetric_sortby']) ? true : false;
00583
00584 $nameObject = $this->inlineNames['object'];
00585 $nameObjectFt = $nameObject . self::Structure_Separator . $foreign_table;
00586 $nameObjectFtId = $nameObjectFt . self::Structure_Separator . $rec['uid'];
00587
00588 $calcPerms = $GLOBALS['BE_USER']->calcPerms(
00589 t3lib_BEfunc::readPageAccess($rec['pid'], $GLOBALS['BE_USER']->getPagePermsClause(1))
00590 );
00591
00592
00593 if ($isPagesTable) {
00594 $localCalcPerms = $GLOBALS['BE_USER']->calcPerms(t3lib_BEfunc::getRecord('pages',$rec['uid']));
00595 }
00596
00597
00598 $permsEdit = ($isPagesTable && ($localCalcPerms&2)) || (!$isPagesTable && ($calcPerms&16));
00599
00600
00601 $enabledControls = $config['appearance']['enabledControls'];
00602
00603 foreach ($this->hookObjects as $hookObj) {
00604 $hookObj->renderForeignRecordHeaderControl_preProcess($parentUid, $foreign_table, $rec, $config, $isVirtual, $enabledControls);
00605 }
00606
00607
00608 $cells['required'] = '<img name="'.$nameObjectFtId.'_req" src="clear.gif" width="10" height="10" hspace="4" vspace="3" alt="" />';
00609
00610 if (isset($rec['__create'])) {
00611 $cells['localize.isLocalizable'] = t3lib_iconWorks::getSpriteIcon('actions-edit-localize-status-low', array('title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xml:localize.isLocalizable', TRUE)));
00612 } elseif (isset($rec['__remove'])) {
00613 $cells['localize.wasRemovedInOriginal'] = t3lib_iconWorks::getSpriteIcon('actions-edit-localize-status-high', array('title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xml:localize.wasRemovedInOriginal', 1)));
00614 }
00615
00616
00617 if ($enabledControls['info'] && !$isNewItem) {
00618 $cells['info']='<a href="#" onclick="'.htmlspecialchars('top.launchView(\''.$foreign_table.'\', \''.$rec['uid'].'\'); return false;').'">'.
00619 t3lib_iconWorks::getSpriteIcon('status-dialog-information', array('title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_web_list.xml:showInfo', TRUE))).
00620 '</a>';
00621 }
00622
00623 if (!$tcaTableCtrl['readOnly'] && !$isVirtualRecord) {
00624
00625
00626 if ($enabledControls['new'] && ($enableManualSorting || $tcaTableCtrl['useColumnsForDefaultValues'])) {
00627 if (
00628 (!$isPagesTable && ($calcPerms&16)) ||
00629 ($isPagesTable && ($calcPerms&8))
00630 ) {
00631 $onClick = "return inline.createNewRecord('".$nameObjectFt."','".$rec['uid']."')";
00632 $class = ' class="inlineNewButton '.$this->inlineData['config'][$nameObject]['md5'].'"';
00633 if ($config['inline']['inlineNewButtonStyle']) {
00634 $style = ' style="'.$config['inline']['inlineNewButtonStyle'].'"';
00635 }
00636 $cells['new']='<a href="#" onclick="'.htmlspecialchars($onClick).'"'.$class.$style.'>'.
00637 t3lib_iconWorks::getSpriteIcon('actions-' . ($isPagesTable? 'page' :'document') . '-new',
00638 array(
00639 'title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_web_list.xml:new' . ($isPagesTable ? 'Page' : 'Record' ), 1)
00640 )
00641 ).
00642 '</a>';
00643 }
00644 }
00645
00646
00647 if ($enabledControls['dragdrop'] && $permsEdit && $enableManualSorting && $config['appearance']['useSortable']) {
00648 $cells['dragdrop'] = t3lib_iconWorks::getSpriteIcon('actions-move-move', array('class' => 'sortableHandle', 'title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.move', TRUE)));
00649 }
00650
00651
00652 if ($enabledControls['sort'] && $permsEdit && $enableManualSorting) {
00653 $onClick = "return inline.changeSorting('".$nameObjectFtId."', '1')";
00654 $style = $config['inline']['first'] == $rec['uid'] ? 'style="visibility: hidden;"' : '';
00655 $cells['sort.up']='<a href="#" onclick="'.htmlspecialchars($onClick).'" class="sortingUp" '.$style.'>'.
00656 t3lib_iconWorks::getSpriteIcon('actions-move-up', array('title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_web_list.xml:moveUp', TRUE))).
00657 '</a>';
00658
00659 $onClick = "return inline.changeSorting('".$nameObjectFtId."', '-1')";
00660 $style = $config['inline']['last'] == $rec['uid'] ? 'style="visibility: hidden;"' : '';
00661 $cells['sort.down']='<a href="#" onclick="'.htmlspecialchars($onClick).'" class="sortingDown" '.$style.'>'.
00662 t3lib_iconWorks::getSpriteIcon('actions-move-down', array('title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_web_list.xml:moveDown', TRUE))).
00663 '</a>';
00664 }
00665
00666
00667 $hiddenField = $tcaTableCtrl['enablecolumns']['disabled'];
00668 if ($enabledControls['hide'] && $permsEdit && $hiddenField && $tcaTableCols[$hiddenField] && (!$tcaTableCols[$hiddenField]['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields',$foreign_table.':'.$hiddenField))) {
00669 $onClick = "return inline.enableDisableRecord('".$nameObjectFtId."')";
00670 if ($rec[$hiddenField]) {
00671 $cells['hide.unhide']='<a href="#" onclick="'.htmlspecialchars($onClick).'">'.
00672 t3lib_iconWorks::getSpriteIcon(
00673 'actions-edit-unhide',
00674 array(
00675 'title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_web_list.xml:unHide' . ($isPagesTable ? 'Page' : ''), 1),
00676 'id' => $nameObjectFtId . '_disabled'
00677 )
00678 ) .
00679 '</a>';
00680 } else {
00681 $cells['hide.hide']='<a href="#" onclick="'.htmlspecialchars($onClick).'">'.
00682 t3lib_iconWorks::getSpriteIcon(
00683 'actions-edit-hide',
00684 array(
00685 'title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_web_list.xml:hide' . ($isPagesTable ? 'Page' : ''), 1),
00686 'id' => $nameObjectFtId . '_disabled'
00687 )
00688 ) .
00689 '</a>';
00690 }
00691 }
00692
00693
00694 if ($enabledControls['delete'] && ($isPagesTable && $localCalcPerms&4 || !$isPagesTable && $calcPerms&16)) {
00695 $onClick = "inline.deleteRecord('".$nameObjectFtId."');";
00696 $cells['delete']='<a href="#" onclick="'.htmlspecialchars('if (confirm('.$GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->getLL('deleteWarning')).')) { '.$onClick.' } return false;').'">'.
00697 t3lib_iconWorks::getSpriteIcon('actions-edit-delete', array('title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_web_list.xml:delete', TRUE))) .
00698 '</a>';
00699 }
00700
00701 } elseif ($isVirtualRecord) {
00702 if ($enabledControls['localize'] && isset($rec['__create'])) {
00703 $onClick = "inline.synchronizeLocalizeRecords('".$nameObjectFt."', ".$rec['uid'].");";
00704 $cells['localize'] = '<a href="#" onclick="'.htmlspecialchars($onClick).'">' .
00705 t3lib_iconWorks::getSpriteIcon('actions-document-localize', array('title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xml:localize', TRUE))) .
00706 '</a>';
00707 }
00708 }
00709
00710
00711 if ($lockInfo=t3lib_BEfunc::isRecordLocked($foreign_table,$rec['uid'])) {
00712 $cells['locked']='<a href="#" onclick="'.htmlspecialchars('alert('.$GLOBALS['LANG']->JScharCode($lockInfo['msg']).');return false;').'">'.
00713 t3lib_iconWorks::getSpriteIcon('status-warning-in-use', array('title' => htmlspecialchars($lockInfo['msg']))) .
00714 '</a>';
00715 }
00716
00717
00718 foreach ($this->hookObjects as $hookObj) {
00719 $hookObj->renderForeignRecordHeaderControl_postProcess($parentUid, $foreign_table, $rec, $config, $isVirtual, $cells);
00720 }
00721
00722 return '
00723 <!-- CONTROL PANEL: '.$foreign_table.':'.$rec['uid'].' -->
00724 <div class="typo3-DBctrl">'.implode('', $cells).'</div>';
00725 }
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738 function renderCombinationTable(&$rec, $appendFormFieldNames, $config = array()) {
00739 $foreign_table = $config['foreign_table'];
00740 $foreign_selector = $config['foreign_selector'];
00741
00742 if ($foreign_selector && $config['appearance']['useCombination']) {
00743 $comboConfig = $GLOBALS['TCA'][$foreign_table]['columns'][$foreign_selector]['config'];
00744 $comboRecord = array();
00745
00746
00747 if ($rec[$foreign_selector] && t3lib_div::testInt($rec[$foreign_selector])) {
00748 $comboRecord = $this->getRecord(
00749 $this->inlineFirstPid,
00750 $comboConfig['foreign_table'],
00751 $rec[$foreign_selector]
00752 );
00753 $isNewRecord = false;
00754
00755 } else {
00756 $comboRecord = $this->getNewRecord(
00757 $this->inlineFirstPid,
00758 $comboConfig['foreign_table']
00759 );
00760 $isNewRecord = true;
00761 }
00762
00763
00764 $out = $this->renderMainFields($comboConfig['foreign_table'], $comboRecord);
00765 $out = $this->wrapFormsSection($out, array(), array('class' => 'wrapperAttention'));
00766
00767
00768 if ($isNewRecord) {
00769 $comboFormFieldName = $this->prependFormFieldNames.'['.$comboConfig['foreign_table'].']['.$comboRecord['uid'].'][pid]';
00770 $out .= '<input type="hidden" name="'.$comboFormFieldName.'" value="'.$comboRecord['pid'].'" />';
00771 }
00772
00773
00774 if ($isNewRecord || $config['foreign_unique'] == $foreign_selector) {
00775 $parentFormFieldName = $this->prependFormFieldNames.$appendFormFieldNames.'['.$foreign_selector.']';
00776 $out .= '<input type="hidden" name="'.$parentFormFieldName.'" value="'.$comboRecord['uid'].'" />';
00777 }
00778 }
00779
00780 return $out;
00781 }
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793 function renderPossibleRecordsSelector($selItems, $conf, $uniqueIds=array()) {
00794 $foreign_table = $conf['foreign_table'];
00795 $foreign_selector = $conf['foreign_selector'];
00796
00797 $selConfig = $this->getPossibleRecordsSelectorConfig($conf, $foreign_selector);
00798 $config = $selConfig['PA']['fieldConf']['config'];
00799
00800 if ($selConfig['type'] == 'select') {
00801 $item = $this->renderPossibleRecordsSelectorTypeSelect($selItems, $conf, $selConfig['PA'], $uniqueIds);
00802 } elseif ($selConfig['type'] == 'groupdb') {
00803 $item = $this->renderPossibleRecordsSelectorTypeGroupDB($conf, $selConfig['PA']);
00804 }
00805
00806 return $item;
00807 }
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820 function renderPossibleRecordsSelectorTypeSelect($selItems, $conf, &$PA, $uniqueIds=array()) {
00821 $foreign_table = $conf['foreign_table'];
00822 $foreign_selector = $conf['foreign_selector'];
00823
00824 $PA = array();
00825 $PA['fieldConf'] = $GLOBALS['TCA'][$foreign_table]['columns'][$foreign_selector];
00826 $PA['fieldConf']['config']['form_type'] = $PA['fieldConf']['config']['form_type'] ? $PA['fieldConf']['config']['form_type'] : $PA['fieldConf']['config']['type'];
00827 $PA['fieldTSConfig'] = $this->fObj->setTSconfig($foreign_table,array(),$foreign_selector);
00828 $config = $PA['fieldConf']['config'];
00829
00830 if(!$disabled) {
00831
00832 $opt = array();
00833 $styleAttrValue = '';
00834 foreach($selItems as $p) {
00835 if ($config['iconsInOptionTags']) {
00836 $styleAttrValue = $this->fObj->optionTagStyle($p[2]);
00837 }
00838 if (!in_array($p[1], $uniqueIds)) {
00839 $opt[]= '<option value="'.htmlspecialchars($p[1]).'"'.
00840 ' style="'.(in_array($p[1], $uniqueIds) ? '' : '').
00841 ($styleAttrValue ? ' style="'.htmlspecialchars($styleAttrValue) : '').'">'.
00842 htmlspecialchars($p[0]).'</option>';
00843 }
00844 }
00845
00846 // Put together the selector box:
00847 $selector_itemListStyle = isset($config['itemListStyle']) ? ' style="'.htmlspecialchars($config['itemListStyle']).'"' : ' style="'.$this->fObj->defaultMultipleSelectorStyle.'"';
00848 $size = intval($conf['size']);
00849 $size = $conf['autoSizeMax'] ? t3lib_div::intInRange(count($itemArray)+1,t3lib_div::intInRange($size,1),$conf['autoSizeMax']) : $size;
00850 $onChange = "return inline.importNewRecord('" . $this->inlineNames['object']. self::Structure_Separator . $conf['foreign_table'] . "')";
00851 $item = '
00852 <select id="'.$this->inlineNames['object'] . self::Structure_Separator . $conf['foreign_table'] . '_selector"'.
00853 $this->fObj->insertDefStyle('select').
00854 ($size ? ' size="'.$size.'"' : '').
00855 ' onchange="'.htmlspecialchars($onChange).'"'.
00856 $PA['onFocus'].
00857 $selector_itemListStyle.
00858 ($conf['foreign_unique'] ? ' isunique="isunique"' : '').'>
00859 '.implode('
00860 ',$opt).'
00861 </select>';
00862
00863
00864
00865
00866
00867 $createNewRelationText = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:cm.createNewRelation',1);
00868 $item .=
00869 '<a href="#" onclick="'.htmlspecialchars($onChange).'" align="abstop">'.
00870 t3lib_iconWorks::getSpriteIcon('actions-document-new', array('title' => $createNewRelationText)) . $createNewRelationText .
00871 '</a>';
00872
00873 $item = '<div style="margin-bottom: 20px;">'.$item.'</div>';
00874 }
00875
00876 return $item;
00877 }
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888 function renderPossibleRecordsSelectorTypeGroupDB($conf, &$PA) {
00889 $foreign_table = $conf['foreign_table'];
00890
00891 $config = $PA['fieldConf']['config'];
00892 $allowed = $config['allowed'];
00893 $objectPrefix = $this->inlineNames['object'] . self::Structure_Separator . $foreign_table;
00894
00895 $createNewRelationText = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:cm.createNewRelation',1);
00896 $onClick = "setFormValueOpenBrowser('db','".('|||'.$allowed.'|'.$objectPrefix.'|inline.checkUniqueElement||inline.importElement')."'); return false;";
00897 $item =
00898 '<a href="#" onclick="'.htmlspecialchars($onClick).'">'.
00899 t3lib_iconWorks::getSpriteIcon('actions-insert-record', array('title' => $createNewRelationText)). $createNewRelationText .
00900 '</a>';
00901
00902 return $item;
00903 }
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915 protected function getLevelInteractionLink($type, $objectPrefix, $conf=array()) {
00916 $nameObject = $this->inlineNames['object'];
00917 $attributes = array();
00918 switch($type) {
00919 case 'newRecord':
00920 $title = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:cm.createnew', 1);
00921 $icon = 'actions-document-new';
00922 $className = 'typo3-newRecordLink';
00923 $attributes['class'] = 'inlineNewButton '.$this->inlineData['config'][$nameObject]['md5'];
00924 $attributes['onclick'] = "return inline.createNewRecord('$objectPrefix')";
00925 if (isset($conf['inline']['inlineNewButtonStyle']) && $conf['inline']['inlineNewButtonStyle']) {
00926 $attributes['style'] = $conf['inline']['inlineNewButtonStyle'];
00927 }
00928 if (isset($conf['appearance']['newRecordLinkAddTitle']) && $conf['appearance']['newRecordLinkAddTitle']) {
00929 $titleAddon = ' '.$GLOBALS['LANG']->sL($GLOBALS['TCA'][$conf['foreign_table']]['ctrl']['title'], 1);
00930 }
00931 break;
00932 case 'localize':
00933 $title = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xml:localizeAllRecords', 1);
00934 $icon = 'actions-document-localize';
00935 $className = 'typo3-localizationLink';
00936 $attributes['onclick'] = "return inline.synchronizeLocalizeRecords('$objectPrefix', 'localize')";
00937 break;
00938 case 'synchronize':
00939 $title = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xml:synchronizeWithOriginalLanguage', 1);
00940 $icon = 'actions-document-synchronize';
00941 $className = 'typo3-synchronizationLink';
00942 $attributes['class'] = 'inlineNewButton '.$this->inlineData['config'][$nameObject]['md5'];
00943 $attributes['onclick'] = "return inline.synchronizeLocalizeRecords('$objectPrefix', 'synchronize')";
00944 break;
00945 }
00946
00947 $icon = ($icon ? t3lib_iconWorks::getSpriteIcon($icon, array('title' => htmlspecialchars($title . $titleAddon))) : '');
00948 $link = $this->wrapWithAnchor($icon . $title . $titleAddon, '#', $attributes);
00949 return '<div' . ($className ? ' class="' . $className . '"' : '').'>' . $link . '</div>';
00950 }
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 function getNewRecordLink($objectPrefix, $conf = array()) {
00962 t3lib_div::logDeprecatedFunction();
00963
00964 return $this->getLevelInteractionLink('newRecord', $objectPrefix, $conf);
00965 }
00966
00967
00968
00969
00970
00971
00972
00973
00974 function addJavaScriptSortable($objectId) {
00975 $this->fObj->additionalJS_post[] = '
00976 inline.createDragAndDropSorting("'.$objectId.'");
00977 ';
00978 }
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996 public function processAjaxRequest($params, $ajaxObj) {
00997
00998 $ajaxArguments = t3lib_div::_GP('ajax');
00999 $ajaxIdParts = explode('::', $GLOBALS['ajaxID'], 2);
01000
01001 if (isset($ajaxArguments) && is_array($ajaxArguments) && count($ajaxArguments)) {
01002 $ajaxMethod = $ajaxIdParts[1];
01003 switch ($ajaxMethod) {
01004 case 'createNewRecord':
01005 case 'synchronizeLocalizeRecords':
01006 case 'getRecordDetails':
01007 $this->isAjaxCall = true;
01008
01009 $this->processAjaxRequestConstruct($ajaxArguments);
01010
01011 $this->parseStructureString($ajaxArguments[0], true);
01012
01013 $ajaxObj->setContentFormat('jsonbody');
01014 $ajaxObj->setContent(
01015 call_user_func_array(array(&$this, $ajaxMethod), $ajaxArguments)
01016 );
01017 break;
01018 case 'setExpandedCollapsedState':
01019 $ajaxObj->setContentFormat('jsonbody');
01020 call_user_func_array(array(&$this, $ajaxMethod), $ajaxArguments);
01021 break;
01022 }
01023 }
01024 }
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037 protected function processAjaxRequestConstruct(&$ajaxArguments) {
01038 global $SOBE, $BE_USER, $TYPO3_CONF_VARS;
01039
01040 require_once(PATH_typo3.'template.php');
01041
01042 $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_alt_doc.xml');
01043
01044
01045 $SOBE = new stdClass();
01046 $SOBE->MOD_MENU = array(
01047 'showPalettes' => '',
01048 'showDescriptions' => '',
01049 'disableRTE' => ''
01050 );
01051
01052 $SOBE->MCONF['name']='xMOD_alt_doc.php';
01053
01054 $SOBE->MOD_SETTINGS = t3lib_BEfunc::getModuleData(
01055 $SOBE->MOD_MENU,
01056 t3lib_div::_GP('SET'),
01057 $SOBE->MCONF['name']
01058 );
01059
01060 $SOBE->doc = t3lib_div::makeInstance('template');
01061 $SOBE->doc->backPath = $GLOBALS['BACK_PATH'];
01062
01063 $SOBE->tceforms = t3lib_div::makeInstance('t3lib_TCEforms');
01064 $SOBE->tceforms->inline = $this;
01065 $SOBE->tceforms->RTEcounter = intval(array_shift($ajaxArguments));
01066 $SOBE->tceforms->initDefaultBEMode();
01067 $SOBE->tceforms->palettesCollapsed = !$SOBE->MOD_SETTINGS['showPalettes'];
01068 $SOBE->tceforms->disableRTE = $SOBE->MOD_SETTINGS['disableRTE'];
01069 $SOBE->tceforms->enableClickMenu = TRUE;
01070 $SOBE->tceforms->enableTabMenu = TRUE;
01071
01072 $SOBE->tceforms->clipObj = t3lib_div::makeInstance('t3lib_clipboard');
01073 $SOBE->tceforms->clipObj->initializeClipboard();
01074
01075 if ($BE_USER->uc['edit_showFieldHelp']!='text' && $SOBE->MOD_SETTINGS['showDescriptions']) {
01076 $SOBE->tceforms->edit_showFieldHelp = 'text';
01077 }
01078 }
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088 protected function getCommonScriptCalls(&$jsonArray, $config) {
01089
01090 if ($headTags = $this->getHeadTags()) {
01091 $jsonArray['headData'] = $headTags;
01092 }
01093
01094 $jsonArray['scriptCall'][] = $this->fObj->JSbottom($this->fObj->formName, true);
01095
01096 if ($config['appearance']['useSortable']) {
01097 $jsonArray['scriptCall'][] = "inline.createDragAndDropSorting('".$this->inlineNames['object']."_records');";
01098 }
01099
01100 if ($this->fObj->extJSCODE) {
01101 $jsonArray['scriptCall'][] = $this->fObj->extJSCODE;
01102 }
01103 }
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114 function initForAJAX($method, &$arguments) {
01115 t3lib_div::logDeprecatedFunction();
01116
01117
01118 if ($method == 'createNewRecord') {
01119 $this->fObj->RTEcounter = intval(array_shift($arguments));
01120 }
01121 }
01122
01123
01124
01125
01126
01127
01128
01129
01130 protected function getErrorMessageForAJAX($message) {
01131 $jsonArray = array(
01132 'data' => $message,
01133 'scriptCall' => array(
01134 'alert("' . $message . '");'
01135 )
01136 );
01137 return $jsonArray;
01138 }
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149 function createNewRecord($domObjectId, $foreignUid = 0) {
01150
01151 $current = $this->inlineStructure['unstable'];
01152
01153 $parent = $this->getStructureLevel(-1);
01154
01155 if (!$this->checkConfiguration($parent['config'])) {
01156 return $this->getErrorMessageForAJAX('Wrong configuration in table ' . $parent['table']);
01157 }
01158 $config = $parent['config'];
01159
01160 $collapseAll = (isset($config['appearance']['collapseAll']) && $config['appearance']['collapseAll']);
01161 $expandSingle = (isset($config['appearance']['expandSingle']) && $config['appearance']['expandSingle']);
01162
01163
01164 $this->fObj->pushToDynNestedStack('inline', $this->inlineNames['object']);
01165
01166
01167 if (!$foreignUid || !t3lib_div::testInt($foreignUid) || $config['foreign_selector']) {
01168 $record = $this->getNewRecord($this->inlineFirstPid, $current['table']);
01169
01170 if ($config['localizationMode']=='select') {
01171 $parentRecord = $this->getRecord(0, $parent['table'], $parent['uid']);
01172 $parentLanguageField = $GLOBALS['TCA'][$parent['table']]['ctrl']['languageField'];
01173 $childLanguageField = $GLOBALS['TCA'][$current['table']]['ctrl']['languageField'];
01174 if ($parentRecord[$languageField]>0) {
01175 $record[$childLanguageField] = $parentRecord[$languageField];
01176 }
01177 }
01178
01179
01180 } else {
01181 $record = $this->getRecord($this->inlineFirstPid, $current['table'], $foreignUid);
01182 }
01183
01184
01185
01186
01187 if ($config['foreign_selector'] && $foreignUid) {
01188 $selConfig = $this->getPossibleRecordsSelectorConfig($config, $config['foreign_selector']);
01189
01190 $record[$config['foreign_selector']] = $selConfig['type'] != 'groupdb' ? '' : $selConfig['table'].'_';
01191 $record[$config['foreign_selector']] .= $foreignUid;
01192 }
01193
01194
01195 $objectPrefix = $this->inlineNames['object'] . self::Structure_Separator . $current['table'];
01196 $objectId = $objectPrefix . self::Structure_Separator . $record['uid'];
01197
01198
01199 $item = $this->renderForeignRecord($parent['uid'], $record, $config);
01200 if($item === false) {
01201 return $this->getErrorMessageForAJAX('Access denied');
01202 }
01203
01204 if (!$current['uid']) {
01205 $jsonArray = array(
01206 'data' => $item,
01207 'scriptCall' => array(
01208 "inline.domAddNewRecord('bottom','".$this->inlineNames['object']."_records','$objectPrefix',json.data);",
01209 "inline.memorizeAddRecord('$objectPrefix','".$record['uid']."',null,'$foreignUid');"
01210 )
01211 );
01212
01213
01214 } else {
01215 $jsonArray = array(
01216 'data' => $item,
01217 'scriptCall' => array(
01218 "inline.domAddNewRecord('after','".$domObjectId.'_div'."','$objectPrefix',json.data);",
01219 "inline.memorizeAddRecord('$objectPrefix','".$record['uid']."','".$current['uid']."','$foreignUid');"
01220 )
01221 );
01222 }
01223 $this->getCommonScriptCalls($jsonArray, $config);
01224
01225 if (!$collapseAll && $expandSingle) {
01226 $jsonArray['scriptCall'][] = "inline.collapseAllRecords('$objectId', '$objectPrefix', '".$record['uid']."');";
01227 }
01228
01229 $jsonArray['scriptCall'][] = "Element.scrollTo('".$objectId."_div');";
01230
01231 $jsonArray['scriptCall'][] = "inline.fadeOutFadeIn('".$objectId."_div');";
01232
01233
01234 $this->fObj->popFromDynNestedStack();
01235
01236
01237 return $jsonArray;
01238 }
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248 protected function synchronizeLocalizeRecords($domObjectId, $type) {
01249 $jsonArray = false;
01250 if (t3lib_div::inList('localize,synchronize', $type) || t3lib_div::testInt($type)) {
01251
01252 $current = $this->inlineStructure['unstable'];
01253
01254 $parent = $this->getStructureLevel(-1);
01255 $parentRecord = $this->getRecord(0, $parent['table'], $parent['uid']);
01256
01257 $cmd = array();
01258 $cmd[$parent['table']][$parent['uid']]['inlineLocalizeSynchronize'] = $parent['field'].','.$type;
01259
01260
01261 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
01262 $tce->stripslashes_values = false;
01263 $tce->start(array(), $cmd);
01264 $tce->process_cmdmap();
01265 $newItemList = $tce->registerDBList[$parent['table']][$parent['uid']][$parent['field']];
01266 unset($tce);
01267
01268 $jsonArray = $this->getExecuteChangesJsonArray($parentRecord[$parent['field']], $newItemList);
01269 $this->getCommonScriptCalls($jsonArray, $parent['config']);
01270 }
01271 return $jsonArray;
01272 }
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282 function getRecordDetails($domObjectId) {
01283
01284 $current = $this->inlineStructure['unstable'];
01285
01286 $parent = $this->getStructureLevel(-1);
01287
01288 if (!$this->checkConfiguration($parent['config'])) {
01289 return $this->getErrorMessageForAJAX('Wrong configuration in table ' . $parent['table']);
01290 }
01291 $config = $parent['config'];
01292
01293 $config['renderFieldsOnly'] = true;
01294
01295 $collapseAll = (isset($config['appearance']['collapseAll']) && $config['appearance']['collapseAll']);
01296 $expandSingle = (isset($config['appearance']['expandSingle']) && $config['appearance']['expandSingle']);
01297
01298
01299 $this->fObj->pushToDynNestedStack('inline', $this->inlineNames['object']);
01300
01301 $record = $this->getRecord($this->inlineFirstPid, $current['table'], $current['uid']);
01302
01303
01304 $objectPrefix = $this->inlineNames['object'] . self::Structure_Separator . $current['table'];
01305 $objectId = $objectPrefix . self::Structure_Separator . $record['uid'];
01306
01307 $item = $this->renderForeignRecord($parent['uid'], $record, $config);
01308 if($item === false) {
01309 return $this->getErrorMessageForAJAX('Access denied');
01310 }
01311
01312 $jsonArray = array(
01313 'data' => $item,
01314 'scriptCall' => array(
01315 'inline.domAddRecordDetails(\'' . $domObjectId . '\',\'' . $objectPrefix . '\',' . ($expandSingle ? '1' : '0') . ',json.data);',
01316 )
01317 );
01318
01319 $this->getCommonScriptCalls($jsonArray, $config);
01320
01321 if (!$collapseAll && $expandSingle) {
01322 $jsonArray['scriptCall'][] = 'inline.collapseAllRecords(\'' . $objectId . '\',\'' . $objectPrefix . '\',\'' . $record['uid'] . '\');';
01323 }
01324
01325
01326 $this->fObj->popFromDynNestedStack();
01327
01328
01329 return $jsonArray;
01330 }
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340 protected function getExecuteChangesJsonArray($oldItemList, $newItemList) {
01341 $parent = $this->getStructureLevel(-1);
01342 $current = $this->inlineStructure['unstable'];
01343
01344 $jsonArray = array('scriptCall' => array());
01345 $jsonArrayScriptCall =& $jsonArray['scriptCall'];
01346
01347 $nameObject = $this->inlineNames['object'];
01348 $nameObjectForeignTable = $nameObject . self::Structure_Separator . $current['table'];
01349
01350 $transOrigPointerField = $GLOBALS['TCA'][$current['table']]['ctrl']['transOrigPointerField'];
01351
01352 $foreignSelector = (isset($parent['config']['foreign_selector']) && $parent['config']['foreign_selector'] ? $parent['config']['foreign_selector'] : false);
01353
01354 $oldItems = $this->getRelatedRecordsUidArray($oldItemList);
01355 $newItems = $this->getRelatedRecordsUidArray($newItemList);
01356
01357 $removedItems = array_diff($oldItems, $newItems);
01358 $localizedItems = array_diff($newItems, $oldItems);
01359
01360 foreach ($removedItems as $item) {
01361 $jsonArrayScriptCall[] = "inline.deleteRecord('".$nameObjectForeignTable . self::Structure_Separator . $item . "', {forceDirectRemoval: true});";
01362 }
01363
01364 foreach ($localizedItems as $item) {
01365 $row = $this->getRecord($this->inlineFirstPid, $current['table'], $item);
01366 $selectedValue = ($foreignSelector ? "'".$row[$foreignSelector]."'" : 'null');
01367 $data.= $this->renderForeignRecord($parent['uid'], $row, $parent['config']);
01368 $jsonArrayScriptCall[] = "inline.memorizeAddRecord('$nameObjectForeignTable', '".$item."', null, $selectedValue);";
01369
01370 if (isset($row[$transOrigPointerField]) && $row[$transOrigPointerField]) {
01371 $jsonArrayScriptCall[] = "inline.fadeAndRemove('" . $nameObjectForeignTable . self::Structure_Separator . $row[$transOrigPointerField] . '_div' . "');";
01372 }
01373 }
01374 if ($data) {
01375 $data = $GLOBALS['LANG']->csConvObj->utf8_encode($data, $GLOBALS['LANG']->charSet);
01376 $jsonArray['data'] = $data;
01377 array_unshift(
01378 $jsonArrayScriptCall,
01379 "inline.domAddNewRecord('bottom', '".$nameObject."_records', '$nameObjectForeignTable', json.data);"
01380 );
01381 }
01382
01383 return $jsonArray;
01384 }
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395 function setExpandedCollapsedState($domObjectId, $expand, $collapse) {
01396
01397 $this->parseStructureString($domObjectId, false);
01398
01399 $current = $this->inlineStructure['unstable'];
01400
01401 $top = $this->getStructureLevel(0);
01402
01403
01404 if (t3lib_div::testInt($top['uid'])) {
01405 $inlineView = (array)unserialize($GLOBALS['BE_USER']->uc['inlineView']);
01406 $inlineViewCurrent =& $inlineView[$top['table']][$top['uid']];
01407
01408 $expandUids = t3lib_div::trimExplode(',', $expand);
01409 $collapseUids = t3lib_div::trimExplode(',', $collapse);
01410
01411
01412 foreach ($expandUids as $uid) {
01413 $inlineViewCurrent[$current['table']][] = $uid;
01414 }
01415
01416 foreach ($collapseUids as $uid) {
01417 $inlineViewCurrent[$current['table']] = $this->removeFromArray($uid, $inlineViewCurrent[$current['table']]);
01418 }
01419
01420
01421 if (is_array($inlineViewCurrent[$current['table']])) {
01422 $inlineViewCurrent = array_unique($inlineViewCurrent);
01423 $GLOBALS['BE_USER']->uc['inlineView'] = serialize($inlineView);
01424 $GLOBALS['BE_USER']->writeUC();
01425 }
01426 }
01427 }
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448 function getRelatedRecords($table, $field, $row, &$PA, $config) {
01449 $records = array();
01450 $pid = $row['pid'];
01451 $elements = $PA['itemFormElValue'];
01452 $foreignTable = $config['foreign_table'];
01453
01454 $localizationMode = t3lib_BEfunc::getInlineLocalizationMode($table, $config);
01455
01456 if ($localizationMode!=false) {
01457 $language = intval($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']]);
01458 $transOrigPointer = intval($row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']]);
01459 if ($language>0 && $transOrigPointer) {
01460
01461 if ($localizationMode=='keep') {
01462 $transOrigRec = $this->getRecord(0, $table, $transOrigPointer);
01463 $elements = $transOrigRec[$field];
01464 $pid = $transOrigRec['pid'];
01465
01466 } elseif ($localizationMode=='select') {
01467 $transOrigRec = $this->getRecord(0, $table, $transOrigPointer);
01468 $pid = $transOrigRec['pid'];
01469 $recordsOriginal = $this->getRelatedRecordsArray($pid, $foreignTable, $transOrigRec[$field]);
01470 }
01471 }
01472 }
01473
01474 $records = $this->getRelatedRecordsArray($pid, $foreignTable, $elements);
01475 $relatedRecords = array('records' => $records, 'count' => count($records));
01476
01477
01478 if (is_array($recordsOriginal)) {
01479 $options = array(
01480 'showPossible' => (isset($config['appearance']['showPossibleLocalizationRecords']) && $config['appearance']['showPossibleLocalizationRecords']),
01481 'showRemoved' => (isset($config['appearance']['showRemovedLocalizationRecords']) && $config['appearance']['showRemovedLocalizationRecords']),
01482 );
01483 if ($options['showPossible'] || $options['showRemoved']) {
01484 $relatedRecords['records'] = $this->getLocalizationDifferences($foreignTable, $options, $recordsOriginal, $records);
01485 }
01486 }
01487
01488 return $relatedRecords;
01489 }
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500 protected function getRelatedRecordsArray($pid, $table, $itemList) {
01501 $records = array();
01502 $itemArray = $this->getRelatedRecordsUidArray($itemList);
01503
01504 foreach($itemArray as $uid) {
01505
01506 if ($record = $this->getRecord($pid, $table, $uid)) {
01507 $records[$uid] = $record;
01508 }
01509 }
01510 return $records;
01511 }
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522 protected function getRelatedRecordsUidArray($itemList) {
01523 $itemArray = t3lib_div::trimExplode(',', $itemList, 1);
01524
01525 foreach($itemArray as $key => &$value) {
01526 $parts = explode('|', $value, 2);
01527 $value = $parts[0];
01528 }
01529 return $itemArray;
01530 }
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544 protected function getLocalizationDifferences($table, array $options, array $recordsOriginal, array $recordsLocalization) {
01545 $records = array();
01546 $transOrigPointerField = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'];
01547
01548 foreach ($recordsLocalization as $uid => $row) {
01549
01550 if (isset($row[$transOrigPointerField]) && $row[$transOrigPointerField]>0) {
01551 $transOrigPointer = $row[$transOrigPointerField];
01552 if (isset($recordsOriginal[$transOrigPointer])) {
01553 unset($recordsOriginal[$transOrigPointer]);
01554 } elseif ($options['showRemoved']) {
01555 $row['__remove'] = true;
01556 }
01557 }
01558 $records[$uid] = $row;
01559 }
01560
01561 if ($options['showPossible']) {
01562 foreach ($recordsOriginal as $uid => $row) {
01563 $row['__create'] = true;
01564 $row['__virtual'] = true;
01565 $records[$uid] = $row;
01566 }
01567 }
01568 return $records;
01569 }
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583 function getPossibleRecords($table,$field,$row,$conf,$checkForConfField='foreign_selector') {
01584
01585 $tcaTableCtrl = $GLOBALS['TCA'][$table]['ctrl'];
01586
01587 $foreign_table = $conf['foreign_table'];
01588 $foreign_check = $conf[$checkForConfField];
01589
01590 $foreignConfig = $this->getPossibleRecordsSelectorConfig($conf, $foreign_check);
01591 $PA = $foreignConfig['PA'];
01592 $config = $PA['fieldConf']['config'];
01593
01594 if ($foreignConfig['type'] == 'select') {
01595
01596 $selItems = $this->fObj->addSelectOptionsToItemArray(
01597 $this->fObj->initItemArray($PA['fieldConf']),
01598 $PA['fieldConf'],
01599 $this->fObj->setTSconfig($table, $row),
01600 $field
01601 );
01602
01603 $keepItemsFunc = create_function('$value', 'return $value[1];');
01604 $selItems = t3lib_div::keepItemsInArray($selItems, $PA['fieldTSConfig']['keepItems'], $keepItemsFunc);
01605
01606 $selItems = $this->fObj->addItems($selItems, $PA['fieldTSConfig']['addItems.']);
01607 if (isset($config['itemsProcFunc']) && $config['itemsProcFunc']) {
01608 $selItems = $this->fObj->procItems($selItems, $PA['fieldTSConfig']['itemsProcFunc.'], $config, $table, $row, $field);
01609 }
01610
01611
01612 $removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
01613 foreach($selItems as $tk => $p) {
01614
01615
01616 $languageDeny = $tcaTableCtrl['languageField'] && !strcmp($tcaTableCtrl['languageField'], $field) && !$GLOBALS['BE_USER']->checkLanguageAccess($p[1]);
01617 $authModeDeny = $config['form_type']=='select' && $config['authMode'] && !$GLOBALS['BE_USER']->checkAuthMode($table,$field,$p[1],$config['authMode']);
01618 if (in_array($p[1],$removeItems) || $languageDeny || $authModeDeny) {
01619 unset($selItems[$tk]);
01620 } elseif (isset($PA['fieldTSConfig']['altLabels.'][$p[1]])) {
01621 $selItems[$tk][0]=$this->fObj->sL($PA['fieldTSConfig']['altLabels.'][$p[1]]);
01622 }
01623
01624
01625 if ($table.'.'.$field == 'pages.doktype') {
01626 if (!($GLOBALS['BE_USER']->isAdmin() || t3lib_div::inList($GLOBALS['BE_USER']->groupData['pagetypes_select'],$p[1]))) {
01627 unset($selItems[$tk]);
01628 }
01629 }
01630 }
01631 } else {
01632 $selItems = false;
01633 }
01634
01635 return $selItems;
01636 }
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646 function getUniqueIds($records, $conf=array(), $splitValue=false) {
01647 $uniqueIds = array();
01648
01649 if (isset($conf['foreign_unique']) && $conf['foreign_unique'] && count($records)) {
01650 foreach ($records as $rec) {
01651
01652 if (!isset($rec['__virtual']) || !$rec['__virtual']) {
01653 $value = $rec[$conf['foreign_unique']];
01654
01655 if ($splitValue) {
01656 $valueParts = t3lib_div::trimExplode('|', $value);
01657 $itemParts = explode('_', $valueParts[0]);
01658 $value = array(
01659 'uid' => array_pop($itemParts),
01660 'table' => implode('_', $itemParts)
01661 );
01662 }
01663 $uniqueIds[$rec['uid']] = $value;
01664 }
01665 }
01666 }
01667
01668 return $uniqueIds;
01669 }
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680 protected function getNewRecordPid($table, $parentPid=null) {
01681 $newRecordPid = $this->inlineFirstPid;
01682 $pageTS = t3lib_beFunc::getPagesTSconfig($parentPid, true);
01683 if (isset($pageTS['TCAdefaults.'][$table.'.']['pid']) && t3lib_div::testInt($pageTS['TCAdefaults.'][$table.'.']['pid'])) {
01684 $newRecordPid = $pageTS['TCAdefaults.'][$table.'.']['pid'];
01685 } elseif (isset($parentPid) && t3lib_div::testInt($parentPid)) {
01686 $newRecordPid = $parentPid;
01687 }
01688 return $newRecordPid;
01689 }
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702 function getRecord($pid, $table, $uid, $cmd='') {
01703 $trData = t3lib_div::makeInstance('t3lib_transferData');
01704 $trData->addRawData = TRUE;
01705 $trData->lockRecords=1;
01706 $trData->disableRTE = $GLOBALS['SOBE']->MOD_SETTINGS['disableRTE'];
01707
01708 $trData->fetchRecord($table, $uid, ($cmd === 'new' ? 'new' : ''));
01709 reset($trData->regTableItems_data);
01710 $rec = current($trData->regTableItems_data);
01711
01712 return $rec;
01713 }
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723 function getNewRecord($pid, $table) {
01724 $rec = $this->getRecord($pid, $table, $pid, 'new');
01725 $rec['uid'] = uniqid('NEW');
01726 $rec['pid'] = $this->getNewRecordPid($table, $pid);
01727 return $rec;
01728 }
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748 function pushStructure($table, $uid, $field = '', $config = array()) {
01749 $this->inlineStructure['stable'][] = array(
01750 'table' => $table,
01751 'uid' => $uid,
01752 'field' => $field,
01753 'config' => $config,
01754 'localizationMode' => t3lib_BEfunc::getInlineLocalizationMode($table, $config),
01755 );
01756 $this->updateStructureNames();
01757 }
01758
01759
01760
01761
01762
01763
01764
01765 function popStructure() {
01766 if (count($this->inlineStructure['stable'])) {
01767 $popItem = array_pop($this->inlineStructure['stable']);
01768 $this->updateStructureNames();
01769 }
01770 return $popItem;
01771 }
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782 function updateStructureNames() {
01783 $current = $this->getStructureLevel(-1);
01784
01785 if ($current !== false) {
01786 $this->inlineNames = array(
01787 'form' => $this->prependFormFieldNames . $this->getStructureItemName($current, self::Disposal_AttributeName),
01788 'object' => $this->prependNaming . self::Structure_Separator . $this->inlineFirstPid . self::Structure_Separator . $this->getStructurePath(),
01789 );
01790
01791 } else {
01792 $this->inlineNames = array();
01793 }
01794 }
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804 function getStructureItemName($levelData, $disposal = self::Disposal_AttributeId) {
01805 if (is_array($levelData)) {
01806 $parts = array($levelData['table'], $levelData['uid']);
01807 if (isset($levelData['field'])) {
01808 $parts[] = $levelData['field'];
01809 }
01810
01811
01812 if ($disposal === self::Disposal_AttributeName) {
01813 $name = '[' . implode('][', $parts) . ']';
01814
01815 } else {
01816 $name = implode(self::Structure_Separator, $parts);
01817 }
01818 }
01819 return $name;
01820 }
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831 function getStructureLevel($level) {
01832 $inlineStructureCount = count($this->inlineStructure['stable']);
01833 if ($level < 0) $level = $inlineStructureCount+$level;
01834 if ($level >= 0 && $level < $inlineStructureCount)
01835 return $this->inlineStructure['stable'][$level];
01836 else
01837 return false;
01838 }
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848 function getStructurePath($structureDepth = -1) {
01849 $structureLevels = array();
01850 $structureCount = count($this->inlineStructure['stable']);
01851
01852 if ($structureDepth < 0 || $structureDepth > $structureCount) {
01853 $structureDepth = $structureCount;
01854 }
01855
01856 for ($i = 1; $i <= $structureDepth; $i++) {
01857 array_unshift(
01858 $structureLevels,
01859 $this->getStructureItemName(
01860 $this->getStructureLevel(-$i),
01861 self::Disposal_AttributeId
01862 )
01863 );
01864 }
01865
01866 return implode(self::Structure_Separator, $structureLevels);
01867 }
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882 function parseStructureString($string, $loadConfig=true) {
01883 $unstable = array();
01884 $vector = array('table', 'uid', 'field');
01885 $pattern = '/^' . $this->prependNaming . self::Structure_Separator . '(.+?)' . self::Structure_Separator . '(.+)$/';
01886 if (preg_match($pattern, $string, $match)) {
01887 $this->inlineFirstPid = $match[1];
01888 $parts = explode(self::Structure_Separator, $match[2]);
01889 $partsCnt = count($parts);
01890 for ($i = 0; $i < $partsCnt; $i++) {
01891 if ($i > 0 && $i % 3 == 0) {
01892
01893 if ($loadConfig) {
01894 t3lib_div::loadTCA($unstable['table']);
01895 $unstable['config'] = $GLOBALS['TCA'][$unstable['table']]['columns'][$unstable['field']]['config'];
01896
01897 $TSconfig = $this->fObj->setTSconfig(
01898 $unstable['table'],
01899 array('uid' => $unstable['uid'], 'pid' => $this->inlineFirstPid),
01900 $unstable['field']
01901 );
01902
01903 if (!$TSconfig['disabled']) {
01904 $unstable['config'] = $this->fObj->overrideFieldConf($unstable['config'], $TSconfig);
01905 }
01906 $unstable['localizationMode'] = t3lib_BEfunc::getInlineLocalizationMode($unstable['table'], $unstable['config']);
01907 }
01908 $this->inlineStructure['stable'][] = $unstable;
01909 $unstable = array();
01910 }
01911 $unstable[$vector[$i % 3]] = $parts[$i];
01912 }
01913 $this->updateStructureNames();
01914 if (count($unstable)) $this->inlineStructure['unstable'] = $unstable;
01915 }
01916 }
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935 function checkConfiguration(&$config) {
01936 $foreign_table = $config['foreign_table'];
01937
01938
01939 if (!$foreign_table || !is_array($GLOBALS['TCA'][$foreign_table])) {
01940 return false;
01941 }
01942
01943 if (!isset($config['appearance']) || !is_array($config['appearance'])) {
01944 $config['appearance'] = array();
01945 }
01946
01947 if (!isset($config['appearance']['levelLinksPosition']) && isset($config['appearance']['newRecordLinkPosition']) && $config['appearance']['newRecordLinkPosition']) {
01948 t3lib_div::deprecationLog('TCA contains a deprecated definition using "newRecordLinkPosition"');
01949 $config['appearance']['levelLinksPosition'] = $config['appearance']['newRecordLinkPosition'];
01950 }
01951
01952 if (isset($config['foreign_selector']) && $config['foreign_selector'] && (!isset($config['appearance']['useCombination']) || !$config['appearance']['useCombination'])) {
01953 $config['appearance']['levelLinksPosition'] = 'none';
01954 } elseif (!isset($config['appearance']['levelLinksPosition']) || !in_array($config['appearance']['levelLinksPosition'], array('top', 'bottom', 'both', 'none'))) {
01955 $config['appearance']['levelLinksPosition'] = 'top';
01956 }
01957
01958 $enabledControls = array(
01959 'info' => true,
01960 'new' => true,
01961 'dragdrop' => true,
01962 'sort' => true,
01963 'hide' => true,
01964 'delete' => true,
01965 'localize' => true,
01966 );
01967 if (isset($config['appearance']['enabledControls']) && is_array($config['appearance']['enabledControls'])) {
01968 $config['appearance']['enabledControls'] = array_merge($enabledControls, $config['appearance']['enabledControls']);
01969 } else {
01970 $config['appearance']['enabledControls'] = $enabledControls;
01971 }
01972
01973 return true;
01974 }
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986 function checkAccess($cmd, $table, $theUid) {
01987
01988
01989 $hasAccess = 0;
01990 $deniedAccessReason = '';
01991
01992
01993 if ($GLOBALS['BE_USER']->isAdmin()) {
01994 return true;
01995 }
01996
01997 if ($cmd=='new') {
01998
01999 if (t3lib_div::testInt($this->inlineFirstPid)) {
02000 $calcPRec = t3lib_BEfunc::getRecord('pages', $this->inlineFirstPid);
02001 if(!is_array($calcPRec)) {
02002 return false;
02003 }
02004 $CALC_PERMS = $GLOBALS['BE_USER']->calcPerms($calcPRec);
02005 if ($table=='pages') {
02006 $hasAccess = $CALC_PERMS&8 ? 1 : 0;
02007 } else {
02008 $hasAccess = $CALC_PERMS&16 ? 1 : 0;
02009 }
02010
02011
02012 } else {
02013 $hasAccess = 1;
02014 }
02015 } else {
02016 $calcPRec = t3lib_BEfunc::getRecord($table,$theUid);
02017 t3lib_BEfunc::fixVersioningPid($table,$calcPRec);
02018 if (is_array($calcPRec)) {
02019 if ($table=='pages') {
02020 $CALC_PERMS = $GLOBALS['BE_USER']->calcPerms($calcPRec);
02021 $hasAccess = $CALC_PERMS&2 ? 1 : 0;
02022 } else {
02023 $CALC_PERMS = $GLOBALS['BE_USER']->calcPerms(t3lib_BEfunc::getRecord('pages',$calcPRec['pid']));
02024 $hasAccess = $CALC_PERMS&16 ? 1 : 0;
02025 }
02026
02027
02028 if ($hasAccess) {
02029 $hasAccess = $GLOBALS['BE_USER']->recordEditAccessInternals($table, $calcPRec);
02030 }
02031 }
02032 }
02033
02034 if(!$GLOBALS['BE_USER']->check('tables_modify', $table)) {
02035 $hasAccess = 0;
02036 }
02037
02038 if(!$hasAccess) {
02039 $deniedAccessReason = $GLOBALS['BE_USER']->errorMsg;
02040 if($deniedAccessReason) {
02041 debug($deniedAccessReason);
02042 }
02043 }
02044
02045 return $hasAccess ? true : false;
02046 }
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057 function compareStructureConfiguration($compare) {
02058 $level = $this->getStructureLevel(-1);
02059 $result = $this->arrayCompareComplex($level, $compare);
02060
02061 return $result;
02062 }
02063
02064
02065
02066
02067
02068
02069
02070
02071 function normalizeUid($string) {
02072 $parts = explode('|', $string);
02073 return $parts[0];
02074 }
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085 function wrapFormsSection($section, $styleAttrs = array(), $tableAttrs = array()) {
02086 if (!$styleAttrs['margin-right']) $styleAttrs['margin-right'] = $this->inlineStyles['margin-right'].'px';
02087
02088 foreach ($styleAttrs as $key => $value) $style .= ($style?' ':'').$key.': '.htmlspecialchars($value).'; ';
02089 if ($style) $style = ' style="'.$style.'"';
02090
02091 if (!$tableAttrs['background'] && $this->fObj->borderStyle[2]) $tableAttrs['background'] = $this->backPath.$this->borderStyle[2];
02092 if (!$tableAttrs['cellspacing']) $tableAttrs['cellspacing'] = '0';
02093 if (!$tableAttrs['cellpadding']) $tableAttrs['cellpadding'] = '0';
02094 if (!$tableAttrs['border']) $tableAttrs['border'] = '0';
02095 if (!$tableAttrs['width']) $tableAttrs['width'] = '100%';
02096 if (!$tableAttrs['class'] && $this->borderStyle[3]) $tableAttrs['class'] = $this->borderStyle[3];
02097
02098 foreach ($tableAttrs as $key => $value) $table .= ($table?' ':'').$key.'="'.htmlspecialchars($value).'"';
02099
02100 $out = '<table '.$table.$style.'>'.$section.'</table>';
02101 return $out;
02102 }
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114 function isInlineChildAndLabelField($table, $field) {
02115 $level = $this->getStructureLevel(-1);
02116 if ($level['config']['foreign_label'])
02117 $label = $level['config']['foreign_label'];
02118 else
02119 $label = $GLOBALS['TCA'][$table]['ctrl']['label'];
02120 return $level['config']['foreign_table'] === $table && $label == $field ? true : false;
02121 }
02122
02123
02124
02125
02126
02127
02128
02129
02130 function getStructureDepth() {
02131 return count($this->inlineStructure['stable']);
02132 }
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167 function arrayCompareComplex($subjectArray, $searchArray, $type = '') {
02168 $localMatches = 0;
02169 $localEntries = 0;
02170
02171 if (is_array($searchArray) && count($searchArray)) {
02172
02173 if (!$type) {
02174 reset($searchArray);
02175 $type = key($searchArray);
02176 $searchArray = current($searchArray);
02177 }
02178
02179
02180 $type = strtoupper($type);
02181
02182
02183 foreach ($searchArray as $key => $value) {
02184 $localEntries++;
02185
02186
02187 if ($key == '%OR') {
02188 $localMatches += $this->arrayCompareComplex($subjectArray, $value, '%OR') ? 1 : 0;
02189
02190 } elseif ($key == '%AND') {
02191 $localMatches += $this->arrayCompareComplex($subjectArray, $value, '%AND') ? 1 : 0;
02192
02193 } elseif (is_array($value) && $this->isAssociativeArray($searchArray)) {
02194 $localMatches += $this->arrayCompareComplex($subjectArray[$key], $value, $type) ? 1 : 0;
02195
02196 } elseif (is_array($value)) {
02197 $localMatches += $this->arrayCompareComplex($subjectArray, $value, $type) ? 1 : 0;
02198
02199 } else {
02200 if (isset($subjectArray[$key]) && isset($value)) {
02201
02202 if (is_bool($value)) {
02203 $localMatches += (!($subjectArray[$key] xor $value) ? 1 : 0);
02204
02205 } elseif (is_numeric($subjectArray[$key]) && is_numeric($value)) {
02206 $localMatches += ($subjectArray[$key] == $value ? 1 : 0);
02207
02208 } else {
02209 $localMatches += ($subjectArray[$key] === $value ? 1 : 0);
02210 }
02211 }
02212 }
02213
02214
02215 if ($type == '%OR' && $localMatches > 0) return true;
02216
02217 if ($type == '%AND' && $localMatches == 0) return false;
02218 }
02219 }
02220
02221
02222 return $localEntries == $localMatches ? true : false;
02223 }
02224
02225
02226
02227
02228
02229
02230
02231
02232 function isAssociativeArray($object) {
02233 return is_array($object) && count($object) && (array_keys($object) !== range(0, sizeof($object) - 1))
02234 ? true
02235 : false;
02236 }
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247 function removeFromArray($needle, $haystack, $strict=null) {
02248 $pos = array_search($needle, $haystack, $strict);
02249 if ($pos !== false) unset($haystack[$pos]);
02250 return $haystack;
02251 }
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262 function getPossibleRecordsFlat($possibleRecords) {
02263 $flat = false;
02264 if (is_array($possibleRecords)) {
02265 $flat = array();
02266 foreach ($possibleRecords as $record) $flat[$record[1]] = $record[0];
02267 }
02268 return $flat;
02269 }
02270
02271
02272
02273
02274
02275
02276
02277
02278 function getPossibleRecordsSelectorConfig($conf, $field = '') {
02279 $foreign_table = $conf['foreign_table'];
02280 $foreign_selector = $conf['foreign_selector'];
02281
02282 $PA = false;
02283 $type = false;
02284 $table = false;
02285 $selector = false;
02286
02287 if ($field) {
02288 $PA = array();
02289 $PA['fieldConf'] = $GLOBALS['TCA'][$foreign_table]['columns'][$field];
02290 $PA['fieldConf']['config']['form_type'] = $PA['fieldConf']['config']['form_type'] ? $PA['fieldConf']['config']['form_type'] : $PA['fieldConf']['config']['type'];
02291 $PA['fieldTSConfig'] = $this->fObj->setTSconfig($foreign_table,array(),$field);
02292 $config = $PA['fieldConf']['config'];
02293
02294 $type = $this->getPossibleRecordsSelectorType($config);
02295
02296 $table = $type == 'select' ? $config['foreign_table'] : $config['allowed'];
02297
02298 if ($foreign_selector && $foreign_selector == $field && $type) {
02299 $selector = $type;
02300 }
02301 }
02302
02303 return array(
02304 'PA' => $PA,
02305 'type' => $type,
02306 'table' => $table,
02307 'selector' => $selector,
02308 );
02309 }
02310
02311
02312
02313
02314
02315
02316
02317
02318 function getPossibleRecordsSelectorType($config) {
02319 $type = false;
02320 if ($config['type'] == 'select') {
02321 $type = 'select';
02322 } elseif ($config['type'] == 'group' && $config['internal_type'] == 'db') {
02323 $type = 'groupdb';
02324 }
02325 return $type;
02326 }
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339 function skipField($table, $field, $row, $config) {
02340 $skipThisField = false;
02341
02342 if ($this->getStructureDepth()) {
02343 $searchArray = array(
02344 '%OR' => array(
02345 'config' => array(
02346 0 => array(
02347 '%AND' => array(
02348 'foreign_table' => $table,
02349 '%OR' => array(
02350 '%AND' => array(
02351 'appearance' => array('useCombination' => true),
02352 'foreign_selector' => $field,
02353 ),
02354 'MM' => $config['MM']
02355 ),
02356 ),
02357 ),
02358 1 => array(
02359 '%AND' => array(
02360 'foreign_table' => $config['foreign_table'],
02361 'foreign_selector' => $config['foreign_field'],
02362 ),
02363 ),
02364 ),
02365 ),
02366 );
02367
02368
02369 $level = $this->getStructureLevel(-1);
02370
02371
02372 if (t3lib_loadDBGroup::isOnSymmetricSide($level['uid'], $level['config'], $row)) {
02373 $searchArray['%OR']['config'][0]['%AND']['%OR']['symmetric_field'] = $field;
02374 $searchArray['%OR']['config'][0]['%AND']['%OR']['symmetric_sortby'] = $field;
02375
02376 } else {
02377 $searchArray['%OR']['config'][0]['%AND']['%OR']['foreign_field'] = $field;
02378 $searchArray['%OR']['config'][0]['%AND']['%OR']['foreign_sortby'] = $field;
02379 }
02380
02381 $skipThisField = $this->compareStructureConfiguration($searchArray, true);
02382 }
02383
02384 return $skipThisField;
02385 }
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396 function getJSON($jsonArray) {
02397 t3lib_div::logDeprecatedFunction();
02398
02399 return json_encode($jsonArray);
02400 }
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410 function getExpandedCollapsedState($table, $uid) {
02411 if (isset($this->inlineView[$table]) && is_array($this->inlineView[$table])) {
02412 if (in_array($uid, $this->inlineView[$table]) !== false) {
02413 return true;
02414 }
02415 }
02416 return false;
02417 }
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427 function updateInlineView(&$uc, $tce) {
02428 if (isset($uc['inlineView']) && is_array($uc['inlineView'])) {
02429 $inlineView = (array)unserialize($GLOBALS['BE_USER']->uc['inlineView']);
02430
02431 foreach ($uc['inlineView'] as $topTable => $topRecords) {
02432 foreach ($topRecords as $topUid => $childElements) {
02433 foreach ($childElements as $childTable => $childRecords) {
02434 $uids = array_keys($tce->substNEWwithIDs_table, $childTable);
02435 if (count($uids)) {
02436 $newExpandedChildren = array();
02437 foreach ($childRecords as $childUid => $state) {
02438 if ($state && in_array($childUid, $uids)) {
02439 $newChildUid = $tce->substNEWwithIDs[$childUid];
02440 $newExpandedChildren[] = $newChildUid;
02441 }
02442 }
02443
02444 if (count($newExpandedChildren)) {
02445 $inlineViewCurrent =& $inlineView[$topTable][$topUid][$childTable];
02446 if (is_array($inlineViewCurrent)) {
02447 $inlineViewCurrent = array_unique(array_merge($inlineViewCurrent, $newExpandedChildren));
02448 } else {
02449 $inlineViewCurrent = $newExpandedChildren;
02450 }
02451 }
02452 }
02453 }
02454 }
02455 }
02456
02457 $GLOBALS['BE_USER']->uc['inlineView'] = serialize($inlineView);
02458 $GLOBALS['BE_USER']->writeUC();
02459 }
02460 }
02461
02462
02463
02464
02465
02466
02467
02468 function getLevelMargin() {
02469 $margin = ($this->inlineStyles['margin-right']+1)*2;
02470 return $margin;
02471 }
02472
02473
02474
02475
02476
02477
02478 protected function getHeadTags() {
02479 $headTags = array();
02480 $headDataRaw = $this->fObj->JStop();
02481
02482 if ($headDataRaw) {
02483
02484 $parseObj = t3lib_div::makeInstance('t3lib_parsehtml');
02485
02486 $headDataRaw = str_replace(array('', ''), '', $headDataRaw);
02487
02488 $headDataRaw = trim(preg_replace('/(^|\r|\n)( |\t)+/', '$1', $headDataRaw));
02489
02490 $tags = array_merge(
02491 $parseObj->getAllParts($parseObj->splitTags('link', $headDataRaw)),
02492 $parseObj->getAllParts($parseObj->splitIntoBlock('script', $headDataRaw))
02493 );
02494
02495 foreach ($tags as $tagData) {
02496 $tagAttributes = $parseObj->get_tag_attributes($parseObj->getFirstTag($tagData), true);
02497 $headTags[] = array(
02498 'name' => $parseObj->getFirstTagName($tagData),
02499 'attributes' => $tagAttributes[0],
02500 'innerHTML' => $parseObj->removeFirstAndLastTag($tagData),
02501 );
02502 }
02503 }
02504
02505 return $headTags;
02506 }
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517 protected function wrapWithAnchor($text, $link, $attributes=array()) {
02518 $link = trim($link);
02519 $result = '<a href="'.($link ? $link : '#').'"';
02520 foreach ($attributes as $key => $value) {
02521 $result.= ' '.$key.'="'.htmlspecialchars(trim($value)).'"';
02522 }
02523 $result.= '>'.$text.'</a>';
02524 return $result;
02525 }
02526 }
02527
02528
02529 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tceforms_inline.php']) {
02530 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tceforms_inline.php']);
02531 }
02532
02533 ?>