kenken999/php
0
1<?php2class AddPage extends RunnerPage3{4 /**5 * The page's message type6 * @type Number7 */8 public $messageType = MESSAGE_ERROR;9 10 protected $auditObj = null;11 12 /**13 * The page's fields array14 */15 protected $addFields = array();16 17 protected $readAddValues = false;18 19 /**20 * The record is being added through the 'List page with search' InlineAdd controls21 */22 protected $insertedSuccessfully = false;23 24 protected $defvalues = array();25 26 protected $newRecordData = array();27 28 /**29 * It could be set up in ADD_MASTER mode only30 */31 public $afterAdd_id = '';32 33 /**34 * The page's action35 * @type String36 */37 public $action = "";38 39 /**40 * It's set up in inline add mode only41 */42 public $screenWidth = 0;43 44 /**45 * It's set up in inline add mode only46 */47 public $screenHeight = 0;48 49 /**50 * It's set up in inline add mode only51 */52 public $orientation = '';53 54 /**55 * It's equal to true when a record is added56 * through the 'List page with search' InlineAdd controls57 */58 public $forListPageLookup = false;59 60 /**61 * The short lookup table name62 * It's set up properly when a record is being added63 * in a lookup 'Add new' popup64 * or through the 'List page with search' InlineAdd controls65 */66 public $lookupTable = "";67 68 /**69 * It's set up properly when a record is being added70 * in a lookup 'Add new' popup71 * or through the 'List page with search' InlineAdd controls72 */73 public $lookupField = "";74 75 /**76 * It's set up properly when a record is being added77 * in a lookup 'Add new' popup78 * or through the 'List page with search' InlineAdd controls79 */80 public $lookupPageType = "";81 82 /**83 * @type Array84 */85 public $parentCtrlsData;86 87 88 /**89 * @type Number90 */91 protected $afterAddAction = null;92 93 /**94 *95 */96 public $fromDashboard = "";97 98 public $forSpreadsheetGrid = false;99 public $hostPageName = "";100 public $newRowId;101 102 public $listPage = "";103 104 protected $sqlValues = array();105 106 /**107 * @constructor108 */109 function __construct(&$params)110 {111 parent::__construct($params);112 113 $this->addFields = $this->getPageFields();114 $this->auditObj = GetAuditObject($this->tName);115 116 $this->headerForms = array( "top" );117 $this->footerForms = array( "below-grid" );118 119 if ( $this->isMultistepped() )120 $this->bodyForms = array( "above-grid", "steps" );121 else122 $this->bodyForms = array( "above-grid", "grid" );123 124 $this->addPageSettings();125 }126 127 function setSessionVariables() {128 parent::setSessionVariables();129 // don't use mastertable pre-stroed in session130 if( !postvalue("mastertable")) {131 $this->masterTable = "";132 } 133 }134 135 /**136 * Add js page settings137 */138 protected function addPageSettings()139 {140 if( $_SESSION[ $this->sessionPrefix . "_recordAdded" ] )141 {142 $this->setProxyValue( $this->shortTableName."_recordAdded", true );143 unset( $_SESSION[ $this->sessionPrefix . "_recordAdded" ] );144 }145 else146 $this->setProxyValue( $this->shortTableName."_recordAdded", false );147 148 if( $this->mode != ADD_SIMPLE && $this->mode != ADD_POPUP )149 return;150 151 $afterAddAction = $this->getAfterAddAction();152 $this->jsSettings["tableSettings"][ $this->tName ]["afterAddAction"] = $afterAddAction;153 154 if ( $afterAddAction == AA_TO_DETAIL_LIST || $afterAddAction == AA_TO_DETAIL_ADD )155 $this->jsSettings["tableSettings"][ $this->tName ]["afterAddActionDetTable"] = GetTableURL( $this->pSet->getAADetailTable() );156 157 if( $this->listPage && $afterAddAction == AA_TO_LIST ) {158 $this->pageData["listPage"] = $this->listPage;159 }160 }161 162 /**163 * Get the correct after add action164 * basing on the table settings165 * @return Number166 */167 protected function getAfterAddAction()168 {169 if( isset( $this->afterAddAction ) && !is_null( $this->afterAddAction ) )170 return $this->afterAddAction;171 172 $action = $this->pSet->getAfterAddAction();173 174 if( $this->mode == ADD_POPUP && $this->pSet->checkClosePopupAfterAdd()175 || $action == AA_TO_VIEW && !$this->viewAvailable()176 || $action == AA_TO_EDIT && !$this->editAvailable() )177 {178 $action = AA_TO_LIST;179 }180 181 if( $action == AA_TO_DETAIL_LIST || $action == AA_TO_DETAIL_ADD )182 {183 $dTName = $this->pSet->getAADetailTable();184 $dPset = new ProjectSettings( $dTName );185 $dPermissions = $this->getPermissions( $dTName );186 187 $listPageAllowed = $dPset->hasListPage() && $dPermissions["search"];188 189 if( !$dTName || $action == AA_TO_DETAIL_LIST && !$listPageAllowed190 || $action == AA_TO_DETAIL_ADD && ( !$dPset->hasAddPage() || !$dPermissions["add"] && !$listPageAllowed ) )191 {192 $action = AA_TO_LIST;193 }194 }195 196 $this->afterAddAction = $action;197 return $this->afterAddAction;198 }199 200 /**201 * Assign session prefix202 */203 protected function assignSessionPrefix()204 {205 if( $this->mode == ADD_DASHBOARD || $this->mode == ADD_MASTER_DASH 206 || ($this->mode == ADD_POPUP || $this->mode == ADD_INLINE || $this->fromDashboard != "" ) && $this->dashTName )207 {208 $this->sessionPrefix = $this->dashTName."_".$this->tName;209 return;210 }211 212 parent::assignSessionPrefix();213 214 if( $this->mode == ADD_ONTHEFLY )215 $this->sessionPrefix.= "_add";216 }217 218 /**219 * Set template file220 */221 public function setTemplateFile()222 {223 if( $this->mode == ADD_INLINE )224 $this->templatefile = GetTemplateName($this->shortTableName, "inline_add");225 226 parent::setTemplateFile();227 }228 229 /**230 * Get the page's fields list231 * @return Array232 */233 protected function getPageFields()234 {235 if( $this->mode == ADD_INLINE )236 {237 if( $this->masterTable && !$this->inlineAddAvailable() && $this->masterPageType == PAGE_ADD ) // #12518238 {239 return $this->pSet->getInlineAddFields();240 }241 242 return $this->pSet->getInlineAddFields();243 }244 245 return $this->pSet->getAddFields();246 }247 248 /**249 * Process a broken request250 */251 public static function handleBrokenRequest()252 {253 if( sizeof($_POST) != 0 || !postvalue('submit') )254 return;255 256 if( postvalue("inline") )257 {258 $returnJSON = array();259 $returnJSON['success'] = false;260 $returnJSON['message'] = "Error occurred";261 $returnJSON['fatalError'] = true;262 echo printJSON($returnJSON);263 exit();264 }265 266 if( postvalue("fly") )267 {268 echo -1;269 exit();270 }271 272 $_SESSION["message_add"] = "<< "."Error occurred"." >>";273 }274 275 /**276 * Redirect after details saved277 */278 public function redirectAfterAdd()279 {280 if( $_SESSION['after_add_data'] ) {281 $aaData =& $_SESSION['after_add_data'];282 } else {283 $aaData = array();284 }285 if( isset($aaData[ $this->afterAdd_id ]) && $aaData[ $this->afterAdd_id ] )286 {287 $data = $aaData[ $this->afterAdd_id ];288 $this->keys = $data['keys'];289 $this->newRecordData = $data['avalues'];290 }291 if( $this->eventsObject->exists("AfterAdd") && isset($aaData[ $this->afterAdd_id ]) && $aaData[ $this->afterAdd_id ] )292 {293 $this->eventsObject->AfterAdd( $data['avalues'], $data['keys'], $data['inlineadd'], $this );294 295 }296 unset( $aaData[ $this->afterAdd_id ] );297 298 foreach( $aaData as $k => $v)299 {300 if( !is_array($v) or !array_key_exists('time', $v) )301 {302 unset( $aaData[ $k ] );303 continue;304 }305 306 if( $v['time'] < time() - 3600 )307 unset($aaData[ $k ]);308 }309 $this->afterAddActionRedirect();310 }311 312 /**313 * Process the page314 */315 public function process()316 {317 if( strlen($this->afterAdd_id) )318 {319 $this->redirectAfterAdd();320 return;321 }322 323 // Before Process event324 if( $this->eventsObject->exists("BeforeProcessAdd") )325 $this->eventsObject->BeforeProcessAdd( $this );326 327 if( $this->action == "added" )328 {329 // insert new record if we have to330 $this->processDataInput();331 332 $this->readAddValues = !$this->insertedSuccessfully;333 334 if( $this->mode != ADD_SIMPLE && $this->mode != ADD_DASHBOARD && $this->mode != ADD_MASTER_DASH )335 {336 $this->reportSaveStatus();337 return;338 }339 340 if( $this->insertedSuccessfully )341 {342 // VBScript fix! don't &&-join these two conditions343 if( $this->afterAddActionRedirect() )344 return;345 }346 }347 348 if( $this->captchaExists() )349 $this->displayCaptcha();350 351 $this->prgReadMessage();352 353 $this->prepareDefvalues();354 355 if( $this->eventsObject->exists("ProcessValuesAdd") )356 $this->eventsObject->ProcessValuesAdd( $this->defvalues, $this );357 358 $this->prepareReadonlyFields();359 $this->prepareEditControls();360 361 $this->prepareButtons();362 $this->prepareSteps();363 $this->prepareDetailsTables();364 365 // add button events if exist366 if( $this->mode == ADD_SIMPLE || $this->mode == ADD_ONTHEFLY )367 $this->addButtonHandlers();368 369 $this->addCommonJs();370 371 $this->doCommonAssignments();372 $this->prepareBreadcrumbs();373 $this->prepareCollapseButton();374 375 $this->displayAddPage();376 }377 378 /**379 * Insert a new record to db380 */381 protected function processDataInput()382 {383 if( $this->action != "added" )384 return;385 386 // CSRF protection387 if( !isPostRequest() )388 return;389 390 $this->buildNewRecordData();391 392 if( !$this->checkCaptcha() )393 return;394 395 if( !$this->recheckUserPermissions() )396 return;397 398 if( !$this->callBeforeAddEvent() )399 return;400 401 //add or set updated lat-lng values for all map fileds with 'UpdateLatLng' ticked402 $this->setUpdatedLatLng( $this->newRecordData );403 404 if( !$this->checkDeniedDuplicatedValues() )405 return;406 407 if( $this->callCustomAddEvent() )408 {409 $insertResult = $this->dataSource->insertSingle( $this->getInsertDataCommand() );410 $this->insertedSuccessfully = $insertResult !== false;411 412 if( !$this->insertedSuccessfully )413 $this->setDatabaseError( $this->dataSource->lastError() );414 else415 {416 $this->newRecordData = $insertResult;417 // set up keys418 foreach( $this->pSet->getTableKeys() as $kf ) {419 if( isset( $this->newRecordData[ $kf ] ) )420 $this->keys[ $kf ] = $this->newRecordData[ $kf ];421 }422 423 if ( count( $this->pSet->getTableKeys() ) != count( $this->keys ) )424 $this->keys = array();425 }426 }427 428 if( !$this->insertedSuccessfully )429 return;430 431 if( $this->getAfterAddAction() == AA_TO_ADD )432 $_SESSION[ $this->sessionPrefix . "_recordAdded" ] = true;433 434 $this->ProcessFiles();435 436 if( $this->auditObj )437 $this->auditObj->LogAdd( $this->tName, $this->newRecordData, $this->keys );438 439 $this->callAfterSuccessfulSave();440 $this->callAfterAddEvent();441 442 $this->messageType = MESSAGE_INFO;443 $this->setSuccessfulUpdateMessage();444 }445 446 /**447 * Fill newRecordData properties448 */449 protected function buildNewRecordData()450 {451 $avalues = array();452 $blobfields = array();453 $afilename_values = array();454 455 foreach($this->addFields as $f)456 {457 $control = $this->getControl( $f, $this->id );458 $control->readWebValue($avalues, $blobfields, NULL, NULL, $afilename_values);459 }460 461 if( Security::advancedSecurityAvailable() ) {462 $securityType = $this->pSet->getAdvancedSecurityType();463 if( !$this->isAdminTable() && ($securityType == ADVSECURITY_EDIT_OWN || $securityType == ADVSECURITY_VIEW_OWN) )464 {465 $tableOwnerIdField = $this->pSet->getTableOwnerIdField();466 // insert owner id value if it exists an It hasn't already set by user467 if( $this->checkIfToAddOwnerIdValue( $tableOwnerIdField, $avalues[ $tableOwnerIdField ] ) )468 $avalues[ $tableOwnerIdField ] = prepare_for_db( $tableOwnerIdField, $_SESSION["_".$this->tName."_OwnerID"] );469 }470 }471 $masterTables = $this->pSet->getMasterTablesArr( );472 // insert master key value if exists and if not specified473 foreach( $masterTables as $mTableData )474 {475 if( $this->masterTable == $mTableData["mDataSourceTable"] )476 {477 foreach( $mTableData["detailKeys"] as $idx => $dk )478 {479 $masterkeyIdx = "masterkey".($idx + 1);480 if( strlen( postvalue($masterkeyIdx) ) )481 $_SESSION[ $this->sessionPrefix."_".$masterkeyIdx ] = postvalue($masterkeyIdx);482 483 if( !isset( $avalues[ $dk ] ) || $avalues[ $dk ] == "" )484 $avalues[ $dk ] = prepare_for_db( $dk, $_SESSION[ $this->sessionPrefix."_".$masterkeyIdx ] );485 }486 }487 }488 489 $this->addLookupFilterFieldValue( $avalues, $avalues );490 491 foreach($afilename_values as $fileFName => $value)492 {493 $avalues[ $fileFName ] = $value;494 }495 496 // calculate order for the reorderRows feature497 $listPSet = $this->getListPSet();498 if( $listPSet->reorderRows() ) {499 $order = postvalue("order"); 500 if( $order ) {501 $order = $this->getUniqueOrder( $listPSet, $order );502 } else {503 $order = $this->getMaxOrderValue( $listPSet ) + 1;504 }505 $avalues[ $listPSet->reorderRowsField() ] = $order;506 }507 508 $this->newRecordData = $avalues;509 }510 511 /**512 * Add to the values array the data about lookup filter field513 * if it hasn't been set yet514 * @param Array recordData515 * @param &Array values516 */517 protected function addLookupFilterFieldValue( $recordData, &$values )518 {519 $lookupPSet = getLookupMainTableSettings($this->tName, $this->lookupTable, $this->lookupField);520 if( !$lookupPSet )521 return;522 523 if( $lookupPSet->useCategory( $this->lookupField ) )524 {525 foreach( $lookupPSet->getParentFieldsData( $this->lookupField ) as $cData )526 {527 if( isset( $this->parentCtrlsData[ $cData['main'] ]) && !isset( $recordData[ $cData['lookup'] ] ) )528 $values[ $cData['lookup'] ]= $this->parentCtrlsData[ $cData['main'] ];529 }530 }531 }532 533 /**534 * Check is captcha exists on current page535 *536 * @intellisense537 */538 function captchaExists()539 {540 if ( $this->mode == ADD_ONTHEFLY || $this->mode == ADD_INLINE )541 {542 return false;543 }544 545 return $this->pSet->hasCaptcha();546 }547 548 /**549 * Get captcha field name550 *551 * @intellisense552 */553 function getCaptchaFieldName()554 {555 return $this->captchaName;556 }557 558 /**559 * @return Boolean560 */561 protected function recheckUserPermissions()562 {563 if( CheckTablePermissions($this->tName, "A") )564 return true;565 566 return parent::recheckUserPermissions();567 }568 569 /**570 * Execute before Add event571 * @return Boolean572 */573 protected function callBeforeAddEvent()574 {575 if( !$this->eventsObject->exists("BeforeAdd") )576 return true;577 578 $this->sqlValues = array();579 $usermessage = "";580 $ret = $this->eventsObject->BeforeAdd( $this->newRecordData, $this->sqlValues, $usermessage, $this->mode == ADD_INLINE, $this );581 if( $usermessage != "" )582 $this->setMessage( $usermessage );583 584 return $ret;585 }586 587 /**588 * Check if some values are duplicated for the fields not allowing duplicates589 * @return Boolean590 */591 public function checkDeniedDuplicatedValues()592 {593 $usermessage = "";594 $ret = $this->hasDeniedDuplicateValues( $this->newRecordData, $usermessage );595 if( $ret )596 $this->setMessage( $usermessage );597 598 return !$ret;599 }600 601 /**602 * #7374603 * @return Boolean604 */605 protected function callCustomAddEvent()606 {607 if( !$this->eventsObject->exists("CustomAdd") )608 return true;609 610 $keys = array();611 $customAddError = "";612 $ret = $this->eventsObject->CustomAdd( $this->newRecordData, $keys, $customAddError, $this->mode == ADD_INLINE, $this );613 614 if( strlen( $customAddError ) > 0 )615 {616 $this->insertedSuccessfully = false;617 $this->setMessage( $customAddError );618 $this->keys = array();619 return false;620 }621 622 // do standard Add processing623 if( $ret )624 return true;625 626 $this->insertedSuccessfully = true;627 628 // update keys and inserted data629 $keyFields = $this->pSet->getTableKeys();630 631 if( !is_array( $keys ) && count( $keyFields ) == 1 )632 $keys = array( $keyFields[0] => $keys );633 634 foreach( $keyFields as $kf ) {635 if( strlen( $keys[ $kf ] ) )636 $this->keys[ $kf ] = $kf;637 else if( array_key_exists( $kf, $this->newRecordData ) )638 $this->keys[ $kf ] = $this->newRecordData[ $kf ];639 else640 $this->keys[ $kf ] = $this->dataSource->lastAutoincValue( $kf );641 642 $this->newRecordData[ $kf ] = $this->keys[ $kf ];643 }644 645 return false;646 }647 648 /**649 * Give possibility to all edit controls to clean their data650 */651 protected function callAfterSuccessfulSave()652 {653 foreach($this->addFields as $f)654 {655 $this->getControl( $f, $this->id )->afterSuccessfulSave();656 }657 }658 659 /**660 * Execute After Add event or prepare all necessary data for its execution after redirect661 */662 protected function callAfterAddEvent()663 {664 if( !$this->eventsObject->exists("AfterAdd") )665 return;666 667 if( $this->mode != ADD_MASTER )668 {669 $this->eventsObject->AfterAdd( $this->newRecordData, $this->keys, $this->mode == ADD_INLINE, $this );670 return;671 }672 673 $this->afterAdd_id = generatePassword(20);674 675 if( !$_SESSION['after_add_data'] ) {676 $_SESSION['after_add_data'] = array();677 }678 $_SESSION['after_add_data'][ $this->afterAdd_id ] = array(679 'avalues' => $this->newRecordData,680 'keys'=> $this->keys,681 'inlineadd' => $this->mode == ADD_INLINE,682 'time' => time()683 );684 }685 686 /**687 * Set a successful update message.688 * Add the corresponding edit/view links to the info message689 */690 protected function setSuccessfulUpdateMessage()691 {692 if( $this->isMessageSet() )693 return;694 695 if( $this->mode == ADD_INLINE )696 $infoMessage = ""."Record was added"."";697 else698 $infoMessage = "<strong><<< "."Record was added"." >>></strong>";699 700 if( $this->mode != ADD_SIMPLE && $this->mode != ADD_MASTER || !$this->keys )701 {702 $this->setMessage( $infoMessage );703 return;704 }705 706 $k = 0;707 $keyParams = array();708 $keysArray = array();709 foreach( $this->keys as $idx => $val )710 {711 $keyParams[] = "editid".( ++$k )."=".runner_htmlspecialchars(rawurlencode(@$val));712 $keysArray[] = $val;713 }714 $keylink = implode("&", $keyParams);715 716 if ( count($keysArray) > 0 && $this->mode == ADD_SIMPLE )717 {718 $_SESSION["successKeys"] = $keysArray;719 }720 else721 {722 $infoMessage.= "<br>";723 724 if( $this->editAvailable() )725 $infoMessage.= " <a href='".GetTableLink( $this->pSet->getShortTableName(), "edit", $keylink )."'>"."Edit"."</a> ";726 727 if( $this->viewAvailable() )728 $infoMessage.= " <a href='".GetTableLink( $this->pSet->getShortTableName(), "view", $keylink )."'>"."View"."</a> ";729 }730 731 $this->setMessage( $infoMessage );732 }733 734 /**735 * Print JSON containing a saved record data on ajax-like request736 */737 protected function reportSaveStatus()738 {739 echo printJSON( $this->getSaveStatusJSON() );740 exit();741 }742 743 /**744 * Get an array containing the record save status745 * @return Array746 */747 protected function getSaveStatusJSON()748 {749 global $globalEvents;750 $returnJSON = array();751 752 if( $this->action != "added" || $this->mode == ADD_SIMPLE )753 return $returnJSON;754 755 $returnJSON['success'] = $this->insertedSuccessfully;756 $returnJSON['message'] = $this->message;757 758 if( !$this->isCaptchaOk )759 {760 $returnJSON['wrongCaptchaFieldName'] = $this->getCaptchaFieldName();761 }762 elseif( $this->mode == ADD_POPUP || $this->mode == ADD_MASTER || $this->mode == ADD_MASTER_POPUP || $this->mode == ADD_MASTER_DASH )763 {764 $sessPrefix = $this->tName . "_" . $this->pageType;765 if( isset($_SESSION["count_passes_captcha"]) || $_SESSION["count_passes_captcha"] > 0 || $_SESSION["count_passes_captcha"] < 5 )766 $returnJSON['hideCaptcha'] = true;767 }768 769 770 if( !$this->insertedSuccessfully )771 return $returnJSON;772 773 $jsKeys = array();774 $keyFields = $this->pSet->getTableKeys();775 if ( $this->keys ) {776 foreach( $keyFields as $idx => $f) {777 $jsKeys[ $idx ] = $this->keys[ $f ];778 }779 }780 781 if( $this->mode == ADD_ONTHEFLY )782 {783 $lokupData = $this->getLookupData();784 $returnJSON['linkValue'] = $lokupData['linkValue'];785 $returnJSON['displayValue'] = $lokupData['displayValue'];786 $returnJSON['vals'] = $lokupData['vals'];787 788 $returnJSON['keys'] = $jsKeys;789 $returnJSON['keyFields'] = $keyFields;790 791 return $returnJSON;792 }793 794 // get current values and show edit controls795 $data = array();796 $haveData = true;797 798 if( $this->keys )799 $data = $this->getRecordData( $this->keys );800 801 if( !$data )802 {803 $data = $this->newRecordData;804 $haveData = false;805 }806 807 $keyParams = array();808 foreach( $this->pSet->getTableKeys() as $i => $kf ) {809 $keyParams[] = "key".($i + 1). "=". runner_htmlspecialchars( rawurlencode( @$data[ $kf ] ));810 }811 $keylink = "&" . implode("&", $keyParams);812 813 $showValues = array();814 $showFields = array();815 $showRawValues = array();816 817 $listPSet = $this->getListPSet();818 819 $listViewControls = new ViewControlsContainer( 820 $listPSet,821 $this->pageType, 822 $this 823 );824 825 foreach( $this->pSet->getFieldsList() as $f )826 {827 $control = $listViewControls->getControl( $f );828 $showValues[ $f ] = $control->showDBValue( $data, $keylink, true );829 $showFields[] = $f;830 831 if( IsBinaryType( $this->pSet->getFieldType( $f ) ) )832 $showRawValues[ $f ] = "";833 else834 $showRawValues[ $f ] = runner_substr($data[ $f ], 0, 100);835 }836 837 // reorderRows stuff838 if( $listPSet->reorderRows() ) {839 $returnJSON['order'] = $data[ $listPSet->reorderRowsField() ];840 }841 842 $returnJSON['keys'] = $jsKeys;843 $returnJSON['vals'] = $showValues;844 $returnJSON['fields'] = $showFields;845 846 $returnJSON['detKeys'] = $this->getShowDetailKeys( $data );847 848 $dmapIconsData = $this->getDashMapsIconsData( $data );849 if( !!$dmapIconsData )850 $returnJSON['mapIconsData'] = $dmapIconsData;851 852 $fieldsIconsData = $this->getFieldMapIconsData( $data );853 if( !!$fieldsIconsData )854 $returnJSON['fieldsMapIconsData'] = $fieldsIconsData;855 856 //$isEditable = Security::userCan('E', $this->tName) || Security::userCan('D', $this->tName);857 $isEditable = true;858 if( $globalEvents->exists("IsRecordEditable", $this->tName) ) {859 $isEditable = $globalEvents->IsRecordEditable( $data, $isEditable, $this->tName );860 }861 862 if( $this->forSpreadsheetGrid ) {863 if( $haveData && $isEditable ) {864 // new added grid row id 865 $newRowId = $this->newRowId ? $this->newRowId : $this->id;866 $editPage = $this->getRelatedInlineEditPage( $this->hostPageName, $this->keys, $newRowId );867 868 $returnJSON["editFields"] = $listPSet->getInlineEditFields();869 870 // use "htmlControls" key no to interfire with dash html data871 $returnJSON["htmlControls"] = array();872 foreach( $listPSet->getInlineEditFields() as $fName ) {873 $controls = $editPage->getContolMapData( $fName, $newRowId, $data, $editPage->editFields );874 // set edit page controlsMap875 $editPage->fillControlsMap( $controls );876 877 if( $editPage->getEditFormat( $fName ) == EDIT_FORMAT_READONLY )878 $editPage->readOnlyFields[ $fName ] = $this->showDBValue( $fName, $data );879 880 $returnJSON["htmlControls"][ $fName ] = $editPage->getSpreadsheetControlMarkup( $fName, $newRowId, $data );881 }882 883 $returnJSON["pageId"] = $newRowId;884 885 $editPage->fillSetCntrlMaps();886 // contols map for spreadsheet inline edit controls887 $returnJSON["spreadControlsMap"] = $editPage->controlsHTMLMap;888 } else {889 $returnJSON['nonEditable'] = true; 890 }891 }892 893 894 if( $this->mode == ADD_INLINE || $this->mode == ADD_POPUP || $this->mode == ADD_DASHBOARD ) { 895 $returnJSON['noKeys'] = !$haveData;896 $returnJSON['keyFields'] = $keyFields;897 $returnJSON['rawVals'] = $showRawValues;898 $returnJSON['hrefs'] = $this->buildDetailGridLinks( $returnJSON['detKeys'] );899 // add link and display value if list page is lookup with search900 if( $this->forListPageLookup )901 {902 $linkAndDispVals = $this->getLookupData();903 $returnJSON['linkValue'] = $linkAndDispVals['linkValue'];904 $returnJSON['displayValue'] = $linkAndDispVals['displayValue'];905 }906 if( $globalEvents->exists("IsRecordEditable", $this->tName) ) {907 if( !$isEditable )908 $returnJSON['nonEditable'] = true;909 }910 911 return $returnJSON;912 }913 914 if( $this->mode == ADD_MASTER || $this->mode == ADD_MASTER_POPUP || $this->mode == ADD_MASTER_DASH )915 {916 $_SESSION["message_add"] = $this->message ? $this->message : "";917 $returnJSON['afterAddId'] = $this->afterAdd_id;918 $tData = array();919 $returnJSON['mKeys'] = $this->getDetailTablesMasterKeys( $tData );920 921 if( $this->mode == ADD_MASTER_POPUP || $this->mode == ADD_MASTER_DASH )922 {923 $returnJSON['noKeys'] = !$haveData;924 $returnJSON['keyFields'] = $keyFields;925 $returnJSON['rawVals'] = $showRawValues;926 $returnJSON['hrefs'] = $this->buildDetailGridLinks( $returnJSON['detKeys'] );927 928 if( $globalEvents->exists("IsRecordEditable", $this->tName) ) {929 if( !$isEditable )930 $returnJSON['nonEditable'] = true;931 }932 }933 934 return $returnJSON;935 }936 }937 938 /**939 * @param &Array data940 * @return Array941 */942 protected function getShowDetailKeys( &$data )943 {944 $showDetailKeys = array();945 foreach( $this->pSet->getDetailTablesArr() as $dt )946 {947 foreach( $dt["masterKeys"] as $idx => $dk)948 {949 $showDetailKeys[ $dt['dDataSourceTable'] ][ "masterkey".($idx + 1) ] = $data[ $dk ];950 }951 }952 953 if( $this->getAfterAddAction() == AA_TO_DETAIL_ADD )954 {955 $AAdTName = $this->pSet->getAADetailTable();956 $dTUrl = GetTableUrl( $AAdTName );957 958 if( !isset( $showDetailKeys[ $dTUrl ] ) )959 $showDetailKeys[ $dTUrl ] = $showDetailKeys[ $AAdTName ];960 }961 962 return $showDetailKeys;963 }964 965 /**966 * @return Array967 */968 protected function getDetailTablesMasterKeys( $data )969 {970 if( !$this->isShowDetailTables || $this->mobileTemplateMode() )971 return array();972 973 $data = $this->newRecordData;974 if( $this->keys )975 $data = $this->getRecordData( $this->keys ) ;976 977 $dpParams = $this->getDetailsParams( $this->id );978 $mKeysData = array();979 for( $i = 0; $i < count( $dpParams['ids'] ); $i++ ) {980 $mKeysData[ $dpParams['strTableNames'][$i] ] = $this->getMasterKeysData( $dpParams['strTableNames'][$i], $data);981 }982 983 return $mKeysData;984 }985 986 /**987 * @param String dTableName988 * @param &Array data989 */990 protected function getMasterKeysData( $dTableName, &$data )991 {992 $mKeyId = 1;993 $mKeysData = array();994 995 $mKeys = $this->pSet->getMasterKeysByDetailTable( $dTableName );996 foreach($mKeys as $mk)997 {998 if( strlen( $data[ $mk ] ) )999 $mKeysData[ 'masterkey'.$mKeyId++ ] = $data[ $mk ];1000 else1001 $mKeysData[ 'masterkey'.$mKeyId++ ] = '';1002 }1003 1004 return $mKeysData;1005 }1006 1007 /**1008 * It redirects to a new page1009 * according to the add page settings1010 * @return Boolean1011 */1012 protected function afterAddActionRedirect()1013 {1014 if( $this->mode != ADD_SIMPLE )1015 return false;1016 1017 switch( $this->getAfterAddAction() )1018 {1019 case AA_TO_ADD:1020 if ( $this->insertedSuccessfully )1021 return $this->prgRedirect();1022 1023 $getParams = array();1024 if( $this->pageName )1025 $getParams[] = "page=".$this->pageName;1026 $getParams[] = $this->getStateUrlParams();1027 HeaderRedirect($this->shortTableName, PAGE_ADD, implode( '&', $getParams ));1028 return true;1029 1030 case AA_TO_LIST:1031 if( $this->pSet->hasListPage() ) {1032 HeaderRedirect( $this->shortTableName, PAGE_LIST, "a=return&"1033 .( $this->listPage ? "page=".$this->listPage."&" : "" ).$this->getStateUrlParams() );1034 } else {1035 HeaderRedirect("menu");1036 }1037 return true;1038 1039 case AA_TO_VIEW:1040 HeaderRedirect( $this->shortTableName, PAGE_VIEW, implode( '&', array( $this->getKeyParams(), $this->getStateUrlParams() ) ) );1041 return true;1042 1043 case AA_TO_EDIT:1044 HeaderRedirect( $this->shortTableName, PAGE_EDIT, implode( '&', array( $this->getKeyParams(), $this->getStateUrlParams() ) ) );1045 return true;1046 1047 case AA_TO_DETAIL_LIST:1048 $dTName = $this->pSet->getAADetailTable();1049 HeaderRedirect( GetTableURL( $dTName ), PAGE_LIST, implode("&", $this->getNewRecordMasterKeys( $dTName ) ). "&mastertable=" .$this->tName );1050 return true;1051 1052 case AA_TO_DETAIL_ADD:1053 $_SESSION["message_add"] = $this->message ? $this->message : "";1054 1055 $dTName = $this->pSet->getAADetailTable();1056 HeaderRedirect( GetTableURL( $dTName ), PAGE_ADD, implode("&", $this->getNewRecordMasterKeys( $dTName ) ). "&mastertable=" .$this->tName );1057 return true;1058 1059 default:1060 return false;1061 }1062 }1063 1064 function getNewRecordMasterKeys( $dTName )1065 {1066 $data = $this->getNewRecordData();1067 1068 $mKeys = array();1069 foreach($this->pSet->getMasterKeysByDetailTable( $dTName ) as $i => $mk)1070 {1071 $mKeys[] = "masterkey". ($i + 1) . "=" .$data[ $mk ];1072 }1073 return $mKeys;1074 }1075 1076 1077 /**1078 * POST-REDIRECT-GET1079 * Redirect after saving the data to avoid saving again on refresh.1080 */1081 protected function prgRedirect()1082 {1083 if( $this->stopPRG )1084 return false;1085 if( !$this->insertedSuccessfully || $this->mode != ADD_SIMPLE || !no_output_done() )1086 return false;1087 // saving message1088 $_SESSION["message_add"] = $this->message ? $this->message : "";1089 $_SESSION["message_add_type"] = $this->messageType;1090 // redirect1091 1092 1093 $getParams = array();1094 if( $this->pageName )1095 $getParams[] = "page=".$this->pageName;1096 1097 $getParams[] = $this->getStateUrlParams();1098 1099 HeaderRedirect( $this->pSet->getShortTableName(), $this->pageType, implode( '&', $getParams ) );1100 // turned on output buffering, so we need to stop script1101 return true;1102 }1103 1104 /**1105 * POST-REDIRECT-GET1106 * Read the saved message on the GET step.1107 */1108 protected function prgReadMessage()1109 {1110 // for PRG rule, to avoid POSTDATA resend. Saving mess in session1111 if( $this->mode == ADD_SIMPLE && isset( $_SESSION["message_add"] ) )1112 {1113 $this->message = $_SESSION["message_add"];1114 $this->messageType = $_SESSION["message_add_type"];1115 unset( $_SESSION["message_add"] );1116 }1117 }1118 1119 /**1120 * @return Array1121 */1122 public function getCurrentRecord()1123 {1124 $data = array();1125 if ( $this->masterTable && !!$this->masterKeysReq )1126 {1127 foreach ($this->detailKeysByM as $key => $detKey )1128 {1129 $data[$detKey] = $this->masterKeysReq[$key+1];1130 }1131 }1132 1133 return $data;1134 }1135 1136 protected function replaceFileFieldsValuesWithCopies( &$defvalues ) {1137 foreach( $this->addFields as $f ) {1138 if( $this->pSet->getEditFormat( $f ) == EDIT_FORMAT_FILE ) //#100231139 $defvalues[ $f ] = $this->getControl( $f, $this->id )->getFieldValueCopy( $defvalues[ $f ] );1140 }1141 }1142 1143 protected function getCopyKeys() {1144 $copyKeys = array();1145 1146 if( !array_key_exists( "copyid1", $_REQUEST ) && !array_key_exists( "editid1", $_REQUEST ) )1147 return $copyKeys;1148 1149 $prefix = array_key_exists( "copyid1", $_REQUEST ) ? "copyid" : "editid";1150 foreach( $this->pSet->getTableKeys() as $idx => $k ) {1151 $copyKeys[ $k ] = postvalue( $prefix . ($idx + 1) );1152 }1153 1154 return $copyKeys;1155 }1156 1157 /**1158 * Set the defvalues property1159 */1160 protected function prepareDefvalues()1161 {1162 $copyKeys = $this->getCopyKeys();1163 1164 if( $copyKeys && $this->mode != ADD_DASHBOARD )1165 {1166 // copy record1167 $dc = $this->getDsCommand( $copyKeys );1168 $prep = $this->dataSource->prepareSQL( $dc );1169 $keyWhere = $prep["where"];1170 1171 $fetchedArray = $this->dataSource->getSingle( $dc )->fetchAssoc();1172 $this->defvalues = $this->cipherer->DecryptFetchedArray( $fetchedArray );1173 1174 $this->replaceFileFieldsValuesWithCopies( $this->defvalues );1175 1176 if( $this->eventsObject->exists("CopyOnLoad") ) {1177 // call CopyOnLoad event1178 $this->eventsObject->CopyOnLoad( $this->defvalues, $keyWhere, $this );1179 1180 if( $keyWhere != $prep["where"] ) {1181 $this->dataSource->overrideWhere( $dc, $keyWhere );1182 $fetchedArray = $this->dataSource->getSingle( $dc )->fetchAssoc();1183 $this->defvalues = $this->cipherer->DecryptFetchedArray( $fetchedArray );1184 1185 $this->replaceFileFieldsValuesWithCopies( $this->defvalues );1186 }1187 }1188 }1189 else1190 {1191 foreach( $this->addFields as $f )1192 {1193 $defaultValue = GetDefaultValue($f, PAGE_ADD, $this->tName );1194 if( strlen($defaultValue) )1195 $this->defvalues[ $f ] = $defaultValue;1196 }1197 }1198 1199 if( Security::advancedSecurityAvailable() ) {1200 $securityType = $this->pSet->getAdvancedSecurityType();