kenken999/php
0
1<?php2require_once(getabspath('classes/orderclause.php'));3require_once(getabspath("classes/sql.php"));4require_once(getabspath("classes/projectsettings.php"));5 6class ListPage extends RunnerPage7{8 9 public $querySQL = "";10 11 /**12 * Page size13 * @var integer14 * @intellisense15 */16 public $gPageSize = 0;17 18 /**19 * OrderClause object. For order clause building20 * @type OrderClause21 */22 protected $orderClause = null;23 24 /**25 * Do export or not26 * @type bool27 */28 public $exportTo = false;29 30 /**31 * Delete records enabled32 * @type bool33 */34 public $deleteRecs = false;35 36 /**37 * Array of fields that is shown on list38 * @type array()39 * array['listFields']= array('fName'=>"@f.strName s", 'viewFormat'=>'@f.strViewFormat');40 */41 public $listFields = array();42 43 44 /**45 * Record set, that retrieved from DB46 * @type link47 */48 protected $recSet = null;49 50 /**51 * If use group scurity or not52 * @type integer53 */54 public $nSecOptions = 0;55 56 57 /**58 * Number of record59 * @type integer60 */61 protected $recNo = 1;62 63 /**64 * Id of row65 * @type integer66 */67 protected $rowId = 0; //fix it68 69 /**70 * Array of selected records for delete71 * @type array72 */73 protected $selectedRecs = array();74 75 /**76 * Number of record for delete77 * @type integer78 */79 protected $recordsDeleted = 0;80 81 /**82 * Original table name83 * @var string84 */85 public $origTName = ""; //fix it86 87 88 89 /**90 * Fields that used for search on panel, and should be open on every page load91 * @type array92 */93 public $panelSearchFields = array();94 95 /**96 * Array of key's fields97 * @type array98 */99 public $arrKeyFields = array();100 101 public $audit = null;102 103 /**104 * Are there records on first page or not105 * @type bool106 */107 public $noRecordsFirstPage = false;108 109 /**110 * String ?? main table owner's Id111 * @type string112 */113 public $mainTableOwnerID = "";114 115 /**116 * Use print friendly or not117 * @type bool118 */119 public $printFriendly = false;120 121 /**122 * Create login page or not123 * @type bool124 */125 public $createLoginPage = false;126 127 /**128 * Searchpanel class builder129 * @type object130 */131 protected $searchPanel = null;132 133 /**134 * Fields for which span val should be added135 * @type array136 */137 protected $arrFieldSpanVal = array();138 139 /**140 * records weren't deleted due locking141 * @type Array142 */143 protected $lockDelRec = array();144 145 public $firstTime = 0;146 147 protected $gMapFields = array();148 149 /**150 * Types of all fields in a list row151 */152 protected $recordFieldTypes = array(); //fix it153 154 /**155 * class names for the fields that were chosen to hide mobile devices156 * @type array157 */158 protected $hiddenColumnClasses = array();159 160 /**161 * Is show add page like popUp or not162 * @type boolean163 * @intellisense164 */165 protected $showAddInPopup = false;166 167 /**168 * Is show edit page like popUp or not169 * @type boolean170 * @intellisense171 */172 protected $showEditInPopup = false;173 174 /**175 * Is show view page like popUp or not176 * @type boolean177 * @intellisense178 */179 protected $showViewInPopup = false;180 181 /**182 * fieldClass function cache183 * @type Array184 */185 protected $fieldClasses = array();186 187 public $sortBy;188 189 protected $addedDetailsCountSubqueries = array();190 191 protected $recordsRenderData = array();192 193 protected $fieldsWithRawValues = array();194 195 protected $editPage = null;196 197 /**198 * goto field value from the request199 */200 public $requestGoto = null;201 202 203 /**204 * Constructor, set initial params205 * @param array $params206 */207 function __construct(&$params)208 {209 // call parent constructor210 parent::__construct($params);211 212 $this->listFields = array();213 $allfields = $this->pSet->getPageFields();214 215 foreach($allfields as $f)216 {217 if(!$this->pSet->appearOnPage($f))218 continue;219 $fieldTag = $this->pdfJsonMode() ? GoodFieldName($f)."_pdfvalue" : GoodFieldName($f)."_value";220 $this->listFields[]= array(221 "fName"=>$f,222 "goodFieldName"=>GoodFieldName($f),223 "valueFieldName" => $fieldTag,224 "viewFormat"=>$this->pSet->getViewFormat($f),225 "editFormat"=>$this->pSet->getEditFormat($f)226 );227 }228 229 230 $this->showAddInPopup = $this->pSet->isShowAddInPopup();231 $this->showEditInPopup = $this->pSet->isShowEditInPopup();232 $this->showViewInPopup = $this->pSet->isShowViewInPopup();233 234 $this->pSet->setPageType(PAGE_SEARCH);235 236 // Before Process event237 $this->beforeProcessEvent();238 239 240 241 // Set language params, if have more than one language242 $this->setLangParams();243 244 if($this->searchClauseObj) //for asp & .net245 $this->jsSettings['tableSettings'][$this->tName]['simpleSearchActive'] = $this->searchClauseObj->simpleSearchActive;246 247 if( $this->pSet->reorderRows() && Security::userCan('E', $this->tName) ) {248 $this->jsSettings['tableSettings'][ $this->tName ]['reorderRows'] = true;249 }250 $this->jsSettings['tableSettings'][ $this->tName ]['addToBottom'] = $this->pSet->inlineAddBottom();251 252 253 254 255 for($i = 0; $i < count($this->allDetailsTablesArr); $i ++)256 {257 // get perm for det tables258 $this->permis[$this->allDetailsTablesArr[$i]['dDataSourceTable']]= $this->getPermissions($this->allDetailsTablesArr[$i]['dDataSourceTable']);259 260 // field names of detail keys of passed detail table, when current is master261 $this->detailKeysByD[$i] = $this->pSet->getDetailKeysByDetailTable($this->allDetailsTablesArr[$i]['dDataSourceTable']);262 }263 264 $this->genId();265 266 267 // fill span val indicator for totals268 $this->jsSettings['tableSettings'][$this->tName]['totalFields'] = array();269 foreach( $this->totalsFields as $tField ) {270 $totalFieldData = array('type'=> $tField['totalsType'], 'fName'=> $tField['fName'], 'format'=> $tField['viewFormat']);271 $totalFieldData['formatSettings'] = getFormatSettings( $tField['viewFormat'], $this->pSet, $tField['fName'] );272 273 $this->jsSettings['tableSettings'][ $this->tName ]['totalFields'][] = $totalFieldData;274 275 if ( $tField['totalsType'] == 'COUNT' ) {276 $this->outputFieldValue($tField['fName'], 1);277 } else {278 $this->outputFieldValue($tField['fName'], 2);279 }280 }281 282 //if scroll body of grid283 $this->jsSettings['tableSettings'][$this->tName]['scrollGridBody'] = (( $this->listGridLayout == gltHORIZONTAL || $this->listGridLayout == gltFLEXIBLE )&& $this->isScrollGridBody);284 285 $this->jsSettings['tableSettings'][$this->tName]['permissions'] = $this->permis[$this->tName];286 if($this->pSet->getAdvancedSecurityType() == ADVSECURITY_EDIT_OWN) {287 $this->jsSettings['tableSettings'][$this->tName]['isEditOwn'] = $this->permis[$this->tName];288 }289 290 $this->settingsMap["tableSettings"]['inlineEdit'] = array("default"=>false,"jsName"=>"isInlineEdit", "option" => array("list", "inlineEdit") );291 $this->settingsMap["tableSettings"]['inlineAdd'] = array("default"=>false,"jsName"=>"isInlineAdd", "option" => array("list", "inlineAdd"));292 $this->settingsMap["tableSettings"]['copy'] = array("default"=>false,"jsName"=>"copy");293 $this->settingsMap["tableSettings"]['view'] = array("default"=>false,"jsName"=>"view");294 295 $this->jsSettings['tableSettings'][$this->tName]['listFields'] = array();296 for($i=0;$i<count($this->listFields);$i++)297 {298 $this->jsSettings['tableSettings'][$this->tName]['listFields'][] = $this->listFields[$i]['fName'];299 // call addGoogleMapData before call proccessRecordValue!!!300 if ($this->listFields[$i]['viewFormat'] == FORMAT_MAP)301 $this->gMapFields[] = $i;302 }303 304 $this->processClickAction();305 306 $this->createOrderByObject();307 308 // init setting for params in hash URL for ajax list309 if ( $this->listAjax && $this->mode != LIST_DETAILS )310 {311 $this->pageData['urlParams'] = $this->getUrlParams();312 }313 314 // RunnerPage fillTableSettings doesn't work well with listGridLayout key315 $this->jsSettings['tableSettings'][ $this->tName ]['listGridLayout'] = $this->listGridLayout;316 317 if( $this->spreadsheetGridApplicable() ) {318 $this->pageData['spreadsheet'] = true;319 $this->jsSettings['tableSettings'][ $this->tName ]['autoAddNewRecord'] = $this->pSet->addNewRecordAutomatically();320 $this->setupRelatedInlineEditPage();321 }322 }323 324 protected function createOrderByObject() {325 // read order by info from request326 $this->orderClause = OrderClause::createFromPage( $this, true );327 }328 329 function processClickAction()330 {331 if( strtoupper($this->tName) == "ADMIN_MEMBERS" || strtoupper($this->tName) == "ADMIN_ADMEMBERS" )332 return;333 334 $clickActionJSON = $this->pSet->getClickActionJSONString();335 if( $clickActionJSON != "" )336 {337 $clickAction = my_json_decode( $clickActionJSON );338 339 foreach ( $clickAction["fields"] as $field => $fSetting )340 {341 if ( !$this->checkAllowClickAction($fSetting) )342 $clickAction["fields"][$field]["action"] = "noaction";343 }344 345 if ( !$this->checkAllowClickAction($clickAction["row"]) )346 $clickAction["row"]["action"] = "noaction";347 348 $this->jsSettings['tableSettings'][$this->tName]["clickActions"] = $clickAction;349 }350 }351 352 function checkAllowClickAction( $actionSet )353 {354 $isActionAllowed = true;355 if ( $actionSet["action"] == "open" )356 {357 switch ($actionSet["openData"]["page"])358 {359 case 'add':360 $isActionAllowed = $this->addAvailable();361 break;362 case 'edit':363 $isActionAllowed = $this->editAvailable();364 break;365 case 'view':366 $isActionAllowed = $this->viewAvailable();367 break;368 case 'print':369 $isActionAllowed = $this->printAvailable();370 break;371 default:372 $isActionAllowed = true;373 break;374 }375 }376 377 return $isActionAllowed;378 }379 380 /**381 * add Order data for set in URL382 */383 function addOrderUrlParam()384 {385 $urlParams = $this->orderClause->getOrderUrlParams();386 387 if ( strlen($urlParams) > 0 )388 {389 if ( !isset($this->pageData["urlParams"]) )390 $this->pageData["urlParams"] = array();391 392 $this->pageData["urlParams"]["orderby"] = $urlParams;393 }394 }395 396 /**397 * Get list params for using in Url hash (ajax reload)398 */399 function getUrlParams()400 {401 $params = array();402 if ( @$_SESSION[$this->sessionPrefix."_qs"] )403 {404 $params["qs"] = rawurlencode($_SESSION[$this->sessionPrefix."_qs"]);405 }406 if ( @$_SESSION[$this->sessionPrefix."_q"] )407 {408 $params["q"] = rawurlencode($_SESSION[$this->sessionPrefix."_q"]);409 }410 if ( @$_SESSION[$this->sessionPrefix."_criteriaSearch"] && $_SESSION[$this->sessionPrefix."_criteriaSearch"] != "and" )411 {412 $params["criteria"] = $_SESSION[$this->sessionPrefix."_criteriaSearch"];413 }414 if ( @$_SESSION[$this->sessionPrefix."_filters"] )415 {416 $params["f"] = rawurlencode($_SESSION[$this->sessionPrefix."_filters"]);417 }418 if( !postvalue("qs") && !postvalue("q") && !isset( $_REQUEST["f"] ) && @$_SESSION[$this->sessionPrefix."_pagenumber"] && @$_SESSION[$this->sessionPrefix."_pagenumber"] > 1 )419 {420 $params["goto"] = $_SESSION[$this->sessionPrefix."_pagenumber"];421 }422 if( @$_SESSION[$this->sessionPrefix."_pagesize"] && $this->gPageSize != $_SESSION[$this->sessionPrefix."_pagesize"])423 {424 $params["pagesize"] = $_SESSION[$this->sessionPrefix."_pagesize"];425 }426 427 if( $this->masterTable )428 {429 $params["mastertable"] = $this->masterTable;430 431 for($i = 1; $i <= count($this->masterKeysReq); $i++)432 {433 $params["masterkey".$i] = $this->masterKeysReq[$i];434 }435 }436 437 if( @$_SESSION[$this->sessionPrefix."_masterpage"] )438 {439 $params["masterpage"] = $_SESSION[$this->sessionPrefix."_masterpage"];440 }441 442 if( $this->searchClauseObj )443 {444 if( $this->searchClauseObj->savedSearchIsRun )445 $params["savedSearch"] = true;446 }447 448 $tabId = $this->getCurrentTabId();449 if( strlen( $tabId ) )450 $params["tab"] = rawurlencode( $tabId );451 452 return $params;453 }454 455 /**456 * Add common html code for all modes on list page457 */458 function addCommonHtml()459 {460 if ( !$this->isDashboardElement() && !$this->mobileTemplateMode() && !$this->pdfJsonMode() )461 $this->body["begin"].= "<div id=\"search_suggest\" class=\"search_suggest\"></div>";462 463 if($this->is508) {464 $this->body["begin"].= "<a href=\"#skipdata\" title=\""."Skip to table data"."\" class=\"".$this->makeClassName("s508")."\">"."Skip to table data"."</a>";465 $this->body["begin"].= "<a href=\"#skipmenu\" title=\""."Skip to menu"."\" class=\"".$this->makeClassName("s508")."\">"."Skip to menu"."</a>";466 $this->body["begin"].= "<a href=\"#skipsearch\" title=\""."Skip to search"."\" class=\"".$this->makeClassName("s508")."\">"."Skip to search"."</a>";467 $this->body["begin"].= "<a href=\"templates/helpshortcut.htm\" title=\""."Hotkeys reference"."\" class=\"".$this->makeClassName("s508")."\">"."Hotkeys reference"."</a>";468 }469 470 //prepare for dispaly master table info on details table471 $this->displayMasterTableInfo();472 }473 474 /**475 * Add common javascript files and code476 */477 function addCommonJs()478 {479 parent::addCommonJs();480 481 $this->addJsForGrid();482 483 // add button events if exist484 $this->addButtonHandlers();485 486 487 if( $this->spreadsheetGridApplicable() ) {488 $this->editPage->addControlsJSAndCSS();489 $this->includes_js = array_merge( $this->includes_js, $this->editPage->includes_js );490 }491 }492 493 /**494 * Add javascript code for grid495 */496 function addJsForGrid()497 {498 if( $this->isResizeColumns )499 $this->prepareForResizeColumns();500 501 if( $this->reorderFieldsFeatureEnabled() )502 {503 $this->AddJSFile( 'include/jquery.dragtable.js' );504 }505 506 $this->jsSettings['tableSettings'][$this->tName]['showRows'] = ($this->numRowsFromSQL ? true : false);507 508 $this->initGmaps();509 }510 511 /**512 * If use resizable columns513 * Prepare for resize main table514 */515 function prepareForResizeColumns()516 {517 $this->AddJSFile( 'include/colresizable.js' );518 }519 520 /**521 * Process master key value from request params522 * For DPInline mode and use this mode on edit or add page523 */524 function processMasterKeyValue()525 {526 parent::processMasterKeyValue();527 528 /*529 // obsolete ?530 // reset search and page number531 $_SESSION[$this->sessionPrefix."_search"] = 0;532 if($this->firstTime)533 $_SESSION[$this->sessionPrefix."_pagenumber"] = 1;534 */535 }536 537 /**538 * Add event before process list539 */540 function beforeProcessEvent()541 {542 if($this->eventExists("BeforeProcessList"))543 $this->eventsObject->BeforeProcessList( $this );544 }545 /**546 * Set session variables547 */548 function setSessionVariables()549 {550 parent::setSessionVariables();551 552 if( $this->searchClauseObj )553 {554 if( $this->searchClauseObj->isSearchFunctionalityActivated() )555 {556 // if search used serialize clause object557 $_SESSION[$this->sessionPrefix.'_advsearch'] = serialize($this->searchClauseObj);558 }559 else560 {561 // Unset session for search if search not used562 unset($_SESSION[$this->sessionPrefix.'_advsearch']);563 }564 565 // Unset session for filters if filters not activated566 if(!$this->searchClauseObj->filtersActivated)567 unset($_SESSION[$this->sessionPrefix.'_filters']);568 }569 else570 {571 unset($_SESSION[$this->sessionPrefix.'_advsearch']);572 unset($_SESSION[$this->sessionPrefix.'_filters']);573 }574 575 576 //set session goto577 if( $this->requestGoto )578 $_SESSION[$this->sessionPrefix."_pagenumber"]= $this->requestGoto;579 580 581 582 // page number583 $this->myPage =(integer) $_SESSION[$this->sessionPrefix."_pagenumber"];584 if(! $this->myPage)585 $this->myPage = 1;586 587 //set page size588 if(!$this->pageSize)589 $this->pageSize = $this->gPageSize;590 if( $this->pdfJsonMode() ) {591 $this->pageSize = -1;592 }593 }594 595 protected function assignColumnHeaderClasses()596 {597 for($i = 0; $i < count($this->listFields); $i ++)598 {599 $field = $this->listFields[$i]['fName'];600 $goodName = GoodFieldname($field);601 // add class for field header as field value602 $fieldClassStr = $this->fieldClass($field);603 // add class for mobile columns hiding604 if( isset( $this->hiddenColumnClasses[$goodName] ) )605 $fieldClassStr .= " ".$this->hiddenColumnClasses[$goodName ];606 $this->xt->assign(GoodFieldName($field)."_class", $fieldClassStr);607 $this->xt->assign(GoodFieldName($field)."_align", $this->fieldAlign($field));608 }609 }610 611 612 /**613 * @return Boolean614 */615 public function isReoderByHeaderClickingEnabled()616 {617 return true;618 }619 620 /**621 * Delete selected records622 */623 function deleteRecords()624 {625 global $globalEvents;626 if( @$_REQUEST["a"] != "delete" )627 return;628 629 // CSRF protection630 if( !isPostRequest() )631 return;632 633 $message_class = "alert-warning";634 $this->deleteMessage = "";635 if(@$_REQUEST["mdelete"])636 {637 foreach(@$_REQUEST["mdelete"] as $ind)638 {639 $selectedKeys = array();640 for($i = 0; $i < count($this->arrKeyFields); $i ++)641 {642 $selectedKeys[ $this->arrKeyFields[$i] ] = refine($_REQUEST["mdelete".($i + 1)][mdeleteIndex($ind)]);643 }644 $this->selectedRecs[] = $selectedKeys;645 }646 }647 elseif(postvalue( "selection" ))648 {649 foreach( postvalue( "selection" ) as $keyblock)650 {651 $arr = explode("&", refine($keyblock));652 if(count($arr) < count($this->arrKeyFields))653 continue;654 $selectedKeys = array();655 for($i = 0; $i < count($this->arrKeyFields); $i ++)656 {657 $selectedKeys[ $this->arrKeyFields[$i] ]= urldecode(@$arr[$i]);658 }659 $this->selectedRecs[] = $selectedKeys;660 }661 }662 663 $this->recordsDeleted = 0;664 $this->lockDelRec = array();665 foreach($this->selectedRecs as $keys)666 {667 $dc = $this->getDeleteCommand( $keys );668 669 $retval = true;670 671 $deletedResult = $this->dataSource->getSingle( $dc );672 $deleted_values = $deletedResult673 ? $this->cipherer->DecryptFetchedArray( $deletedResult->fetchAssoc() )674 : array();675 676 if($globalEvents->exists("IsRecordEditable", $this->tName))677 {678 if(!$globalEvents->IsRecordEditable($deleted_values, true, $this->tName))679 continue;680 }681 if( $this->eventExists("BeforeDelete") || $this->eventExists("AfterDelete") ) {682 $prep = $this->dataSource->prepareSQL( $dc );683 $where = $prep["where"];684 }685 686 if($this->eventExists("BeforeDelete"))687 {688 RunnerContext::pushRecordContext( $deleted_values, $this );689 $tdeleteMessage = $this->deleteMessage;690 $retval = $this->eventsObject->BeforeDelete($where, $deleted_values, $tdeleteMessage, $this);691 $this->deleteMessage = $tdeleteMessage;692 RunnerContext::pop();693 }694 695 $lockRecord = false;696 697 if($this->lockingObj)698 {699 $lockWhere = array();700 foreach($keys as $keysvalue)701 {702 $lockWhere[] = rawurlencode($keysvalue);703 }704 705 if( $this->lockingObj->isLocked( $this->origTName, implode("&", $lockWhere), "1" ) )706 {707 $lockRecord = true;708 $this->lockDelRec[] = $keys;709 }710 711 if( $this->mode == LIST_SIMPLE )712 $_SESSION[$this->sessionPrefix."_lockDelRec"] = $this->lockDelRec;713 }714 715 if(!$lockRecord && @$_REQUEST["a"] == "delete" && $retval)716 {717 $this->recordsDeleted ++;718 // delete associated uploaded files if any719 DeleteUploadedFiles($this->pSet, $deleted_values);720 721 if( !$this->dataSource->deleteSingle( $dc ) ) {722 $this->deleteMessage .= ( $this->deleteMessage ? '<br>' : '' ) . $this->dataSource->lastError();723 }724 725 if($this->audit && $deleted_values)726 {727 $fieldsList = $this->pSet->getFieldsList();728 $i=0;729 foreach($deleted_values as $key=>$value)730 {731 if( IsBinaryType( $this->pSet->getFieldType($fieldsList[$i]) ) )732 $deleted_audit_values[ $fieldsList[$i] ] = $value;733 else734 $deleted_audit_values[ $key ] = $value;735 $i++;736 }737 $this->audit->LogDelete($this->tName, $deleted_audit_values, $keys);738 }739 if ( $this->tName == ADMIN_USERS && Security::dynamicPermissions() ) {740 // delete _ugmembers corr. rec.741 $dataSource = Security::getUgMembersDatasource();742 743 $user = $deleted_values[ Security::usernameField() ];744 // TODO - delete plugin user745 $dc = new DsCommand();746 $dc->filter = DataCondition::FieldEquals( 747 "UserName", 748 $user, 749 0, 750 Security::caseInsensitiveUsername() ? dsCASE_INSENSITIVE : dsCASE_STRICT 751 );752 753 $dataSource->deleteSingle( $dc, false );754 }755 if($this->eventExists("AfterDelete"))756 {757 RunnerContext::pushRecordContext( $deleted_values, $this );758 $tdeleteMessage = $this->deleteMessage;759 $this->eventsObject->AfterDelete($where, $deleted_values,$tdeleteMessage, $this);760 $this->deleteMessage = $tdeleteMessage;761 RunnerContext::pop();762 $message_class = "alert-info";763 764 }765 }766 767 }768 if( count($this->selectedRecs) && $this->eventExists("AfterMassDelete") )769 $this->eventsObject->AfterMassDelete($this->recordsDeleted, $this);770 771 if ( $this->deleteMessage ) {772 $this->xt->assignbyref("message", $this->deleteMessage);773 $this->xt->assignbyref( "message_class", $message_class );774 $this->xt->assign("message_block",true);775 }776 777 }778 779 /**780 * PRG rule, to avoid POSTDATA resend781 */782 function rulePRG()783 {784 if( $this->stopPRG )785 return false;786 787 if(no_output_done() && count($this->selectedRecs) && !strlen($this->deleteMessage))788 {789 $getParams = implode( '&', array( "a=return", $this->getStateUrlParams() ) );790 791 if ( postvalue("page") )792 $getParams .= "&page=" . postvalue("page");793 794 // redirect, add a=return param for saving SESSION795 HeaderRedirect($this->shortTableName, $this->getPageType(), $getParams);796 // turned on output buffering, so we need to stop script797 exit();798 }799 }800 801 /**802 * Add code from program before show list803 */804 function BeforeShowList()805 {806 if($this->eventExists("BeforeShowList"))807 {808 $templatefile = $this->templatefile;809 $this->eventsObject->BeforeShowList($this->xt, $templatefile, $this);810 $this->templatefile = $templatefile;811 }812 }813 814 /**815 * Common assign for diferent mode on list page816 * Branch classes add to this method its individualy code817 */818 function commonAssign()819 {820 parent::commonAssign();821 822 $this->xt->assignbyref("body", $this->body);823 824 $this->xt->assign("newrecord_controls_block", $this->inlineAddAvailable() || $this->addAvailable() );825 826 if( ( $this->isDispGrid() || $this->listAjax ) && (827 $this->printAvailable()828 || $this->exportAvailable()829 || $this->deleteAvailable()830 || $this->updateSelectedAvailable()831 || $this->inlineEditAvailable()832 || $this->inlineAddAvailable()833 || $this->showAddInPopup && $this->addAvailable()834 )835 )836 {837 $this->xt->assign("record_controls_block", true);838 }839 840 if( $this->numRowsFromSQL == 0 )841 $this->hideElement("recordcontrol");842 843 // add link844 if( $this->addAvailable() )845 {846 $this->xt->assign("add_link", true);847 $add_attrs = 'id="addButton'.$this->id.'"';848 849 $this->xt->assign("addlink_attrs", $add_attrs);850 851 if ( $this->dashTName )852 {853 $this->xt->assign("addlink_getparams", "?fromDashboard=" . $this->dashTName);854 }855 }856 // inline add link857 $this->inlineAddLinksAttrs();858 859 if($this->isShowMenu() || $this->isAdminTable())860 $this->xt->assign("quickjump_attrs", 'class="'.$this->makeClassName("quickjump").'"');861 862 foreach ($this->googleMapCfg['mainMapIds'] as $mapId)863 {864 $this->xt->assign_event($mapId, $this, 'createMapDiv', array('mapId'=>$mapId, 'width'=>$this->googleMapCfg['mapsData'][$mapId]['width'], 'height'=>$this->googleMapCfg['mapsData'][$mapId]['height']));865 }866 867 $this->assignSortByDropdown();868 869 //add assign for grid block870 $this->addAssignForGrid();871 $this->xt->assign("grid_block", true);872 873 //select all link and attr874 $this->selectAllLinkAttrs();875 876 //edit selected link and attr877 $this->editSelectedLinkAttrs();878 879 //update selected link and attr880 $this->updateSelectedLinkAttrs();881 882 //save all link, attr, span883 $this->saveAllLinkAttrs();884 885 //cansel all link, attr, span886 $this->cancelAllLinkAttrs();887 888 $this->hideItemType("details_preview");889 $this->hideItemType("grid_inline_save");890 $this->hideItemType("grid_inline_cancel");891 }892 893 /**894 * Common assign for grid block in diferent mode on list page895 */896 function addAssignForGrid()897 {898 if( !$this->recordsOnPage && $this->listAjax ) {899 $this->deleteSelectedLink();900 $this->hideItemType("delete");901 }902 903 if( !$this->isDispGrid() )904 return;905 906 if($this->is508)907 {908 if( $this->listGridLayout == gltVERTICAL )909 $this->xt->assign_section("grid_header", "<div style=\"display:none\">Table data</div>", "");910 else911 $this->xt->assign_section("grid_header", "<caption style=\"display:none\">Table data</caption>", "");912 }913 914 $this->xt->assign("endrecordblock_attrs", "colid=\"endrecord\"");915 916 917 for($i = 0; $i < count($this->listFields); $i ++)918 {919 $this->xt->assign(GoodFieldName($this->listFields[$i]['fName'])."_fieldheadercolumn", true);920 $this->xt->assign(GoodFieldName($this->listFields[$i]['fName'])."_fieldcolumn", true);921 $this->xt->assign(GoodFieldName($this->listFields[$i]['fName'])."_fieldfootercolumn", true);922 }923 924 925 $record_header = array("data" => array());926 $record_footer = array("data" => array());927 928 $rheader = array();929 $rfooter = array();930 $record_header["data"][] = $rheader;931 $record_footer["data"][] = $rfooter;932 933 $this->xt->assignbyref("record_header", $record_header);934 $this->xt->assignbyref("record_footer", $record_footer);935 $this->xt->assign("grid_header", true);936 $this->xt->assign("grid_footer", true);937 938 939 //checkbox column940 $this->checkboxColumnAttrs();941 942 if( $this->editAvailable() )943 {944 $this->xt->assign("edit_column", true);945 $this->xt->assign("edit_headercolumn", true);946 $this->xt->assign("edit_footercolumn", true);947 }948 949 if( $this->inlineEditAvailable() && !$this->spreadsheetGridApplicable() )950 {951 $this->xt->assign("inlineedit_column", true);952 $this->xt->assign("inlineedit_headercolumn", true);953 $this->xt->assign("inlineedit_footercolumn", true);954 }955 956 if( $this->inlineEditAvailable() || $this->inlineAddAvailable() )957 {958 $this->xt->assign("inline_cancel", true);959 $this->xt->assign("inline_save", true);960 }961 962 if( $this->inlineAddAvailable() && $this->spreadsheetGridApplicable() ) {963 $this->xt->assign("grid_inline_add_link", true);964 965 }966 967 //copy link968 if( $this->copyAvailable() )969 $this->xt->assign("copy_column", true);970 971 //view column972 if( $this->displayViewLink() )973 $this->xt->assign("view_column", true);974 975 //for list icons instead of list links976 $this->assignListIconsColumn();977 978 if( $this->detailsInGridAvailable() )979 {980 $this->xt->assign(GoodFieldName($this->tName)."_dtable_column", true);981 $this->xt->assign("dtables_link", true);982 }983 984 //delete link and attr985 $this->deleteSelectedLink();986 987 }988 989 function createMapDiv( &$params ) {990 echo '<div id="'.$params['mapId'].'" style="width: 100%; height: 100%"></div>';991 }992 /**993 * Show import link994 * Add import link attributes995 */996 function importLinksAttrs()997 {998 $this->xt->assign("import_link", $this->permis[$this->tName]['import']);999 $this->xt->assign("importlink_attrs", "id=\"import_".$this->id."\" name=\"import_".$this->id."\"");1000 }1001 1002 /**1003 * Show inline add link1004 * Add inline add attributes1005 */1006 1007 function getInlineAddLinksAttrs()1008 {1009 return "name=\"inlineAdd_".$this->id."\" href='".1010 GetTableLink( $this->shortTableName, "add", $this->getStateUrlParams() )."' id=\"inlineAdd".$this->id."\"";1011 }1012 1013 function getAddLinksAttrs()1014 {1015 return "href='".GetTableLink($this->shortTableName, "add")."' id=\"addButton".$this->id."\"";1016 }1017 1018 function inlineAddLinksAttrs()1019 {1020 if( !$this->inlineAddAvailable() )1021 return;1022 //inline add link and attr1023 $this->xt->assign("inlineadd_link", true );1024 $this->xt->assign("inlineaddlink_attrs", $this->getInlineAddLinksAttrs() );1025 }1026 1027 /**1028 * Assign selectAll link and attrs1029 */1030 function selectAllLinkAttrs()1031 {1032 $this->xt->assign("selectall_link", $this->deleteAvailable() || $this->permis[$this->tName]['export']|| $this->permis[$this->tName]['edit']);1033 $this->xt->assign("selectalllink_span", $this->buttonShowHideStyle());1034 $this->xt->assign("selectalllink_attrs",1035 "name=\"select_all".$this->id."\"1036 id=\"select_all".$this->id."\"1037 href=\"#\"");1038 }1039 1040 /**1041 * Assign checkbox column, header and header attrs1042 */1043 function checkboxColumnAttrs()1044 {1045 $showColumn = $this->deleteAvailable() || $this->exportAvailable() || $this->inlineEditAvailable() || $this->printAvailable() || $this->updateSelectedAvailable();1046 $this->xt->assign("checkbox_column", $showColumn);1047 $this->xt->assign("checkbox_header", true);1048 $this->xt->assign("checkboxheader_attrs", "id=\"chooseAll_".$this->id."\" class=\"chooseAll".$this->id."\"");1049 }1050 1051 /**1052 * Get common attrs for Print and Export links1053 */1054 function getPrintExportLinkAttrs($page)1055 {1056 if(!$page)1057 return '';1058 return "name=\"".$page."_selected".$this->id."\"1059 id=\"".$page."_selected".$this->id."\"1060 href = '".GetTableLink($this->shortTableName, $page)."'";1061 }1062 1063 /**1064 * Show or hide current button1065 */1066 function buttonShowHideStyle($link="")1067 {1068 if($link == 'saveall' || $link == 'cancelall')1069 return ' style="display:none;" ';1070 1071 return $this->numRowsFromSQL > 0 ? '' : ' style="display:none;" ';1072 }1073 1074 /**1075 * Assign editSelected link and attrs1076 */1077 function editSelectedLinkAttrs()1078 {1079 if( !$this->inlineEditAvailable() )1080 return;1081 1082 $this->xt->assign("editselected_link", true );1083 $this->xt->assign("editselectedlink_span", $this->buttonShowHideStyle());1084 $this->xt->assign("editselectedlink_attrs","1085 href='".GetTableLink($this->shortTableName, "edit")."'1086 name=\"edit_selected".$this->id."\"1087 id=\"edit_selected".$this->id."\"");1088 }1089 1090 function updateSelectedLinkAttrs()1091 {1092 if( !$this->updateSelectedAvailable() )1093 return;1094 1095 $this->xt->assign("updateselected_link", true );1096 $this->xt->assign("updateselectedlink_attrs", $this->getUpdateSelectedAttrs() . $this->buttonShowHideStyle() );1097 }1098 1099 protected function getUpdateSelectedAttrs() {1100 return " name=\"update_selected".$this->id."\" id=\"update_selected".$this->id."\"";1101 }1102 1103 /**1104 * Assign saveAll link and attrs1105 */1106 function saveAllLinkAttrs() {1107 if( $this->spreadsheetGridApplicable() ) {1108 $this->xt->assign("saveall_link", false);1109 return;1110 }1111 $this->xt->assign("saveall_link", $this->permis[$this->tName]['edit'] || $this->permis[$this->tName]['add']);1112 $this->xt->assign("savealllink_span", $this->buttonShowHideStyle('saveall'));1113 $this->xt->assign("savealllink_attrs", "name=\"saveall_edited".$this->id."\" id=\"saveall_edited".$this->id."\"");1114 }1115 1116 /**1117 * Assign cancelAll link and attrs1118 */1119 function cancelAllLinkAttrs() {1120 if( $this->spreadsheetGridApplicable() ) {1121 $this->xt->assign("cancelall_link", false);1122 return;1123 } 1124 $this->xt->assign("cancelall_link", $this->permis[$this->tName]['edit'] || $this->permis[$this->tName]['add']);1125 $this->xt->assign("cancelalllink_span", $this->buttonShowHideStyle('cancelall'));1126 $this->xt->assign("cancelalllink_attrs", "name=\"revertall_edited".$this->id."\" id=\"revertall_edited".$this->id."\"");1127 }1128 1129 /**1130 * Assign delete selected link1131 */1132 function deleteSelectedLink()1133 {1134 if( !$this->deleteAvailable() )1135 return;1136 1137 $this->xt->assign("deleteselected_link", true );1138 1139 $this->xt->assign("deleteselectedlink_span", $this->buttonShowHideStyle());1140 $this->xt->assign("deleteselectedlink_attrs", $this->getDeleteLinksAttrs());1141 }1142 1143 function getDeleteLinksAttrs()1144 {1145 return "id=\"delete_selected".$this->id."\" name=\"delete_selected".$this->id."\" ";1146 }1147 1148 function getEditLinksAttrs()1149 {1150 return "id=\"edit_selected".$this->id."\" name=\"edit_selected".$this->id."\" ";1151 }1152 1153 function getFormInputsHTML()1154 {1155 return '';1156 }1157 1158 function getFormTargetHTML()1159 {1160 return '';1161 }1162 1163 public function getOrderByClause()1164 {1165 // use builtin orderClause object1166 return $this->orderClause->getOrderByExpression();1167 }1168 1169 1170 /**1171 * Check if its possible to add to the main table query a subquery that contes the number of details. #98751172 * @param String dDataSourceTable The detail datasource table name1173 * @param Number dTableIndex The detail table index in the allDetailsTablesArr prop1174 * @return Boolean1175 */1176 protected function isDetailTableSubquerySupported( $dDataSourceTName, $dTableIndex )1177 {1178 global $cman, $bSubqueriesSupported;1179 1180 return $bSubqueriesSupported1181 && $this->connection->checkDBSubqueriesSupport()1182 && $cman->checkTablesSubqueriesSupport( $this->tName, $dDataSourceTName )1183 && $this->checkfDMLinkFieldsOfTheSameType( $dDataSourceTName, $dTableIndex )1184 && !$this->gQuery->HasJoinInFromClause();1185 }1186 1187 /**1188 * Check if to add a details counting sub-query to the page's sql-query1189 * @return Boolean1190 */1191 protected function useDetailsCountBySubquery()1192 {1193 $entType = $this->pSet->getEntityType();1194 if( $entType !== titTABLE && $entType !== titVIEW ) {1195 return false;1196 }1197 // mind ASP conversion before modifying this code!!!1198 $manyPages = false;1199 if( $this->numRowsFromSQL > 0 )1200 $manyPages = ($this->pageSize / $this->numRowsFromSQL < 0.1);