'', 'end'=> '');
/**
* Master table name
* @var string
* @intellisense
*/
public $masterTable = "";
/**
* Master page name
* @var string
* @intellisense
*/
public $masterPage = "";
/**
* Master table record data
* @var object
* @intellisense
*/
public $masterRecordData = array();
/**
* Array of all details tables data
* @var array
* @intellisense
*/
public $allDetailsTablesArr = array();
/**
* Array of java script settings for page
* @var array
* @intellisense
*/
public $jsSettings = array();
/**
* Array of controls HTML map
* @var array
* @intellisense
*/
public $controlsHTMLMap = array();
/**
* Array of view controls HTML map
* @var array
* @intellisense
*/
public $viewControlsHTMLMap = array();
/**
* Array of controls map
* @var array
* @intellisense
*/
public $controlsMap = array();
/**
* Page data to pass to JS code. Link to an element in the global $pagesData array
* @var array
* @intellisense
*/
public $pageData = array();
/**
* Array of view controls map
* @var array
* @intellisense
*/
public $viewControlsMap = array();
/**
* Array of field settings for use it in javascript settings
* @var array
* @intellisense
*/
public $settingsMap = array();
/**
* Array of records per page for list and report without group fields
* @var array
* @intellisense
*/
public $arrRecsPerPage = array();
/**
* Number of page size
* @var integer
* @intellisense
*/
public $pageSize = 0;
/**
* The page's table type: list, report or chart
* @var string
* @intellisense
*/
protected $tableType = "";
/**
* Events object for the current table
* @var object
* @intellisense
*/
public $eventsObject;
/**
* Master table requested keys
* @var array
*/
public $masterKeysReq = array();
/**
* Detail keys by master table
* @var array
* @intellisense
*/
public $detailKeysByM = array();
/**
* Locking object
* @var object
* @intellisense
*/
public $lockingObj = null;
/**
* Is use Video player or not
* @var boolean
* @intellisense
*/
protected $isUseVideo = false;
/**
* Is columns will be resizable or not
* @var boolean
* @intellisense
*/
protected $isResizeColumns = false;
/**
* Is use CKeditor or not
* @var boolean
* @intellisense
*/
protected $isUseCK = false;
/**
* Is display detail data on page or not
* @var boolean
* @intellisense
*/
// delete this variable
public $isShowDetailTables = true;
/**
* arrays of files to process after adding or editing a record
* @intellisense
*/
public $filesToSave = array(); //FileFieldSingle
public $filesToMove = array();
public $filesToDelete = array();
/**
* Master keys by detail table
* @var array
* @intellisense
*/
protected $masterKeysByD = array();
/**
* Indicator is permissions dynamic
* @var bool
* @intellisense
*/
public $isDynamicPerm = false;
/**
* If nedd add web report or not
* @var bool
* @intellisense
*/
protected $isAddWebRep = true;
/**
* Indicator, is used section 508
* @var bool
* @intellisense
*/
protected $is508 = false;
/**
* Instance of Cypher class for encoding/decoding fields values
* @var object
* @intellisense
*/
public $cipherer = null;
/**
* Project settings
* @type ProjectSettings
* @intellisense
*/
public $pSet = null;
/**
* Project settings for the users table. This var is used in global pages
* @type ProjectSettings
* @intellisense
*/
public $pSetUsers = null;
/**
* Project settings for edit controls
* @type ProjectSettings
* @intellisense
*/
public $pSetEdit = null;
/**
* Number of rows
* @var integer
* @intellisense
*/
public $numRowsFromSQL = 0;
/**
* Index of my page
* @var integer
* @intellisense
*/
protected $myPage = 0;
protected $mapProvider = 0;
protected $recordsOnPage = 0;
/**
* Number of records per row list
* @var integer
* @intellisense
*/
public $recsPerRowList = 0;
/**
* Number of records per row print
* @var integer
* @intellisense
*/
public $recsPerRowPrint = 0;
/**
* grid layout - gltHORIZONTAL, gltVERTICAL or gltCOLUMNS
* @type bool
*/
public $listGridLayout = false;
/**
* grid layout - gltHORIZONTAL, gltVERTICAL or gltCOLUMNS
* @type bool
*/
public $printGridLayout = false;
/**
*
* @type array
*/
public $gridTabs = array();
/**
* An array that keys are different field's css rules
* @type array
*/
protected $fieldCssRules = array();
/**
* Cells' custom css rules
* @type string
*/
protected $cell_css_rules = "";
/**
* Rows' custom css rules
* @type string
*/
protected $row_css_rules = "";
/**
* css rules to hide fields on mobile devices columns
* It could be also applied to the desktop version
* @type string
*/
protected $mobile_css_rules = "";
protected $colsOnPage = 1;
/**
* Array of field names that used for totals
* @type array
* array['totalsFields']= array('fName'=>"@f.strName s", 'totalsType'=>'@f.strTotalsType', 'viewFormat'=>"@f.strViewFormat");
*/
public $totalsFields = array();
/**
* Number of founed rows
* @var bool
* @intellisense
*/
public $rowsFound = false;
/**
* Constructor, set initial params
* @param array $params
* @intellisense
*/
protected $deleteMessage = '';
/**
* Number of maximum pages
* @var integer
* @intellisense
*/
protected $maxPages = 1;
/**
* Name of the templete file
* @var string
* @intellisense
*/
public $templatefile = "";
/**
* Array of menu nodes
* @var array
* @intellisense
*/
public $menuNodes = array();
/**
* Refferense to sqlquery object
* @var object
* @intellisense
*/
protected $gQuery = null;
/**
* Flag. True if fillSetCntrlMaps already called
* @intellisense
*/
protected $isControlsMapFilled = false;
/**
* Instance of EditControlsContainer
* @var {object}
* @intellisense
*/
protected $controls = null;
/**
* Instance of ViewControlsContainer
* @var {object}
* @intellisense
*/
public $viewControls = null;
/**
* Associative array of readonly fields for add, edit and register page
* @var array
* @intellisense
*/
public $readOnlyFields = array();
/**
* It indicates if the searchpanel brick id added to the page's layout
*/
protected $searchPanelActivated = false;
/**
* the instance of the "projectSettings" object
* It differs from the pSet (and is set as a pSet for the Search panel's searh table)
* in case the Search panel is activated on the non table page
* @type ProjectSettings
*/
public $pSetSearch = null;
/**
* The real Search panel's searh table name.
* It differs from the tName in case the Search panel is activated on the non table page
*/
public $searchTableName = "";
/**
* Page layout object
*/
protected $pageLayout = null;
protected $warnLeavingPages = null;
/**
* Indicator showing if It's neccessary to add the search panel fields's settings
* It's set equal to true when the Search panel is added on the non table page
*/
public $tableBasedSearchPanelAdded = false;
public $mainTable = ""; //fix it
public $mainField = ""; //fix it
/**
* Cached results of getWhereComponents function
*/
protected $_cachedWhereComponents = null;
/**
* the local time format regexp
* @type String
*/
protected $timeRegexp;
protected $dispNoneStyle = 'style="display: none;"';
/**
* Detail keys by detail table
*/
protected $detailKeysByD = array();
/**
* The page's searchParamsLogger class instance
* @type Object
*/
public $searchLogger = null;
/**
* @type Boolean
*/
public $searchSavingEnabled = false;
/**
* @type Boolean
*/
public $pageHasSavedSearches = false;
/**
* The 'form' logic elements
* @type Array
*/
protected $formBricks = array();
protected $headerForms = array();
protected $footerForms = array();
protected $bodyForms = array();
/**
* The instance of class representing a db connection
* @type Connection
*/
public $connection = null;
/**
* Dashboard name
* @type string
*/
public $dashTName = '';
/**
* Element from dashboard
* @type string
*/
public $dashElementName = '';
/**
* @type ProjectSettings
*/
protected $dashSet;
/**
* @type Array
*/
protected $dashElementData = array();
/**
* PDF rendering mode.
* empty - regular page display
* "build" - build page and return PDF
* "prepare" - build page and return HTML for browser post-processing
* "convert" - convert post-processed HTML to PDF
*/
public $pdfMode = "";
/**
* In a multistepped layout the step number
* @type Integer
*/
public $initialStep = 0;
/**
* This property is used by ReportPrint page only to indicate that export to Word/Excel is in progress.
* @type String
*/
public $format = "";
public $message = "";
/**
* @type Boolean
*/
public $mapRefresh = false;
/**
* @type Array
*/
public $vpCoordinates = array();
public $querySQL = "";
/**
* When the page is Details Preview, masterPageType has master table page type
* @type String
*/
public $masterPageType = "";
public $masterPSet;
/**
* View page data
* @type array
*/
protected $data = null;
/**
* errorFields
*/
public $errorFields = array();
protected $menuRoots = array();
protected $detailsTableObjects = array();
/**
* If use body scroll for grid
* @type bool
*/
public $isScrollGridBody = false;
/**
* Suppress Post/Redirect/Get pattern after submitting the form on Add/Edit/Register/Delete pages
* With $this->stopPRG=false the page will not be redirected.
*/
public $stopPRG = false;
/**
* Override default page title
* @type String
*/
public $pageTitle = null;
/**
* Indicates if the page should save its context in the global stack.
* If true, destructor must pop context from global stack
* @type Boolean
*/
public $pushContext = true;
/**
* Standalone context for using in page events
* This should be used with pushContext=false only
* @type Object
*/
public $standaloneContext = null;
/**
* Key field values of current or newly added record on Add/Edit/View pages
*/
public $keys = array();
/**
* Array of selected record ids used on Print, Export and Edit Selected pages
* @type Array
*/
public $selection = array();
/**
* This is a hack, sorry.
* Temporary substitute the WHERE tab name to calculate number of records in a tab
* Used in getCurrentTabWhere function
*
* @type String - substitute the tab id. Set to NULL to use current tab
*/
public $tabChangeling = null;
/**
* One more hack
* Temporary skip coordinates WHERE clause to calculate number of records in a tab
* Used in getWhereByMap function
*
* @type Boolean
*/
public $skipMapFilter = false;
public $changeDetailsTabTitles = true;
/**
* See auxTable comments in ProjectSettings
*/
public $pageTable = "";
/**
* Embedded details preview variables
*/
var $renderedBody = "";
var $renderedButtons = "";
var $pdfBackgroundImage = "";
public $addRawFieldValues = false;
/**
* DataSource
*/
protected $dataSource = null;
protected $queryCommand = null;
/**
* @constructor
* @param &Array params
*/
function __construct(&$params)
{
global $locale_info, $cCharset, $page_layouts, $projectBuildKey, $wizardBuildKey;
// copy properties to object
RunnerApply($this, $params);
if( $this->pushContext )
RunnerContext::pushPageContext( $this );
else
$this->standaloneContext = new RunnerContextItem( CONTEXT_PAGE, array( "pageObj" => $this ));
// Sanitize input. It must be checked before that, but just in case add it here.
$this->id = 0 + $this->id;
if( !$this->id )
$this->id = 1;
// see how this converts to ASP & ASP.NET
global $pagesData;
$pagesData[$this->id] = &$this->pageData;
$this->pageData["proxy"] = array();
$this->xt->pageId = $this->id;
$this->xt->setPage( $this );
$this->xt->assign( "pageid", $this->id );
$this->setTableConnection();
if( $this->pageTable == "" ) {
$this->pageTable = $this->tName;
}
$this->createProjectSettings();
$this->setDataSource();
$this->checkOauthLogin();
$this->pageName = $this->pSet->pageName();
$this->pageData["pageName"] = $this->pageName;
$this->pageData["helperFormItems"] = $this->pSet->helperFormItems();
$this->pageData["helperItemsByType"] = $this->pSet->helperItemsByType();
$this->pageData["helperFieldItems"] = $this->pSet->allFieldItems();
$this->pageData["buttons"] = $this->pSet->buttons();
$this->pageData["fieldItems"] = $this->pSet->allFieldItems();
foreach( $this->pSet->buttons() as $b ) {
$this->AddJSFile( "include/button_".$b.".js" );
}
$this->pageData["renderedMediaType"] = getMediaType();
$this->pSetEdit = $this->pSet;
$this->pSetSearch = new ProjectSettings($this->tName, PAGE_SEARCH, $this->pageName, $this->pageTable );
$this->searchTableName = $this->tName;
if( $this->dashTName )
{
$this->dashSet = new ProjectSettings( $this->dashTName );
if( $this->isDashboardElement() )
$this->dashElementData = $this->dashSet->getDashboardElementData( $this->dashElementName );
}
$this->assignCipherer();
$this->prepareCharts();
include_once getabspath("classes/controls/EditControlsContainer.##@ext##");
$this->controls = new EditControlsContainer($this, $this->pSetEdit, $this->pageType);
include_once getabspath("classes/controls/ViewControlsContainer.##@ext##");
$this->viewControls = new ViewControlsContainer($this->pSet, $this->pageType, $this);
$this->gQuery = $this->pSet->getSQLQuery();
//set google map configuration
$this->googleMapCfg = array('isUseMainMaps'=>false, 'isUseFieldsMaps'=> false, 'isUseGoogleMap'=>false, 'APIcode'=>GetGlobalData("apiGoogleMapsCode",""), 'mainMapIds'=>array(), 'fieldMapsIds'=>array(), 'mapsData'=>array());
//set recaptcha configuration
$captchaSettings = GetGlobalData("CaptchaSettings", "");
$this->captchaPassesCount = $captchaSettings["captchaPassesCount"];
if ( $captchaSettings["type"] == RE_CAPTCHA )
{
$this->AddJSFile('include/runnerJS/ReCaptcha.js');
$this->reCaptchaCfg = array('siteKey' => $captchaSettings["siteKey"], 'inputCaptchaId' => "");
}
$this->debugJSMode = false;
if($this->flyId < $this->id+1)
$this->flyId = $this->id+1;
// get permissions
if ($this->tName)
{
$this->permis[$this->tName]= $this->getPermissions();
$this->eventsObject = &getEventObject($this->tName);
}
if( !$this->sessionPrefix )
$this->assignSessionPrefix();
$this->isDisplayLoading = $this->pSet->displayLoading();
$this->shortTableName = GetTableURL($this->tName);
// set layout
$this->pageLayout = GetPageLayout($this->pageTable, $this->pageName );
/*
if ($this->pageType == PAGE_REGISTER || $this->pageType == PAGE_CHANGEPASS || $this->pageType == PAGE_LOGIN || $this->pageType == PAGE_REMIND )
$this->pageLayout = GetPageLayout( GLOBAL_PAGES, $this->pageName );
else
$this->pageLayout = GetPageLayout($this->tName, $this->pageName );
*/
//init settingMap globalSettings
$this->settingsMap["globalSettings"] = array();
$this->settingsMap["globalSettings"]["shortTNames"] = array();
$this->searchPanelActivated = $this->checkIfSearchPanelActivated( $this->mobileTemplateMode() );
//global settings including "shortTNames" might be updated
$this->setParamsForSearchPanel();
$this->searchSavingEnabled = $this->isSearchSavingEnabled() && $this->needSearchClauseObj;
if ( $this->mode != LIST_MASTER )
$this->setSessionVariables();
// get locking object
$this->lockingObj = $this->getLockingObject();
$this->warnLeavingPages = $this->pSet->warnLeavingPages();
$this->is508 = isEnableSection508() && !$this->pdfJsonMode();
$this->mapProvider = getMapProvider();
$this->isUseVideo = $this->pSet->isUseVideo();
$this->strCaption = GetTableCaption(GoodFieldName($this->tName));
$this->tableType = $this->pSet->getTableType();
$this->isAddWebRep = GetGlobalData("isAddWebRep",false);
// get details keys by master table
$this->detailKeysByM = $this->getDetailKeysByMasterTable();
$this->isDynamicPerm = GetGlobalData("isDynamicPerm",false);
$this->isResizeColumns = $this->pSet->isResizeColumns();
$this->isUseAjaxSuggest = $this->pSetSearch->isUseAjaxSuggest();
// get all details table for current table
if ( $this->mode != LIST_MASTER )
$this->allDetailsTablesArr = $this->pSet->getDetailTablesArr();
// set template file
$this->setTemplateFile();
if($this->pageLayout)
{
$this->jsSettings['tableSettings'][$this->tName]['pageSkinStyle'] = array();
$this->jsSettings['tableSettings'][$this->tName]['pageSkinStyle'][ $this->pageType ] = $this->pageLayout->style." page-".$this->pageLayout->name;
$this->AddCSSFile( $this->pageLayout->getCSSFiles(isRTL(), isPageLayoutMobile( $this->templatefile ), $this->pdfMode != "" ) );
// show all forms by default
if( $this->getLayoutVersion() === PD_BS_LAYOUT )
{
$helper =& $this->pSet->helperFormItems();
$formItems =& $helper["formItems"];
foreach( array_keys($formItems) as $l ) {
$this->xt->assign( $l . "_block", true );
}
}
}
if( $this->mobileTemplateMode() )
{
$this->recsPerRowList = 1;
$this->isScrollGridBody = false;
$this->listAjax = false;
$this->isUseAjaxSuggest = false;
}
// init jsSettings
$this->jsSettings = array();
$this->jsSettings["tableSettings"] = array();
$this->jsSettings["tableSettings"][$this->tName] = array();
$this->jsSettings["tableSettings"][$this->tName]["proxy"] = array("proxy" => "");
$this->jsSettings["tableSettings"][$this->tName]['fieldSettings'] = array();
$this->settingsMap["globalSettings"]["webRootPath"] = projectPath();
// projectRoot is used for cookies and local storage
$this->settingsMap["globalSettings"]["projectRoot"] = projectPath();
$this->settingsMap["globalSettings"]["ext"] = "##@ext##";
$this->settingsMap["globalSettings"]["charSet"] = $cCharset;
$this->settingsMap["globalSettings"]["curretLang"] = mlang_getcurrentlang(); // need for Runner.getGoogleLanguage() see Issue #10990
$this->settingsMap["globalSettings"]["debugMode"] = $this->debugJSMode;
$this->settingsMap["globalSettings"]["googleMapsApiCode"] = $this->googleMapCfg['APIcode'];
$this->settingsMap["globalSettings"]["shortTNames"][$this->tName] = $this->shortTableName;
$this->settingsMap["globalSettings"]["useCookieBanner"] = $this->isPD() && GetGlobalData("useCookieBanner", false );
$this->settingsMap["globalSettings"]["cookieBanner"] = Labels::getCookieBanner();
$this->settingsMap["globalSettings"]["projectBuildKey"] = $projectBuildKey;
$this->settingsMap["globalSettings"]["wizardBuildKey"] = $wizardBuildKey;
$globalPopupPagesLayoutNames = GetGlobalData("popupPagesLayoutNames", array());
if( !$this->mobileTemplateMode() && count( $globalPopupPagesLayoutNames ) )
$this->settingsMap["globalSettings"]["popupPagesLayoutNames"] = $globalPopupPagesLayoutNames;
##if @BUILDER.nLoginMethod==SECURITY_AD##
if ($this->mode == RIGHTS_PAGE)
$this->settingsMap["globalSettings"]["shortTNames"]["admin_admembers"] = "admin_admembers";
//Active Directory
$this->settingsMap["globalSettings"]["isAD"] = true;
##endif##
$this->settingsMap["globalSettings"]["isMobile"] = $this->mobileTemplateMode();
$this->settingsMap["globalSettings"]["mobileDeteced"] = detectMobileDevice();
// s508 must be in global settings
$this->settingsMap['globalSettings']['s508'] = $this->is508;
$this->settingsMap['globalSettings']['mapProvider'] = $this->mapProvider;
$this->settingsMap['globalSettings']['staticMapsOnly'] = $this->pageType == PAGE_PRINT;
$this->settingsMap["globalSettings"]["locale"] = array();
$this->settingsMap["globalSettings"]["locale"]["dateFormat"] = $locale_info["LOCALE_IDATE"];
$this->settingsMap["globalSettings"]["locale"]["langName"] = $locale_info["LOCALE_LANGNAME"];
$this->settingsMap["globalSettings"]["locale"]["ctryName"] = $locale_info["LOCALE_CTRYNAME"];
$this->settingsMap["globalSettings"]["locale"]["startWeekDay"] = $locale_info["LOCALE_IFIRSTDAYOFWEEK"];
$this->settingsMap["globalSettings"]["locale"]["dateDelimiter"] = $locale_info["LOCALE_SDATE"];
$this->settingsMap["globalSettings"]["locale"]["is24hoursFormat"] = $locale_info["LOCALE_ITIME"];
$this->settingsMap["globalSettings"]["locale"]["leadingZero"] = $locale_info["LOCALE_ITLZERO"];
$this->settingsMap["globalSettings"]["locale"]["timeDelimiter"] = $locale_info["LOCALE_STIME"];
$this->settingsMap["globalSettings"]["locale"]["timePmLetter"] = $locale_info["LOCALE_S2359"];
$this->settingsMap["globalSettings"]["locale"]["timeAmLetter"] = $locale_info["LOCALE_S1159"];
$this->settingsMap["globalSettings"]["showDetailedError"] = GetGlobalData("showDetailedError", true);
$this->settingsMap["globalSettings"]["customErrorMessage"] = GetGlobalData("customErrorMessage", "");
$this->settingsMap["tableSettings"] = array();
$this->settingsMap['tableSettings']['entityType'] = array("default"=> 0 , "jsName"=>"entityType" );
$this->settingsMap['tableSettings']['hasEvents'] = array("default"=>false,"jsName"=>"hasEvents");
$this->settingsMap["tableSettings"]["strCaption"] = array("default"=>"","jsName"=>"strCaption");
$this->settingsMap["tableSettings"]["isUseAudio"] = array("default"=>false,"jsName"=>"isUseAudio"); //fix it
$this->settingsMap["tableSettings"]["isUseVideo"] = array("default"=>false,"jsName"=>"isUseVideo");
$this->settingsMap['tableSettings']['listGridLayout'] = array("default"=> gltHORIZONTAL, "jsName"=>"listGridLayout");
$this->settingsMap["tableSettings"]["rowHighlite"] = array("default"=>false,"jsName"=>"isUseHighlite");
$this->settingsMap["tableSettings"]["isUseToolTips"] = array("default"=>false,"jsName"=>"isUseToolTips");
$this->settingsMap['tableSettings']['recsPerRowList'] = array("default"=>1,"jsName"=>"recsPerRowList");
$this->settingsMap["tableSettings"]["showAddInPopup"] = array("default"=>false, "jsName"=>"showAddInPopup");
$this->settingsMap["tableSettings"]["showEditInPopup"] = array("default"=>false,"jsName"=>"showEditInPopup");
$this->settingsMap["tableSettings"]["showViewInPopup"] = array("default"=>false,"jsName"=>"showViewInPopup");
$this->settingsMap["tableSettings"]["updateSelected"] = array("default"=>false,"jsName"=>"updateSelected");
$this->settingsMap["tableSettings"]["isResizeColumns"] = array("default"=>false,"jsName"=>"isUseResize");
$this->settingsMap["tableSettings"]["detailsLinksOnList"] = array("default"=>DL_SINGLE,"jsName"=>"detailsLinksOnList");
$this->settingsMap["tableSettings"]["isDisplayLoading"] = array("default"=>false, "jsName"=>"displayLoading");
//if the Search panel added to the non table based page ajax suggests should be configured according to the search table's settings
$ajaxSuggestDefault = $this->tableBasedSearchPanelAdded ? !$this->isUseAjaxSuggest : true;
$this->settingsMap["tableSettings"]["isUseAjaxSuggest"] = array("default"=>$ajaxSuggestDefault,"jsName"=>"ajaxSuggest");
$this->settingsMap["tableSettings"]["pages"] = array("default"=>array(),"jsName"=>"pages");
$this->settingsMap["tableSettings"]["Keys"] = array("default"=>array(),"jsName"=>"keyFields");
$this->controlsMap["oldLayout"] = $this->isOldLayout();
$this->controlsMap["layoutVersion"] = $this->getLayoutVersion();
$this->controlsMap["layoutName"] = $this->getLayoutName();
$this->controlsMap["pageTable"] = $this->pSet->pageTable();
$this->settingsMap["fieldSettings"] = array();
$this->settingsMap["fieldSettings"]["UseTimestamp"] = array("default"=>false,"jsName"=>"isUseTimeStamp");
$this->settingsMap["fieldSettings"]["strName"] = array("default"=>"","jsName"=>"strName");
$this->settingsMap["fieldSettings"]["ShowTime"] = array("default"=>false,"jsName"=>"showTime");
$this->settingsMap["fieldSettings"]["EditFormat"] = array("default"=>"","jsName"=>"editFormat");
$this->settingsMap["fieldSettings"]["DateEditType"] = array("default"=>EDIT_DATE_SIMPLE,"jsName"=>"dateEditType");
$this->settingsMap["fieldSettings"]["RTEType"] = array("default"=>"","jsName"=>"RTEType");
$this->settingsMap["fieldSettings"]["ViewFormat"] = array("default"=>"","jsName"=>"viewFormat");
$this->settingsMap["fieldSettings"]["validateAs"] = array("default"=>null,"jsName"=>"validation");
$this->settingsMap["fieldSettings"]["strEditMask"] = array("default"=>null,"jsName"=>"mask");
$this->settingsMap["fieldSettings"]["LastYearFactor"] = array("default"=>10,"jsName"=>"lastYear");
$this->settingsMap["fieldSettings"]["InitialYearFactor"] = array("default"=>100,"jsName"=>"initialYear");
$this->settingsMap["fieldSettings"]["ShowListOfThumbnails"] = array("default"=>false,"jsName"=>"showListOfThumbnails");
$this->settingsMap["fieldSettings"]["ImageWidth"] = array("default"=>0,"jsName"=>"imageWidth");
$this->settingsMap["fieldSettings"]["ImageHeight"] = array("default"=>0,"jsName"=>"imageHeight");
$this->settingsMap["fieldSettings"]["weekdays"] = array("default"=>"","jsName"=>"weekdays");
$this->settingsMap["fieldSettings"]["weekdayMessage"] = array("default"=>"","jsName"=>"weekdayMessage");
if( $this->pageType == PAGE_VIEW )
$this->settingsMap["fieldSettings"]["fieldViewEvents"] = array("default"=>false,"jsName"=>"events");
else
$this->settingsMap["fieldSettings"]["fieldEvents"] = array("default"=>false,"jsName"=>"events");
$this->jsSettings["tableSettings"][$this->tName]["strCaption"] = $this->strCaption;
$this->jsSettings["tableSettings"][$this->tName]["pageMode"] = $this->mode;
$this->jsSettings["tableSettings"][$this->tName]["defaultPages"] = $this->pSet->getDefaultPages();
if ($this->listAjax)
$this->jsSettings['tableSettings'][$this->tName]['pageMode'] = LIST_AJAX;
if($this->lockingObj)
$this->jsSettings['tableSettings'][$this->tName]['locking'] = true;
if( $this->warnLeavingPages && ($this->pageType ==PAGE_REGISTER || $this->pageType ==PAGE_ADD || $this->pageType ==PAGE_EDIT) )
$this->jsSettings['tableSettings'][$this->tName]['warnOnLeaving'] = true;
//If current table has detail tables
if(count($this->allDetailsTablesArr))
{
if($this->pageType==PAGE_LIST)
$this->jsSettings['tableSettings'][$this->tName]['detailTables'] = array();
$this->jsSettings['tableSettings'][$this->tName]['isShowDetails'] = $this->isShowDetailTables;
for($i = 0; $i < count($this->allDetailsTablesArr); $i ++)
{
$dTable = $this->allDetailsTablesArr[$i]['dDataSourceTable'];
$dPset = new ProjectSettings( $dTable );
$this->settingsMap["globalSettings"]['shortTNames'][ $this->allDetailsTablesArr[$i]['dDataSourceTable'] ] = $this->allDetailsTablesArr[$i]['dShortTable'];
$dPermission = $this->getPermissions( $this->allDetailsTablesArr[$i]['dDataSourceTable'] );
$this->permis[$this->allDetailsTablesArr[$i]['dDataSourceTable']] = $dPermission;
// field names of master keys of current table for passed details table name
$this->masterKeysByD[$i] = $this->allDetailsTablesArr[$i]['masterKeys'];
if(($this->pageType == PAGE_LIST) || ($this->pageType == PAGE_REPORT) || ($this->pageType == PAGE_CHART))
{
unset($_SESSION[$this->allDetailsTablesArr[$i]['dDataSourceTable'].'_advsearch']);
$dPermission = $this->getPermissions( $this->allDetailsTablesArr[$i]['dDataSourceTable'] );
if( $dPermission["search"] )
{
$this->jsSettings['tableSettings'][$this->tName]['detailTables'][ $this->allDetailsTablesArr[$i]['dDataSourceTable'] ] =
array(
'pageType' => $this->allDetailsTablesArr[$i]['dType'],
'dispChildCount' => $this->pSet->detailsShowCount( $dTable ),
'hideChild' => $this->pSet->detailsHideEmpty( $dTable ),
'listShowType'=> $this->pSet->detailsPreview( $dTable ),
'addShowType' => $this->pSet->detailsPreview( $dTable ),
'editShowType' => $this->pSet->detailsPreview( $dTable ),
'viewShowType' => $this->pSet->detailsPreview( $dTable ),
'proceedLink' => $this->pSet->detailsProceedLink( $dTable ),
'label'=> GetTableCaption( GoodFieldName( $this->allDetailsTablesArr[$i]['dDataSourceTable'] ) ),
'pageId' => $this->pSet->detailsPageId( $dTable ),
'hideEmptyPreview' => $this->pSet->detailsHideEmptyPreview( $dTable ),
);
}
if( $this->pSet->detailsPreview( $dTable ) == DP_POPUP )
$this->jsSettings['tableSettings'][$this->tName]['isUsePopUp'] = true;
}
}
if( ($this->pageType==PAGE_ADD || $this->pageType==PAGE_EDIT) && $this->isShowDetailTables )
$this->controlsMap["dControlsMap"] = array();
}
$this->controlsMap["video"] = array();
$this->controlsMap['toolTips'] = array();
$this->addLookupSettings();
$this->addMultiUploadSettings();
$this->controlsMap["searchPanelActivated"] = $this->searchPanelActivated;
if($this->pageType != PAGE_LIST || $this->mode != LIST_DETAILS)
{
$this->controlsMap["controls"] = array();
if( !($this->pageType == PAGE_ADD && $this->mode == ADD_INLINE) && !($this->pageType == PAGE_EDIT && $this->mode == EDIT_INLINE) )
{
if( $this->getLayoutVersion() === PD_BS_LAYOUT )
$allSearchFields = $this->pSet->getAllSearchFields();
else
$allSearchFields = $this->pSetSearch->getAllSearchFields();
$this->controlsMap["search"] = array();
$this->controlsMap["search"]["searchBlocks"] = array();
$this->controlsMap["search"]["allSearchFields"] = $allSearchFields;
$this->controlsMap["search"]["allSearchFieldsLabels"] = $this->getSearchFieldsLabels( $allSearchFields );
$this->controlsMap["search"]["panelSearchFields"] = $this->pSet->getPanelSearchFields();
$this->controlsMap["search"]["googleLikeFields"] = $this->pSet->getGoogleLikeFields();
$this->controlsMap["search"]["inflexSearchPanel"] = !$this->pSet->isFlexibleSearch();
$this->controlsMap["search"]["requiredSearchFields"] = $this->pSet->getSearchRequiredFields();
$this->controlsMap["search"]["isSearchRequired"] = $this->pSet->noRecordsOnFirstPage();
$this->controlsMap["search"]["searchTableName"] = $this->searchTableName;
$this->controlsMap["search"]["shortSearchTableName"] = $this->pSetSearch->getShortTableName();
if($this->pageType!=PAGE_SEARCH)
$this->controlsMap["search"]["submitPageType"] = $this->pageType;
else
{
if(postvalue("rname")){
$this->controlsMap["search"]["submitPageType"] = "dreport";
$this->controlsMap["search"]["baseParams"]["rname"] = postvalue("rname");
if($_SESSION["crossLink"])
{
if(substr($_SESSION["crossLink"],0,1)=="&")
$_SESSION["crossLink"]=substr($_SESSION["crossLink"],1);
$alink=explode("&",$_SESSION["crossLink"]);
foreach($alink as $param)
{
$arrtmp=explode("=",$param);
$this->controlsMap["search"]["baseParams"][$arrtmp[0]] = $arrtmp[1];
}
}
}elseif(postvalue("cname")){
$this->controlsMap["search"]["submitPageType"] = "dchart";
$this->controlsMap["search"]["baseParams"]["cname"] = postvalue("cname");
}else{
$this->controlsMap["search"]["submitPageType"] = $this->tableType;
}
}
}
}
$this->isUseToolTips = $this->isUseToolTips || $this->pSet->isUseToolTips();
$this->googleMapCfg["APIcode"] = "##@BUILDER.strGoogleApiKey s##";
$this->processMasterKeyValue();
if ( $this->masterTable )
{
$this->pageData[ "masterTable" ] = $this->masterTable;
$this->pageData[ "masterKeys" ] = $this->getMasterKeysParams();
$this->pageData[ "masterPageName" ] = $this->getMasterPageName();
}
// set default grid tabs - They can be changed in events
$this->gridTabs = $this->pSet->getGridTabs();
$this->assignSearchLogger();
}
/**
* limit row count
*
* @param Integer $rowCount
* @param Object $pSet
* @return Integer
*/
function limitRowCount( $rowCount, $pSet = null ) {
if ( is_null($pSet) )
$pSet = $this->pSet;
return $pSet->getRecordsLimit() && $rowCount > $pSet->getRecordsLimit() ? $pSet->getRecordsLimit() : $rowCount;
}
/**
* Get tab by tabId
*
* @param String $tabId
* @return Array
*/
function getGridTab($tabId)
{
foreach ( $this->gridTabs as $tab )
{
if ( $tab["tabId"] === $tabId )
return $tab;
}
return false;
}
function getCurrentTab()
{
if( !$this->gridTabs )
return false;
// find tab with current id
$tab = $this->getGridTab( $_SESSION[ $this->sessionPrefix . "_currentTab" ] );
if( $tab )
{
if( !$tab['hidden'] )
return $tab;
}
// find tab with empty id
$tab = $this->getGridTab( "" );
if( $tab )
{
if( !$tab['hidden'] )
return $tab;
}
// return first available tab
for( $i=0; $i< count( $this->gridTabs ); ++$i )
{
if( !$this->gridTabs[$i]['hidden'] )
return $this->gridTabs[$i];
}
return $this->gridTabs[0];
}
function getCurrentTabWhere()
{
if( $this->tabChangeling === null )
$currentTab = $this->getCurrentTab();
else
$currentTab = $this->getGridTab( $this->tabChangeling );
if( $currentTab ) {
return DB::PrepareSQL( $currentTab["where"] );
}
return "";
}
function getCurrentTabId()
{
$currentTab = $this->getCurrentTab();
if( $currentTab ) {
return $currentTab["tabId"];
}
return "";
}
function setCurrentTabId( $tabId )
{
$_SESSION[ $this->sessionPrefix . "_currentTab" ] = $tabId;
}
function prepareGridTabs()
{
// delete master-dependent tabs
if( !$this->masterTable )
{
foreach ($this->gridTabs as $key => $tab )
{
$masterTokent = DB::readMasterTokens( $tab["where"] );
if ( count($masterTokent) > 0 )
unset($this->gridTabs[$key]);
}
}
// calculate row counts. Mark tabs as hidden
if( $this->gridTabsAvailable() )
{
for ( $i=0; $i < count( $this->gridTabs ); ++$i )
{
$tab = $this->gridTabs[$i];
if ( $tab['showRowCount'] || $tab['hideEmpty'] )
{
$this->gridTabs[$i][ 'count' ] = $this->getRowCountByTab( $tab["tabId"] );
if( $tab['hideEmpty'] && !$this->gridTabs[$i][ 'count' ] )
$this->gridTabs[$i][ 'hidden' ] = true;
}
}
}
}
function getTabsHtml()
{
$currentTab = $this->getCurrentTab();
$tabs = array();
foreach ($this->gridTabs as $key => $tab )
{
$linkAttrs = array();
$getParams = array();
$getParams[] = "tab=" . $tab["tabId"];
$getParams[] = $this->getStateUrlParams();
if( $this->pageName != $defaultPage )
$getParams[] = "page=" . $this->pageName;
$linkAttrs[] = 'href="' . GetTableLink($this->shortTableName, $this->pageType, implode( '&', $getParams ) ) . '"';
$linkAttrs[] = 'data-pageid="' . $this->id . '"';
$linkAttrs[] = 'data-tabid="' . $tab["tabId"] . '"';
$tabAttrs = array();
if( $currentTab["tabId"] === $tab["tabId"] )
$tabAttrs[] = 'class="active"';
if ( $tab['hidden'] )
{
$tabAttrs[] = 'data-hidden';
}
$countRowHtml = $tab['showRowCount'] ? " (" . $tab['count'] . ")" : "";
$tabs[] = '
'.$this->getTabTitle($tab['tabId']) . $countRowHtml . '';
}
return implode("", $tabs);
}
/**
* Returns number of visible grid tabs
* @return Integer
*/
public function getGridTabsCount()
{
$tcount = 0;
foreach ($this->gridTabs as $key => $tab )
{
if ( !$tab['hidden'] )
++$tcount;
}
return $tcount;
}
/**
* Process grid tabs
*
*/
function processGridTabs()
{
$this->pageData['gridTabs'] = "";
$tabId = $this->getCurrentTabId();
$this->prepareGridTabs();
if ( count($this->gridTabs) <= 1 )
return;
$html = $this->getTabsHtml();
$this->pageData['gridTabs'] = $html;
$this->pageData['tabId'] = $this->getCurrentTabId();
if( $this->displayTabsInPage() )
{
$this->xt->assign('grid_tabs', true);
$this->xt->assign('grid_tabs_content', $html );
}
return $tabId != $this->pageData['tabId'];
}
function addTab($where, $title, $tabId)
{
if ( $this->getGridTab($tabId) !== false )
return false;
$this->gridTabs[] = array(
'tabId' => $tabId,
'name' => $title,
'nameType' => "Text",
'where' => $where
);
return true;
}
function deleteTab($tabId)
{
$deleteKey = false;
foreach ($this->gridTabs as $key => $tab)
{
if ( $tab["tabId"] === $tabId )
{
$deleteKey = $key;
break;
}
}
if( $deleteKey !== false)
unset( $this->gridTabs[ $deleteKey ] );
}
function setTabTitle($tabId, $title)
{
foreach ($this->gridTabs as $key => $tab)
{
if ( $tab["tabId"] === $tabId )
{
$this->gridTabs[$key]['name'] = $title;
$this->gridTabs[$key]['nameType'] = "Text";
return true;
}
}
return false;
}
function setTabWhere($tabId, $where)
{
foreach ($this->gridTabs as $key => $tab)
{
if ( $tab["tabId"] === $tabId )
{
$this->gridTabs[$key]['where'] = $where;
return true;
}
}
return false;
}
function getTabTitle($tabId)
{
$tab = $this->getTabInfo( $tabId );
if( !$tab )
return false;
if ( $tab['nameType'] !== "Text" )
return GetCustomLabel($tab['name']);
return $tab['name'];
}
function getTabInfo( $tabId )
{
foreach ($this->gridTabs as $key => $tab)
{
if ( $tab["tabId"] === $tabId )
return $tab;
}
return null;
}
function getTabFlags($tabId)
{
$flags = array();
$tab = $this->getGridTab($tabId);
if ( !$tab )
return false;
$flags["showCount"] = $tab["showRowCount"];
$flags["hideEmpty"] = $tab["hideEmpty"];
return $flags;
}
function setTabFlags($tabId, $flags)
{
foreach ($this->gridTabs as $key => $tab)
{
if ( $tab["tabId"] === $tabId )
{
if ( isset($flags["showCount"]) )
$this->gridTabs[$key]['showRowCount'] = $flags["showCount"];
if ( isset($flags["showCount"]) )
$this->gridTabs[$key]['hideEmpty'] = $flags["hideEmpty"];
return true;
}
}
return false;
}
/**
* get locking object
* @retunr Mixed
*/
protected function getLockingObject()
{
return GetLockingObject( $this->tName );
}
/**
* Check is dashboard element
*/
function isDashboardElement()
{
if ( $this->dashElementName == "" )
{
return false;
}
return true;
}
/**
* Init the page's functionality.
* The method is invoked just after the constructor has been called
*/
function init()
{
if( $this->xt )
$this->xt->assign("pagetitle", $this->getPageTitle(
$this->pageName,
$this->tName == GLOBAL_PAGES ? "" : GoodFieldName($this->tName),
null,
null,
false
));
//build the Search panel if the "searchpanel" brick is added to the page's layout
$this->buildAddedSearchPanel();
##if @BUILDER.bCreateLoginPage##
$this->initLogin();
##endif##
if( $this->pageType == PAGE_LIST && ($this->mode == LIST_AJAX || $this->mode == LIST_SIMPLE || $this->mode == LIST_LOOKUP) || $this->pageType == PAGE_DASHBOARD
|| ( $this->pageType == PAGE_REPORT && $this->mode === REPORT_SIMPLE || $this->pageType == PAGE_CHART && $this->mode == CHART_SIMPLE ) )
{
$filterPanelVisible = $this->buildFilterPanel();
if( !$filterPanelVisible ) {
$this->hideElement("filterpanel");
}
}
}
/**
* Set the 'connection' property if the table is page based #9875
*/
protected function setTableConnection()
{
global $cman;
if( $this->tName != GLOBAL_PAGES )
$this->connection = $cman->byTable( $this->tName );
}
protected function setDataSource()
{
$this->dataSource = getDataSource( $this->tName, $this->pSet, $this->connection );
}
public function getDataSource()
{
return $this->dataSource;
}
/**
* Set the 'cipherer' property
*/
protected function assignCipherer()
{
$this->cipherer = new RunnerCipherer($this->tName, $this->pSet);
}
/**
* Init login form
*/
function initLogin()
{
global $cLoginTable;
$this->settingsMap["globalSettings"]["twoFactorAuth"] = GetGlobalData("bTwoFactorAuth", false);
$this->settingsMap["globalSettings"]["loginFormType"] = $this->pSet->getLoginFormType();
if( $this->mobileTemplateMode() )
$this->settingsMap["globalSettings"]["loginFormType"] = LOGIN_SEPARATE;
$this->settingsMap["globalSettings"]["loginTName"] = $cLoginTable;
$this->xt->assign("security_block", true);
// The user might rewrite $_SESSION["UserName"] value with HTML code in an event, so no encoding will be performed while printing this value.
$this->xt->assign("username", $_SESSION["UserName"]);
$this->xt->assign("logoutlink_attrs", 'id="logoutButton'.$this->id.'"');
$loggedAsGuest = isLoggedAsGuest();
$this->xt->assign("loggedas_message", !$loggedAsGuest);
$this->xt->assign("guestloginbutton", $loggedAsGuest);
$this->xt->assign("logoutbutton", isSingleSign() && !$loggedAsGuest);
if( $this->isPD() )
{
$this->xt->assign("guest_register", $loggedAsGuest);
}
if($this->mobileTemplateMode())
{
$this->xt->assign("guestloginlink_attrs", 'id="loginButton'.$this->id.'"');
return;
}
$this->xt->assign("guestloginlink_attrs", 'id="loginButton'.$this->id.'"');
if( $this->pSet->getLoginFormType() == LOGIN_EMBEDED ) {
if( !$this->mobileTemplateMode() )
{
$this->xt->assign("embeded_log_fields", true);
$this->xt->assign("embeded_log_ctrls", true);
if( $this->isPD() )
{
$this->xt->assign("embeded_username", $loggedAsGuest);
$this->xt->assign("embeded_password", $loggedAsGuest);
if( $loggedAsGuest )
{
$this->xt->assign("username_attrs", 'id="username'.$this->id.'" placeholder="login"');
$this->xt->assign("password_attrs", 'id="password'.$this->id.'" placeholder="password"');
}
}
else
{
$this->xt->assign("username_attrs", 'id="username" placeholder="login"');
$this->xt->assign("password_attrs", 'id="password" placeholder="password"');
}
$rememberbox_attrs = 'id="remember_password" name="remember_password" value="1"';
if( @$_COOKIE["token"] )
$rememberbox_attrs.= " checked";
$this->xt->assign("rememberbox_attrs", $rememberbox_attrs);
}
else
{
$this->xt->assign("embeded_log_fields", false);
$this->xt->assign("embeded_log_ctrls", false);
if( $this->isPD() )
{
$this->xt->assign("embeded_username", false);
$this->xt->assign("embeded_password", false);
}
}
}
}
/**
* @return Mixed
*/
protected function getSqlPreparedLoginTableValue( $value, $fName, $fieldType, $cipherer = null )
{
if( !$cipherer )
$cipherer = $this->cipherer;
if( $cipherer->isFieldEncrypted( $fName ) )
return $cipherer->MakeDBValue( $fName, $value, "", true );
if( NeedQuotes( $fieldType ) )
return $this->connection->prepareString( $value );
return 0 + $value;
}
/**
* @param String strPassword
* @return String
*/
public function getPasswordHash( $strPassword )
{
##if @BUILDER.Registration.nEncryptPasswordMethod == 0##
return getPasswordHash( $strPassword );
##else##
return md5( $strPassword );
##endif##
}
/**
* Makes assigns for admin
*/
function assignAdmin()
{
if($this->isAdminTable())
{
$this->xt->assign("exitadminarea_link", true);
$this->xt->assign("exitaalink_attrs", "id=\"exitAdminArea".$this->id."\"");
}
if($this->isDynamicPerm && IsAdmin())
{
$this->xt->assign("adminarea_link", true);
$this->xt->assign("adminarealink_attrs", "id=\"adminArea".$this->id."\"");
}
}
protected function assignSessionPrefix()
{
$this->sessionPrefix = $this->tName;
}
/**
* Check if the 'Search saving' is enabled basing on
* the project settings and the current page's type
* @return Boolean
*/
public function isSearchSavingEnabled()
{
$searchSavingEnabled = $this->pSet->isSearchSavingEnabled();
if( !$searchSavingEnabled )
return false;
return $this->pageType == PAGE_LIST && ($this->mode == LIST_AJAX || $this->mode == LIST_SIMPLE)
|| $this->pageType == PAGE_REPORT && $this->mode == REPORT_SIMPLE
|| $this->pageType == PAGE_CHART && $this->mode == CHART_SIMPLE;
}
/**
* Assign the page's 'searchLogger' object
* if the 'Search saving' is enabled
*/
protected function assignSearchLogger()
{
if( !$this->searchSavingEnabled || !$this->searchClauseObj )
return;
include_once getabspath("classes/searchParamsLogger.##@ext##");
$this->searchLogger = new searchParamsLogger( $this->tName );
$this->jsSettings['tableSettings'][$this->tName]['searchSaving'] = true;
$savedSearches = $this->searchLogger->getSavedSeachesParams();
if( count($savedSearches) )
{
$this->pageHasSavedSearches = true;
$this->controlsMap["search"]["savedSearches"] = $savedSearches;
$this->controlsMap["search"]["savedSearchIsRun"] = $this->searchClauseObj->savedSearchIsRun;
}
$this->assignSearchSavingButtons();
}
/**
* @return Boolean
*/
public function processSaveSearch()
{
// Read Search parameters from the request
if( postvalue("saveSearch") && postvalue("searchName") && !is_null($this->searchLogger) )
{
$searchName = postvalue("searchName");
$searchParams = $this->getSearchParamsForSaving();
$this->searchLogger->saveSearch( $searchName, $searchParams );
$this->searchClauseObj->savedSearchIsRun = true;
$_SESSION[$this->sessionPrefix.'_advsearch'] = serialize( $this->searchClauseObj );
echo my_json_encode( $searchParams );
return true;
}
// Delete the saved search
if( postvalue("deleteSearch") && postvalue("searchName") && !is_null($this->searchLogger) )
{
$searchName = postvalue("searchName");
$this->searchLogger->deleteSearch( $searchName );
echo my_json_encode( array() );
return true;
}
return false;
}
/**
* Assign search saving buttons block
*/
protected function assignSearchSavingButtons()
{
$this->xt->assign('searchsaving_block', true);
if( $this->listAjax ) {
$this->xt->assign("saveSeachButton", true);
}
if( $this->searchClauseObj->isSearchFunctionalityActivated() ) {
$this->xt->assign("saveSeachButton", true);
if( $this->searchClauseObj->savedSearchIsRun ) {
$this->hideItemType( 'save_search' );
}
} elseif( $this->listAjax ) {
$this->hideItemType( 'save_search' );
}
$this->xt->assign("savedSeachesButton", true);
if( !$this->pageHasSavedSearches )
{
if( $this->isPD() )
$this->hideItemType('saved_searches');
else
$this->xt->assign('saveSearchButtonAttrs', $this->dispNoneStyle);
}
}
/**
* The searchClauseObj method wrapper
* @return Array
*/
public function getSearchParamsForSaving()
{
return $this->searchClauseObj->getSearchParamsForSaving();
}
/**
* Get the search fields labels array
* @param Array
* @return Array
*/
protected function getSearchFieldsLabels($searchFields)
{
$sFieldLabels = array();
foreach($searchFields as $sField)
{
$sFieldLabels[ $sField ] = $this->pSetSearch->label($sField);
}
return $sFieldLabels;
}
/**
* Add css rules
* Wrapper function
*
* @param &Array data
* @param &Array row
* @param &Array record
*/
function spreadRowStyles(&$data, &$row, &$record)
{
$this->spreadRowStyle($data, $row, $record);
$this->spreadRowCssStyle($data, $row, $record);
}
/**
* Add css rules to the record fields' "_style" elements if the row's "rowstyle" attribute is set
*
* @param &Array data
* @param &Array row
* @param &Array record
*/
protected function spreadRowStyle(&$data, &$row, &$record)
{
if(!array_key_exists("rowstyle",$row))
return;
$style = extractStyle($row["rowstyle"]);
if($style=="")
return;
foreach(array_keys($data) as $field)
{
$record[GoodFieldName($field)."_style"] = injectStyle($record[GoodFieldName($field)."_style"], $style);
}
}
/**
* Add css rules to the record fields' "_css" elements if the row's "style" attribute is set
*
* @param &Array data
* @param &Array row
* @param &Array record
*/
protected function spreadRowCssStyle(&$data, &$row, &$record)
{
if( !isset($row["style"]) )
return;
$style = $row["style"];
if( trim($style) == "" )
{
return;
}
foreach(array_keys($data) as $field)
{
$record[GoodFieldName($field)."_css"] = $style."; ".$record[GoodFieldName($field)."_css"];
}
}
/**
* Set the custom css rules for the current record in process adding
* corresponding css rules to the "row_css_rules" string property
*
* @param string $rowCssRule
*/
protected function setRowCssRule($rowCssRule)
{
$tdSelector = '[data-record-id="'.$this->recId.'"][data-pageid="' . $this->id . '"]';
$selectors = ' td'.$tdSelector.$tdSelector;
if( $this->listGridLayout == gltVERTICAL )
$selectors.= ' td';
$this->row_css_rules.= $selectors.'{'.$this->getCustomCSSRule( $rowCssRule ).'}';
}
/**
* Form a cell's custom css rule string
* @param String unprocessedCss
* @return String
*/
protected function getCustomCSSRule($unprocessedCss)
{
$cssRules = array();
$rules = explode(";", $unprocessedCss);
for($i = 0; $i < count($rules); $i++)
{
if(trim($rules[$i]) != "")
$cssRules[] = $rules[$i] . " !important" ;
}
return implode(";", $cssRules);
}
/**
* Check whether such a css rule exists. If It does get the existing class's name.
* If It doesn't form a new class name, add a rule to the "fieldCssRules" array and
* add a prepared css rule to the "cell_css_rules" string property
*
* @param String fieldCssRule
* @param String fieldName
* @return String
*/
protected function setFieldCssRule($fieldCssRule, $fieldName)
{
if( isset($this->fieldCssRules[ $fieldCssRule ]) )
return $this->fieldCssRules[ $fieldCssRule ];
$className = 'rnr-style'.$this->recId.'-'.$fieldName;
$this->fieldCssRules[ $fieldCssRule ] = $className;
if( $this->listGridLayout == gltVERTICAL )
$selectors = ' td[data-record-id][data-record-id][data-record-id][data-record-id] td.'.$className.', .'.$className . ':not([data-label-col])';
else
$selectors = ' td[data-record-id][data-record-id][data-record-id][data-record-id].'.$className.', .'.$className;
$this->cell_css_rules.= $selectors.'{'.$this->getCustomCSSRule( $fieldCssRule ).'}';
return $className;
}
/**
* Add a cells' custom style block at the beginning of grid_block
*/
function addCustomCss()
{
if( !$this->cell_css_rules && !$this->row_css_rules && !$this->mobile_css_rules )
return;
$gbl = $this->xt->getVar("grid_block");
if( $gbl )
{
$rules = $this->row_css_rules.$this->cell_css_rules."\n".$this->mobile_css_rules;
if( !is_array($gbl) )
$gbl = array("begin" => '');
else
$gbl["begin"] = $gbl["begin"]. '';
$this->xt->assign("grid_block", $gbl);
}
}
/**
* Set row css rules
*
* @param &Array $record
*/
function setRowCssRules(&$record)
{
if( $record["css"] )
$this->setRowCssRule( $record["css"] );
if( $record["hovercss"] )
$this->setRowHoverCssRule( $record["hovercss"] );
}
/**
* Set row class names
*
* @param &Array $record
* @param string $field
*/
function setRowClassNames(&$record, $field)
{
$gFieldName = GoodFieldName( $field );
$record[ $gFieldName."_class" ] .= $this->fieldClass( $field );
if( $record[ $gFieldName."_css" ] )
{
$className = $this->setFieldCssRule( $record[ $gFieldName."_css" ], $gFieldName );
$record[ $gFieldName."_class" ] .= " ".$className;
}
if( $record[ $gFieldName."_hovercss" ] )
{
$classNameHover = $this->setRowHoverCssRule( $record[ $gFieldName."_hovercss" ], $gFieldName );
if( $classNameHover !== $className)
$record[ $gFieldName."_class" ] .= " ".$classNameHover;
}
}
/**
* Get the page layout's name
* @return string
*/
function getLayoutName()
{
if($this->pageLayout)
return $this->pageLayout->style;
else
return "";
}
function getLayoutVersion()
{
if($this->pageLayout)
return $this->pageLayout->version;
else
return 2; // modern, non-bootstrap layout
}
function isBootstrap()
{
return $this->getLayoutVersion() >= BOOTSTRAP_LAYOUT;
}
function isPD()
{
return $this->getLayoutVersion() == PD_BS_LAYOUT;
}
/**
* addMultiUploadSettings
* Adding js-settings for FileField
* @intellisense
*/
function addMultiUploadSettings()
{
$this->settingsMap["fieldSettings"]["autoUpload"] = array("default"=>false, "jsName"=>"autoUpload");
$this->settingsMap["fieldSettings"]["acceptFileTypes"] = array("default"=>".+$", "jsName"=>"acceptFileTypes");
$this->settingsMap["fieldSettings"]["CompatibilityMode"] = array("default"=>false, "jsName"=>"compatibilityMode");
$this->settingsMap["fieldSettings"]["maxFileSize"] = array("default"=>null, "jsName"=>"maxFileSize");
$this->settingsMap["fieldSettings"]["maxTotalFilesSize"] = array("default"=>null, "jsName"=>"maxTotalFilesSize");
$this->settingsMap["fieldSettings"]["maxNumberOfFiles"] = array("default"=>1, "jsName"=>"maxNumberOfFiles");
}
/**
* Process master key value.
* Copy master keys values to SESSION
*/
function processMasterKeyValue()
{
// legacy #14869
if(count($this->masterKeysReq))
{
// copy keys to session
for($i = 1; $i <= count($this->masterKeysReq); $i++)
{
$_SESSION[$this->sessionPrefix."_masterkey".$i] = $this->masterKeysReq[$i];
}
if( isset($_SESSION[$this->sessionPrefix."_masterkey".$i]) )
unset($_SESSION[$this->sessionPrefix."_masterkey".$i]);
}
else
{
// read masterKeysReq from session
$this->masterKeysReq = array();
$i = 1;
while( isset( $_SESSION[$this->sessionPrefix."_masterkey".$i] ) ) {
$this->masterKeysReq[ $i ] = $_SESSION[$this->sessionPrefix."_masterkey".$i];
++$i;
}
}
if( $this->masterTable )
{
$_SESSION[ $this->masterTable . "_masterRecordData" ] = $this->getMasterRecord();
}
}
/**
* Display the 'Back to Master' link and master table info
*/
public function displayMasterTableInfo()
{
$masterTableData = $this->getMasterTableInfo();
if( !$masterTableData )
return;
$backButtonHref = GetTableLink( $masterTableData['mShortTable'], $masterTableData["type"], "a=return" );
if ( !$this->isBootstrap() )
{
$this->xt->assign("mastertable_block", true);
$this->xt->assign("backtomasterlink_attrs", "href=\"".$backButtonHref."\"");
$this->xt->assign("backtomasterlink_caption", GetTableCaption( GoodFieldName($masterTableData['mDataSourceTable']) ));
}
if( !$this->pSet->masterPreview($masterTableData['mDataSourceTable']) )
return;
if( ( $this->pageType == PAGE_PRINT || $this->pageType == PAGE_RPRINT || $this->pdfJsonMode() ) && $masterTableData["type"] == PAGE_CHART )
return;
$this->pageData["hasMasterList"] = true;
$detailKeys = $masterTableData['detailKeys'];
$masterKeys = array();
for($j = 0; $j < count($detailKeys); $j ++)
{
//$masterKeys[]= @$_SESSION[$this->sessionPrefix."_masterkey".($j + 1)];
$masterKeys[] = $this->masterKeysReq[ $j + 1 ];
}
$this->addMasterInfoJSAndCSS( $masterTableData["type"], $masterTableData["mDataSourceTable"], $masterTableData["mShortTable"] );
$master = array();
$mrData = $this->getListMasterRecordData( $masterTableData['mDataSourceTable'], $masterKeys );
$this->genId();
$params = array("detailtable" => $this->tName, "keys" => $masterKeys, "recId" => $this->recId, "masterRecordData" => $mrData);
$keys = array();
foreach( $this->pSet->getTableKeys() as $kf ) {
$keys[ $kf ] = @$this->masterRecordData[ $kf ];
}
$this->pageData["masterPageKeys"] = $keys;
$xt = new Xtempl();
//$xt->eventsObject = getEventObject( $masterTableData['mDataSourceTable'] ); //#13517 all snippets in $globalEvents
$mParams = array();
$mParams["xt"] = &$xt;
$mParams["flyId"] = $params["recId"];
$mParams["id"] = $params["recId"];
$mParams["masterRecordData"] = $mrData;
$mParams["pushContext"] = false;
$mParams["masterPageType"] = $masterTableData["type"];
$mPSet = new ProjectSettings( $mTName, PAGE_LIST );
$mParams["pageName"] = $mPSet->getDefaultPage( $masterTableData["type"] );
$mParams["tName"] = $masterTableData['mDataSourceTable'];
if( $this->pdfJsonMode() )
$mParams["pdfJson"] = true;
if( $this->pageType == PAGE_PRINT || $this->pageType == PAGE_RPRINT )
{
/*
if ( $mParams["masterPageType"] == PAGE_REPORT )
{
$mParams["pageType"] = PAGE_RPRINT;
}
else
{
$mParams["pageType"] = PAGE_PRINT;
}
*/
$mParams["pageType"] = "masterprint";
if( $mParams["masterPageType"] == PAGE_REPORT )
$mParams["pageType"] = "masterrprint";
$mParams["mode"] = PRINT_MASTER;
include_once(getabspath('classes/printpage.##@ext##'));
include_once(getabspath('classes/printpage_master.##@ext##'));
$masterPage = new PrintPage_Master( $mParams );
}
else
{
if( $mParams["masterPageType"] == PAGE_CHART )
{
$mParams["pageType"] = "masterchart";
// $mParams["pageType"] = PAGE_CHART;
$mParams["pageMode"] = CHART_SIMPLE;
include_once(getabspath('classes/chartpage.##@ext##'));
include_once(getabspath('classes/chartpage_master.##@ext##'));
$masterPage = new ChartPage_Master( $mParams );
}
else
{
$mParams["pageType"] = "masterlist";
// $mParams["pageType"] = $mParams["masterPageType"];
if( $mParams["masterPageType"] == PAGE_REPORT )
$mParams["pageType"] = "masterreport";
$mParams["mode"] = LIST_MASTER;
include_once(getabspath('classes/listpage.##@ext##'));
include_once(getabspath('classes/listpage_simple.##@ext##'));
include_once(getabspath('classes/listpage_master.##@ext##'));
$masterPage = ListPage::createListPage($masterTableData['mDataSourceTable'], $mParams);
}
}
RunnerContext::push( $masterPage->standaloneContext );
$masterPage->init();
if( !$masterPage->pSet->pageName() ) {
return;
}
$masterPage->preparePage();
foreach( $masterPage->pageData["buttons"] as $b ) {
$this->AddJSFile( "include/button_".$b.".js" );
}
$this->pageData["buttons"] = array_merge( $this->pageData["buttons"], $masterPage->pageData["buttons"] );
$this->xt->assign("mastertable_block", true);
$backButtonHref = GetTableLink( $masterTableData['mShortTable'], $masterTableData["type"], "a=return" );
if ( $this->isBootstrap() ) {
$masterPage->xt->assign("backtomasterlink_attrs", "href=\"".$backButtonHref."\"");
$masterPage->xt->assign("backtomasterlink_caption", GetTableCaption( GoodFieldName($masterTableData['mDataSourceTable']) ));
}
else
{
$this->xt->assign("backtomasterlink_attrs", "href=\"".$backButtonHref."\"");
$this->xt->assign("backtomasterlink_caption", GetTableCaption( GoodFieldName($masterTableData['mDataSourceTable']) ));
}
//$this->xt->assign("master_heading", $masterPage->getMasterHeading() );
$this->jsSettings["tableSettings"][$this->tName]["masterPageId"] = $masterPage->id;
$this->xt->assign_method("showmasterfile", $masterPage, "showMaster",array());
$this->addMasterMapsSettings( $masterTableData['mDataSourceTable'], $masterPage->recId, $mrData, $masterTableData["type"] );
$this->genId();
RunnerContext::pop();
}
/**
* Get master record data for display on master table info
* @param String mTName
* @param Array masterKeys
*/
public function getListMasterRecordData( $mTName, $masterKeys )
{
$detailtable = $this->tName;
$mCiph = new RunnerCipherer( $mTName );
$mPSet = new ProjectSettings( $mTName, PAGE_LIST );
$masterDs = getDataSource( $this->masterTable, $mPSet );
$filters = array();
$filters[] = Security::SelectCondition( "S", $mPSet );
foreach($mPSet->getDetailTablesArr() as $dt)
{
if( $dt["dDataSourceTable"] == $detailtable )
{
foreach( $dt["masterKeys"] as $i=>$mk )
{
$filters[] = DataCondition::FieldEquals( $mk, $masterKeys[ $i ] );
}
break;
}
}
$dc = new DsCommand;
$dc->filter = DataCondition::_And( $filters );
$dc->reccount = 1;
return $mCiph->DecryptFetchedArray( $masterDs->getList( $dc )->fetchAssoc() );
}
/**
* Add master maps settings
* @param String mTName master table name
* @param Number recId master record id
* @param &Array data master record data
*/
public function addMasterMapsSettings( $mTName, $recId, &$data, $mPageType )
{
if( $mPageType == PAGE_CHART )
return;
$masterType = "masterlist";
if( $mPageType == PAGE_REPORT )
$masterType = "masterreport";
else if( $this->isPD() && ( $this->pageType == PAGE_PRINT || $this->pageType == PAGE_RPRINT ) )
$masterType = "masterprint";
$mPSet = new ProjectSettings( $mTName, $masterType );
if( !count($data) )
return;
$haveMap = false;
foreach( $mPSet->getMasterListFields() as $fName )
{
$fieldMapData = $mPSet->getMapData( $fName );
if( !count($fieldMapData) )
continue;
$mapData = array();
$mapData['fName'] = $fName;
$mapData['zoom'] = isset( $fieldMapData['zoom'] ) ? $fieldMapData['zoom'] : '';
$mapData['type'] = 'FIELD_MAP';
$mapData['mapFieldValue'] = $data[ $fName ];
$address = $data[ $fieldMapData['address'] ] ? $data[ $fieldMapData['address'] ] : "";
$lat = str_replace(",", ".", ( $data[ $fieldMapData['lat'] ] ? $data[ $fieldMapData['lat'] ] : ''));
$lng = str_replace(",", ".", ($data[ $fieldMapData['lng'] ] ? $data[ $fieldMapData['lng'] ] : ''));
$desc = $data[ $fieldMapData['desc'] ] ? $data[ $fieldMapData['desc'] ] : $address;
$mapData['markers'][] = array(
'address' => $address,
'lat' => $lat,
'lng' => $lng,
/*'link' => $viewLink,*/
'desc' => $desc,
'keys' => $keys,
'mapIcon' => $mPSet->getMapIcon($fName, $data)
);
$mapId = 'littleMap_'.GoodFieldName( $fName ).'_'.$recId;
$this->googleMapCfg['mapsData'][ $mapId ] = $mapData;
$this->googleMapCfg['fieldMapsIds'][] = $mapId;
$haveMap = true;
}
if( $haveMap )
{
$this->googleMapCfg['isUseGoogleMap'] = true;
$this->googleMapCfg['isUseFieldsMaps'] = true;
}
}
/**
* Add to the page master info page's extra js/css files
* @param String mPageType the master page type
* @param String mTableName the master page data source table name
* @param String mShortTableName the master page short table name
*/
protected function addMasterInfoJSAndCSS( $mPageType, $mTableName, $mShortTableName )
{
if( $mPageType == PAGE_CHART )
$mastertype = "masterchart";
elseif( $mPageType == PAGE_REPORT )
$mastertype = "masterreport";
else
{
$mastertype = "masterlist";
if( $this->isPD() && ( $this->pageType == PAGE_PRINT || $this->pageType == PAGE_RPRINT ) )
$mastertype = "masterprint";
}
if( $mPageType != PAGE_CHART )
{
include_once getabspath('classes/controls/ViewControlsContainer.##@ext##');
$viewControls = new ViewControlsContainer(new ProjectSettings($mTableName, $mastertype), $mastertype);
$viewControls->addControlsJSAndCSS();
$this->includes_js = array_merge($this->includes_js, $viewControls->includes_js);
$this->includes_jsreq = array_merge($this->includes_jsreq, $viewControls->includes_jsreq);
$this->includes_css = array_merge($this->includes_css, $viewControls->includes_css);
$this->viewControlsMap['mViewControlsMap'] = $viewControls->viewControlsMap;
}
$layout = GetPageLayout( $mTableName, $mastertype );
if( $layout )
{
$layoutMobile = isPageLayoutMobile( GetTemplateName($mShortTableName, $mastertype) );
$this->AddCSSFile( $layout->getCSSFiles(isRTL(), $layoutMobile, $this->pdfMode != "" ) );
}
}
/**
* Get master record
* User API function
*
* @return Array
* @intellisense
*/
function getMasterRecord()
{
if( $this->masterRecordData )
return $this->masterRecordData;
if( !$this->masterTable )
return null;
$masterPSet = new ProjectSettings($this->masterTable, PAGE_LIST);
$masterDs = getDataSource( $this->masterTable, $masterPSet );
$filters = array();
$filters[] = Security::SelectCondition( "S", $masterPSet );
$masterTablesInfoArr = $this->pSet->getMasterTablesArr();
for($i=0; $i < count($masterTablesInfoArr); $i++)
{
if($this->masterTable == $masterTablesInfoArr[$i]['mDataSourceTable'])
{
$masterKeys = $this->getActiveMasterKeys();
for($j=0; $j < count($masterTablesInfoArr[$i]['masterKeys']); $j++)
{
$mKey = $masterTablesInfoArr[$i]['masterKeys'][$j];
$filters[] = DataCondition::FieldEquals( $mKey, $masterKeys[$j] );
}
}
}
$dc = new DsCommand;
$dc->filter = DataCondition::_And( $filters );
$dc->reccount = 1;
return $masterDs->getList( $dc )->fetchAssoc();
}
/**
* Returns the list of master key values read from either request or session
* @return Array
*/
function getActiveMasterKeys()
{
$i = 1;
$ret = array();
while(true)
{
if( isset( $this->masterKeysReq[$i] ) )
$ret[] = $this->masterKeysReq[$i];
/*else if( isset( $_SESSION[$this->sessionPrefix."_masterkey".$i] ) )
$ret[] = $_SESSION[$this->sessionPrefix."_masterkey".$i];*/
else
break;
++$i;
}
return $ret;
}
/**
* Set Proxy Value
* Fill array serverData for using in js OnLoad event
*
* User function
* Using only in events by users
*
* @param{string} name of data
* @param{string} value of data
* @intellisense
*/
function setProxyValue($name, $value)
{
if(!$name)
return;
$this->pageData["proxy"][$name] = $value;
}
/**
* Get Proxy Value
*
* User function
* Using only in events by users
*
* @param{string} name of data
* @return{}
* @intellisense
*/
function getProxyValue($name)
{
if(!$name)
return null;
return $this->pageData["proxy"][$name];
}
/**
* Set template file if it empty
* @intellisense
*/
function setTemplateFile()
{
if( isAdminPage( $this->pageTable) ) {
$this->templatefile = GetTemplateName( GetTableURL( $this->pageTable ), $this->pageType);
}
if(!$this->templatefile)
{
if( $this->pageName ) {
$pageId = $this->pageName;
} else {
$pageId = $this->pSet->getDefaultPage( $this->pageType );
}
$this->templatefile = GetTemplateName( GetTableURL( $this->pageTable ), $pageId);
}
$this->xt->set_template($this->templatefile);
}
/**
* Get menu nodes if use menu on page
* @intellisense
*/
function &getMenuNodes($name = 'main')
{
if(!count($this->menuNodes[$name]))
{
global $menuNodesObject;
$menuNodesObject = &$this;
require_once(getabspath("include/menunodes_".$name.".##@ext##"));
if($name == 'main')
{
getMenuNodes_main($menuNodesObject);
return $this->menuNodes[$name];
}
##if @BUILDER.bDynamicPermissions##
if($name == 'adminarea')
{
getMenuNodes_adminarea($menuNodesObject);
return $this->menuNodes[$name];
}
##endif##
##foreach @BUILDER.m_arrProjectMenus as @m##
if($name == '##@m.m_strMenuName##')
{
getMenuNodes_##@m.m_strMenuName s##($menuNodesObject);
return $this->menuNodes[$name];
}
##endfor##
}
return $this->menuNodes[$name];
}
/**
* Check is use menu on page
* @intellisense
*/
function menuAppearInLayout()
{
if( !$this->pageLayout )
return false;
$menuBricks = array('vmenu', 'vmenu_mobile', 'hmenu', 'bsmenu', 'quickjump');
foreach( $menuBricks as $b )
{
if( $this->isBrickSet( $b ) )
return true;
}
return false;
}
/**
* Check is need to show menu
* @intellisense
*/
function isShowMenu()
{
if( !$this->menuAppearInLayout() && $this->pageType != PAGE_MENU && $this->pageType != PAGE_ADD && $this->pageType != PAGE_VIEW && $this->pageType != PAGE_EDIT )
return false;
$allowedMenuItems = $this->getAllowedMenuItems();
if( $allowedMenuItems > 1 )
return true;
return false;
}
/**
* @param String menuName (optional)
* @return Number
*/
function getAllowedMenuItems( $menuName = "main" )
{
$menuNodes = $this->getMenuNodes( $menuName );
$allowedMenuItems = 0;
for($i = 0; $i < count($menuNodes); $i++)
{
if( $menuNodes[$i]["linkType"] == "Internal" )
{
if( $this->isUserHaveTablePerm($menuNodes[$i]["table"], $menuNodes[$i]["pageType"]) )
$allowedMenuItems++;
}
elseif( $menuNodes[$i]["linkType"] != "None" || $menuNodes[$i]["type"] != "Group" )
$allowedMenuItems++;
}
if( $this->isDynamicPerm && IsAdmin() && $this->pageType == PAGE_MENU )
$allowedMenuItems++;
if( $this->isAddWebRep )
$allowedMenuItems++;
return $allowedMenuItems;
}
/**
* Check if user have permission for link
* @param {string} table name
* @param {string} page type
* @return {boolean}
* @intellisense
*/
function isUserHaveTablePerm($tName, $pageType)
{
if( $tName === WEBREPORTS_TABLE )
return true;
if(!strlen($tName))
return false;
$type = $this->getPermisType($pageType);
$strPerm = GetUserPermissions($tName);
if( !strlen($type) ) //temporary #9784 fix
return false;
if(strpos($strPerm, $type) !== false)
return true;
return false;
}
/**
* Get type of permission
* @param String pageType
* @return String
* @intellisense
*/
function getPermisType($pageType)
{
$pageType = strtolower($pageType);
$type = '';
if ($pageType == "list" || $pageType == "view" || $pageType == "search" || $pageType == "report" || $pageType == "chart" || $pageType == "dashboard")
$type = "S";
elseif ($pageType == "add")
$type = "A";
elseif ($pageType == "edit")
$type = "E";
elseif ($pageType == "print" || $pageType == "export")
$type = "P";
elseif ($pageType == "import")
$type = "I";
return $type;
}
/**
* Clear session kyes
* @intellisense
*/
function clearSessionKeys()
{
if( ($this->pageType == PAGE_LIST || $this->pageType == PAGE_CHART || $this->pageType == PAGE_REPORT || $this->pageType == PAGE_DASHBOARD )
&& !count($_POST)
&& (
IsEmptyRequest()
|| @$_GET["editType"] == ADD_ONTHEFLY
)
)
{
$this->unsetAllPageSessionKeys();
}
if( $this->pageType == PAGE_LIST && ( $this->mode === LIST_DETAILS || $this->mode === LIST_LOOKUP )
|| ( $this->pageType == PAGE_REPORT && $this->mode != REPORT_SIMPLE || $this->pageType == PAGE_CHART && $this->mode != CHART_SIMPLE ) )
{
unset( $_SESSION[$this->sessionPrefix."_filters"] );
}
}
/**
* Unset all session keys started with the page's session prefix
* @param String sessionPrefix
*/
protected function unsetAllPageSessionKeys( $sessionPrefix = "" )
{
if( !$sessionPrefix )
$sessionPrefix = $this->sessionPrefix;
$prefixLength = strlen($sessionPrefix);
$sess_unset = array();
foreach($_SESSION as $key => $value)
{
if( substr($key, 0, $prefixLength + 1) == $sessionPrefix."_" && strpos(substr($key, $prefixLength + 1), "_") === false )
$sess_unset[] = $key;
}
foreach($sess_unset as $key)
{
unset( $_SESSION[ $key ] );
}
}
/**
* Set session variables
* @intellisense
*/
function setSessionVariables()
{
//clear session keys
$this->clearSessionKeys();
// Process master table value
//#14869 legacy
if( $this->masterTable != "" ) {
$_SESSION[$this->sessionPrefix."_mastertable"] = $this->masterTable;
}
else
{
$this->masterTable = $_SESSION[$this->sessionPrefix."_mastertable"];
}
// SearchClause class stuff
if( $this->needSearchClauseObj && !$this->searchClauseObj )
$this->searchClauseObj = $this->getSearchObject();
if( $this->searchSavingEnabled && $this->searchClauseObj )
$this->searchClauseObj->storeSearchParamsForLogging();
//set session page size
if(@$_REQUEST["pagesize"])
{
$_SESSION[$this->sessionPrefix."_pagesize"] = @$_REQUEST["pagesize"];
$_SESSION[$this->sessionPrefix."_pagenumber"] = 1;
}
//set page size
$this->pageSize = (integer) $_SESSION[$this->sessionPrefix."_pagesize"];
if ( isset($_REQUEST["tab"]) )
{
$_SESSION[ $this->sessionPrefix . "_currentTab" ] = postvalue("tab");
$_SESSION[$this->sessionPrefix."_pagenumber"] = 1;
}
}
/**
* Add lookup settings to settings map
* Use on list and add pages
* @intellisense
*/
function addLookupSettings()
{
$this->settingsMap["fieldSettings"]["parentFields"] = array("default" => array(), "jsName" => "parentFields");
$this->settingsMap["fieldSettings"]["LCType"] = array("default" => LCT_DROPDOWN, "jsName" => "lcType");
$this->settingsMap["fieldSettings"]["LookupTable"] = array("default" => "", "jsName" => "lookupTable");
$this->settingsMap["fieldSettings"]["SelectSize"] = array("default" => 1, "jsName" => "selectSize");
$this->settingsMap["fieldSettings"]["Multiselect"] = array("default" => false, "jsName" => "Multiselect");
$this->settingsMap["fieldSettings"]["LinkField"] = array("default" => "", "jsName" => "linkField");
$this->settingsMap["fieldSettings"]["DisplayField"] = array("default" => "", "jsName" => "dispField");
$this->settingsMap["fieldSettings"]["LookupOrderBy"] = array("default" => "", "jsName" => "lookupOrderBy");
$this->settingsMap["fieldSettings"]["LookupDesc"] = array("default" => false, "jsName" => "lookupDesc");
$this->settingsMap["fieldSettings"]["freeInput"] = array("default" => false, "jsName" => "freeInput");
$this->settingsMap["fieldSettings"]["HorizontalLookup"] = array("default" => false, "jsName" => "HorizontalLookup");
$this->settingsMap["fieldSettings"]["autoCompleteFields"] = array("default" => array(), "jsName" => "autoCompleteFields");
$this->settingsMap["fieldSettings"]["listPageId"] = array("default" => array(), "jsName" => "listPageId");
$this->settingsMap["fieldSettings"]["addPageId"] = array("default" => array(), "jsName" => "addPageId");
}
/**
* Fill global settings
* @intellisense
*/
function fillGlobalSettings()
{
$this->jsSettings["global"] = array();
foreach($this->settingsMap["globalSettings"] as $key => $val)
$this->jsSettings["global"][$key] = $val;
// start augment id from this value
$this->jsSettings["global"]['idStartFrom'] = $this->flyId;
}
/**
* Fill table settings
* @intellisense
*/
protected function fillTableSettings( $table = "", $pSet = null )
{
if( !$table )
{
$table = $this->tName;
$pSet = $this->pSet;
}
foreach($this->settingsMap["tableSettings"] as $key => $val)
{
if( !isset( $val["option"] ) )
$tData = $pSet->getTableData(".".$key);
else
$tData = $pSet->getPageOptionArray( $val["option"] );
$isDefault = false;
if(is_array($tData))
$isDefault = !count($tData);
else if(!is_array($val['default']))
$isDefault = ($tData == $val['default']);
if(!$isDefault)
$this->jsSettings['tableSettings'][ $table ][$val['jsName']] = $tData;
}
$this->jsSettings['global']['shortTNames'][ $table ] = GetTableURL( $table );
}
function addFieldsSettings($arrFields, $pSet, $pageBased, $pageType)
{
$tableJsSettings = & $this->jsSettings['tableSettings'][ $this->tName ];
foreach($arrFields as $fName)
{
if( !array_key_exists($fName, $tableJsSettings['fieldSettings'] ) )
$tableJsSettings['fieldSettings'][ $fName ] = array();
$fieldJsSettings = &$tableJsSettings['fieldSettings'][ $fName ];
if( !array_key_exists($pageType, $fieldJsSettings) )
$fieldJsSettings[ $pageType ] = array();
$fieldPageJsSettings = &$fieldJsSettings[ $pageType ];
$matchDK = $this->matchWithDetailKeys($fName) && $this->pageType != PAGE_SEARCH && $this->pageType != PAGE_LIST && $pageBased;
foreach($this->settingsMap["fieldSettings"] as $key => $val)
{
$fData = $pSet->getFieldData($fName, $key);
if( $key == "weekdayMessage" ) {
$fData = getCustomMessage( $fData );
}
if( $key == "DateEditType" && $this->isBootstrap() )
{
// search panel control
if( $pageType == PAGE_SEARCH && ( $this->pageType == PAGE_LIST || $this->pageType == PAGE_CHART || $this->pageType == PAGE_REPORT) ||
$this->pageType == PAGE_SEARCH && $this->mode == SEARCH_LOAD_CONTROL )
{
// show edit box date in search panel in Bootstrap layouts
if( $fData == EDIT_DATE_DD )
$fData = EDIT_DATE_SIMPLE;
else if( $fData == EDIT_DATE_DD_DP )
$fData = EDIT_DATE_SIMPLE_DP;
else if( $fData == EDIT_DATE_DD_INLINE )
$fData = EDIT_DATE_SIMPLE_INLINE;
}
}
if( $key == "validateAs" && !$matchDK )
{
if( $pageType == PAGE_ADD || $pageType == PAGE_EDIT || $pageType == PAGE_REGISTER || $pageType == PAGE_LOGIN )
$this->fillValidation($fData, $val, $fieldPageJsSettings);
continue;
}
if( $key == "EditFormat" )
{
if($matchDK)
$fData = EDIT_FORMAT_READONLY;
}
elseif( $key == "RTEType" )
{
$fData = $pSet->getRTEType($fName);
if($fData == "RTECK")
{
$this->isUseCK = true;
$fieldPageJsSettings['nWidth'] = $pSet->getNCols($fName);
$fieldPageJsSettings['nHeight'] = $pSet->getNRows($fName);
}
}
elseif( $key == "autoCompleteFields" )
$fData = $pSet->getAutoCompleteFields( $fName );
elseif( $key == "parentFields" )
$fData = $pSet->getLookupParentFNames( $fName );
$isDefault = false;
if( is_array($fData) )
$isDefault = !count($fData);
else if( !is_array($val['default']) )
$isDefault = $fData === $val['default'];
if( !$isDefault && !$matchDK )
$fieldPageJsSettings[ $val['jsName'] ] = $fData;
else if( $matchDK && ($key == "EditFormat" || $key == "strName" || $key == "autoCompleteFields" || $key == "LinkField") )
$fieldPageJsSettings[ $val['jsName'] ] = $fData;
}
$tableJsSettings['isUseCK'] = $this->isUseCK;
if( count($this->googleMapCfg) != 0 && $this->googleMapCfg['isUseGoogleMap'] )
{
$tableJsSettings['isUseGoogleMap'] = true;
$tableJsSettings['googleMapCfg'] = $this->googleMapCfg;
}
$lookupTableName = $pSet->getLookupTable($fName);
if( $lookupTableName )
$this->jsSettings['global']['shortTNames'][ $lookupTableName ] = GetTableURL($lookupTableName);
if( $pSet->getEditFormat($fName) == 'Time' )
$this->fillTimePickSettings($fName, "", $pSet, $pageType);
}
}
/**
* Fill field settings for current table
* @intellisense
*/
function fillFieldSettings()
{
$arrFields = $this->pSet->getFieldsList();
$this->addFieldsSettings($arrFields, $this->pSet, true, $this->pageType);
$this->addExtraFieldsToFieldSettings();
if( $this->searchPanelActivated && $this->permis[$this->searchTableName]["search"] )
{
$arrFields = $this->pSetSearch->getAllSearchFields();
$this->addFieldsSettings($arrFields, $this->pSetSearch, true, PAGE_SEARCH);
}
}
/**
* Match field with details keys
*
* @param string $fName The field name
*
* @return boolean
* @intellisense
*/
function matchWithDetailKeys($fName)
{
$match = false;
if($this->detailKeysByM)
{
for($j=0;$jdetailKeysByM);$j++)
{
if($this->detailKeysByM[$j]==$fName)
{
$match = true;
break;
}
}
}
return $match;
}
/**
* Fill preload array for js settings
* Use on Add, Edit, Register pages and for search fields only
*
* @param String fName
* @param Array pageFields
* @param Array values
* @param EditControlsContainer controls An instance of the 'EditControlsContainer' class OPTIONAL
*
* @return boolean|array
* @intellisense
*/
function fillPreload($fName, $pageFields, $values, $controls = null)
{
if( $this->matchWithDetailKeys($fName) || !$this->pSet->useCategory($fName) )
return false;
$vals = $this->getRawPreloadData( $fName, $values, $pageFields );
if( $this->pageType == PAGE_ADD || $this->pageType == PAGE_EDIT || $this->pageType == PAGE_REGISTER )
return $this->getPreloadArr($fName, $vals);
return $this->getSearchPreloadArr($fName, $vals, $controls);
}
/**
* Get parent fields data
* @param String fName
* @param Array values
* @param Array pageFields
* @return Array
*/
protected function getRawPreloadData( $fName, $values, $pageFields )
{
$vals = array();
$vals[ $fName ] = @$values[ $fName ];
if( $this->pageType != PAGE_ADD && $this->pageType != PAGE_EDIT && $this->pageType != PAGE_REGISTER )
return $vals;
foreach( $this->getLookupParentFieldsNames( $fName ) as $parentFName )
{
if( in_array($parentFName, $pageFields) )
$vals[ $parentFName ] = @$values[ $parentFName ];
}
return $vals;
}
/**
* Get main lookup controls field names for the dependent lookup field
*
* @param string $fName The field name
* @return Array An array of category control field names
* @intellisense
*/
function getLookupParentFieldsNames( $fName )
{
if( ($this->pSet->getEditFormat($fName) != EDIT_FORMAT_LOOKUP_WIZARD || $this->pSet->getEditFormat($fName) != EDIT_FORMAT_RADIO) && !$this->pSet->useCategory($fName) )
return array();
return $this->pSet->getLookupParentFNames( $fName );
}
/**
* Get lookup display field with wrappers if needed
* Used only when we create SQL to access lookup table
*
* @param string $field The field
* @param object $connection The connection object
* @param object $pSet The project settings object
*
* @return String
*/
static function sqlFormattedDisplayField($field, $connection, $pSet)
{
$displayField = $pSet->getDisplayField($field);
$lookupType = $pSet->getLookupType( $field );
if( 0 == strlen($displayField) || $pSet->getCustomDisplay( $field ) )
return $displayField;
if( $lookupType != LT_QUERY )
return $connection->addFieldWrappers( $displayField );
$lookupPSet = new ProjectSettings( $pSet->getLookupTable( $field ) );
return RunnerPage::_getFieldSQL( $displayField, $connection, $lookupPSet );
}
/**
* Get field underlying SQL as it's defined in the original SQL string.
*
*
* @param string $field The field name - can be NULL
* @param object $connection The connection object - can be NULL
* @param object $pSet The settings object - can be NULL
*
* @return string
*/
static function _getFieldSQL($field, $connection, $pSet)
{
$fname = "";
if( $pSet )
$fname = DB::PrepareSQL( $pSet->getFullFieldName($field) );
global $cman;
if( !$connection )
$connection = $cman->getDefault();
if( !$connection->dbBased() ) {
return "";
}
if ( $fname == "" )
return $connection->addFieldWrappers($field);
if (!$pSet->isSQLExpression($field)) {
// use field name as is with unparsed SQL
return $connection->addFieldWrappers( $fname );
}
return $fname;
}
/**
* Get field underlying SQL as it's defined in the original SQL string.
* Add decryption clause if Database-based Encryption is set for the field.
*
*
* @param string $field The field name
* @param object $connection The connection object - can be NULL
* @param object $pSet The settings object - can be NULL
* @param object $cipherer The cypherer object - can be NULL
*
* @return string
*/
static function _getFieldSQLDecrypt($field, $connection, $pSet, $cipherer)
{
$fname = RunnerPage::_getFieldSQL( $field, $connection, $pSet );
if( $cipherer && $pSet )
{
if ( $pSet->hasEncryptedFields() && !$cipherer->isEncryptionByPHPEnabled() )
return $cipherer->GetFieldName($fname, $field);
}
return $fname;
}
/**
* Get field underlying SQL as it's defined in the original SQL string.
* Add decryption clause if Database-based Encryption is set for the field.
* Use current page connection and settings
*
* @param string $field The field name
*
* @return string
*/
function getFieldSQLDecrypt($field)
{
return RunnerPage::_getFieldSQLDecrypt( $field, $this->connection, $this->pSet, $this->cipherer );
}
/**
* Get field underlying SQL as it's defined in the original SQL string.
* Use current page connection and settings
*
* @param string $field The field name
*
* @return string
*/
function getFieldSQL($field)
{
return RunnerPage::_getFieldSQL( $field, $this->connection, $this->pSet );
}
/**
* Returns just the wrapped underlying field name - to be used only in SQL UPDATE and INSERT clauses.
* Add wrappers if needed.
*
* Example
************************************************
* Original SQL:
* select cars.make as carmake from cars
*
* getTableField("carmake") -> "`make`"
*
* Insert/Update SQL:
* insert into cars ( `make` ) values ("aaa")
* update cars set `make`="aaa"
************************************************
* @param string $field The field name
*
* @return string
*/
function getTableField($field)
{
$strField = $this->pSet->getStrField($field);
if( $strField != "" )
return $this->connection->addFieldWrappers( $strField );
return $this->getFieldSQL($field);
}
/**
* Return JS for preload dependent ctrl
*
* @param string fName
* @param Array vals Dependent and main fields' values
* @return mixed
* @intellisense
*/
function getPreloadArr($fName, $vals)
{
if( $this->pageType != PAGE_ADD && $this->pageType != PAGE_EDIT && $this->pageType != PAGE_REGISTER )
return false;
$parentFNames = $this->getLookupParentFieldsNames( $fName );
if( !count($parentFNames) )
return false;
if( !$this->checkFieldOnPage( $fName ) )
return false;
$categoryFieldAppear = true;
if( $this->pageType == PAGE_ADD )
{
foreach( $parentFNames as $pFName )
{
$categoryFieldAppear = $this->checkFieldOnPage( $pFName );
if( $categoryFieldAppear )
break;
}
}
$output = array();
if( !$this->pSet->isFreeInput($fName) )
{
$parentFiltersData = array();
foreach( $parentFNames as $pFName )
{
$parentFiltersData[ $pFName ] = @$vals[ $pFName ];
}
$output = $this->getControl($fName)->loadLookupContent( $parentFiltersData, @$vals[ $fName ], $categoryFieldAppear );
}
else if( isset($vals[ $fName ]) )
$output = array(0 => @$vals[ $fName ], 1 => @$vals[ $fName ]);
if( !count($output) )
return false;
$fVal = "";
if( strlen($vals[ $fName ]) )
$fVal = $vals[ $fName ];
if( $this->pageType == PAGE_EDIT && $this->pSet->multiSelect($fName) )
$fVal = splitLookupValues($fVal);
return array("vals" => $output, "fVal" => $fVal);
}
/**
* A stub
* @param String fName
* @return Boolean
*/
protected function checkFieldOnPage( $fName )
{
return true;
}
/*
* Assign for add/edit/view/search page
* @intellisense
*/
function headerCommonAssign()
{
$this->xt->assign( "logo_block", true );
$this->xt->assign( "collapse_block", true );
##if @BUILDER.bCreateLoginPage##
$this->assignAdmin();
$this->xt->assign("changepwd_link", $_SESSION["AccessLevel"]!= ACCESS_LEVEL_GUEST && !$_SESSION["pluginLogin"] );
$this->xt->assign("changepwdlink_attrs", "href=\"".GetTableLink("changepwd")."\" onclick=\"window.location.href='".projectPath().GetTableLink("changepwd")."';return false;\"");
##endif##
}
/**
* Common assign for diferent mode on list page
* Branch classes add to this method its individualy code
* @intellisense
*/
function commonAssign()
{
$this->headerCommonAssign();
$this->xt->assign("quickjump_attrs", 'class="'.$this->makeClassName("quickjump").'"');
if( $this->pdfMode == "" )
$this->xt->assign( "defaultCSS", true );
$this->xt->assign("more_list", true);
$this->hideElement("searchpanel");
$this->prepareCollapseButton();
$this->prepareBreadcrumbs();
$stateParams = $this->getStateUrlParams();
if( $stateParams ) {
$this->xt->assign("stateLink", "&" . $this->getStateUrlParams() );
$this->xt->assign("stateLink_full", "?" . $this->getStateUrlParams() );
}
}
function prepareCollapseButton()
{
if( $_COOKIE["collapse_leftbar"] ) {
$this->xt->assign("leftbar_class", "r-left-collapsed");
$this->hideItemType('collapse_button');
$this->hideItemType('logo');
} else {
$this->hideItemType('expand_button');
}
}
/**
* Return JS for preload dependent ctrl for search fields
*
* @param String fName field name
* @param Array vals dependent and main fields' values
* @param Object contorls
* @return Mixed
* @intellisense
*/
function getSearchPreloadArr($fName, $vals, $controls)
{
if( is_null($controls) || $this->pSet->getEditFormat($fName) != EDIT_FORMAT_LOOKUP_WIZARD || !$this->pSet->useCategory( $fName ) )
return false;
$parentsFieldsData = array();
$searchApplied = $this->searchClauseObj->isUsedSrch();
foreach( $this->pSet->getParentFieldsData( $fName ) as $cData )
{
$parentField = $cData['main'];
if( !$this->searchFieldAppearsOnPage( $parentField ) )
continue;
$parentsFieldsData[ $parentField ] = "";
if( $searchApplied )
{
$categoryFieldParams = $this->searchClauseObj->getSearchCtrlParams( $parentField );
if( count($categoryFieldParams) )
$parentsFieldsData[ $parentField ] = $categoryFieldParams[0]['value1'];
}
else
{
$defaultValue = GetDefaultValue( $parentField, PAGE_SEARCH);
if( strlen($defaultValue) )
$parentsFieldsData[ $parentField ] = $defaultValue;
}
}
$output = $controls->getControl( $fName )->loadLookupContent( $parentsFieldsData, $vals[ $fName ], count($parentsFieldsData) > 0 );
if( !count( $output ) )
return false;
$fVal = $vals[ $fName ];
if( $this->pSet->multiSelect( $fName ) )
$fVal = splitLookupValues( $fVal );
return array("vals" => $output, "fVal" => $fVal);
}
/**
* Add additional fields to field settings
* Use only for:
* register page,
* changepwd page,
* admin members page with Active Directory
* @intellisense
*/
function addExtraFieldsToFieldSettings($isCaptcha = false)
{
$extraParams = array('fields' => array());
if($isCaptcha)
{
$extraParams['fields'] = array($this->getCaptchaFieldName());
$extraParams['format'] = 'Text Field';
}
else if($this->pageType == PAGE_REGISTER )
{
$extraParams['fields'] = array('confirm');
$extraParams['format'] = 'Password';
}
else if($this->pageType == PAGE_CHANGEPASS)
{
$extraParams['fields'] = array('oldpass', 'newpass', 'confirm');
$extraParams['format'] = 'Password';
}
else if((GetGlobalData("nLoginMethod", 0) == SECURITY_AD) && ($this->mode == MEMBERS_PAGE))
{
$extraParams['fields'] = array('displayname', 'name', 'category');
$extraParams['format'] = 'Text Field';
}
foreach($extraParams['fields'] as $fName)
{
$arrSetVals = array();
$arrSetVals['strName'] = $fName;
$arrSetVals['EditFormat'] = $extraParams['format'];
$arrSetVals['validation']['validationArr'][] = 'IsRequired';
$this->jsSettings['tableSettings'][$this->tName]['fieldSettings'][$fName][$this->pageType] = $arrSetVals;
}
}
/**
* Fill validation for current field
* @intellisense
*/
function fillValidation($fData, $val, &$arrSetVals)
{
$fData = $this->refineVaidationData( $fData );
if( !count($fData) )
return;
if( count( $fData['basicValidate'] ) )
$arrSetVals[ $val['jsName'] ]["validationArr"] = $fData['basicValidate'];
if( array_key_exists("customMessages", $fData) && count( $fData["customMessages"] ) )
$arrSetVals[ $val['jsName'] ]["customMessages"] = $fData["customMessages"];
if( array_key_exists("regExp", $fData) )
$arrSetVals[ $val['jsName'] ]["regExp"] = $fData["regExp"];
if( in_array("IsTime", $fData['basicValidate']) )
{
if( !$this->timeRegexp )
$this->timeRegexp = $this->getTimeRegexp();
$arrSetVals[ $val['jsName'] ]["regExp"] = $this->timeRegexp;
}
}
/**
* Remove excessive validation for page
*/
protected function refineVaidationData( &$fData )
{
return $fData;
}
/**
* Get the local time format regexp
*/
function getTimeRegexp()
{
global $locale_info;
$timeDelimiter = $locale_info["LOCALE_STIME"];
$timeFormat = $locale_info["LOCALE_STIMEFORMAT"];
$is24hoursFormat = $locale_info["LOCALE_ITIME"] == "1";
$leadingZero = $locale_info["LOCALE_ITLZERO"] == "1";
if($locale_info["LOCALE_ITIME"] == "0")
$designators = preg_quote($locale_info["LOCALE_S1159"],"")."|".preg_quote($locale_info["LOCALE_S2359"],"");
if($is24hoursFormat)
{
if($leadingZero)
$timeFormat = str_replace("HH", "(?:0[0-9]|1[0-9]|2[0-3])" ,$timeFormat);
else
$timeFormat = str_replace("H", "(?:[1-9]|1[0-9]|2[0-3])", $timeFormat);
}
else
{
if($leadingZero)
$timeFormat = str_replace("hh", "(?:0[1-9]|1[0-2])",$timeFormat);
else
$timeFormat = str_replace("h", "(?:[1-9]|1[0-2])",$timeFormat);
$timeFormat = str_replace("tt", "[\s]{0,2}(?:".$designators."|am|pm)[\s]{0,2}", $timeFormat);
}
$timeSep = $timeDelimiter == ":" ? ":" : "(?:".$timeDelimiter."|:)";
$timeFormat = str_replace($timeDelimiter."mm".$timeDelimiter."ss", "(?:".$timeSep."[0-5][0-9](?:".$timeSep."[0-5][0-9])?)?", $timeFormat);
$timeFormat = "^".str_replace(" ", "[\s]{0,2}", $timeFormat)."$";
return $timeFormat;
}
/**
* Fill all settings for current table
* @intellisense
*/
function fillSettings()
{
$this->fillGlobalSettings();
$this->fillTableSettings();
$this->fillFieldSettings();
}
/**
* Fill tool tips for current table fields
* @param $fName - filed name
* @intellisense
*/
function fillFieldToolTips($fName)
{
// don't fill tooltips in Bootstrap layout
if( $this->isBootstrap() )
return;
$toolTipText = GetFieldToolTip( GoodFieldname($this->tName), GoodFieldname($fName) );
if( strlen($toolTipText) )
$this->controlsMap['toolTips'][$fName] = $toolTipText;
}
/**
* Fill controls map
* For add, edit, search pages - controls
*
* @param Array arr an array of settings for one control
* @param Boolean addSet indicates if to add additional settings to control or not
* @param String fName (optional) a field's name
* @intellisense
*/
function fillControlsMap($arr, $addSet = false, $fName="")
{
if(!$addSet)
{
foreach($arr as $key=>$val)
{
initArray($this->controlsMap, $key);
$this->controlsMap[$key][] = $val;
}
return;
}
foreach($arr as $key=>$val)
{
foreach($val as $vkey=>$vval)
{
if(!$fName)
$this->controlsMap[$key][ count($this->controlsMap[$key]) - 1 ][$vkey] = $vval;
else
{
for($i = 0; $i < count($this->controlsMap[$key]); $i++)
{
if($this->controlsMap[$key][$i]['fieldName']==$fName)
{
$this->controlsMap[$key][$i][$vkey] = $vval;
break;
}
}
}
}
}
}
/**
* Fill field settings for current table
* @intellisense
*/
function fillControlsHTMLMap()
{
$this->controlsHTMLMap[$this->tName] = array();
$this->controlsHTMLMap[$this->tName][$this->pageType] = array();
$this->controlsHTMLMap[$this->tName][$this->pageType][$this->id] = array();
$this->controlsMap['gMaps'] = $this->googleMapCfg;
if($this->searchClauseObj)
{
if(!isset($this->controlsMap["search"]))
{
$this->controlsMap["search"] = array();
}
$this->controlsMap["search"]["usedSrch"] = $this->searchClauseObj->isUsedSrch();
}
foreach($this->controlsMap as $key=>$val)
{
$this->controlsHTMLMap[$this->tName][$this->pageType][$this->id][$key] = $val;
}
$this->viewControlsHTMLMap[$this->tName] = array();
$this->viewControlsHTMLMap[$this->tName][$this->pageType] = array();
$this->viewControlsHTMLMap[$this->tName][$this->pageType][$this->id] = array();
foreach($this->viewControlsMap as $key => $val)
$this->viewControlsHTMLMap[$this->tName][$this->pageType][$this->id][$key] = $val;
}
/**
* Fill jsSettings and controlsHTMLMap arrays for current table
* @intellisense
*/
function fillSetCntrlMaps()
{
if( $this->isControlsMapFilled )
return;
$this->fillSettings();
$this->fillControlsHTMLMap();
$this->isControlsMapFilled = true;
}
/**
* Fill timepicker settings for current field
* @intellisense
*/
function fillTimePickSettings($field, $value = "", $pSet = null, $pageType = "")
{
if(is_null($pSet))
$pSet = $this->pSet;
if($pageType == "")
$pageType = $this->pageType;
$timeAttrs = $pSet->getFormatTimeAttrs($field);
if(count($timeAttrs) && $timeAttrs["useTimePicker"])
{
$convention = $timeAttrs["hours"];
$locAmPm = getLacaleAmPmForTimePicker($convention, true);
$tpVal = getValForTimePicker($pSet->getFieldType($field),$value,$locAmPm['locale']);
$range = array();
if($convention==24)
{
for($h = 0;$h < $convention;$h ++)
$range[]= $h;
}
else
{
for($h = 1;$h <= $convention;$h ++)
$range[] = $h;
}
$minutes = array();
for($m = 0; $m < 60; $m += $timeAttrs["minutes"])
$minutes[] = $m;
//settings
$timePickSet = array('convention'=>$convention,
'range'=>$range,
'apm'=>array($locAmPm['am'],$locAmPm['pm']),
'rangeMin'=>$minutes,
'locale'=>$locAmPm['locale'],
'showSec'=>$timeAttrs["showSeconds"],
'minutes'=>$timeAttrs["minutes"]);
if(count($tpVal['dbtime'])>0)
$timePickSet['hover'] = array('0'=>$tpVal['dbtime'][3],'1'=>$tpVal['dbtime'][4],'2'=>$tpVal['dbtime'][5]);
if(!array_key_exists($field,$this->jsSettings['tableSettings'][$this->tName]['fieldSettings']))
{
$this->jsSettings['tableSettings'][$this->tName]['fieldSettings'][$field] = array();
$this->jsSettings['tableSettings'][$this->tName]['fieldSettings'][$field][$pageType] = array();
$this->jsSettings['tableSettings'][$this->tName]['fieldSettings'][$field][$pageType]['timePick'] = $timePickSet;
}
elseif(!array_key_exists("timePick",$this->jsSettings['tableSettings'][$this->tName]['fieldSettings'][$field][$pageType]))
$this->jsSettings['tableSettings'][$this->tName]['fieldSettings'][$field][$pageType]['timePick'] = $timePickSet;
$this->fillControlsMap(array('controls'=>array('open'=>($tpVal['val'] ? true : false))),true,$field);
}
}
/**
* Assign body end
* @intellisense
*/
function assignBodyEnd($params = "")
{
global $pagesData;
$this->fillSetCntrlMaps();
echo "\r\n";
echo "\r\n";
echo "";
}
/**
* Generates new id, same as flyId on front-end
*
* @return int
* @intellisense
*/
function genId()
{
$this->flyId++;
$this->recId = $this->flyId;
return $this->flyId;
}
/**
* Get page type
* @intellisense
*/
function getPageType()
{
return $this->pageType;
}
/**
* Add js files for page
* @intellisense
*/
function AddJSFileNoExt($file)
{
$this->includes_js[] = GetRootPathForResources($file);
}
function AddJSFile($file, $req1 = "", $req2 = "", $req3 = "")
{
$rootPath = GetRootPathForResources($file);
$this->includes_js[] = $rootPath;
if($req1!="")
{
$this->includes_jsreq[$rootPath] = array(GetRootPathForResources($req1));
}
if($req2!="")
{
$this->includes_jsreq[$rootPath][] = GetRootPathForResources($req2);
}
if($req3!="")
{
$this->includes_jsreq[$rootPath][] = GetRootPathForResources($req3);
}
}
/**
* Grab all js files
* @intellisense
*/
function grabAllJsFiles()
{
$jsFiles = array();
foreach($this->includes_js as $file)
{
$jsFiles[$file] = array();
if(array_key_exists($file, $this->includes_jsreq))
$jsFiles[$file] = $this->includes_jsreq[$file];
}
$this->includes_js = array();
$this->includes_jsreq = array();
return $jsFiles;
}
/**
* Grab all css files
* @intellisense
*/
function copyAllJsFiles($jsFiles)
{
foreach($jsFiles as $file=>$reqFiles)
{
$this->includes_js[] = $file;
if(array_key_exists($file,$this->includes_jsreq))
{
foreach($reqFiles as $rFile)
{
if(array_key_exists($rFile,$this->includes_jsreq[$file]))
continue;
$this->includes_jsreq[$file][] = $rFile;
}
}
else
$this->includes_jsreq[$file] = $reqFiles;
}
}
/**
* Add css files for page
* @intellisense
*/
function AddCSSFile($file)
{
if(is_array($file))
{
foreach($file as $f)
{
$this->includes_css[] = $f;
}
}
else
$this->includes_css[] = $file;
}
function successPageType() {
switch( $this->pageType ) {
case PAGE_CHANGEPASS:
return "changepwd_success";
case PAGE_REGISTER:
return "register_success";
case PAGE_REMIND:
return "remind_success";
}
return $this->pageType;
}
function switchToSuccessPage()
{
$this->pSet = new ProjectSettings($this->tName, $this->pageType, $this->pageName, GLOBAL_PAGES );
$this->pageName = $this->pSet->getDefaultPage( $this->successPageType() );
$this->pSet = new ProjectSettings($this->tName, $this->pageType, $this->pageName, GLOBAL_PAGES );
$this->templatefile = "";
$this->setTemplateFile();
$this->pageLayout = GetPageLayout( GLOBAL_PAGES, $this->pageName );
}
/**
* Grab all css files
* @intellisense
*/
function grabAllCSSFiles()
{
$cssFiles = $this->includes_css;
$this->includes_css = array();
return $cssFiles;
}
/**
* Copy all css files
* @intellisense
*/
function copyAllCssFiles($cssFiles)
{
foreach($cssFiles as $file)
$this->AddCSSFile($file);
}
/**
* Load js and css files
* @intellisense
*/
function LoadJS_CSS()
{
$this->includes_js = array_unique($this->includes_js);
$this->includes_css = array_unique($this->includes_css);
$out = "";
foreach($this->includes_js as $file)
{
$out .= "Runner.util.ScriptLoader.addJS(['".$file."']";
if(array_key_exists($file,$this->includes_jsreq))
{
foreach($this->includes_jsreq[$file] as $req)
$out.=",'".$req."'";
}
$out.=");\r\n";
}
$out.= " Runner.util.ScriptLoader.load();";
return $out;
}
/**
* Set languge params for page
* @intellisense
*/
function setLangParams()
{
##if @BUILDER.arrLanguages.len>1##
SetLangVars($this->xt, $this->shortTableName, $this->pageType);
##endif##
}
/**
* Add general js or css files for pages
* @intellisense
*/
function addCommonJs()
{
if( $this->isBootstrap() )
{
$this->AddCSSFile("include/jquery-ui/smoothness/jquery-ui.min.css"); // css?
$this->AddCSSFile("include/bootstrap/css/jquery.mCustomScrollbar.css"); // css?
}
if ($this->pSet->isAddPageEvents() && $this->pageType != PAGE_LOGIN && $this->shortTableName != "")
{
$this->AddJSFile("include/runnerJS/events/pageevents_".$this->shortTableName.".js");
}
##if @BUILDER.arrEventHandlers[strEventID == "EVENT_JS_ONLOAD"].len || @BUILDER.controlHandlers[strEventID == "EVENT_BUTTON"].len##
if ($this->pageType == PAGE_MENU || $this->pageType == PAGE_REGISTER || $this->pageType == PAGE_LOGIN || $this->pageType == PAGE_CHANGEPASS || $this->pageType == PAGE_REMIND)
{
$this->AddJSFile("include/runnerJS/events/globalevents.js");
}
##endif##
if ( !$this->isBootstrap() )
$this->AddJSFile("include/yui/yui-min.js");
if ($this->isUseAjaxSuggest)
{
$this->AddJSFile("include/ajaxsuggest.js");
}
elseif(count($this->allDetailsTablesArr))
{
for($i = 0; $i < count($this->allDetailsTablesArr); $i ++)
{
if($this->pSet->detailsPreview( $this->allDetailsTablesArr[$i]['dDataSourceTable'] ) == DP_POPUP)
$this->AddJSFile("include/ajaxsuggest.js");
break;
}
}
if($this->isUseCK)
$this->AddJSFile("plugins/ckeditor/ckeditor.js");
$this->addControlsJSAndCSS();
}
function addControlsJSAndCSS()
{
$this->controls->addControlsJSAndCSS();
$this->viewControls->addControlsJSAndCSS();
}
/**
* Prepare js code
* @intellisense
*/
function PrepareJS()
{
return $this->LoadJS_CSS();
}
function addButtonHandlers()
{
if ( !$this->pSet->isAddPageEvents() || $this->shortTableName == "")
return false;
$this->AddJSFile("include/runnerJS/events/pageevents_".$this->shortTableName.".js");
return true;
}
function setGoogleMapsParams($fieldsArr)
{
$this->googleMapCfg['isUseMainMaps'] = $this->pSet->hasMap();
$this->googleMapCfg['isUseFieldsMaps'] = $this->pSet->isUseFieldsMaps();
if ($this->googleMapCfg['isUseFieldsMaps'])
{
foreach($fieldsArr as $f)
{
if ($f['viewFormat'] == FORMAT_MAP)
{
$this->googleMapCfg['fieldsAsMap'][$f['fName']] = array();
$fieldMap = $this->pSet->getMapData($f['fName']);
$this->googleMapCfg['fieldsAsMap'][$f['fName']]['width'] = $fieldMap['width'] ? $fieldMap['width'] : 0;
$this->googleMapCfg['fieldsAsMap'][$f['fName']]['height'] = $fieldMap['height'] ? $fieldMap['height'] : 0;
$this->googleMapCfg['fieldsAsMap'][$f['fName']]['addressField'] = $fieldMap['address'];
$this->googleMapCfg['fieldsAsMap'][$f['fName']]['latField'] = $fieldMap['lat'];
$this->googleMapCfg['fieldsAsMap'][$f['fName']]['lngField'] = $fieldMap['lng'];
$this->googleMapCfg['fieldsAsMap'][$f['fName']]['descField'] = $fieldMap['desc'];
$this->googleMapCfg['fieldsAsMap'][$f['fName']]['mapIcon'] = $this->pSet->getMapIcon($f['fName'], $this->data);
if (isset($fieldMap['zoom'])){
$this->googleMapCfg['fieldsAsMap'][$f['fName']]['zoom'] = $fieldMap['zoom'];
}
}
}
}
$this->googleMapCfg['isUseGoogleMap'] = $this->googleMapCfg['isUseMainMaps'] || $this->googleMapCfg['isUseFieldsMaps'] || $this->mapsExists();
$this->googleMapCfg['tName'] = $this->tName;
}
function fillAdvancedMapData()
{
$advMaps = array();
$clustering = false;
foreach ($this->googleMapCfg['mapsData'] as $mapId => $mapData)
{
if( $this->googleMapCfg['mapsData'][$mapId]['showAllMarkers'] )
$advMaps[] = $mapId;
if( $this->googleMapCfg['mapsData'][$mapId]['clustering'] && $this->mapProvider == GOOGLE_MAPS )
$clustering = true;
}
if( !$advMaps )
return;
if( $clustering )
$this->AddJSFile("include/markerclusterer.js");
$tKeys = $this->pSet->getTableKeys();
$dc = $this->queryCommand;
if( !$dc ) {
$dc = $this->getSubsetDataCommand();
}
$dc->reccount = -1;
$dc->startRecord = 0;
$rs = $this->dataSource->getList( $dc );
$recId = $this->recId;
while( $data = $rs->fetchAssoc() )
{
$editlink = "";
$keys = array();
for($i = 0; $i < count($tKeys); $i ++) {
if($i != 0) {
$editlink.= "&";
}
$editlink.= "editid".($i + 1)."=".runner_htmlspecialchars(rawurlencode($data[$tKeys[$i]]));
$keys[$i] = $data[$tKeys[$i]];
}
foreach( $advMaps as $mapId )
$this->addBigGoogleMapMarker($mapId, $data, $keys, ++$recId, $editlink );
}
}
/**
*
*/
function addBigGoogleMapMarkers(&$data, $keys, $editLink = '')
{
foreach ($this->googleMapCfg['mainMapIds'] as $mapId)
{
// skip heatmaps
if( $this->fetchMapMarkersInSeparateQuery( $mapId ) )
continue;
$this->addBigGoogleMapMarker( $mapId, $data, $keys, $this->recId, $editLink);
}
}
function fetchMapMarkersInSeparateQuery( $mapId )
{
return ($this->googleMapCfg['mapsData'][$mapId]['heatMap'] || $this->googleMapCfg['mapsData'][$mapId]['clustering']) && $this->mapProvider == GOOGLE_MAPS;
}
function addBigGoogleMapMarker($mapId, &$data, $keys, $recId, $editLink = '')
{
$latF = $this->googleMapCfg['mapsData'][$mapId]['latField'];
$lngF = $this->googleMapCfg['mapsData'][$mapId]['lngField'];
$addressF = $this->googleMapCfg['mapsData'][$mapId]['addressField'];
if( !strlen( $data[ $latF ] ) && !strlen( $data[ $lngF ] )&& !strlen( $data[ $addressF ] ) )
return;
$descF = $this->googleMapCfg['mapsData'][$mapId]['descField'];
$markerAsEditLink = $this->googleMapCfg['mapsData'][$mapId]['markerAsEditLink'];
$weightF = $this->googleMapCfg['mapsData'][$mapId]['weightField'];
$markerArr = array();
$markerArr['lat'] = str_replace(",", ".", ($data[$latF] ? $data[$latF] : ''));
$markerArr['lng'] = str_replace(",", ".", ($data[$lngF] ? $data[$lngF] : ''));
$markerArr['address'] = $data[$addressF] ? $data[$addressF] : '';
$markerArr['desc'] = $data[$descF] ? $data[$descF] : $markerArr['address'];
if( $weightF )
$markerArr['weight'] = str_replace(",", ".", ($data[$weightF] ? $data[$weightF] : ''));
if( $markerAsEditLink && $this->editAvailable())
$markerArr['link'] = GetTableLink( $this->shortTableName, "edit", $editLink . '&' . $this->getStateUrlParams() );
elseif($this->viewAvailable())
$markerArr['link'] = GetTableLink( $this->shortTableName, "view", $editLink . '&' . $this->getStateUrlParams() );
$markerArr['recId'] = $recId;
$markerArr['keys'] = $keys;
if( $this->googleMapCfg['mapsData'][ $mapId ]['dashMap'] )
{
$markerArr['mapIcon'] = $this->dashSet->getDashMapIcon( $this->dashElementName, $data );
$markerArr["masterKeys"] = $this->getDetailTablesMasterKeys( $data );
}
else
{
// big map on a List page
if( $this->googleMapCfg['mapsData'][$mapId]['markerField'] )
$markerArr['mapIcon'] = $data[ $this->googleMapCfg['mapsData'][$mapId]['markerField'] ];
if( !$markerArr['mapIcon'] && $this->googleMapCfg['mapsData'][$mapId]['markerIcon'] )
$markerArr['mapIcon'] = $this->googleMapCfg['mapsData'][$mapId]['markerIcon'];
}
$this->googleMapCfg['mapsData'][$mapId]['markers'][] = $markerArr;
}
/**
* @param &Array data
* @return Array
* {
detailTableName1 : { masterkey1 : ..., masterkey2: ..., ... },
detailTableName2 : { masterkey1 : ..., masterkey2: ..., ... },
...
}
*/
protected function getDetailTablesMasterKeys( &$data )
{
$masterKeys = array();
for($i = 0; $i < count($this->allDetailsTablesArr); $i ++)
{
$detailTableData = $this->allDetailsTablesArr[$i];
$dDataSourceTable = $detailTableData['dDataSourceTable'];
if( $detailTableData['dType'] == PAGE_LIST && !$this->permis[ $dDataSourceTable ]["search"] )
continue;
$masterKeys[ $dDataSourceTable ] = array();
foreach($this->masterKeysByD[$i] as $idx => $m)
{
$curM = $m;
if( $this->pageType == PAGE_REPORT )
$curM = goodFieldName($curM).'_dbvalue';
$masterKeys[ $dDataSourceTable ]["masterkey".($idx + 1)] = $data[ $curM ];
}
}
return $masterKeys;
}
/**
* call addGoogleMapData before call proccessRecordValue!!!
* @param String fName
* @param &Array data
* @param Array keys
* @param String editLink
* @return Array
*/
function addGoogleMapData($fName, &$data, $keys = array(), $editLink = '')
{
$fieldMap = $this->pSet->getMapData( $fName );
$mapData = array();
$mapData['fName'] = $fName;
$mapData['zoom'] = isset( $fieldMap['zoom'] ) ? $fieldMap['zoom'] : '';
$mapData['type'] = 'FIELD_MAP';
$mapData['mapFieldValue'] = $data[ $fName ];
$address = $data[ $fieldMap['address'] ] ? $data[ $fieldMap['address'] ] : "";
$lat = str_replace(",", ".", ( $data[ $fieldMap['lat'] ] ? $data[ $fieldMap['lat'] ] : ''));
$lng = str_replace(",", ".", ($data[ $fieldMap['lng'] ] ? $data[ $fieldMap['lng'] ] : ''));
$desc = $data[ $fieldMap['desc'] ] ? $data[ $fieldMap['desc'] ] : $address;
$viewLink = "";
if ( $this->pageType != PAGE_VIEW && $this->viewAvailable() )
$viewLink = GetTableLink( $this->shortTableName, "view", $editLink . '&' . $this->getStateUrlParams() );
$mapData['markers'][] = array(
'address' => $address,
'lat' => $lat,
'lng' => $lng,
'link' => $viewLink,
'desc' => $desc,
'recId' => $this->recId,
'keys' => $keys,
'mapIcon' => $this->pSet->getMapIcon( $fName, $data )
);
$mapId = 'littleMap_'.GoodFieldName( $fName ).'_'.$this->recId;
$this->googleMapCfg['mapsData'][ $mapId ] = $mapData;
$this->googleMapCfg['fieldMapsIds'][] = $mapId;
return $this->googleMapCfg['mapsData'][ $mapId ];
}
/**
* @param &Array data
* @return Array
*/
protected function getDashMapsIconsData( &$data )
{
$mapIconsData = array();
if( !$this->dashTName )
return $mapIconsData;
foreach( $this->dashSet->getDashboardElements() as $dElem )
{
if( $dElem["table"] != $this->tName || $dElem["type"] != DASHBOARD_MAP )
continue;
$mapIconsData[ $dElem["elementName"] ] = $this->dashSet->getDashMapIcon( $dElem["elementName"], $data );
}
return $mapIconsData;
}
/**
* @param &Array data
* @return Array
*/
protected function getFieldMapIconsData( &$data )
{
$iconsData = array();
if( $this->pSet->isUseFieldsMaps() )
{
foreach($this->pSet->getFieldsList() as $f)
{
if( $this->pSet->getViewFormat($f) == FORMAT_MAP )
$iconsData[ $f ] = $this->pSet->getMapIcon($f, $data);
}
}
return $iconsData;
}
function initGmaps()
{
if( !$this->googleMapCfg['isUseGoogleMap'] )
return;
foreach ($this->googleMapCfg['mainMapIds'] as $mapId)
{
if ($this->googleMapCfg['mapsData'][$mapId]['showCenterLink'] === 1)
{
$this->googleMapCfg['centerLinkText'] = $this->googleMapCfg['mapsData'][$mapId]['centerLinkText'];
break;
}
}
$this->jsSettings["tableSettings"][$this->tName]["editAvailable"] = $this->editAvailable();
$this->jsSettings["tableSettings"][$this->tName]["viewAvailable"] = $this->viewAvailable();
$this->includeOSMfile();
// projectPath is added to avoid double loading
$this->AddJSFile( projectPath() . "include/runnerJS/MapManager.js", "include/runnerJS/ControlConstants.js");
$this->AddJSFile("include/runnerJS/".$this->getIncludeFileMapProvider(), projectPath() . "include/runnerJS/MapManager.js");
$this->googleMapCfg['id'] = $this->id;
if( !$this->googleMapCfg['APIcode'] )
$this->googleMapCfg['APIcode'] = '##@BUILDER.strGoogleApiKey##';
$this->controlsMap['gMaps'] = &$this->googleMapCfg;
}
function addCenterLink(&$value, $fName)
{
if( !$this->googleMapCfg['isUseMainMaps'] )
return $value;
foreach ($this->googleMapCfg['mainMapIds'] as $mapId)
{
// if no center link than continue;
if ($this->googleMapCfg['mapsData'][$mapId]['addressField'] != $fName || !$this->googleMapCfg['mapsData'][$mapId]['showCenterLink'])
continue;
// if use user defined link if prop = 1 or use value if prop = 2
if($this->googleMapCfg['mapsData'][$mapId]['showCenterLink'] === 1)
$value = $this->googleMapCfg['mapsData'][$mapId]['centerLinkText'];
return ''.$value.'';
}
return $value;
}
/**
* Get geo coordinates by address
* @intellisense
* @param String values
*/
function getGeoCoordinates($address)
{
return getLatLngByAddr($address);
}
/**
* Glue text adress from adress fields
* @intellisense
* @param Array values
*/
function glueAddressByAddressFields($values)
{
$address = "";
$geoData = $this->pSet->getGeocodingData();
foreach ($geoData["addressFields"] as $field )
{
$addressField = trim($values[$field]);
if ( isset($values[$field]) && strlen($addressField) )
{
$address .= $addressField . " ";
}
}
return trim($address);
}
/**
* Update 'latitude' and 'longitude' field's values
* @intellisense
* @param &Array values
* @param Array oldvalues (optional)
*/
function setUpdatedLatLng(&$values, $oldvalues = null)
{
//check if 'UpdateLatLng' is ticked for a table
if( !$this->pSet->isUpdateLatLng() )
return;
$mapData = $this->pSet->getGeocodingData();
$address = $this->glueAddressByAddressFields($values);
if( $address == "" )
return;
if ( !is_null($oldvalues) ) {
$oldaddress = $this->glueAddressByAddressFields($oldvalues);
}
else if ( trim($values[$mapData['latField']]) != "" && trim($values[$mapData['lngField']]) != "" )
{
return;
}
// check if the actual map's address value were added/changed and lat/lng not empty
if ( $oldvalues && trim($oldvalues[$mapData['latField']]) != "" && trim($oldvalues[$mapData['lngField']]) != "" && $address == $oldaddress )
return;
//get updated coordinates
$location = $this->getGeoCoordinates($address);
if( !$location )
return;
$values[ $mapData['latField'] ] = $location['lat'];
$values[ $mapData['lngField'] ] = $location['lng'];
}
protected function getMapCondition()
{
if( !$this->mapRefresh || !count( $this->vpCoordinates ) )
return null;
$tGrid = $this->hasTableDashGridElement();
foreach( $this->dashSet->getDashboardElements() as $dElem )
{
if( $dElem["table"] == $this->tName && $dElem["type"] == DASHBOARD_MAP && ( $dElem["updateMoved"] || !$tGrid ) )
return $this->getLatLngCondition( $dElem["latF"], $dElem["lonF"] );
}
return null;
}
/**
* @deprecated
* @return String
*/
/*protected function getWhereByMap()
{
if( !$this->mapRefresh || !count( $this->vpCoordinates ) )
return "";
$tGrid = $this->hasTableDashGridElement();
foreach( $this->dashSet->getDashboardElements() as $dElem )
{
if( $dElem["table"] == $this->tName && $dElem["type"] == DASHBOARD_MAP && ( $dElem["updateMoved"] || !$tGrid ) )
return $this->getLatLngWhere( $dElem["latF"], $dElem["lonF"] );
}
return "";
}*/
protected function getLatLngCondition( $latFName, $lngFName )
{
if( $this->skipMapFilter )
return null;
if( !$this->mapRefresh || !count( $this->vpCoordinates ) )
return null;
$s = $this->vpCoordinates["s"];
$n = $this->vpCoordinates["n"];
$w = $this->vpCoordinates["w"];
$e = $this->vpCoordinates["e"];
$conditions = array();
$conditions[] = DataCondition::_Not( DataCondition::FieldIs( $latFName, dsopLESS, $s ) );
$conditions[] = DataCondition::_Not( DataCondition::FieldIs( $latFName, dsopMORE, $n ) );
if( $w <= $e ) {
$conditions[] = DataCondition::_Not( DataCondition::FieldIs( $lngFName, dsopLESS, $w ) );
$conditions[] = DataCondition::_Not( DataCondition::FieldIs( $lngFName, dsopMORE, $e ) );
} else {
// region is across the International Date Line
$conditions[] = DataCondition::_Or( array(
DataCondition::_Not( DataCondition::FieldIs( $lngFName, dsopLESS, $w ) ),
DataCondition::_Not( DataCondition::FieldIs( $lngFName, dsopMORE, $e ) )
) );
}
return DataCondition::_And( $conditions );
}
/**
* @deprecated
* @param String latFName
* @param String lngFName
* @return String
*/
protected function getLatLngWhere( $latFName, $lngFName )
{
if( $this->skipMapFilter )
return "";
if( !$this->mapRefresh || !count( $this->vpCoordinates ) )
return "";
$latSQLName = $this->getFieldSQLDecrypt( $latFName );
$lngSQLName = $this->getFieldSQLDecrypt( $lngFName );
$s = $this->cipherer->MakeDBValue( $latFName, $this->vpCoordinates["s"], "", true );
$n = $this->cipherer->MakeDBValue( $latFName, $this->vpCoordinates["n"], "", true );
$w = $this->cipherer->MakeDBValue( $lngFName, $this->vpCoordinates["w"], "", true );
$e = $this->cipherer->MakeDBValue( $lngFName, $this->vpCoordinates["e"], "", true );
if( $this->vpCoordinates["w"] <= $this->vpCoordinates["e"] )
return $latSQLName.">=".$s." AND ".$latSQLName."<=".$n." AND ".$lngSQLName."<=".$e." AND ".$lngSQLName.">=".$w;
else
return $latSQLName.">=".$s." AND ".$latSQLName."<=".$n." AND (".$lngSQLName."<=".$e." OR ".$lngSQLName.">=".$w.")";
}
/**
* A stub. Get the page's fields list
* @return Array
*/
protected function getPageFields()
{
return $this->pSet->getFieldsList();
}
/**
* Get permissions for pages
* @intellisense
*/
function getPermissions($tName = "")
{
$resArr = array();
if(!$tName)
$tName = $this->tName;
$strPerm = GetUserPermissions($tName);
if(isLogged())
{
$resArr["add"]=(strpos($strPerm, "A") !== false);
$resArr["delete"]=(strpos($strPerm, "D") !== false);
$resArr["edit"]=(strpos($strPerm, "E") !== false);
}
$resArr["search"]=(strpos($strPerm, "S") !== false);
$resArr["export"]=(strpos($strPerm, "P") !== false);
$resArr["import"]=(strpos($strPerm, "I") !== false);
return $resArr;
}
/**
* Check is event exists on current page
* @param {string} - event name
* @intellisense
*/
function eventExists($name)
{
if(!$this->eventsObject)
return false;
return $this->eventsObject->exists($name);
}
function events()
{
return $this->eventsObject;
}
/**
* Check is googlemaps exists on current page
*
* @intellisense
*/
function mapsExists()
{
return $this->pSet->hasMap();
/* if(!$this->eventsObject)
return false;
return $this->eventsObject->existsMap($this->pageType);
*/
}
/**
* @return Boolean
*/
protected function hasTableDashGridElement()
{
if( !$this->dashSet )
return false;
foreach( $this->dashSet->getDashboardElements() as $dElem )
{
if( $dElem["table"] == $this->tName && $dElem["type"] == DASHBOARD_LIST )
return true;
}
return false;
}
/**
* @return Boolean
*/
protected function hasDashMapElement()
{
if( !$this->dashSet )
return false;
foreach( $this->dashSet->getDashboardElements() as $dElem )
{
if( $dElem["table"] == $this->tName && $dElem["type"] == DASHBOARD_MAP )
return true;
}
return false;
}
/**
* Returns array(
* "prevWhere" => String
* "nextWhere" => String
* "prevOrder" => String
* "nextOrder" => String
* )
* @param &Array data - current record
* @return Array
*/
function getNextPrevQueryComponents( &$data )
{
require_once(getabspath('classes/orderclause.php'));
$orderClause = OrderClause::createFromPage( $this, false );
$orderFields =& $orderClause->getOrderFields();
$query = $this->pSet->getSQLQuery();
if( !$orderFields || !$query )
return array();
// build SQL Query parts wor the next and prev records
$nextWhere = "";
$prevWhere = "";
$nextOrder = array();
$prevOrder = array();
for( $i = count($orderFields) - 1; $i >= 0; --$i )
{
$of = $orderFields[$i];
$sqlColumn = $this->connection->addFieldWrappers( $of["column"] );
$nextOrder[] = $sqlColumn . ' ' . $of["dir"];
$prevOrder[] = $sqlColumn . ' ' . ( $of["dir"] == "ASC" ? "DESC" : "ASC" );
$sqlValue = $this->cipherer->MakeDBValue( $of["column"], $data[ $of["column"] ], "", true );
// Build this sort of exporessions:
// field1 > x or field1 = x and ( field2 > y or field2=y and ( field3 ... ) )
$equal = "";
if( $i < count($orderFields) - 1 )
$equal = sqlEqual( $sqlColumn, $sqlValue );
$next = sqlMoreThan( $sqlColumn, $sqlValue );
$prev = sqlLessThan( $sqlColumn, $sqlValue );
if( $of["dir"] == "DESC" )
{
$prev = sqlMoreThan( $sqlColumn, $sqlValue );
$next = sqlLessThan( $sqlColumn, $sqlValue );
}
$nextWhere = SQLQuery::combineCases( array(
$next,
SQLQuery::combineCases( array(
$equal,
$nextWhere ),
"and" )),
"or" );
$prevWhere = SQLQuery::combineCases( array(
$prev,
SQLQuery::combineCases( array(
$equal,
$prevWhere ),
"and" )),
"or" );
}
return array(
"nextWhere" => $nextWhere,
"prevWhere" => $prevWhere,
"nextOrder" => implode( ", ", array_reverse( $nextOrder ) ),
"prevOrder" => implode( ", ", array_reverse( $prevOrder ) )
);
}
/**
* Returns array(
* "prev" => Array( value> key pairs )
* "next" => Array( value> key pairs )
* )
* @param &Array data - current record
* @return Array
*/
function getNextPrevRecordKeys( &$data, $what = BOTH_RECORDS )
{
$dc = RunnerPage::getSubsetDataCommand();
return $this->dataSource->getNextPrevKeys($dc, $data, $what);
}
/**
* Get an ORDER BY clause set on the corresponding list page
* to retrieve the right record on the edit/view pages
* without 'editid' params passed
* @return String
*/
public function getOrderByClause()
{
require_once(getabspath('classes/orderclause.php'));
$orderClause = OrderClause::createFromPage( $this );
return $orderClause->getOrderByExpression();
}
/**
* Get URL keys params string
* editid1=a&editid2=b&...
*
* Uses $this->keys if parameter is not specified
* Returns empty string if empty array passed
* @return String
*/
protected function getKeyParams( $keys = null )
{
if( is_null( $keys ) )
$keys = $this->keys;
if( !$keys )
return "";
$keyParams = array();
foreach( $this->pSet->getTableKeys() as $i => $k )
{
$keyParams[] = "editid" . ($i + 1) . "=" . rawurldecode( isset( $keys[ $k ] ) ? $keys[ $k ] : $keys[ $i ] ) ;
}
return implode("&", $keyParams);
}
/**
* Assign xt variables connected to the'Prev/Next' buttons
* @param Boolean showNext
* @param Boolean showPrev
* @param Boolean dashBased
*/
public function assignPrevNextButtons( $showNext, $showPrev, $dashGridBased = false )
{
if( !$this->pSet->useMoveNext() )
return;
if( $showNext || $dashGridBased )
{
$this->xt->assign("next_button", true);
$this->xt->assign("nextbutton_attrs", 'id="nextButton'.$this->id.'"');
if ( $dashGridBased )
$this->xt->assign("nextbutton_class", "rnr-invisible-button");
}
else if( $showPrev )
{
$this->xt->assign("next_button", true);
$this->xt->assign("nextbutton_class", "rnr-invisible-button");
}
else
$this->xt->assign("next_button", false);
if( $showPrev || $dashGridBased )
{
$this->xt->assign("prev_button", true);
$this->xt->assign("prevbutton_attrs", 'id="prevButton'.$this->id.'"');
if ( $dashGridBased )
$this->xt->assign("prevbutton_class", "rnr-invisible-button");
}
else if( $showNext )
{
$this->xt->assign("prev_button", true);
$this->xt->assign("prevbutton_class", "rnr-invisible-button");
}
else
$this->xt->assign("prev_button", false);
}
/**
* Check captcha
* @return Boolean
*/
function checkCaptcha()
{
$this->isCaptchaOk = true;
if ( !$this->captchaExists() )
return true;
// skip N CAPTCHA checks after successful test
if ( isset($_SESSION["count_passes_captcha"]) )
{
$_SESSION["count_passes_captcha"] = $_SESSION["count_passes_captcha"] + 1;
return true;
}
// ???
if ( !isset($_SESSION["isCaptcha" . $this->getCaptchaId() . "Showed"]) && $this->captchaValue == '' )
return true;
$captchaSettings = GetGlobalData("CaptchaSettings", "");
// check FLASH captcha
if ( $captchaSettings["type"] == FLASH_CAPTCHA && @strtolower($this->captchaValue) != strtolower(@$_SESSION["captcha_" . $this->getCaptchaId()]) )
{
$this->isCaptchaOk = false;
$this->message = ##message SEC_INVALID_CAPTCHA_CODE##;
}
// check recaptcha
if( $captchaSettings["type"] == RE_CAPTCHA )
{
$verifyResponse = verifyRecaptchaResponse($this->captchaValue);
if ( !$verifyResponse["success"] )
{
$this->isCaptchaOk = false;
$this->message = $verifyResponse["message"];
}
}
// CAPTCHA ok, clean up
if( $this->isCaptchaOk )
{
if( $captchaSettings["type"] == FLASH_CAPTCHA )
{
unset($_SESSION["captcha_" . $this->getCaptchaId()]);
}
unset($_SESSION["isCaptcha" . $this->getCaptchaId() . "Showed"]);
$_SESSION["count_passes_captcha"] = 0;
}
return $this->isCaptchaOk;
}
function displayCaptcha()
{
$captchaFieldName = $this->getCaptchaFieldName();
if( ( !isset($_SESSION["count_passes_captcha"]) ) or ( $_SESSION["count_passes_captcha"] >= $this->captchaPassesCount ) )
{
##if @BUILDER.pCaptchaSettings.nType == 0##
$this->xt->assign("captcha_block", true);
$this->xt->assign("captcha", $this->getCaptchaHtml($captchaFieldName));
##elseif @BUILDER.pCaptchaSettings.nType == 1##
$this->reCaptchaCfg['inputCaptchaId'] = 'value_'.$captchaFieldName.'_' . $this->id;
$this->controlsMap['reCaptcha'] = &$this->reCaptchaCfg;
$this->xt->assign("captcha_block", true);
$this->xt->assign("captcha", $this->getCaptchaHtml($captchaFieldName));
##endif##
$this->xt->assign("captcha_field_name", $captchaFieldName);
if ( isset($_SESSION["count_passes_captcha"]) )
unset($_SESSION["count_passes_captcha"]);
$_SESSION["isCaptcha" . $this->getCaptchaId() . "Showed"] = 1;
}
//create control and settings for captcha field, if it show on page
$controls = array('controls'=>array());
$controls['controls']['ctrlInd'] = 0;
$controls['controls']['id'] = $this->id;
$controls['controls']['fieldName'] = $captchaFieldName;
$controls['controls']['mode'] = $this->pageType;
if ( !$this->isCaptchaOk )
$controls["controls"]["isInvalid"] = true;
$this->fillControlsMap($controls);
$this->addExtraFieldsToFieldSettings(true);
}
function getCaptchaHtml($_captchaFieldName)
{
$captchaHTML = '';
##if @BUILDER.pCaptchaSettings.nType == 0##
$typeCodeMessage = ##message SEC_TYPETHECODE##;
$path = GetCaptchaPath();
$swfPath = GetCaptchaSwfPath();
$captchaHTML .= '
';
$captchaHTML .= '
'.$typeCodeMessage.':
*
';
##elseif @BUILDER.pCaptchaSettings.nType == 1##
$captchaHTML .= '
';
##endif##
$captchaHTML.='
';
return $captchaHTML;
}
function getCaptchaId() {
return $this->id;
}
/**
* Get captcha field name
*
* @intellisense
*/
function getCaptchaFieldName()
{
return "captcha";
}
/**
* Assign the recsPerPage xt variable
*/
public function createPerPage()
{
if( false && $this->isBootstrap() )
{
return $this->bsCreatePerPage();
}
$classString = "";
$allMessage = ##message SHOW_ALL##;
if( $this->isBootstrap() )
{
$classString = 'class="form-control"';
$allMessage = ##message ALL##;
}
$rpp = "";
$this->xt->assign("recsPerPage", $rpp);
}
function bsCreatePerPage()
{
$txtVal = $this->pageSize;
if( $this->pageSize == -1 )
$txtVal = ##message SHOW_ALL##;
$rpp = '
';
$this->xt->assign("recsPerPage", $rpp);
}
function ProcessFiles()
{
foreach($this->filesToDelete as $f)
{
$f->Delete();
}
foreach($this->filesToMove as $f)
{
$f->Move();
}
foreach($this->filesToSave as $f)
{
$f->Save();
}
}
/**
* Use for count details recs number, if subQueryes not supported, or keys have different types
*
* @param integer $i
* @param array $detailid
* @intellisense
*/
function countDetailsRecsNoSubQ($dInd, &$detailid)
{
global $cman;
$dDataSourceTable = $this->allDetailsTablesArr[ $dInd ]['dDataSourceTable'];
$detPSet = new ProjectSettings($dDataSourceTable);
$detailsDs = getDataSource( $dDataSourceTable, $detPSet );
$filters = array();
$filters[] = Security::SelectCondition( "S", $detPSet );
// master-details filter
$detailKeys = $detPSet->getDetailKeysByMasterTable( $this->tName );
$detailsKeyValues = array();
foreach($this->masterKeysByD[ $dInd ] as $idx => $val)
{
$filters[] = DataCondition::FieldEquals( $detailKeys[$idx], $detailid[$idx] );
$detailsKeyValues[ $detailKeys[$idx] ] = $detailid[$idx];
}
$dc = new DsCommand;
$dc->filter = DataCondition::_And( $filters );
RunnerContext::pushMasterContext( $detailsKeyValues );
$ret = $this->limitRowCount( $detailsDs->getCount( $dc ), $detPSet);
RunnerContext::pop();
return $ret;
}
function noRecordsMessage()
{
$isSearchRun = $this->isSearchFunctionalityActivated();
if( !$isSearchRun && $this->getCurrentTabWhere() != "" )
$isSearchRun = true;
if( $this->pSetSearch->noRecordsOnFirstPage() && !$isSearchRun )
return ##message NOTHING_TO_SEE##;
if( !$this->rowsFound && !$isSearchRun )
return ##message NO_DATA_YET##;
if( $isSearchRun && !$this->rowsFound )
return ##message NO_RECORDS##;
}
function showNoRecordsMessage()
{
$message = ($this->is508 == true ? "" : "").$this->noRecordsMessage();
$message= "id."\">".$message."";
$this->xt->assign("message",$message);
$this->xt->assign( "message_class", "alert-warning");
$this->xt->assign("message_block",true);
}
/**
* Calcs pagination info
*
* @intellisense
*/
function buildPagination()
{
$separator = " ";
$advSeparator = " : ";
if( $this->isBootstrap() )
{
$separator = "";
$advSeparator = "";
}
// hide colunm headers if needed
if($this->pageSize && $this->pageSize!=-1)
$this->maxPages = ceil($this->numRowsFromSQL / $this->pageSize);
if($this->myPage > $this->maxPages)
$this->myPage = $this->maxPages;
if($this->myPage < 1)
$this->myPage = 1;
$this->recordsOnPage = $this->numRowsFromSQL -($this->myPage - 1) * $this->pageSize;
if($this->recordsOnPage > $this->pageSize && $this->pageSize!=-1)
$this->recordsOnPage = $this->pageSize;
if( $this->isPD() ) {
$this->colsOnPage = 1;
} else {
$this->colsOnPage = $this->recsPerRowList;
if($this->colsOnPage > $this->recordsOnPage && $this->listGridLayout != gltVERTICAL)
$this->colsOnPage = $this->recordsOnPage;
if($this->colsOnPage < 1)
$this->colsOnPage = 1;
}
// Pagination:
if((!$this->numRowsFromSQL) && ($this->deleteMessage == ''))
{
$this->rowsFound = false;
$this->showNoRecordsMessage();
if($this->listAjax || $this->mode == LIST_LOOKUP)
{
$this->xt->assign("pagination_block", true);
$this->hideElement("pagination");
if( $this->listAjax )
$this->xt->assign("pagination", " ");
}
$this->hideItemType("details_found");
$this->hideItemType("page_size");
}
else
{
$this->rowsFound = true;
$this->xt->assign("details_found", true );
$this->xt->assign("message_block",false);
if($this->listAjax || $this->mode == LIST_LOOKUP)
{
$this->xt->assign("message_block",true);
$this->xt->assign( "message_class", "alert-warning");
$this->hideElement("message");
}
else if ($this->deleteMessage != ''){
$this->xt->assign("message_block",true);
}
$this->xt->assign("records_found", $this->numRowsFromSQL);
$this->jsSettings["tableSettings"][$this->tName]['maxPages'] = $this->maxPages;
$firstDisplayed = ( $this->myPage - 1 ) * $this->pageSize + 1;
$lastDisplayed = ( $this->myPage ) * $this->pageSize;
if( $this->pageSize < 0 || $lastDisplayed > $this->numRowsFromSQL )
$lastDisplayed = $this->numRowsFromSQL;
$this->prepareRecordsIndicator( $firstDisplayed, $lastDisplayed, $this->numRowsFromSQL );
$this->xt->assign("page", $this->myPage);
$this->xt->assign("maxpages", $this->maxPages);
$this->xt->assign("pagination_block", false);
$limit=10;
if ($this->mobileTemplateMode())
$limit=5;
// write pagination
if($this->maxPages > 1)
{
$this->xt->assign("pagination_block", true);
$pagination = '';
$counterstart = $this->myPage - ($limit-1);
if($this->myPage % $limit != 0)
$counterstart = $this->myPage -($this->myPage % $limit) + 1;
$counterend = $counterstart + $limit-1;
if($counterend > $this->maxPages)
$counterend = $this->maxPages;
if($counterstart != 1)
{
$pagination.= $this->getPaginationLink(1,##message FIRST##) . $advSeparator;
$pagination.= $this->getPaginationLink($counterstart - 1,##message PREVIOUS##).$separator;
}
$pageLinks = "";
if(isRTL())
{
for($counter = $counterend; $counter >= $counterstart; $counter --)
{
$pageLinks .= $separator . $this->getPaginationLink($counter,$counter, $counter == $this->myPage );
}
}
else
{
for($counter = $counterstart; $counter <= $counterend; $counter ++)
{
$pageLinks .= $separator . $this->getPaginationLink($counter,$counter, $counter == $this->myPage );
}
}
if( !$this->isBootstrap() )
{
$pageLinks = "[" . $pageLinks . $separator . "]";
}
$pagination .= $pageLinks;
if($counterend != $this->maxPages)
{
$pagination.= $separator . $this->getPaginationLink($counterend + 1,##message NEXT##) . $advSeparator;
$pagination.= $this->getPaginationLink($this->maxPages,##message LAST##);
}
if( $this->isBootstrap() )
$pagination = '';
else
$pagination = "id . "\">" . $pagination . "
";
$this->xt->assign("pagination", $pagination);
$this->xt->assign("pagination", $pagination);
}
else
{
if($this->listAjax || $this->mode == LIST_LOOKUP || $this->mode == MEMBERS_PAGE)
{
$this->xt->assign("pagination_block", true);
$this->hideElement("pagination");
}
}
}
}
function prepareRecordsIndicator($firstDisplayed, $lastDisplayed, $totalDisplayed)
{
$this->xt->assign("firstrecord", $firstDisplayed );
$this->xt->assign("lastrecord", $lastDisplayed );
$first = ''.$firstDisplayed.'';
$last = ''.$lastDisplayed.'';
$total = ''.$totalDisplayed.'';
if ( $this->isPD() )
{
$this->xt->assign( "details_found", true );
foreach ( $this->pSet->detailsFoundLabelsData() as $itemId => $mLString )
{
$template = str_replace( array( '%first%', '%last%', '%total%'), array( $first, $last, $total), GetMLString( $mLString ) );
$this->xt->assign( "details_found_label".$itemId, $template );
}
}
else
{
$template = ##message DISPLAYING##;
$template = str_replace( array( '%first%', '%last%', '%total%'), array( $first, $last, $total), $template );
$this->xt->assign( "records_indicator", $template );
}
}
/**
* Get pagination link for build pagination block
*
* @return string
* @intellisense
*/
function getPaginationLink($pageNum, $linkText, $active = false)
{
if( $this->isBootstrap() )
{
$href = GetTableLink( GetTableURL( $this->tName ), $this->pageType)."?goto=".$pageNum . $this->getStateUrlParams();
return ''.$linkText.'';
}
if( $active )
return "" . $pageNum . "";
return ''.$linkText.'';
}
/**
* Check is current table is admin table
*
* @return bool
* @intellisense
*/
function isAdminTable()
{
if($this->tName)
return $this->tName === 'admin_rights' || $this->tName === 'admin_members' || $this->tName === 'admin_users';
else
return false;
}
function fieldAlign($f)
{
if( $this->pSet->getEditFormat($f) == FORMAT_LOOKUP_WIZARD )
return 'left';
$format = $this->pSet->getViewFormat($f);
if( $format == FORMAT_FILE || $format == FORMAT_AUDIO || $format == FORMAT_CHECKBOX )
return 'left';
if( $format == FORMAT_NUMBER || IsNumberType( $this->pSet->getFieldType($f) ) )
return 'right';
return 'left';
}
/**
* Get the field's class name to align the field's value
* basing on its edti and view formats
* @param String f
* @return String
*/
function fieldClass($f)
{
if( $this->pSet->getEditFormat($f) == FORMAT_LOOKUP_WIZARD )
return '';
$format = $this->pSet->getViewFormat($f);
if( $format == FORMAT_FILE )
return ' rnr-field-file';
if( $format == FORMAT_AUDIO )
return ' rnr-field-audio';
if( $format == FORMAT_CHECKBOX )
return ' rnr-field-checkbox';
if( $format == FORMAT_NUMBER || IsNumberType( $this->pSet->getFieldType($f) ) )
return ' r-field-number';
return "r-field-text";
}
/**
* buildDetailGridLinks
* Build master-details links href-attribute on list grid
* @param {array} master key values
* @return {array} array of links hrefs and ids
* @intellisense
*/
function buildDetailGridLinks(&$data)
{
$hrefs = array();
foreach($this->allDetailsTablesArr as $detailsData)
{
$dShortTable = $detailsData['dShortTable'];
$masterquery = "mastertable=".rawurlencode($this->tName);
for($idx = 1; $idx <= count($detailsData["masterKeys"]); $idx ++)
{
$masterquery.= "&masterkey".($idx)."=".rawurlencode( $data[ $detailsData['dDataSourceTable'] ]["masterkey".$idx] );
}
$idLink = $dShortTable;
if ( !$this->isPD() )
$idLink = $this->pSet->detailsPreview( $detailsData['dDataSourceTable'] ) == DP_INLINE ? $dShortTable."_preview" : "master_".$dShortTable."_";
$hrefs[] = array("id" => $idLink
, "href" => GetTableLink($dShortTable, $detailsData["dType"], $masterquery));
}
return $hrefs;
}
/**
* Create new control (if needed) for edit field, and return it
* @param {string} field field name
* @param {string} id (optional) field id
* @param {array} extraParams (optional)
* @return {object} edit control
* @intellisense
*/
function getControl($field, $id = "", $extraParams = array())
{
return $this->controls->getControl($field, $id, $extraParams);
}
/**
* Create new control (if needed) for view field, and return it
* @param {string} field name
* @param {string} predefined view format
* @intellisense
*/
function getViewControl($field, $format = null)
{
return $this->viewControls->getControl($field, $format);
}
function setForExportVar($forExport)
{
$this->viewControls->setForExportVar($forExport);
}
/**
* showDBValue
* Wrapper for ViewControl creation and showDBValue call on it
* @param {string} field name
* @param {array} associative array with record data
* @param {string} string with record keys and values
* @intellisense
*/
function showDBValue($field, &$data, $keylink = "", $html = true )
{
if( !$keylink && $data ) {
$tKeys = $this->pSet->getTableKeys();
$keylink = "";
for($i = 0; $i < count($tKeys); $i ++) {
$keylink.= "&key".($i + 1)."=".rawurlencode(@$data[ $tKeys[$i] ]);
}
}
if( $this->pdfJsonMode() ) {
return $this->getViewControl($field)->getPdfValue($data, $keylink);
}
return $this->getViewControl($field)->showDBValue($data, $keylink, $html );
}
function showTextValue($field, &$data )
{
return $this->getViewControl($field)->getTextValue( $data );
}
/**
* showDBValue
* Wrapper for ViewControl creation and showDBValue call on it
* @param {string} field name
* @param {array} associative array with record data
* @intellisense
*/
function getTextValue( $field, &$data )
{
return $this->getViewControl($field)->getTextValue( $data );
}
/**
* Wrapper for the ViewControl's getExportValue method
* @param String field
* @param Array &data
* @param String keylink (optional)
* @return String
*/
function getExportValue($field, &$data, $keylink = "", $html )
{
return $this->getViewControl($field)->getExportValue($data, $keylink, $html );
}
/**
* Hide the field on the page
* @param String fieldName
*/
function hideField($fieldName, $recordId = "")
{
if( $this->isPD() ) {
$items = $this->pSet->getFieldItems( $fieldName );
if( is_array( $items ) ) {
foreach( $items as $i )
$this->hideItem( $i, $recordId );
}
} else {
if(!is_null($this->xt))
$this->xt->hideField($fieldName);
}
}
/**
* Show the hidden field on the page
* @param String fieldName
*/
function showField($fieldName)
{
if( $this->isPD() )
{
$items = $this->pSet->getFieldItems( $fieldName );
if( is_array( $items ) ) {
foreach( $items as $i )
$this->showItem( $i );
}
}
else
{
if(!is_null($this->xt))
$this->xt->showField($fieldName);
}
}
/**
* The settings object 'getDetailKeysByMasterTable' method's wrapper
* @return Array
*/
function getDetailKeysByMasterTable()
{
return $this->pSet->getDetailKeysByMasterTable($this->masterTable);
}
/**
* Get the page's layout
* @return {string}
*/
function getPageLayout($tName="", $pageType="", $suffix = "")
{
global $page_layouts;
if(!$tName)
$tName = $this->tName;
if(!$pageType)
$pageType = $this->pageType;
$templateName = GetTableURL($tName)."_".$pageType;
if($suffix)
$templateName = $templateName."_".$suffix;
if(!$this->isPageTableBased() || $this->pageType == PAGE_REGISTER )
{
//the name of the non table page's layout
$templateName = $pageType;
}
return $page_layouts[$templateName];
}
/**
* Check if the pabe is table based or not
* @return Boolean
*/
function isPageTableBased()
{
if($this->pageType == PAGE_MENU || $this->pageType == PAGE_LOGIN || $this->pageType == PAGE_REMIND || $this->pageType == PAGE_CHANGEPASS)
{
return false;
}
return true;
}
/**
* Check if the brick is set in the layout or not
*
* @param {string} $brickName
* @return {boolean}
*/
function isBrickSet($brickName)
{
return true;
$layout = $this->getPageLayout();
if($layout)
{
return $layout->isBrickSet($brickName);
}
return false;
}
/**
* Get the brick's table name (if it's set)
*
* @param {string} $brickName
* @return {string}
*/
function getBrickTableName($brickName)
{
$layout = $this->getPageLayout();
if($layout)
{
return $layout->getBrickTableName($brickName);
}
return "";
}
/**
* Sets all necessary params for the Search panel added to the non table page
*/
function setParamsForSearchPanel()
{
if(!$this->searchPanelActivated)
{
return;
}
include_once(getabspath("classes/searchclause.##@ext##"));
$this->needSearchClauseObj = true;
$seachTableName = $this->getBrickTableName("searchpanel");
if($seachTableName)
{
//if the brick's table name is set it'll used as the table name for the searchpanel's ProjectSettings object
$this->pSetSearch = new ProjectSettings($seachTableName, PAGE_SEARCH);
//set the correct search table's name
$this->searchTableName = $seachTableName;
//add some globale settings for the search table
$this->settingsMap["globalSettings"]["shortTNames"][$seachTableName] = $this->pSetSearch->getShortTableName();
$this->permis[$this->searchTableName] = $this->getPermissions($seachTableName);
if( $this->permis[$this->searchTableName]["search"] && (!$this->isPageTableBased() || $this->pageType == PAGE_REGISTER) )
{
//for edit controls to render correctly
$this->tableBasedSearchPanelAdded = true;
}
}
}
/**
* Check if the search panel brick is set in the current layout
* $param Boplean mobile
* @return Boolean
*/
protected function checkIfSearchPanelActivated( $mobile )
{
return $this->pSet->showSearchPanel() || $this->pageType === PAGE_DASHBOARD;
}
/**
* Build the Search panel if the "searchpanel" brick is added to the page's layout
*/
protected function buildAddedSearchPanel()
{
if( $this->pageType != PAGE_REPORT && $this->pageType != PAGE_CHART && $this->pageType != PAGE_LIST
&& !($this->pageType == PAGE_ADD && $this->mode == ADD_INLINE) && !($this->pageType == PAGE_EDIT && $this->mode == EDIT_INLINE ) )
{
$this->buildSearchPanel();
}
}
/**
* Build the activated Search panel
*/
public function buildSearchPanel()
{
if( !$this->searchPanelActivated || !$this->permis[$this->searchTableName]["search"] )
{
return;
}
include_once(getabspath("classes/searchpanel.##@ext##"));
include_once(getabspath("classes/searchpanelsimple.##@ext##"));
include_once(getabspath("classes/searchcontrol.##@ext##"));
include_once(getabspath("classes/panelsearchcontrol.##@ext##"));
$params = array();
$params['pageObj'] = &$this;
$searchPanelObj = new SearchPanelSimple($params);
$searchPanelObj->buildSearchPanel();
}
/**
* Build and show the Filter panel on the page
* if there are corresponding search permissions
*/
function buildFilterPanel()
{
if( !$this->permis[$this->tName]["search"]
|| $this->pSetEdit->isSearchRequiredForFiltering() && !$this->isRequiredSearchRunning() )
{
$this->prepareEmptyFPMarkup();
return false;
}
if( !$this->pSet->getFilterFields() )
return false;
include_once getabspath("classes/filterpanel.##@ext##");
$params = array();
$params["pageObj"] = &$this;
$filterPanel = new FilterPanel($params);
return $filterPanel->buildFilterPanel();
}
/**
* A stub
*/
protected function prepareEmptyFPMarkup()
{
}
/**
*
*/
function isSearchFunctionalityActivated()
{
if( !$this->searchClauseObj )
return false;
return $this->searchClauseObj->isSearchFunctionalityActivated();
}
/**
* Search clause method wrapper
* @return Boolean
*/
function isRequiredSearchRunning()
{
if( !$this->searchClauseObj )
return false;
return $this->searchClauseObj->isRequiredSearchRunning();
}
/**
* Check whether the page's layout is table-based
*/
function isOldLayout()
{
if(!$this->pageLayout)
return false;
return ($this->pageLayout->version == 1);
}
/**
* Forms class name with an appropriate prefix
*/
function makeClassName($name)
{
if($this->isOldLayout())
return "runner-".$name;
return "rnr-".$name;
}
/**
* Check if the fieldData array contains at least one duplicated field's value
*
* @param {Array} $fieldsData
* @param {String} $message
* @return {Boolean}
*/
function hasDeniedDuplicateValues($fieldsData, &$message)
{
foreach($fieldsData as $fieldName => $value)
{
if($this->pSet->allowDuplicateValues($fieldName))
continue;
if($this->hasDuplicateValue($fieldName, $value))
{
$this->errorFields[] = $fieldName;
if( !( $this->pageType == PAGE_EDIT && $this->mode == EDIT_POPUP )
&& !( $this->pageType == PAGE_ADD && $this->mode == ADD_POPUP ) ) {
$displayedValue = $value;
$ctrl = $this->getViewControl( $fieldName );
if( $ctrl ) {
$data = array( $fieldName => $value );
$displayedValue = $ctrl->showDBValue( $data, "", false );
}
$message = $this->getDenyDuplicatedMessage( $fieldName, $displayedValue );
}
return true;
}
}
return false;
}
/**
* @param String fName
* @param String value
* @return String
*/
protected function getDenyDuplicatedMessage( $fName, $value )
{
$validationData = $this->pSet->getValidation( $fName);
$messageData = $validationData["customMessages"]["DenyDuplicated"];
if( $messageData["messageType"] == "Text" )
$message = $messageData["message"];
else
$message = GetCustomLabel( $messageData["message"] );
return $this->pSet->label( $fName ).": ".str_replace( "%value%", substr( $value, 0, 10), $message );
}
/**
* Check if the field's value duplicates with any of database field's values
*
* @param {String} $fieldName
* @param {String | Number} $value
* @retrun {Boolean}
*/
function hasDuplicateValue($fieldName, $value)
{
//skip empty value
if( !strlen( $value ) )
return false;
$dc = new DsCommand();
$dc->filter = DataCondition::FieldEquals( $fieldName, $value, 0, dsCASE_DEFAULT );
$dc->totals = array();
$dc->totals[] = array(
"total" => "count",
"alias" => "count_".$fieldName,
"field" => $fieldName,
);
$qResult = $this->dataSource->getTotals( $dc );
$data = $qResult->fetchAssoc();
if( !$data[ "count_".$fieldName ] )
return false;
return true;
}
/**
* Fetch blocks ( {BEGIN ...} {END ...} ) content
* @param Array|String blocks
* @param Boolean dash (optional)
* @return String
*/
function fetchBlocksList( $blocks, $dash = false )
{
if( !is_array( $blocks ) )
return $this->xt->fetch_loaded( $blocks );
$fetchedBlocks = "";
$firstRightAligned = true;
$hasRightAligned = false;
$brickCount = 0;
foreach( $blocks as $b )
{
++$brickCount;
$align="";
if( is_array($b) )
{
$name = $b["name"];
$align= $b["align"];
}
else
{
$name = $b;
}
$fetched = $this->xt->fetch_loaded( $name );
if( !$fetched )
continue;
if( $dash )
{
$alignClass = "";
if( $align == "right" )
$alignClass = "rnr-dberight";
$fetched = '' . $fetched . "";
if( $align == "right" && $firstRightAligned)
{
$fetched = "" . $fetched;
$firstRightAligned = false;
$hasRightAligned = true;
}
}
$fetchedBlocks.= $fetched;
}
if( $dash && $fetchedBlocks!= "" && $brickCount > 1 && !$hasRightAligned )
$fetchedBlocks .= "";
return $fetchedBlocks;
}
/**
* @return Boolean
*/
protected function needPopupSettings()
{
return true;
}
/**
* @param String templatefile
* @param Number id
*/
function displayAJAX($templatefile, $id)
{
if( $this->gridTabsAvailable() )
{
$this->pageData['tabs'] = $this->getTabsHtml();
$this->pageData['tabId'] = $this->getCurrentTabId();
}
$returnJSON = array();
$returnJSON["success"] = true;
global $pagesData;
$returnJSON["pagesData"] = $pagesData;
if( count( $this->controlsHTMLMap ) )
$returnJSON['controlsMap'] = $this->controlsHTMLMap;
if( count( $this->viewControlsHTMLMap ) )
$returnJSON['viewControlsMap'] = $this->viewControlsHTMLMap;
if( count($this->includes_css) )
$returnJSON['CSSFiles'] = array_unique($this->includes_css);
$returnJSON['additionalJS'] = $this->grabAllJsFiles();
$returnJSON['idStartFrom'] = $id;
if( $this->getLayoutVersion() === PD_BS_LAYOUT )
{
$this->xt->load_template($templatefile);
if( count( $this->headerForms ) )
$returnJSON['headerCont'] = $this->fetchForms( $this->headerForms );
if( count( $this->footerForms ) )
$returnJSON['footerCont'] = $this->fetchForms( $this->footerForms );
}
else
{
if( $this->formBricks['header'] )
$returnJSON['headerCont'] = $this->fetchBlocksList( $this->formBricks['header'] );
if( $this->formBricks['footer'] )
$returnJSON['footerCont'] = $this->fetchBlocksList( $this->formBricks['footer'] );
}
if( $this->pageType == PAGE_CHART )
{
$returnJSON['headerCont'] = ''
. $this->getPageTitle( $this->pageType, GoodFieldName($this->tName) )
. "";
}
$this->assignFormFooterAndHeaderBricks( false );
$returnJSON['html'] = $this->getBodyMarkup( $templatefile );
if( $this->needPopupSettings() )
$returnJSON['settings'] = $this->jsSettings;
$extraParams = $this->getExtraAjaxPageParams();
if( count($extraParams) )
{
foreach( $extraParams as $param => $paramValue )
{
$returnJSON[ $param ] = $paramValue;
}
}
echo printJSON($returnJSON);
}
/**
* @param templatefile string
* @return string
*/
protected function getBodyMarkup( $templatefile )
{
if( $this->getLayoutVersion() === PD_BS_LAYOUT )
return $this->fetchForms( $this->bodyForms );
$this->xt->load_template( $templatefile );
return $this->xt->fetch_loaded('body');
}
/**
* A stub.
* Get extra JSON params to display the page on AJAX-like request
* @return Array
*/
protected function getExtraAjaxPageParams()
{
return array();
}
/**
* Assign 'form' footer and header elements
* @param Boolean assignValue
*/
public function assignFormFooterAndHeaderBricks( $assignValue = true )
{
if( $this->formBricks["header"] )
{
if( !is_array( $this->formBricks["header"] ) )
{
$this->formBricks["header"] = array( $this->formBricks["header"] );
}
foreach( $this->formBricks["header"] as $b )
{
$name = $b;
if( is_array($b) )
$name = $b["name"];
$this->xt->assign( $name, $assignValue );
}
}
if( $this->formBricks["footer"] )
{
if( !is_array( $this->formBricks["footer"] ) )
{
$this->formBricks["footer"] = array( $this->formBricks["footer"] );
}
foreach( $this->formBricks["footer"] as $b )
{
$name = $b;
if( is_array($b) )
$name = $b["name"];
$this->xt->assign( $name, $assignValue );
}
}
}
/**
* Assign styles to the page
* @param Boolean isPdfPage (optional)
*/
function assignStyleFiles( $isPdfPage = false )
{
global $wizardBuildKey, $projectBuildKey;
for ( $i = 0; $i < count($this->includes_css); $i++ )
{
$f = $this->includes_css[$i];
if ( $this->isCustomCssFile($f) )
$addKey = "?" . $projectBuildKey;
else
$addKey = "?" . $wizardBuildKey;
if ( strpos($f, "style.css") > 0 )
$addKey .= "&" . $projectBuildKey;
$this->includes_css[$i] = $f . $addKey;
}
$this->xt->assign_array("styleCSSFiles", "stylepath", array_unique($this->includes_css));
$this->includes_css = array();
$this->xt->assign("wizardBuildKey", $wizardBuildKey);
}
function isCustomCssFile( $file ) {
return strpos( $file, "/pages/" ) > 0
|| strpos( $file, "/custom/" ) > 0;
}
/**
* Displays the page using $templatefile
*/
function display($templatefile)
{
$this->assignStyleFiles();
$this->xt->display($templatefile);
}
/**
* returns where clause for active master-detail relationship
* @param Boolean basedOnProp (optional) true view-edit dp case
* @return string
*/
function getMasterTableSQLClause()
{
$where = "";
if( !count( $this->detailKeysByM ) )
return $where;
for($i = 0; $i < count( $this->detailKeysByM ); $i++)
{
if($i != 0)
$where.= " and ";
//#14869
$mKey = $this->masterKeysReq[ $i + 1 ];
/*$mKey = $_SESSION[ $this->sessionPrefix."_masterkey".($i + 1) ];*/
if( $this->cipherer && $this->cipherer->isEncryptionByPHPEnabled() )
$mValue = $this->cipherer->MakeDBValue( $this->detailKeysByM[ $i ], $mKey );
else
$mValue = make_db_value( $this->detailKeysByM[$i], $mKey, "", "", $this->tName );
if( strlen($mValue) != 0 )
$where.= $this->getFieldSQLDecrypt( $this->detailKeysByM[$i] ) . "=" . $mValue;
else
$where.= "1=0";
}
return $where;
}
/**
* A wrapper for the SecuritySQL function
* @param String strAction
* @paran String table
* @return String
*/
function SecuritySQL($strAction )
{
return SecuritySQL($strAction, $this->tName );
}
function showGridOnly() {
return "";
}
/**
* Show a detail preview page
* @param Array params - asp compatibility issue
*/
function showPageDp($params = "")
{
if( $this->isBootstrap() )
{
return $this->showGridOnly();
}
global $page_layouts;
$layout =& $page_layouts[$this->shortTableName.'_'.$this->pageType];
$pageSkinStyle = $layout->style.' page-'.$layout->name;
//set bricks, which must be shown on details preview page
if( $this->pageType == PAGE_CHART )
$bricksExcept = array('chart', 'message');
else
$bricksExcept = array('grid', 'pagination', 'message');
$bricksExcept[] = "bsgrid_tabs";
// if we use details inline. We don't need show the header/footer.
$this->xt->assign("header", false);
$this->xt->assign("footer", false);
$this->xt->hideAllBricksExcept($bricksExcept);
$this->xt->prepare_template($this->templatefile);
$contents = $this->renderPageBody();
echo ''.$contents.'
';
}
function renderPageBody()
{
return $this->xt->fetch_loaded('body');
}
/**
* Proccess master-details
*
* @param array $record
* @param array $data
* @param Number gridRowInd
*/
function proccessDetailGridInfo(&$record, &$data, $gridRowInd)
{
$hideDPLink = true;
$hiddenPreviewTabs = array();
// not bs layouts
$tabNamesToHide = array();
for($i = 0; $i < count($this->allDetailsTablesArr); $i ++)
{
$detailTableData = $this->allDetailsTablesArr[$i];
$dDataSourceTable = $detailTableData['dDataSourceTable'];
$dPset = new ProjectSettings( $dDataSourceTable );
$detTableType = $dPset->getEntityType();
$detListAvailabel = ( $dPset->hasListPage() || isChart( $detTableType ) || isReport( $detTableType ) ) && $this->permis[$dDataSourceTable]["search"];
$detAddAvailabel = $dPset->hasAddPage() && $this->permis[$dDataSourceTable]["add"];
$detEditAvailabel = $dPset->hasEditPage() && $this->permis[$dDataSourceTable]["edit"];
if( $detailTableData['dType'] == PAGE_LIST && !$detListAvailabel && !$detAddAvailabel && !$detEditAvailabel )
continue;
$dShortTable = $detailTableData['dShortTable'];
$masterquery = "mastertable=".rawurlencode($this->tName);
initArray($this->controlsMap, 'gridRows');
initArray($this->controlsMap['gridRows'], $gridRowInd);
initArray($this->controlsMap['gridRows'][ $gridRowInd ], 'masterKeys');
$this->controlsMap['gridRows'][ $gridRowInd ]['masterKeys'][ $dDataSourceTable ] = array();
$detailid = array();
foreach($this->masterKeysByD[$i] as $idx => $m)
{
$curM = $m;
if ($this->pageType==PAGE_REPORT)
{
$curM = goodFieldName($curM);
$curM .= '_dbvalue';
}
$masterquery.= "&masterkey".($idx + 1)."=".rawurlencode( $data[ $curM ] );
// Don't need to use here make_db_value func, it use in countDetailsRecsNoSubQ func
$detailid[] = $data[ $curM ];
$this->controlsMap['gridRows'][ $gridRowInd ]['masterKeys'][ $dDataSourceTable ]["masterkey".($idx + 1)] = $data[ $curM ];
}
// skip the rest if no details link needed
if( !$this->detailsInGridAvailable() )
continue;
// add count of child records to SQL
if( ( $this->pSet->detailsShowCount( $dDataSourceTable )
|| $this->pSet->detailsHideEmpty( $dDataSourceTable )
|| $this->pSet->detailsHideEmptyPreview( $dDataSourceTable ) )
&& !$this->isDetailTableSubqueryApplied( $dDataSourceTable ) )
{
$data[ $dDataSourceTable."_cnt" ] = $this->countDetailsRecsNoSubQ($i, $detailid);
}
//detail tables
$record[ $dShortTable."_dtable_link" ] = $this->permis[ $dDataSourceTable ]['add']
|| $this->permis[ $dDataSourceTable ]['edit'] || $this->permis[ $dDataSourceTable ]['search'];
if( $this->pSet->detailsShowCount( $dDataSourceTable ) )
{
if( $data[ $dDataSourceTable."_cnt" ] + 0 )
$record[ $dShortTable."_childcount" ] = true;
else if( $this->isBootstrap() )
{
if( $this->pSet->detailsLinks() != DL_INDIVIDUAL )
$record[ $dShortTable."_childcount" ] = true;
$record[ $dShortTable."_dlink_class" ] = "hidden-badge";
$record[ $dShortTable."_cntspan_class" ] = "hidden-detcounter";
}
$record[ $dShortTable."_childnumber" ] = $data[ $dDataSourceTable."_cnt" ];
$record[ $dShortTable."_childnumber_attr" ] = " id='cntDet_".$dShortTable."_".$this->recId."'";
$this->controlsMap['gridRows'][ $gridRowInd ]['childNum'] = $data[ $dDataSourceTable."_cnt" ];
}
// detail link prepare
if ( $detListAvailabel ) {
$detHref = GetTableLink($dShortTable, $detailTableData['dType'], $masterquery);
}
else if ( $detAddAvailabel )
{
$detHref = GetTableLink($dShortTable, PAGE_ADD, $masterquery);
}
else if ( $detEditAvailabel )
{
$detHref = GetTableLink($dShortTable, PAGE_EDIT, $masterquery);
}
$record[ $dShortTable."_link_attrs" ] = " href=\"".$detHref."\" id=\"details_".$this->recId."_".$dShortTable."\" ";
if ( $this->getLayoutVersion() < PD_BS_LAYOUT ) {
if( $this->pSet->detailsPreview($dDataSourceTable) == DP_INLINE )
{
$record[ $dShortTable."_dtablelink_attrs" ] = "id = \"".$dShortTable."_preview".$this->recId."\"
caption = \"".runner_htmlspecialchars( GetTableCaption(GoodFieldName($dDataSourceTable)) )."\"".
"href = \"".$detHref."\"";
}
else if( $this->pSet->detailsPreview($dDataSourceTable) == DP_POPUP )
{
$record[ $dShortTable."_dtablelink_attrs" ] = "id=\"master_".$dShortTable."_".$this->recId."\" href=\"".$detHref."\"";
}
else
{
$record[ $dShortTable."_dtablelink_attrs" ] = "href=\"".$detHref."\"";
}
}
if( $this->pSet->detailsHideEmpty($dDataSourceTable) )
{
if( !($data[ $dDataSourceTable."_cnt" ] + 0) )
{
if ( $this->getLayoutVersion() === PD_BS_LAYOUT )
{
$record[ $dShortTable."_link_attrs" ] .= " class=\"".$this->makeClassName("hiddenelem")."\" data-hidden";
}
else
{
$record[ $dShortTable."_dtablelink_attrs" ] .= " class=\"".$this->makeClassName("hiddenelem")."\" data-hidden";
$tabNamesToHide[] = $dDataSourceTable; // ?? hide empty tabs for single mode
}
}
elseif( $this->pSet->detailsPreview( $dDataSourceTable ) && $hideDPLink )
{
$hideDPLink = false;
}
}
elseif( $hideDPLink )
$hideDPLink = false;
if ( $this->pSet->detailsHideEmptyPreview( $dDataSourceTable ) && !($data[ $dDataSourceTable."_cnt" ] + 0) )
$hiddenPreviewTabs[] = $dDataSourceTable;
}
// Issue #12581
if ( $this->pSet->detailsLinks() == DL_SINGLE )
{
if ( count($this->allDetailsTablesArr) == 1 && !$detListAvailabel && ( $detAddAvailabel || $detEditAvailabel ) )
{
$record["dtables_link_attrs"] = " href=\"".$detHref."\"";
}
else
{
$record["dtables_link_attrs"] = " href=\"#\" id=\"details_".$this->recId."\" ";
}
}
if( $hideDPLink )
{
$record["dtables_link_attrs"].= " class=\"".$this->makeClassName("hiddenelem")."\" data-hidden";
if( $this->isBootstrap() )
$record["dtables_link_class"] = $this->makeClassName("hiddenelem");
}
if( $this->pSet->detailsLinks() == DL_SINGLE && count($tabNamesToHide) ) {
$record["dtables_link_attrs"].= " data-hiddentabs=\"".runner_htmlspecialchars( my_json_encode( $tabNamesToHide ) )."\"";
$this->controlsMap['gridRows'][ $gridRowInd ][ 'hiddentabs' ] = $tabNamesToHide;
}
if( $hiddenPreviewTabs )
{
$this->controlsMap['gridRows'][ $gridRowInd ][ 'hiddenPreviewTabs' ] = $hiddenPreviewTabs;
}
}
/**
* Get proceed link for details previews
* return HTML link
*/
function getProceedLink()
{
if( $this->isBootstrap() )
return "";
$masterPSet = $this->getMasterPSet();
if( !$masterPSet->detailsProceedLink( $this->tName ) )
return "";
return ''
.''
. ##message PROCEED_TO## . ' '. GetTableCaption( GoodFieldName( $this->tName ) )
. ''
. " ";
}
public function getProceedUrl()
{
for($i = 1; $i <= count( $this->masterKeysReq ); $i++)
{
$strkey.= "&masterkey".($i)."=".rawurlencode( $this->masterKeysReq[$i] );
}
return GetTableLink( $this->shortTableName, $this->pageType ) . "?mastertable=".rawurlencode( $this->masterTable ) . $strkey;
}
/**
* A stub #9875
* @param String dDataSourceTable The detail datasource table name
* @param Number dTableIndex The detail table index in the allDetailsTablesArr prop
* @return Boolean
*/
protected function isDetailTableSubquerySupported( $dDataSourceTName, $dTableIndex )
{
return false;
}
/**
* @param String table The detail datasource table name
* @return Boolean
*/
protected function isDetailTableSubqueryApplied( $table )
{
return false;
}
/**
* Get details params
* @param Number ids
* @return Array
*/
public function getDetailsParams( $ids )
{
$dpParams = array();
if( $this->pageType != PAGE_VIEW && $this->pageType != PAGE_EDIT && $this->pageType != PAGE_ADD )
return $dpParams;
foreach( $this->allDetailsTablesArr as $detailData )
{
$strDetTableName = $detailData["dDataSourceTable"];
if( $this->pSet->detailsPreview( $strDetTableName ) != DP_INLINE )
continue;
$dpPermis = $this->getPermissions( $strDetTableName );
if( ($this->pageType == PAGE_VIEW || $this->pageType == PAGE_EDIT) && $dpPermis['search'] || $this->pageType == PAGE_EDIT && $dpPermis['edit']
|| $this->pageType == PAGE_ADD && $dpPermis['add'] )
{
$dpParams['ids'][] = ++$ids;
$dpParams['strTableNames'][] = $strDetTableName;
$dpParams['type'][] = $detailData["dType"];
$dpParams['shorTNames'][] = $detailData["dShortTable"];
}
}
return $dpParams;
}
/**
* Prepare the detail preview data, fille coresssponding controls maps and
* assign all required xt variables
* @param String dpType
* @param String dpTableName
* @param Number dpId
* @param &Array data
*/
public function setDetailPreview( $dpType, $dpTableName, $dpId, &$data)
{
if( $this->pageType != PAGE_EDIT && $this->pageType != PAGE_VIEW && $this->pageType != PAGE_ADD || !CheckTablePermissions($dpTableName, "S") )
return;
if( $dpType == PAGE_CHART )
$this->setDetailChartOnEditView( $dpTableName, $dpId, $data );
elseif( $dpType == PAGE_REPORT )
$this->setDetailReportOnEditView( $dpTableName, $dpId, $data );
else // $dpType == PAGE_LIST
$this->setDetailList( $dpTableName, $dpId, $data );
}
/**
*
*/
protected function getDetailsPageObject( $tName, $listId = 0, $data = array() )
{
include_once( getabspath('classes/reportpage.##@ext##') );
if( $this->detailsTableObjects[ $tName ] )
return $this->detailsTableObjects[ $tName ];
// new page id is required when creating the page object
if( !$listId )
return null;
$entityType = GetEntityType( $tName );
$options = array();
$options["id"] = $listId;
$options["firstTime"] = 1;
$options["pdfMode"] = $this->pdfMode;
$options["masterTable"] = $this->tName;
$options["masterPageType"] = $this->pageType;
$options["xt"] = new Xtempl( true ); //#9607 1. Temporary fix
$options["flyId"] = $this->genId() + 1;
$options["masterKeysReq"] = array();
$options["pushContext"] = false;
if( $this->pdfJsonMode() )
$options["pdfJson"] = true;
$mkr = 1;
$mKeys = $this->pSet->getMasterKeysByDetailTable( $tName );
$masterKeys = array(); //for PAGE_EDIT only
foreach($mKeys as $mk)
{
$options["masterKeysReq"][ $mkr ] = $data[ $mk ];
$masterKeys["masterKey".$mkr] = $data[ $mk ];
$mkr++;
}
if ( $this->getLayoutVersion() === PD_BS_LAYOUT )
$options["pageName"] = $this->pSet->detailsPageId( $tName );
if( titTABLE == $entityType || titVIEW == $entityType || titSQL == $entityType || titREST == $entityType )
{
$options["mode"] = $this->pdfJsonMode() ? LIST_PDFJSON: LIST_DETAILS;
$options["pageType"] = PAGE_LIST;
$pageObject = ListPage::createListPage($tName, $options);
}
else if( isReport( $entityType ) )
{
$options["tName"] = $tName;
$options["mode"] = REPORT_DETAILS;
$options["pageType"] = PAGE_REPORT;
$pageObject = new ReportPage($options);
}
else if( isChart( $entityType ) )
{
$options["tName"] = $tName;
$options["mode"] = CHART_DETAILS;
$options["pageType"] = PAGE_CHART;
$pageObject = new ChartPage($options);
}
$this->detailsTableObjects[ $tName ] = $pageObject;
return $pageObject;
}
/**
* A stub
*/
function assignButtonsOnMasterEdit( $masterXt )
{
}
/**
* @param String listTName
* @param Number listId
* @param &Array data
*/
protected function setDetailList( $listTName, $listId, &$data )
{
include_once( getabspath('classes/listpage.##@ext##') );
include_once( getabspath('classes/listpage_embed.##@ext##') );
include_once( getabspath('classes/listpage_dpinline.##@ext##') );
//array of params for classes
$listPageObject = $this->getDetailsPageObject( $listTName, $listId, $data );
RunnerContext::push( $listPageObject->standaloneContext );
$listPageObject->prepareForBuildPage();
if( $listPageObject->shouldDisplayDetailsPage() )
{
//set page events
foreach( $listPageObject->eventsObject->events as $event => $name )
{
$listPageObject->xt->assign_event($event, $listPageObject->eventsObject, $event, array());
}
//add detail settings to master settings
$listPageObject->addControlsJSAndCSS();
$listPageObject->fillSetCntrlMaps();
$listPageObject->BeforeShowList();
$this->assignDisplayDetailTableXtVariable( $listPageObject );
$this->copyDetailPreviewJSAndCSS( $listPageObject );
$this->updateSettingsWidthDPData( $listPageObject );
$this->viewControlsMap["dViewControlsMap"][ $listTName ] = $listPageObject->viewControlsMap;
$this->controlsMap["dControlsMap"][ $listTName ] = $listPageObject->controlsMap;
if( $this->pageType == PAGE_EDIT )
$this->controlsMap["dControlsMap"]["masterKeys"] = $masterKeys; //?
$this->controlsMap["dpTablesParams"][] = array("tName" => $listTName, "id" => $listId, "pType" => PAGE_LIST);
}
$this->flyId = $listPageObject->recId + 1;
RunnerContext::pop();
}
/**
* @param String reportTName
* @param Number reportId
* @param &Array data
*/
protected function setDetailReportOnEditView( $reportTName, $reportId, &$data )
{
include_once( getabspath('classes/reportpage.##@ext##') );
//array of params for ReportPage constructor
$options = array();
$options["id"] = $reportId;
$options["mode"] = REPORT_DETAILS;
$options["pdfMode"] = $this->pdfMode;
$options["tName"] = $reportTName;
$options["pageType"] = PAGE_REPORT;
$options["masterPageType"] = $this->pageType;
$options["masterTable"] = $this->tName;
$options["xt"] = new Xtempl( true ); //#9607 1. Temporary fix
$options["flyId"] = $this->genId() + 1;
$options["masterKeysReq"] = array();
$options["pushContext"] = false;
if( $this->pdfJsonMode() )
$options["pdfJson"] = true;
$mkr = 1;
$mKeys = $this->pSet->getMasterKeysByDetailTable( $reportTName );
foreach($mKeys as $mk)
{
$options["masterKeysReq"][ $mkr++ ] = $data[ $mk ];
}
$reportPageObject = new ReportPage( $options );
RunnerContext::push( $reportPageObject->standaloneContext );
$reportPageObject->init();
if( $this->mobileTemplateMode() )
$reportPageObject->pageSize = -1;
// build tabs and set current
$reportPageObject->processGridTabs();
$reportPageObject->prepareDetailsForEditViewPage();
if( !$reportPageObject->shouldDisplayDetailsPage() )
return false;
//add detail settings to master settings
$reportPageObject->addControlsJSAndCSS();
$reportPageObject->fillSetCntrlMaps();
$reportPageObject->beforeShowReport();
$this->assignDisplayDetailTableXtVariable( $reportPageObject );
$this->copyDetailPreviewJSAndCSS( $reportPageObject );
$this->updateSettingsWidthDPData( $reportPageObject );
$this->viewControlsMap["dViewControlsMap"][ $reportTName ] = $reportPageObject->viewControlsMap;
$this->controlsMap["dControlsMap"][ $reportTName ] = $reportPageObject->controlsMap;
$this->controlsMap["dpTablesParams"][] = array("tName" => $reportTName, "id" => $options["id"], "pType" => PAGE_REPORT);
RunnerContext::pop();
}
/**
* @param String chartTName
* @param Number chartId
* @param &Array data
*/
protected function setDetailChartOnEditView( $chartTName, $chartId, &$data )
{
if( $this->pdfMode )
return;
include_once( getabspath('classes/chartpage.##@ext##') );
$xt = new Xtempl( true ); //#9607 1. Temporary fix
$options = array();
$options["xt"] = &$xt;
$options["id"] = $chartId;
$options["tName"] = $chartTName;
$options["mode"] = CHART_DETAILS;
$options["pageType"] = PAGE_CHART;
$options["masterPageType"] = $this->pageType;
$options["masterTable"] = $this->tName;
$options["flyId"] = $this->genId() + 1; //fix it
$options["pushContext"] = false;
$mkr = 1;
$mKeys = $this->pSet->getMasterKeysByDetailTable( $chartTName );
foreach($mKeys as $mk)
{
$options["masterKeysReq"][ $mkr++ ] = $data[ $mk ];
}
$masterKeysReq = $options["masterKeysReq"];
if(count($masterKeysReq))
{
// copy keys to session
for($i = 1; $i <= count($masterKeysReq); $i++)
$_SESSION[ $chartTName."_masterkey".$i ] = $masterKeysReq[ $i ];
if( isset($_SESSION[ $chartTName."_masterkey".$i ]) )
unset( $_SESSION[ $chartTName."_masterkey".$i ] );
}
$chartPageObject = new ChartPage($options);
RunnerContext::push( $chartPageObject->standaloneContext );
$chartPageObject->init();
$chartXtParams["id"] = $options["flyId"];
$chartXtParams["table"] = $chartTName;
$chartXtParams["ctype"] = $chartPageObject->pSet->getChartType();
$chartXtParams["chartName"] = $chartPageObject->shortTableName;
$chartXtParams["singlePage"] = true;
$chartXtParams["containerId"] = "rnr" . $chartXtParams["chartName"] . $chartXtParams["id"];
$xt->assign_function( $chartPageObject->shortTableName."_chart","xt_showchart", $chartXtParams );
// build tabs and set current
$chartPageObject->processGridTabs();
$chartPageObject->prepareDetailsForEditViewPage();
if( $this->mobileTemplateMode() )
$xt->assign("container_menu", false);
$chartPageObject->addControlsJSAndCSS();
$chartPageObject->fillSetCntrlMaps();
$this->AddJSFile('libs/js/anychart.min.js');
// $this->AddJSFile('libs/js/migrationTool.js');
$chartPageObject->beforeShowChart();
$this->assignDisplayDetailTableXtVariable( $chartPageObject );
$this->copyDetailPreviewJSAndCSS( $chartPageObject );
//add detail settings to master settings
$this->updateSettingsWidthDPData( $chartPageObject );
$this->viewControlsMap["dViewControlsMap"][ $chartTName ] = $chartPageObject->viewControlsMap;
$this->controlsMap["dControlsMap"][ $chartTName ] = $chartPageObject->controlsMap;
$this->controlsMap["dpTablesParams"][] = array("tName" => $chartTName, "id" => $options['id'], "pType" => PAGE_CHART );
RunnerContext::pop();
}
/**
* Get the key values array form the record data array passed
* // It's used on the edit/view pages only
* @param Array data
* @return Array
*/
protected function getKeysFromData( $data )
{
$keys = array();
$keyFields = $this->pSet->getTableKeys();
foreach( $keyFields as $keyField )
{
$keys[ $keyField ] = $data[ $keyField ];
}
return $keys;
}
/**
* Add detail JS and CSS files to the master's files list
* @param &RunnerPage dtPageObject
*/
protected function copyDetailPreviewJSAndCSS( &$dtPageObject )
{
$layout = GetPageLayout( $dtPageObject->tName, $dtPageObject->pageType );
if($layout)
$this->AddCSSFile( $layout->getCSSFiles(isRTL(), isPageLayoutMobile($this->templatefile), $this->pdfMode != "" ) );
//Add detail's js files to master's files
$this->copyAllJSFiles( $dtPageObject->grabAllJSFiles() );
//Add detail's css files to master's files
$this->copyAllCSSFiles( $dtPageObject->grabAllCSSFiles() );
}
/**
* Add detail settings to master settings
* @param &RunnerPage dtPageObject
*/
protected function updateSettingsWidthDPData( &$dtPageObject )
{
$tName = $dtPageObject->tName;
$this->jsSettings["tableSettings"][ $tName ] = $dtPageObject->jsSettings["tableSettings"][ $tName ];
foreach($dtPageObject->jsSettings["global"]["shortTNames"] as $keySet => $val)
{
if( !array_key_exists($keySet, $this->settingsMap["globalSettings"]["shortTNames"]) )
$this->settingsMap["globalSettings"]["shortTNames"][ $keySet ] = $val;
}
}
/**
* @param &RunnerPage dtPageObject
*/
protected function assignDisplayDetailTableXtVariable( &$dtPageObject )
{
if( $this->getLayoutVersion() >= BOOTSTRAP_LAYOUT ) {
$dtPageObject->prepareDisplayDetails();
$this->xt->assign_method( "detailslButtons_". $dtPageObject->shortTableName , $dtPageObject, 'showButtonsDp', false );
$this->xt->assign( "proceedAttrs_". $dtPageObject->shortTableName, 'href="' .$dtPageObject->getProceedUrl().'"' );
}
$this->xt->assign( "details_". $dtPageObject->shortTableName, true );
$this->xt->assign_method( "displayDetailTable_". $dtPageObject->shortTableName , $dtPageObject, 'showPageDp', false );
}
/**
* Remove columns hidden on the current device from the inline control fields list
* @param &Array inlineControlFields
* @param Number screenWidth
* @param Number screenHeight
* @param String orientation The current device orientation identifier
* @return Array
*/
public function removeHiddenColumnsFromInlineFields( $inlineControlFields, $screenWidth, $screenHeight, $orientation )
{
// don't remove inline fields if the user can show them
if( $this->showHideFieldsFeatureEnabled() )
return $inlineControlFields;
$devices = array( DESKTOP, TABLET_10_IN, SMARTPHONE_LANDSCAPE, SMARTPHONE_PORTRAIT, TABLET_7_IN );
foreach( $devices as $d )
{
$columnsToHide = $this->pSet->getHiddenFields( $d );
if( !count($columnsToHide) || !$this->isColumnHiddenForDevice( $d, $screenWidth, $screenHeight, $orientation ) )
continue;
foreach( $columnsToHide as $hiddenField => $status )
{
$fieldPos = array_search( $hiddenField, $inlineControlFields );
if( $fieldPos !== FALSE )
array_splice( $inlineControlFields, $fieldPos, 1);
}
return $inlineControlFields;
}
return $inlineControlFields;
}
/**
* Check if some columns must be hidden on a device of particular type
* if the current device has certain screen width and height params.
* See also ProjectSettings::getDeviceMediaClause method
* @param Number d Device identifier
* @param Number screenWidth
* @param Number screenHeight
* @param String orientation
*/
protected function isColumnHiddenForDevice( $d, $screenWidth, $screenHeight, $orientation )
{
if( $d == DESKTOP )
return $screenWidth >= 1281;
if( $d == TABLET_10_IN )
return $screenWidth == 768 && $screenHeight == 1024 || $screenWidth >= 1025 && $screenWidth <= 1280 && $screenHeight <= 1023 || $screenHeight >= 1025 && $screenHeight <= 1280 && $screenWidth <= 1023;
if( $d == TABLET_7_IN )
return $screenWidth <= 1024 && $screenHeight <= 800 || $screenHeight <= 1024 && $screenWidth <= 800;
if( $d == SMARTPHONE_LANDSCAPE )
return $screenHeight <= 420 && $orientation == 'landscape' || $screenWidth <= 420 && $orientation == 'landscape' ;
if( $d == SMARTPHONE_PORTRAIT )
return $screenHeight <= 420 && $orientation == 'portrait' || $screenWidth <= 420 && $orientation == 'portrait';
return false;
}
/**
* @param String table A table name
* @param ProjectSettings pSet
* @return STring
*/
protected static function getKeysTitleTemplate($table, $pSet)
{
$keys = $pSet->getTableKeys();
$str = "";
foreach($keys as $k)
{
if( strlen($str) )
$str .= ", ";
$str .= "{%". GoodFieldName( $k ). "}";
}
return $str;
}
/**
* Get the default page's title template
* @param String page
* @param String table A good table name
* @param ProjectSettings pSet
* @return STring
*/
public static function getDefaultPageTitle($page, $table, $pSet)
{
if( $page == "add" )
return GetTableCaption($table).", ".##message ADD_NEW##;
if( $page == "edit" )
return GetTableCaption($table).", ".##message EDIT##." [". RunnerPage::getKeysTitleTemplate( $table, $pSet ). "]";
if( $page == "view" )
return GetTableCaption($table)." [". RunnerPage::getKeysTitleTemplate( $table, $pSet ). "]";
if( $page == "export" )
return ##message EXPORT##;
if( $page == "import" )
return GetTableCaption($table).", ".##message IMPORT##;
if( $page == "search" )
return GetTableCaption($table)." - ".##message ADVANCED_SEARCH##;
if( $page == "print" )
return GetTableCaption($table);
if( $page == "rprint" )
return GetTableCaption($table);
if( $page == "list" )
return GetTableCaption($table);
if( $page == "masterlist" )
return GetTableCaption($table)." [". RunnerPage::getKeysTitleTemplate( $table, $pSet ). "]";
if( $page == "masterchart" )
return GetTableCaption($table);
if( $page == "masterreport" )
return GetTableCaption($table)." [". RunnerPage::getKeysTitleTemplate( $table, $pSet ). "]";
if( $page == "masterprint" )
return GetTableCaption($table)." [". RunnerPage::getKeysTitleTemplate( $table, $pSet ). "]";
if( $page == "login" )
return ##message LOGIN##;
if( $page == "register" )
return ##message REGISTER##;
if( $page == "register_success" )
return ##message REG_SUCCESS##;
if( $page == "changepwd" )
return ##message CHANGE_PASSWORD##;
if( $page == "changepwd_success" )
return ##message CHANGE_PASSWORD##;
if( $page == "remind" )
return ##message REMINDER##;
if( $page == "remind_success" )
return ##message REMINDER##;
if( $page == "chart" )
return GetTableCaption($table);
if( $page == "report" )
return GetTableCaption($table);
if( $page == "dashboard" )
return GetTableCaption($table);
if( $page == "menu" )
return ##message MENU##;
if( $page == "admin_rights_list" || $page == "admin_members_list" || $page == "admin_admembers_list" )
return GetTableCaption($table);
}
/**
* Get a page's title template
* @param String page
* @param String table A good table name
* @param ProjectSettings pSet (optional)
* @return String
*/
protected function getPageTitleTemplate( $page, $table, $pSet )
{
global $page_titles;
if( !$table || $page == PAGE_REGISTER )
$table = ".global";
$templ = "";
if( array_key_exists($table, $page_titles) )
{
$templ = @$page_titles[ $table ][ mlang_getcurrentlang() ][ $page ];
}
if( strlen($templ) )
return $templ;
return RunnerPage::getDefaultPageTitle( $pSet->getPageType(), $table, $pSet );
}
/**
* @param String page
* @param String table (optional) A good table name
* @param Array record (optional) A source record data
* @param ProjectSettings settings (optional)
* @return String
*/
public function getPageTitle($page, $table = "", $record = null, $settings = null, $html = true )
{
$pSet = is_null( $settings ) ? $this->pSet : $settings;
$templ = $this->getPageTitleTemplate($page, $table, $pSet);
$masterRecord = array();
// check if template requires master record
if ( stripos($templ, "{%master." ) !== FALSE )
$masterRecord = $this->getMasterRecord();
$currentRecord = array();
if( $record )
{
$currentRecord = $record;
}
else
{
// check if template requires current record
if( preg_match('/{\%(?!master\.)[\w\s\-\.]*}/', $templ ) !== FALSE )
$currentRecord = $this->getCurrentRecord();
}
return $this->calcPageTitle( $templ, $currentRecord, $this->masterTable, $masterRecord, $pSet, $html );
}
/**
*
*/
public function calcPageTitle( $templ, $currentRecord = array(), $masterTable = "" , $masterRecord = array(), $pSet = null, $html = true )
{
if( !$pSet )
$pSet = $this->pSet;
if( !is_array( $masterRecord ) )
$masterRecord = array();
if( !is_array( $currentRecord ) )
$currentRecord = array();
$matches = array();
if( !preg_match_all('/{\%([\w\.\s\-]*)\}/', $templ, $matches) )
return $templ;
foreach( $matches[0] as $m )
{
if( !strcasecmp( substr($m, 0, 9), "{%master." ) )
{
$mSettings = new ProjectSettings( $masterTable, PAGE_LIST );
$field = $mSettings->getFieldByGoodFieldName( trim(substr( $m, 9, strlen($m) - 10 )) );
include_once getabspath('classes/controls/ViewControlsContainer.php');
$masterViewControl = new ViewControlsContainer($mSettings, PAGE_LIST);
$templ = str_replace($m, $masterRecord ? $masterViewControl->showDBValue($field, $masterRecord, "", "", $html) : "", $templ);
}
else
{
$field = $pSet->getFieldByGoodFieldName( trim(substr( $m, 2, strlen($m) - 3 )) );
$fieldValue = "";
if( $currentRecord ) {
$fieldValue = $this->pdfJsonMode()
? jsreplace( $this->getTextvalue( $field, $currentRecord) )
: $this->showDBValue( $field, $currentRecord, "", $html );
}
$templ = str_replace($m, $fieldValue, $templ );
}
}
return $templ;
}
public function setPageTitle( $str ) {
$this->xt->assign( "pagetitlelabel", $str );
}
function getCurrentRecord()
{
return array();
}
/**
* @param String field name (A good field name case-sensitive)
* @param String label value
* @return Boolean
*/
public function setFieldLabel($field, $label)
{
global $field_labels;
if(isset($field_labels[GoodFieldName($this->tName)][mlang_getcurrentlang()][GoodFieldName($field)]))
{
$field_labels[GoodFieldName($this->tName)][mlang_getcurrentlang()][GoodFieldName($field)] = $label;
return true;
}
else
return false;
}
protected function assignBody()
{
if( $this->pdfJsonMode() ) {
return;
}
$this->body["begin"] .= GetBaseScriptsForPage(false);
if( !$this->mobileTemplateMode() )
$this->body["begin"] .= "id."\">
\r\n";
$this->body['end'] = XTempl::create_method_assignment( "assignBodyEnd", $this );
$this->xt->assign("body", $this->body);
}
/**
*
*/
public function getInputElementId( $field, $pSet = null )
{
if( !$pSet )
$pSet = $this->pSet;
$format = $pSet->getEditFormat( $field );
if($format == EDIT_FORMAT_DATE)
{
$type = $pSet->getDateEditType($field);
if($type==EDIT_DATE_DD || $type==EDIT_DATE_DD_DP)
return "dayvalue_".GoodFieldName($field)."_".$this->id;
else
return "value_".GoodFieldName($field)."_".$this->id;
}
else if($format==EDIT_FORMAT_RADIO)
return "radio_".GoodFieldName($field)."_".$this->id."_0";
else if($format==EDIT_FORMAT_LOOKUP_WIZARD)
{
$lookuptype = $pSet->lookupControlType($field);
if( $this->mobileTemplateMode() && $lookuptype == LCT_AJAX )
$lookuptype = LCT_DROPDOWN;
if($lookuptype==LCT_AJAX || $lookuptype==LCT_LIST)
return "display_value_".GoodFieldName($field)."_".$this->id;
else
return "value_".GoodFieldName($field)."_".$this->id;
}
else
return "value_".GoodFieldName($field)."_".$this->id;
}
/**
* Get the current record data to build correct edit controls (xt_buildeditcontrol)
* @return Array
*/
public function getFieldControlsData()
{
return array();
}
/**
* @return Boolean
*/
public function isSearchPanelActivated()
{
return $this->searchPanelActivated;
}
/**
* Builds SQL expression based on key values:
* key1=1 and key2='a'
*
* @return String
*/
public function keysSQLExpression( $keys )
{
$keyFields = $this->pSet->getTableKeys();
$chunks = array();
foreach($keyFields as $kf)
{
$value = $this->cipherer->MakeDBValue($kf, $keys[ $kf ], "", true);
if( $this->connection->dbType == nDATABASE_Oracle )
$valueisnull = $value === "null" || $value == "''";
else
$valueisnull = $value === "null";
if( $valueisnull )
$chunks[] = $this->getFieldSQL( $kf )." is null";
else
$chunks[] = $this->getFieldSQLDecrypt( $kf )."=".$this->cipherer->MakeDBValue($kf, $keys[ $kf ], "", true);
}
return implode( " and ", $chunks );
}
/**
* Counts totals, depending on theirs type
*
* @param array $totals
* @param array $data
*/
function countTotals(&$totals, &$data)
{
for($i = 0; $i < count($this->totalsFields); $i ++)
{
$curTotalFieldValue = $data[$this->totalsFields[$i]['fName']];
if ( !isset($totals[$this->totalsFields[$i]['fName']]) )
{
$totals[$this->totalsFields[$i]['fName']] = 0;
}
if($this->totalsFields[$i]['totalsType'] == 'COUNT')
{
if ( $this->totalsFields[$i]['viewFormat'] == FORMAT_CHECKBOX && ( is_null($curTotalFieldValue) || !$curTotalFieldValue ) )
{
continue;
}
if(0 != strlen($curTotalFieldValue))
$totals[$this->totalsFields[$i]['fName']]++;
}
else if($this->totalsFields[$i]['viewFormat'] == "Time")
{
$time = GetTotalsForTime($curTotalFieldValue);
$totals[$this->totalsFields[$i]['fName']] += $time[2]+$time[1]*60 + $time[0]*3600;
}
else
$totals[$this->totalsFields[$i]['fName']]+=($curTotalFieldValue+ 0);
if($this->totalsFields[$i]['totalsType'] == 'AVERAGE')
{
if(!is_null($curTotalFieldValue) && $curTotalFieldValue!=="")
$this->totalsFields[$i]['numRows']++;
}
}
}
function deleteAvailable() {
return $this->pSet->hasDelete() && $this->permis[$this->tName]["delete"];
}
function importAvailable() {
return $this->permis[$this->tName]["import"] && $this->pSet->hasImportPage();
}
function editAvailable() {
return $this->pSet->hasEditPage() && $this->permis[$this->tName]["edit"];
}
function addAvailable() {
return $this->pSet->hasAddPage() && $this->permis[$this->tName]["add"];
}
function copyAvailable() {
return $this->pSet->hasCopyPage() && $this->permis[$this->tName]["add"];
}
function inlineEditAvailable() {
return $this->permis[$this->tName]["edit"] && $this->pSet->hasInlineEdit();
}
function updateSelectedAvailable() {
return $this->permis[$this->tName]["edit"] && $this->pSet->hasUpdateSelected();
}
function inlineAddAvailable() {
return $this->permis[$this->tName]["add"] && $this->pSet->hasInlineAdd();
}
function viewAvailable() {
return $this->permis[$this->tName]["search"] && $this->pSet->hasViewPage();
}
function exportAvailable() {
return $this->permis[$this->tName]["export"] && $this->pSet->hasExportPage();
}
function printAvailable() {
return $this->permis[$this->tName]["export"] && $this->pSet->hasPrintPage();
}
function advSearchAvailable() {
return $this->permis[$this->tName]["search"] && count( $this->pSet->getAdvSearchFields() );
}
/**
* Checks if grid tabs should be displayed on the the page.
* True for List, chart, report pages
* @return Boolean
*/
function gridTabsAvailable() {
return false;
}
function getIncludeFileMapProvider()
{
switch( getMapProvider() ){
case GOOGLE_MAPS:
return "gmap.js";
break;
case OPEN_STREET_MAPS:
return "osmap.js";
break;
case BING_MAPS:
return "bingmap.js";
break;
}
}
function includeOSMfile()
{
if( getMapProvider() == OPEN_STREET_MAPS )
$this->AddJSFile("plugins/OpenLayers.js");
}
/**
* Returns true is the page has multistepped layout
* @return boolean
*/
function isMultistepped()
{
return $this->pSet->isMultistepped();
}
/**
*
*/
function prepareSteps()
{
if( !$this->isMultistepped() )
return;
$this->xt->assign('steps_block', true);
$this->controlsMap['initialStep'] = $this->initialStep;
$this->controlsMap['multistep'] = true;
$this->xt->assign("nextStepButton", true);
}
protected function preparePdfControls()
{
if( $this->pdfMode )
return;
$this->controlsMap['printPdf'] = array();
$this->controlsMap['printPdf']['pageType'] = $this->pageType;
$this->xt->assign("pdflink_block", true);
}
function formatReportFieldValue( $field, &$data, $keylink = "" )
{
if( $this->format == "excel" || $this->format == "word")
{
return $this->getExportValue( $field, $data, $keylink, true );
}
return $this->showDBValue($field, $data, $keylink);
}
/**
*
*/
function getMasterTableInfo( $table = "")
{
if( $table == "" )
$table = $this->masterTable;
return $this->getMasterTableInfoByPSet($this->tName, $table, $this->pSet);
}
/**
* @param String tName
* @param String mtName
* @param ProjectSettings pSet
* @return Array
*/
protected function getMasterTableInfoByPSet( $tName, $mtName, $pSet )
{
$masterTablesInfoArr = $pSet->getMasterTablesArr();
if( !$masterTablesInfoArr )
return array();
foreach( $masterTablesInfoArr as $masterTableData )
{
if( $mtName == $masterTableData['mDataSourceTable'] )
return $masterTableData;
}
return array();
}
/**
* A wrapper for SearchClause::getSearchObject
* @return SearchClause
*/
public function getSearchObject()
{
return SearchClause::getSearchObject( $this->tName, $this->dashTName, $this->sessionPrefix,
$this->cipherer, $this->searchSavingEnabled, $this->pSet, $this->getLayoutVersion() === PD_BS_LAYOUT );
}
public function displayMenu($menuName, $menuType)
{
global $projectMenus;
if ( $this->isPD() && !in_array($menuName, $projectMenus) )
{
$menuName = "main";
}
if( $this->isAdminTable() )
$menuName = "adminarea";
$xt = new Xtempl();
$xt->assign("menuName", $menuName);
$xt->assign("menustyle", $menuStyle ? "second" : "main" );
if( $menuType == "quickjump" )
$menuMode = MENU_QUICKJUMP;
else if( $menuType == "horizontal" )
$menuMode = MENU_HORIZONTAL;
else
$menuMode = MENU_VERTICAL;
/* ??? */
if( !$this->isAdminTable() )
{
if( $menuMode != MENU_QUICKJUMP )
{
if( ProjectSettings::isMenuTreelike( $menuName ) )
{
if( MENU_VERTICAL == $menuMode )
$xt->assign("treeLikeTypeMenu",true);
else
$xt->assign("simpleTypeMenu",true);
}
else
{
if( !$this->mobileTemplateMode() )
$xt->assign("simpleTypeMenu",true);
else
$xt->assign("treeLikeTypeMenu",true);
}
}
if($this->pageType == PAGE_MENU && IsAdmin() && !$this->mobileTemplateMode())
$xt->assign("adminarea_link",true);
}
else
{
//Admin Area menu items
$xt->assign("adminAreaTypeMenu",true);
}
$menuRoot = $this->getMenuRoot( $menuName, $menuMode );
MenuItem::setMenuSession();
// call xtempl assign, set session params
$menuRoot->assignMenuAttrsToTempl($xt);
$menuRoot->setCurrMenuElem($xt);
$xt->assign("mainmenu_block",true);
$mainmenu = array();
if(isEnableSection508())
$mainmenu["begin"]="";
$mainmenu["end"] = '';
$countLinks = 0;
$countGroups = 0;
$showMenuCollapseExpandAll = false;
foreach($menuRoot->children as $ind=>$val)
{
if($val->showAsLink)
$countLinks++;
if ($val->showAsGroup)
{
if (count($val->children))
$showMenuCollapseExpandAll = true;
$countGroups++;
}
}
$xt->assign("menu_collapse_expand_all", $showMenuCollapseExpandAll);
$xt->assignbyref("mainmenu_block",$mainmenu);
$menufile = $menuName;
if($this->getLayoutVersion() == 1)
{
$menufile = "old".$menuName;
}
if($this->getLayoutVersion() == 3 || $this->getLayoutVersion() == 4)
{
$menufile = "bs".$menuName;
}
if( MENU_QUICKJUMP == $menuMode )
$menufile .= "_"."mainmenu_quickjump.htm";
else if( MENU_HORIZONTAL == $menuMode )
$menufile .= "_"."mainmenu_horiz.htm";
else if($this->mobileTemplateMode() && $this->getLayoutVersion() != 1)
$menufile .= "_"."mainmenu_m.htm";
else
{
// vertical menu
if(($this->getLayoutVersion() == 3 || $this->getLayoutVersion() == 4) && $menuName != WELCOME_MENU )
{
if( ProjectSettings::isMenuTreelike( $menuName ) )
$menufile .= "_"."mainmenu_tree.htm";
else
$menufile .= "_"."mainmenu_horiz.htm";
}
else
{
$menufile .= "_"."mainmenu.htm";
}
}
$xt->load_template( $menufile );
if( $peers )
{
$menuContent = array();
foreach( $peers as $p )
{
$menuContent[] = $xt->fetch_loaded("item".$p->id."_menulink");
}
$xt->assign("active_submenu", implode( "", $menuContent ));
}
$xt->display_loaded();
}
/**
* @param String mTName
* @param String mType
* @param String tName
* @param String pType
* @return Array
*/
protected function getMenuItemDetailPeersData( $mTName, $mType, $tName, $pType )
{
$mPSet = new ProjectSettings( $mTName, $mType );
$peers = array();
foreach( $mPSet->getDetailTablesArr() as $dt )
{
if( $dt["dDataSourceTable"] == $tName && $dt["dType"] == $pType )
continue;
if( $dt["dType"] == PAGE_LIST )
$type = "List";
elseif( $dt["dType"] == PAGE_CHART )
$type = "Chart";
else
$type = "Report";
if( !$this->isUserHaveTablePerm( $dt["dDataSourceTable"], $type ) )
continue;
$mKeys = array();
$masterRecordData = $_SESSION[ $mTName . "_masterRecordData" ];
$detailsData = array();
if( !$masterRecordData )
$masterRecordData = $this->getMasterRecord();
$keyLabelTemplates = array();
foreach( $dt["masterKeys"] as $idx => $dk )
{
$mKeys[] = "masterkey".($idx + 1)."=".rawurlencode( $masterRecordData[ $dk ] );
$keyLabelTemplates[] = "{%" . GoodFieldName( $dt["detailKeys"][$idx] ) . "}";
$detailsData[ $dt["detailKeys"][$idx] ] = $masterRecordData[ $dk ];
}
$href = GetTableLink( GetTableURL( $dt["dDataSourceTable"] ), $dt["dType"] );
$href.= "?".implode("&", $mKeys) ."&mastertable=" . rawurlencode($mTName);
$labelTemplate = Labels::getBreadcrumbsLabelTempl( $dt["dDataSourceTable"] , $mTName );
if( $labelTemplate == "" )
$labelTemplate = GetTableCaption( GoodFieldName( $dt["dDataSourceTable" ]) ) ." [" . implode( ", ", $keyLabelTemplates ) . "]";
$caption = $this->calcPageTitle($labelTemplate, $detailsData, $mTName, $masterRecordData, new ProjectSettings( $dt["dDataSourceTable"] ) );
$peers[] = array("title" => $caption, "href" => $href);
}
return $peers;
}
/**
* @param &MenuItem menuRoot
* @param &MenuItem currentMenuItem
* @return Array
*/
protected function getMasterDetailMenuItems( &$menuRoot, &$currentMenuItem )
{
$items = array();
$pSet = $this->pSet;
$tName = $this->tName;
$caption = GetTableCaption( GoodFieldName($tName) );
$pType = $this->pageType;
$sessionPrefix = $this->sessionPrefix;
while( isset( $_SESSION[ $sessionPrefix."_mastertable" ] ) )
{
$mTName = $_SESSION[ $sessionPrefix."_mastertable" ];
$masterTableData = $this->getMasterTableInfoByPSet( $tName, $mTName, $pSet );
if( !count( $masterTableData ) )
break;
$masterRecordData = $_SESSION[ $mTName . "_masterRecordData" ];
$detailsData = array();
$keyLabelTemplates = array();
foreach( $masterTableData["masterKeys"] as $idx => $dk )
{
$keyLabelTemplates[] = "{%" . GoodFieldName( $masterTableData["detailKeys"][$idx] ) . "}";
$detailsData[ $masterTableData["detailKeys"][$idx] ] = $masterRecordData[ $dk ];
}
if( $currentMenuItem )
{
$itemData = array("isMenuItem" => true, "menuItem" => $currentMenuItem, "title" => $currentMenuItem->title);
}
else
{
$caption = GetTableCaption( GoodFieldName( $tName ) );
$href = GetTableLink( GetTableURL( $tName ), $pType );
$itemData = array("isMenuItem" => false, "menuItem" => array( "href" => $href ), "title" => $caption );
}
if( !count( $items ) )
{
$otherDetailsData = $this->getMenuItemDetailPeersData( $mTName, $masterTableData["type"], $tName, $pType );
if( count( $otherDetailsData ) > 0 )
$itemData["detailPeers"] = $otherDetailsData;
}
$labelTemplate = Labels::getBreadcrumbsLabelTempl( $tName, $mTName );
if( $labelTemplate == "" )
$labelTemplate = $itemData["title"] . " [" . implode(", ", $keyLabelTemplates) . "]";
$itemData["title"] = $this->calcPageTitle( $labelTemplate, $detailsData, $mTName, $masterRecordData, $pSet );
$items[] = $itemData;
$currentMenuItem = $menuRoot->getItemByTypeAndTable( $mTName, $masterTableData["type"] );
$tName = $mTName;
$pType = $masterTableData["type"];
$sessionPrefix = $mTName;
$pSet = new ProjectSettings( $mTName, $masterTableData["type"] );
}
if( count( $items ) )
{
$crumb = array();
if( $currentMenuItem )
{
$crumb = array("isMenuItem" => true, "menuItem" => $currentMenuItem, "title" => $currentMenuItem->title );
}
else
{
$href = GetTableLink( GetTableURL( $tName ), $pType );
$crumb = array("isMenuItem" => false, "menuItem" => array( "href" => $href ), "title" => $caption );
}
$labelTemplate = Labels::getBreadcrumbsLabelTempl( $tName );
if( $labelTemplate != "" )
$crumb[ "title" ] = $this->calcPageTitle( $labelTemplate );
$items[] = $crumb;
}
return $items;
}
function getBreadcrumbMenuId() {
return "main";
}
protected function checkShowBreadcrumbs()
{
return true;
}
/**
* @param String menuId
*/
protected function prepareBreadcrumbs()
{
if ( !$this->checkShowBreadcrumbs() ) {
return;
}
$menuId = $this->getBreadcrumbMenuId();
if( !$this->isBootstrap() )
return;
if( $this->isPD() && !$this->pSet->hasBreadcrumb() ) {
return;
}
//$detailItem = isset( $_SESSION[ $this->sessionPrefix."_mastertable" ] ); // #14869
$detailItem = strlen( $this->masterTable ) > 0;
$menuRoot = $this->getMenuRoot( $menuId, MENU_HORIZONTAL );
MenuItem::setMenuSession();
$currentMenuItem = $menuRoot->getCurrentItem( $_SESSION["menuItemId"] );
if( !$currentMenuItem && !$detailItem )
return;
if( $currentMenuItem && !$detailItem )
{
if( !$currentMenuItem->parentItem )
return;
}
$this->xt->assign( "breadcrumbs", true );
if( $this->isPD() )
$this->xt->assign( "breadcrumb", true );
$this->xt->assign( "crumb_home_link", runner_htmlspecialchars( GetLocalLink("menu") ) );
$breadChain = $this->getMasterDetailMenuItems( $menuRoot, $currentMenuItem );
$firstShowPeersIndex = count( $breadChain );
if( $firstShowPeersIndex > 0 && $breadChain[ $firstShowPeersIndex - 1 ]["isMenuItem"] )
$currentMenuItem = $breadChain[ $firstShowPeersIndex - 1 ]["menuItem"]->parentItem;
if( $currentMenuItem )
{
while( $currentMenuItem->parentItem )
{
$crumb = array("isMenuItem" => true, "menuItem" => $currentMenuItem);
$labelTemplate = Labels::getBreadcrumbsLabelTempl( $currentMenuItem->getTable(), "", $currentMenuItem->getPageType() );
if( $labelTemplate != "" )
$crumb[ "title" ] = $this->calcPageTitle( $labelTemplate );
else
$crumb[ "title" ] = $currentMenuItem->title;
$breadChain[] = $crumb;
$currentMenuItem = $currentMenuItem->parentItem;
}
}
$breadcrumbs = array();
// add home item
for( $i = count( $breadChain ) - 1; $i >= 0; --$i )
{
$itemData = $breadChain[ $i ];
$crumb = array();
$item = null;
$attrs = array();
if( $itemData["isMenuItem"] )
{
$item = $itemData["menuItem"];
$attrs = $item->getMenuItemAttributes();
$href = $attrs["href"];
}
else
{
$href = $itemData["menuItem"]["href"];
}
$title = $itemData["title"];
if( $i < $firstShowPeersIndex && $i )
$crumb["crumb_attrs"] = 'href="' . $href . ( strpos( $href, "?" ) !== FALSE ? "&a=return" : "?a=return") . '"';
else
$crumb["crumb_attrs"] = 'href="' . $href . '"';
if( $firstShowPeersIndex > 0 && $i == 0 )
$crumb["crumb_title_span"] = true;
else
$crumb["crumb_title_link"] = true;
$crumb["crumb_title"] = $title;
if( $i < $firstShowPeersIndex && ( !count( $itemData["detailPeers"] ) || !$itemData["isMenuItem"] )
|| ( $this->isAdminTable() && GetGlobalData("nLoginMethod", 0) == SECURITY_AD ) )
{
$breadcrumbs[] = $crumb;
continue;
}
if ( is_null($item) )
continue;
$dropItems = array();
$peers = array();
$detailPeers = count( $itemData["detailPeers"] ) > 0;
if( $detailPeers )
$peers = $itemData["detailPeers"];
else
$item->parentItem->getItemDescendants( $peers );
if( count( $peers ) > 1 || $detailPeers )
{
foreach( $peers as $p )
{
if( $detailPeers )
{
$dropItems[] = ''. $p["title"] .'';
continue;
}
if( $p->id == $item->id )
continue;
$attrs = array();
if( !$p->isShowAsLink() && $p->isShowAsGroup() )
{
// show link to the first child if group
$childWithLink = $p->getFirstChildWithLink();
if( $childWithLink )
$attrs = $childWithLink->getMenuItemAttributes();
}
else if( $p->isShowAsLink() )
{
$attrs = $p->getMenuItemAttributes();
}
if( count( $attrs ) )
$dropItems[] = '' . $p->title . '';
}
if( count( $dropItems ) > 0 )
{
$crumb["crumb_title"] .= '';
$crumb["crumb_attrs"] .= ' class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"';
$crumb["crumb_item_class"] = 'dropdown';
$crumb["crumb_dropdown"] = '';
}
}
$breadcrumbs[] = $crumb;
}
$this->xt->assign_loopsection( "crumb", $breadcrumbs );
}
/**
*
*/
protected function prepareActiveMenuBranch( $menuRoot, $xt )
{
// display only current element peers and their children
$parentItem = $menuRoot;
$currentMenuItem = $menuRoot->getCurrentItem( $_SESSION["menuItemId"] );
if( $currentMenuItem )
{
$parentItem = $currentMenuItem->parentItem;
}
$peers = array();
$parentItem->getItemDescendants( $peers, 1 );
$peerIds = array();
foreach( $peers as $p )
$peerIds[ $p->id ] = true;
$menuRoot->assignMenuAttrsToTempl( $xt, $peerIds );
if( $peers && $parentItem->id != $menuRoot->id )
{
// return only 1st level siblings
$peers = array();
$parentItem->getItemDescendants( $peers, 0 );
return $peers;
}
else
return array();
}
/*
* Creates MenuItem object tree and returns the root node
* @param string $menuId
* @param string $menuMode - either MENU_HORIZONTAL or MENU_VERTICAL
*/
public function getMenuRoot( $menuId, $menuMode )
{
if( !isset( $this->menuRoots[ $menuMode . '-' . $menuId ] ) )
{
$menuNodes = $this->getMenuNodes($menuId);
// need to predefine vars
$nullParent = NULL;
$rootInfoArr = array("id"=>0, "href"=>"");
/* $menuNodesIndex must be set to 0 for to operate properly */
global $menuNodesIndex;
$menuNodesIndex=0;
$menuMap = array();
$this->menuRoots[ $menuMode . '-' . $menuId ] = new MenuItem($rootInfoArr, $menuNodes, $nullParent, $menuMap, $this, $menuId, $menuMode );
}
return $this->menuRoots[ $menuMode . '-' . $menuId ];
}
/**
*
*/
public function fillControlFlags( $field, $required = false )
{
if( $this->isBootstrap() && ( $required || $this->pSet->isRequired( $field ) ) )
$this->xt->assign( GoodFieldName( $field ) . "_label", array( "end" => ' ' ) );
else
$this->xt->assign( GoodFieldName( $field ) . "_label", true );
}
public function assignDetailsTablesBadgeColors()
{
$colors = array();
$colors[] = "lightslategrey";
$colors[] = "dodgerblue";
$colors[] = "maroon";
$colors[] = "teal";
$colors[] = "orange";
$colors[] = "chocolate";
$colors[] = "crimson";
$colors[] = "indianred";
$colors[] = "slateblue";
$colors[] = "mediumseagreen";
$colors[] = "darkolivegreen";
$styles = array();
foreach( $this->allDetailsTablesArr as $dt )
{
$styles[] = "." . $dt['dShortTable'] . "_badge { background-color: " . $colors[ rand(0, count($colors) - 1 ) ] . "; }";
}
$this->xt->assign( "containerCss", $this->xt->getvar( "containerCss" ) . implode( "", $styles ) );
}
protected function setDetailsBadgeStyles()
{
if( !$this->detailsInGridAvailable() )
return;
foreach( $this->allDetailsTablesArr as $detData )
{
$dDataSourceTable = $detData['dDataSourceTable'];
if( !$this->pSet->detailsShowCount($dDataSourceTable) )
continue;
$dSet = new ProjectSettings( $detData["dDataSourceTable"], $detData["dType"] );
$color = $dSet->getDetailsBadgeColor();
if( strlen( $color ) )
$this->row_css_rules = ".badge.badge.".$detData["dShortTable"]."_badge { background-color: #".$color." }\n".$this->row_css_rules;
}
}
function detailsInGridAvailable()
{
for($i = 0; $i < count($this->allDetailsTablesArr); $i ++)
{
$detTable = $this->allDetailsTablesArr[$i]['dDataSourceTable'];
$dPset = new ProjectSettings( $detTable );
$detTablePermis = $this->permis[ $detTable ];
$detTableType = $dPset->getEntityType();
$detListAvailabel = ( $dPset->hasListPage() || isReport( $detTableType ) || isChart( $detTableType ) ) && $detTablePermis["search"];
$detAddAvailabel = $dPset->hasAddPage() && $detTablePermis["add"];
$detEditAvailabel = $dPset->hasEditPage() && $detTablePermis["edit"];
if( $detListAvailabel || ( ( $this->pSet->detailsLinks() == DL_INDIVIDUAL || count($this->allDetailsTablesArr) == 1 ) && ( $detAddAvailabel || $detEditAvailabel ) ) )
{
return true;
}
}
return false;
}
public function mobileTemplateMode() {
return mobileDeviceDetected() && !$this->isBootstrap();
}
/**
*
* @return Array
*/
protected function getColumnsToHide()
{
return $this->getHiddenColumnsByDevice();
}
protected static function deviceClassToMacro( $deviceClass ) {
if( $deviceClass == TABLET_10_IN || $deviceClass == TABLET_7_IN )
return 1;
if( $deviceClass == SMARTPHONE_LANDSCAPE || $deviceClass == SMARTPHONE_PORTRAIT )
return 2;
return 0;
}
protected function getSpecificPageSettings( $pageType ) {
$pSet = $this->pSet;
if( $this->getPageType() !== $pageType ) {
$pSet = new ProjectSettings( $this->tName, $pageType );
}
return $pSet;
}
protected function showHideFieldsFeatureEnabled() {
$pSet = $this->getSpecificPageSettings( PAGE_LIST );
return $pSet->isAllowShowHideFields();
}
protected function reorderFieldsFeatureEnabled() {
$pSet = $this->getSpecificPageSettings( PAGE_LIST );
return $pSet->isAllowFieldsReordering();
}
/**
* Prepare array with Show/Hide fields data combined with Columns by device
* @return Array
*/
protected function getCombinedHiddenColumns()
{
if( !$this->showHideFieldsFeatureEnabled() )
return $this->getHiddenColumnsByDevice();
include_once getabspath("classes/paramsLogger.php");
$logger = new paramsLogger( $this->tName, SHFIELDS_PARAMS_TYPE );
$hideColumns = $logger->getShowHideData();
$columnsByDeviceEnabled = $this->pSet->columnsByDeviceEnabled();
$ret = array();
$devices = array( DESKTOP, TABLET_10_IN, SMARTPHONE_LANDSCAPE, SMARTPHONE_PORTRAIT, TABLET_7_IN );
foreach( $devices as $d )
{
if( !$columnsByDeviceEnabled )
$ret[ $d ] = $hideColumns[ 0 ];
else if( $hideColumns[ RunnerPage::deviceClassToMacro($d) ] )
$ret[ $d ] = $hideColumns[ RunnerPage::deviceClassToMacro($d) ];
else
{
$ret[ $d ] = array_keys( $this->pSet->getHiddenGoodNameFields( $d ) );
}
}
return $ret;
}
/**
* Prepare array with Columns by device
* @return Array
*/
protected function getHiddenColumnsByDevice()
{
$columnsToHide = array();
$devices = array( TABLET_7_IN, SMARTPHONE_PORTRAIT, SMARTPHONE_LANDSCAPE, TABLET_10_IN, DESKTOP );
foreach( $devices as $d )
{
$columnsToHide[ $d ] = array_keys($this->pSet->getHiddenGoodNameFields( $d ));
}
return $columnsToHide;
}
/*
*
*/
public static function sendEmailByTemplate($toEmail, $template, $data)
{
$templateFile = "email/" . mlang_getcurrentlang() . "/" . $template . ".txt";
return sendEmailTemplate( $toEmail, $templateFile, $data );
}
/**
* @return Mixed
*/
protected function getSelectedRecords()
{
$selected_recs = array();
$keyFields = $this->pSet->getTableKeys();
// process selection
if( @$_REQUEST["mdelete"] )
{
foreach( @$_REQUEST["mdelete"] as $ind )
{
$keys = array();
foreach( $keyFields as $idx => $f )
{
$keys[ $f ] = refine( $_REQUEST[ "mdelete" + ( $idx + 1 ) ][ mdeleteIndex( $ind ) ] );
}
$selected_recs[] = $keys;
}
}
elseif( $this->selection )
{
foreach( $this->selection as $keyblock )
{
$arr = explode( "&", refine( $keyblock ) );
if( count( $arr ) < count( $keyFields ) )
continue;
$keys = array();
foreach( $keyFields as $idx => $f)
{
$keys[ $f ] = urldecode( $arr[ $idx ] );
}
$selected_recs[] = $keys;
}
}
else
return null;
return $selected_recs;
}
/**
* @return Array
*/
protected function getSelection()
{
if( "##@ext##" == "asp")
{
$selection = array();
foreach( $this->selection as $s )
{
$selection[] = $s;
}
return $selection;
}
else
{
return $this->selection;
}
}
/**
* Data command for a specific WHERE tab.
* @return DsCommand
*/
function getTabDataCommand( $tab )
{
$this->tabChangeling = $tab;
$dc = $this->getSubsetDataCommand();
$this->tabChangeling = null;
return $dc;
}
/**
* Simple mode - page displayed in a separate browser's window with no AJAX involved
* @return Boolean
*/
function simpleMode()
{
// More rigid check would involve checking $this->mode for each page type
// i.e. in ChartPage ($this->mode == CHART_SIMPLE)
return $this->id == 1;
}
/**
* Checks if grid tabs should be displayed inside the page.
* True for simple mode, false for dashboards etc
* @return Boolean
*/
function displayTabsInPage()
{
return $this->simpleMode();
}
/**
* Add table captions to grid tab titles.
* We need them when displaying tabs from different details tables in a single tab control:
* Suppliers - All data (100) | Suppliers - good ones (5) | Shippers - all | Shippers - reliable
*/
function updateDetailsTabTitles()
{
if( !$this->changeDetailsTabTitles )
return;
for( $i=0; $i < count( $this->gridTabs ); ++$i )
{
$id = $this->gridTabs[$i]["tabId"];
$this->setTabTitle( $id, GetTableCaption( GoodFieldName($this->tName) ) . ' - ' . $this->getTabTitle( $id ) );
}
}
/**
* Checks if the page should be displayed in the details mode
* Applies to List/Chart/Report pages displayed on master's Add/Edit/View
* @return Boolean
*/
function shouldDisplayDetailsPage()
{
return true;
}
/**
* Hide all items of the specified type
*/
function hideItemType( $type ) {
if( $type == "grid_message") {
$this->hideGridMessage();
} else if( $type == "grid" ) {
$this->hideForm( "grid" );
} else {
$itemsByType =& $this->pSet->helperItemsByType();
$this->xt->displayItemsHidden( $itemsByType[ $type ] );
}
}
function hideItem( $itemId, $recordId = "" ) {
$this->xt->displayItemHidden( $itemId, $recordId );
}
function showItem( $itemId, $recordId = "" ) {
$this->xt->showHiddenItem( $itemId, $recordId );
}
function hideAllFormItems( $location ) {
$helper = $this->pSet->helperFormItems();
if( !is_array( $helper[ "formItems" ][ $location ] ) ) {
return;
}
$this->xt->displayItemsHidden( $helper[ "formItems" ][ $location ] );
}
function showItemType( $type ) {
$itemsByType =& $this->pSet->helperItemsByType();
$this->xt->showHiddenItems( $itemsByType[ $type ] );
}
function hideForm( $form ) {
$this->xt->assign( "form_".$form , $this->xt->getvar( "form_". $form ). " data-hidden");
}
function setPageData( $key, $value ) {
$this->pageData[$key] = $value;
}
function getMasterPSet() {
if( !$this->masterPSet && $this->masterTable ) {
$this->masterPSet = new ProjectSettings( $this->masterTable, $this->masterPageType, $this->masterPage );
}
return $this->masterPSet;
}
function fetchForms( $forms ) {
$formBlocks = array();
foreach( $forms as $f )
{
$formBlocks[] = $f."_block";
}
return $this->fetchBlocksList( $formBlocks );
}
function hideElement( $name ) {
if( $this->isPD()) {
$itemTypes = $this->element2Item( $name );
foreach( $itemTypes as $it ) {
$this->hideItemType( $it );
}
} else {
$this->xt->displayBrickHidden( $this->element2Brick( $name ) );
}
}
function element2Brick( $name ) {
return $name;
}
function element2Item( $name ) {
if( $name == "recordcontrol") {
return array( "inline_save_all", "inline_cancel_all", "delete", "update_selected", "export_selected", "delete_selected" );
}
if( $name == "reorder_records") {
return array( 'sort_dropdown' );
}
if( $name == "printpanel") {
return array( 'print_panel' );
}
if( $name == "message") {
return array( 'message' );
}
if( $name == "searchpanel") {
return array( 'search_panel', 'hide_search_panel' );
}
if( $name == "pagination") {
return array( 'pagination' );
}
if( $name == "filterpanel") {
return array( 'filter_panel' );
}
return $name;
}
function hideGridMessage() {
$this->xt->assign("grid_message_attrs", "data-hidden");
}
public function prepareDisplayDetails() {
}
public function showButtonsDp() {
}
function prepareCharts()
{
$chartXtParams = array( "id" => $this->id );
$this->xt->assign_function("chart", "xt_showpdchart", $chartXtParams);
}
function hideRecordItem( $itemId, $recordid ) {
if( !$this->pdfJsonMode() )
$this->recordAssign( $recordid, "item_" . $itemId, 'data-hidden' );
else
$this->recordAssign( $recordid, "item_hide_" . $itemId, '1' );
}
function recordAssign( $recordid, $key, $value ) {
$data =& $this->findRecordAssigns( $recordid );
$data[ $key ] = $value;
}
/**
* Returns reference to the array that holds record values for XTempl
* It is the same array that is passed to the BeforeMoveNext event as $record
*/
function &findRecordAssigns( $recordid ) {
return array();
}
function pdfJsonMode() {
return false;
}
function searchFieldAppearsOnPage( $field ) {
if( $this->pageType === PAGE_SEARCH ) {
return $this->pSet->appearOnPage( $field );
}
return $this->pSet->appearAlwaysOnSearchPanel( $field );
}
function createProjectSettings() {
$this->pSet = new ProjectSettings($this->tName, $this->pageType, $this->pageName, $this->pageTable );
/**
* Page type here has priority over page name. If supplied pageName is not compatible with the pageType, ignore the former.
* ATTENTION! It is not so in the PageSettings class. On the opposite, pageName has priority there.
*/
if( $this->pSet->getPageType() !== $this->pageType ) {
$this->pSet = new ProjectSettings($this->tName, $this->pageType, null, $this->pageTable );
}
}
/**
* format interval group value, like number interval or date part ( April 2010 )
* @return String
*/
function formatGroupValue( $fName, $intervalType, $value )
{
return $this->formatGroupValueStatic( $fName, $intervalType, $value, $this->pSet, $this, $this->pdfJsonMode() );
}
static function formatGroupValueStatic( $fName, $intervalType, $value, $pSet, $fieldControls, $pdfJsonMode )
{
if( !$intervalType ) {
$data = array( $fName => $value );
return $fieldControls->showDBValue( $fName, $data );
}
$fType = $pSet->getFieldType( $fName );
if( IsNumberType( $fType ) ) {
$start = $value - ($value % $intervalType);
if( !IsFloatType( $fType ) ) {
// 10 - 19, 20 - 29
$end = $start + $intervalType - 1;
} else {
// just a guess: 10.00-19.99, 20.00 - 29.99
$end = $start + $intervalType - 0.01;
}
$dataStart = array( $fName => $start );
$dataEnd = array( $fName => $end );
$strStart = $fieldControls->showDBValue( $fName, $dataStart );
$strEnd = $fieldControls->showDBValue( $fName, $dataEnd );
return $pdfJsonMode
// remove exessive ' wrappers: start "'1'", end "'2'" --> "'1-2'"
? substr( $strStart, 0 , strlen( $strStart ) - 1 )." - ".substr( $strEnd, 1 )
: $strStart . " - " . $strEnd;
}
else if( isCharType( $fType ) )
{
$result = xmlencode( substr( $value, 0, $intervalType ) );
return $pdfJsonMode ? "'". jsreplace( $result ) ."'" : $result;
}
else if( IsDateFieldType( $fType ) )
{
$result = formatDateIntervalValue( $value, $intervalType );
return $pdfJsonMode ? "'". jsreplace( $result ) ."'" : $result;
}
return $value;
}
/**
* preloads and assigns "background" parameter
*/
function preparePDFBackground() {
if( !$this->pdfBackgroundImage ) {
return;
}
// CAREFUL! $this->pdfBackgroundImage comes from client's browser
// Only files from "/images" can be used
$filename = "images/" . str_replace('..', '', $this->pdfBackgroundImage );
$image = myfile_get_contents_binary( getabspath( $filename ));
$imgSize = getImageDimensions( $image );
if( $imgSize ) {
$this->xt->assign( "bgWidth", $imgSize["width"] );
$this->xt->assign( "bgHeight", $imgSize["height"] );
}
$url = imageDataUrl( $image );
if( !$url )
return;
$this->xt->assign( "backgroundImage", "'" . jsreplace( $url ) . "'" );
}
function getMasterCondition() {
if( !count( $this->detailKeysByM ) )
return null;
$conditions = array();
for( $i = 0; $i < count( $this->detailKeysByM ); ++$i )
{
$conditions[] = DataCondition::FieldEquals( $this->detailKeysByM[ $i ], $this->masterKeysReq[ $i + 1 ] );
}
return DataCondition::_And( $conditions );
}
/**
* returns current details key value
* @return string
*/
function getDetailsKeyValue( $field ) {
foreach( $this->detailKeysByM as $i => $f ) {
if( $field == $f )
return $this->masterKeysReq[ $i + 1 ];
}
return false;
}
function getSecurityCondition() {
return Security::SelectCondition( "S", $this->pSet );
}
function getDataSourceFilterCriteria( $ignoreFilterField = "" )
{
$security = $this->getSecurityCondition();
$search = $this->searchClauseObj->getSearchDataCondition( $controls );
$filter = $this->searchClauseObj->getFilterCondition( $this->pSet, $ignoreFilterField );
$master = $this->getMasterCondition();
$tab = DataCondition::SQLCondition( $this->getCurrentTabWhere() );
return DataCondition::_And( array( $security, $master, $filter, $search, $tab ) );
}
public function getSubsetDataCommand( $ignoreFilterField = "" ) {
$ret = new DsCommand;
$ret->filter = $this->getDataSourceFilterCriteria( $ignoreFilterField );
$orderObject = $this->getOrderObject();
$ret->order = $orderObject->getOrderFields();
return $ret;
}
function getMasterTableDataClause()
{
if( !count( $this->detailKeysByM ) )
return null;
$ret = array();
for($i = 0; $i < count( $this->detailKeysByM ); $i++)
{
$mKey = $_SESSION[ $this->sessionPrefix."_masterkey".($i + 1) ];
$ret[] = DataCondition::FieldEquals(
$this->detailKeysByM[$i],
$_SESSION[ $this->sessionPrefix."_masterkey".($i + 1) ]
);
}
return DataCondition::_And( $ret );
}
function getOrderObject() {
require_once(getabspath('classes/orderclause.php'));
return OrderClause::createFromPage( $this, false );
}
/**
* editid1=...& editid2=...&...
* for template variable
*/
function getEditLink( &$data )
{
$keyLinkParts = array();
$tKeys = $this->pSet->getTableKeys();
for( $i = 0; $i < count($tKeys); $i++ )
{
$keyValue = rawurlencode( $data[ $tKeys[$i] ] );
$keyLinkParts[] = "editid".($i + 1)."=".runner_htmlspecialchars( $keyValue );
}
return implode( "&", $keyLinkParts );
}
/**
* read masterkeyN request params
*/
public static function readMasterKeysFromRequest()
{
$i = 1;
$options = array();
while( isset( $_REQUEST["masterkey".$i] ) )
{
$options[ $i ] = $_REQUEST["masterkey".$i];
$i++;
}
return $options;
}
/**
* get master keys data
* keys: masterkeyN
*/
protected function getMasterKeysParams()
{
$params = array();
if( !$this->masterKeysReq )
return $params;
for( $i = 1; $i <= count( $this->masterKeysReq ); $i++ )
{
$params[ "masterkey".$i ] = $this->masterKeysReq[ $i ];
}
return $params;
}
/**
* page state params for #14869
*/
protected function getStateParams()
{
$params = array();
if( $this->masterTable )
{
$params = $this->getMasterKeysParams();
$params["mastertable"] = $this->masterTable;
}
return $params;
}
/**
* @param startWidth String
* for startWidth "?"
return "?mastertable=...&masterkey1=..."
* for startWidth "&"
return "&mastertable=...&masterkey1=..."
* default result is
"mastertable=...&masterkey1=..."
*
* return "" in case getStateParams returns an empty array
*
* @return String
*/
function getStateUrlParams()
{
$urlParams = array();
foreach( $this->getStateParams() as $name => $value )
{
$urlParams[] = $name."=".runner_htmlspecialchars( rawurlencode( $value ) );
}
return implode( "&", $urlParams );
}
/**
* @return String
*/
protected function getMasterPageName() {
$masterTableData = $this->getMasterTableInfo();
if( $this->pageType == PAGE_PRINT || $this->pageType == PAGE_RPRINT ) {
if( $masterTableData["type"] == PAGE_REPORT )
$mPageType = "masterrprint";
else
$mPageType = "masterprint";
} else {
$mPageType = "masterlist";
if( $masterTableData["type"] == PAGE_CHART )
$mPageType = "masterchart";
if( $masterTableData["type"] == PAGE_REPORT )
$mPageType = "masterreport";
}
$mpSet = new ProjectSettings( $masterTableData['mDataSourceTable'], $mPageType );
return $mpSet->pageName();
}
/**
* Get rows count for tab
*/
protected function getRowCountByTab($tab)
{
$dc = $this->getTabDataCommand( $tab );
$this->callBeforeQueryEvent( $dc );
return $this->dataSource->getCount( $dc );
}
function callBeforeQueryEvent( $dc )
{
}
/**
*
*/
protected function checkOauthLogin() {
if( !$this->dataSource ) {
return true;
}
if( $this->dataSource->checkAuthorization() )
return true;
$request = $this->dataSource->getAuthorizationInfo();
Security::saveRedirectURL();
header( "Location: " . $request->getUrl() );
exit();
/*
$rconn = getRestConnection( $this->pSet );
if( !$rconn )
return;
if( $rconn->oauthNeedLogin() ) {
Security::saveRedirectURL();
HeaderRedirect( "oauthcallback", "", "connid=" . $rconn->connId );
exit();
}
*/
}
<<<<<<< .working
||||||| .merge-left.r35441
return new EditPage( $params );
}
=======
return new EditPage( $params );
}
>>>>>>> .merge-right.r35442
}
class DetailsPreview extends RunnerPage
{
function __construct($params)
{
parent::__construct($params);
}
protected function assignSessionPrefix()
{
$this->sessionPrefix = "_detailsPreview";
}
}
$menuNodesObject = null;
?>