kenken999 commited on
Commit
b88bcb2
1 Parent(s): 5468bf4
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. admin_comments_edit.php +107 -0
  2. admin_comments_list.php +163 -0
  3. admin_comments_search.php +95 -0
  4. api/api.php +148 -0
  5. api/v1.php +278 -0
  6. appointments_add.php +108 -0
  7. appointments_edit.php +107 -0
  8. appointments_export.php +53 -0
  9. appointments_import.php +53 -0
  10. appointments_list.php +163 -0
  11. appointments_print.php +46 -0
  12. appointments_search.php +95 -0
  13. appointments_view.php +67 -0
  14. autocomplete.php +60 -0
  15. autofillfields.php +42 -0
  16. buildpdf.php +17 -0
  17. buttonhandler.php +982 -0
  18. callVideo.mp3 +0 -0
  19. chat_files_list.php +163 -0
  20. chat_files_search.php +95 -0
  21. chat_functions.php +868 -0
  22. chat_groups_add.php +108 -0
  23. chat_groups_edit.php +107 -0
  24. chat_groups_list.php +163 -0
  25. chat_groups_search.php +95 -0
  26. chat_history_add.php +108 -0
  27. chat_history_search.php +95 -0
  28. chat_peopletype_search.php +95 -0
  29. chat_settings_edit.php +107 -0
  30. chat_settings_search.php +95 -0
  31. chat_timezone_search.php +95 -0
  32. chat_users_search.php +95 -0
  33. checkduplicates.php +80 -0
  34. classes/addpage.php +1885 -0
  35. classes/advancedsearchcontrol.php +29 -0
  36. classes/base32.php +98 -0
  37. classes/button.php +208 -0
  38. classes/chartpage.php +374 -0
  39. classes/chartpage_master.php +71 -0
  40. classes/charts.php +2033 -0
  41. classes/cipherer.php +341 -0
  42. classes/context.php +623 -0
  43. classes/controls/CheckboxField.php +91 -0
  44. classes/controls/Control.php +790 -0
  45. classes/controls/DatabaseFileField.php +287 -0
  46. classes/controls/DateField.php +293 -0
  47. classes/controls/DateTimeControl.php +25 -0
  48. classes/controls/EditControlsContainer.php +330 -0
  49. classes/controls/FileField.php +455 -0
  50. classes/controls/FileFieldSingle.php +277 -0
admin_comments_edit.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ @ini_set("display_errors","1");
4
+ @ini_set("display_startup_errors","1");
5
+
6
+ require_once("include/dbcommon.php");
7
+ require_once("classes/searchclause.php");
8
+ require_once("include/admin_comments_variables.php");
9
+ require_once('include/xtempl.php');
10
+ require_once('classes/editpage.php');
11
+
12
+ add_nocache_headers();
13
+
14
+ if( Security::hasLogin() ) {
15
+ if( !EditPage::processEditPageSecurity( $strTableName ) )
16
+ return;
17
+ }
18
+
19
+ EditPage::handleBrokenRequest();
20
+
21
+ // render all necessary layouts
22
+
23
+
24
+ // parse control parameters
25
+ $pageMode = EditPage::readEditModeFromRequest();
26
+
27
+ $xt = new Xtempl();
28
+
29
+ $id = postvalue_number("id");
30
+ $id = intval($id) == 0 ? 1 : $id;
31
+
32
+
33
+ // $keys could not be set properly if editid params were no passed
34
+ $keys = array();
35
+ $keys["CommentID"] = postvalue("editid1");
36
+
37
+ //array of params for classes
38
+ $params = array();
39
+ $params["id"] = $id;
40
+ $params["xt"] = &$xt;
41
+ $params["keys"] = $keys;
42
+ $params["mode"] = $pageMode;
43
+ $params["pageType"] = PAGE_EDIT;
44
+ $params["pageName"] = postvalue("page");
45
+ $params["tName"] = $strTableName;
46
+ $params["action"] = postvalue("a");
47
+ $params["selectedFields"] = postvalue("fields");
48
+
49
+ ;
50
+ $params["captchaName"] = "captcha_1209xre";
51
+ $params["captchaValue"] = postvalue("value_captcha_1209xre_" . $id);
52
+ $params["selection"] = postvalue("selection");
53
+ $params["rowIds"] = my_json_decode( postvalue("rowIds") );
54
+
55
+ $params["masterTable"] = postvalue("mastertable");
56
+ if( $params["masterTable"] )
57
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
58
+
59
+ // locking parameters
60
+ $params["lockingAction"] = postvalue("action");
61
+ $params["lockingSid"] = postvalue("sid");
62
+ $params["lockingKeys"] = postvalue("keys");
63
+ $params["lockingStart"] = postvalue("startEdit");
64
+
65
+ if( $pageMode == EDIT_INLINE )
66
+ {
67
+ $params["screenWidth"] = postvalue("screenWidth");
68
+ $params["screenHeight"] = postvalue("screenHeight");
69
+ $params["orientation"] = postvalue("orientation");
70
+ }
71
+
72
+ if( $pageMode == EDIT_DASHBOARD )
73
+ {
74
+ $params["dashElementName"] = postvalue("dashelement");
75
+ $params["dashTName"] = postvalue("table");
76
+ $params["dashPage"] = postvalue("dashPage");
77
+
78
+ if( postvalue("mapRefresh") )
79
+ {
80
+ $params["mapRefresh"] = true;
81
+ $params["vpCoordinates"] = my_json_decode( postvalue("vpCoordinates") );
82
+ }
83
+ }
84
+
85
+ if(( $pageMode == EDIT_POPUP || $pageMode == EDIT_INLINE ) && postvalue("dashTName"))
86
+ {
87
+ $params["dashTName"] = postvalue("dashTName");
88
+ $params["dashElementName"] = postvalue("dashelement");
89
+ $params["dashPage"] = postvalue("dashPage");
90
+ }
91
+
92
+ $params["forSpreadsheetGrid"] = postvalue("spreadsheetGrid");
93
+ $params["hostPageName"] = postvalue("hostPageName");
94
+ $params["listPage"] = postvalue("listPage");
95
+
96
+ $pageObject = EditPage::EditPageFactory($params);
97
+
98
+ if( $pageObject->isLockingRequest() )
99
+ {
100
+ $pageObject->doLockingAction();
101
+ exit();
102
+ }
103
+
104
+ $pageObject->init();
105
+
106
+ $pageObject->process();
107
+ ?>
admin_comments_list.php ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ $requestTable = "admin_comments";
6
+ $requestPage = "list";
7
+
8
+ require_once("include/dbcommon.php");
9
+ add_nocache_headers();
10
+
11
+ require_once('include/xtempl.php');
12
+
13
+ require_once("classes/searchcontrol.php");
14
+ require_once("classes/searchclause.php");
15
+ require_once("classes/panelsearchcontrol.php");
16
+ require_once("include/admin_comments_variables.php");
17
+ require_once('classes/listpage.php');
18
+ require_once('include/lookuplinks.php');
19
+
20
+ // Check whether the page was called as a part of Lookup wizard - List page with search.
21
+ // Verify the eligibility of such a call.
22
+
23
+ InitLookupLinks();
24
+ if( Security::hasLogin() ) {
25
+ if( !ListPage::processListPageSecurity( $strTableName ) )
26
+ return;
27
+ }
28
+
29
+ if( ListPage::processSaveParams( $strTableName ) )
30
+ return;
31
+
32
+ $options = array();
33
+ //array of params for classes
34
+
35
+ // Include necessary files in accordance with the page displaying mode
36
+ $mode = ListPage::readListModeFromRequest();
37
+ if( $mode == LIST_SIMPLE )
38
+ {
39
+ require_once('classes/listpage_simple.php');
40
+ require_once("classes/searchpanelsimple.php");
41
+ }
42
+ elseif( $mode == LIST_AJAX )
43
+ {
44
+ require_once('classes/listpage_simple.php');
45
+ require_once('classes/listpage_ajax.php');
46
+ require_once("classes/searchpanelsimple.php");
47
+ }
48
+ elseif( $mode == LIST_LOOKUP )
49
+ {
50
+ require_once('classes/listpage_embed.php');
51
+ require_once('classes/listpage_lookup.php');
52
+
53
+ $options["mainTable"] = postvalue("table");
54
+ $options["mainField"] = postvalue("field");
55
+ $options["mainPageType"] = postvalue("pageType");
56
+
57
+ $options["mainRecordData"] = my_json_decode( postvalue('data') );
58
+ $options["mainRecordMasterTable"] = postvalue('mainRecordMasterTable');
59
+
60
+ if( postvalue("parentsExist") )
61
+ $options["parentCtrlsData"] = my_json_decode( postvalue("parentCtrlsData") );
62
+ }
63
+ elseif( $mode == LIST_POPUPDETAILS )
64
+ {
65
+ require_once('classes/listpage_embed.php');
66
+ require_once('classes/listpage_dpinline.php');
67
+ require_once('classes/listpage_dppopup.php');
68
+ }
69
+ elseif( $mode == LIST_DETAILS )
70
+ {
71
+ require_once('classes/listpage_embed.php');
72
+ require_once('classes/listpage_dpinline.php');
73
+ require_once('classes/listpage_dplist.php');
74
+ }
75
+ elseif( $mode == LIST_DASHDETAILS )
76
+ {
77
+ require_once('classes/listpage_embed.php');
78
+ require_once('classes/listpage_dashboard.php');
79
+ require_once('classes/listpage_dpdash.php');
80
+ }
81
+ elseif( $mode == LIST_DASHBOARD )
82
+ {
83
+ require_once('classes/listpage_embed.php');
84
+ require_once('classes/listpage_dashboard.php');
85
+ }
86
+ elseif( $mode == MAP_DASHBOARD )
87
+ {
88
+ require_once('classes/listpage_embed.php');
89
+ require_once('classes/listpage_dashboard.php');
90
+ require_once('classes/map_dashboard.php');
91
+ }
92
+
93
+ $xt = new Xtempl( $mode != LIST_SIMPLE ); //#9607 1. Temporary fix
94
+
95
+ $options["pageName"] = postvalue("page");
96
+ $options["pageType"] = PAGE_LIST;
97
+ $options["id"] = postvalue_number("id") ? postvalue_number("id") : 1;
98
+ $options["flyId"] = (int)postvalue("recordId");
99
+ $options["mode"] = $mode;
100
+ $options["xt"] = &$xt;
101
+ $options["firstTime"] = postvalue("firstTime");
102
+ $options["sortBy"] = postvalue("sortby");
103
+ $options["requestGoto"] = postvalue_number("goto");
104
+
105
+
106
+ $options["masterPageType"] = postvalue("masterpagetype");
107
+ $options["masterPage"] = postvalue("masterpage");
108
+ $options["masterId"] = postvalue("masterid");
109
+
110
+ $options["masterTable"] = postvalue("mastertable");
111
+ if( $options["masterTable"] )
112
+ $options["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
113
+
114
+
115
+ if( $mode == LIST_DASHBOARD && postvalue("nodata") && strlen($options["masterTable"]) )
116
+ $options["showNoData"] = true;
117
+
118
+ if( $mode != LIST_LOOKUP )
119
+ {
120
+ $options["dashElementName"] = postvalue("dashelement");
121
+ $options["dashTName"] = postvalue("table");
122
+ $options["dashPage"] = postvalue("dashPage");
123
+ }
124
+
125
+ if( postvalue("mapRefresh") )
126
+ {
127
+ $options["mapRefresh"] = true;
128
+ $options["vpCoordinates"] = my_json_decode( postvalue("vpCoordinates") );
129
+ }
130
+
131
+ if( postvalue("firstTime") )
132
+ $options["firstTime"] = true;
133
+
134
+ // Create $pageObject
135
+ $pageObject = ListPage::createListPage($strTableName, $options);
136
+
137
+ if( $pageObject->processSaveSearch() )
138
+ exit();
139
+
140
+ if( $pageObject->updateRowOrder() )
141
+ exit();
142
+
143
+ if ( $pageObject->processFieldFilter() )
144
+ exit();
145
+
146
+ if( $pageObject->processTotals() )
147
+ exit();
148
+
149
+ if( $mode != LIST_DETAILS && $mode != MAP_DASHBOARD && $mode != LIST_DASHBOARD )
150
+ {
151
+ //maps
152
+ }
153
+
154
+ unset($_SESSION["message_add"]);
155
+ unset($_SESSION["message_edit"]);
156
+
157
+ // prepare code for build page
158
+ $pageObject->prepareForBuildPage();
159
+
160
+ // show page depends of mode
161
+ $pageObject->showPage();
162
+
163
+ ?>
admin_comments_search.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ require_once("include/dbcommon.php");
6
+ add_nocache_headers();
7
+
8
+ require_once("classes/searchclause.php");
9
+ require_once("include/admin_comments_variables.php");
10
+ require_once("classes/searchcontrol.php");
11
+ require_once("classes/advancedsearchcontrol.php");
12
+ require_once("classes/panelsearchcontrol.php");
13
+
14
+
15
+ Security::processLogoutRequest();
16
+
17
+ if( !isLogged() )
18
+ {
19
+ Security::saveRedirectURL();
20
+ redirectToLogin();
21
+ }
22
+
23
+ require_once( "include/reportfunctions.php" );
24
+ $cname = postvalue("cname");
25
+ $rname = postvalue("rname");
26
+ if( $rname || $cname ) {
27
+ $rpt_array = wrGetEntityArray(
28
+ $rname ? $rname : $cname,
29
+ $rname ? WR_REPORT : WR_CHART
30
+ );
31
+ $accessGranted = @$rpt_array['status'] != "private" || @$rpt_array['owner'] != Security::getUserName();
32
+ } else {
33
+ $accessGranted = CheckTablePermissions( $strTableName, "S" );
34
+ }
35
+ if(!$accessGranted)
36
+ {
37
+ HeaderRedirect("menu");
38
+ }
39
+
40
+
41
+ require_once('include/xtempl.php');
42
+ require_once('classes/searchpage.php');
43
+ require_once('classes/searchpage_dash.php');
44
+
45
+ $xt = new Xtempl();
46
+ $pageMode = SearchPage::readSearchModeFromRequest();
47
+
48
+ if( $pageMode == SEARCH_LOAD_CONTROL )
49
+ $layoutVersion = postvalue("layoutVersion");
50
+
51
+
52
+ $params = array();
53
+ $params['xt'] = &$xt;
54
+ $params['id'] = postvalue_number("id");
55
+ $params['mode'] = $pageMode;
56
+ $params['tName'] = $strTableName;
57
+ $params["pageName"] = postvalue("page");
58
+ $params['pageType'] = PAGE_SEARCH;
59
+ $params['chartName'] = $cname;
60
+ $params['reportName'] = $rname;
61
+ $params['templatefile'] = $templatefile;
62
+ $params['shortTableName'] = 'admin_comments';
63
+ $params['layoutVersion'] = $layoutVersion;
64
+
65
+ $params['searchControllerId'] = postvalue('searchControllerId') ? postvalue('searchControllerId') : $id;
66
+ $params['ctrlField'] = postvalue('ctrlField');
67
+
68
+ $params['needSettings'] = postvalue('isNeedSettings');
69
+
70
+ if( $pageMode == SEARCH_DASHBOARD )
71
+ {
72
+ $params["dashTName"] = postvalue("table");
73
+ $params["dashElementName"] = postvalue("dashelement");
74
+ $params["dashPage"] = postvalue("dashPage");
75
+ }
76
+
77
+ // e.g. crosstable params
78
+ $params["extraPageParams"] = SearchPage::getExtraPageParams();
79
+
80
+ $params["masterTable"] = postvalue("mastertable");
81
+ if( $params["masterTable"] )
82
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
83
+
84
+
85
+ $pageObject = new SearchPage($params);
86
+
87
+ if( $pageMode == SEARCH_LOAD_CONTROL )
88
+ {
89
+ $pageObject->displaySearchControl();
90
+ return;
91
+ }
92
+
93
+ $pageObject->init();
94
+ $pageObject->process();
95
+ ?>
api/api.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class API {
4
+ public static function sendError( $text, $responseCode = 500 ) {
5
+ API::sendResponse( false, array(
6
+ "error" => $text
7
+ ), $responseCode );
8
+ }
9
+
10
+ public static function sendResponse( $success, $data, $responseCode = 0 ) {
11
+ if( !$responseCode ) {
12
+ $responseCode = $success ? 200 : 500;
13
+ }
14
+ http_response_code( $responseCode );
15
+ $data["success"] = $success;
16
+ echo my_json_encode( $data );
17
+ exit();
18
+ }
19
+
20
+ // read one record from the result
21
+ public static function readRecord( $result, $pSet ) {
22
+ $data = $result->fetchAssoc();
23
+ if( !$data ) {
24
+ return null;
25
+ }
26
+ foreach( array_keys( $data ) as $f ) {
27
+ if( IsBinaryType( $pSet->getFieldType( $f ) ) && GetGlobalData("restReturnEncodedBinary") ) {
28
+ $data[ $f ] = base64_encode( $data[ $f ] );
29
+ }
30
+ }
31
+ return $data;
32
+ }
33
+
34
+ // read result into array of records
35
+ public static function readResult( $result, $pSet, $recordLimit = 0 ) {
36
+ $ret = array();
37
+ while( ( !$recordLimit || count( $ret ) < $recordLimit ) && ( $data = API::readRecord( $result, $pSet ) ) ) {
38
+ $ret[] = $data;
39
+ }
40
+ return $ret;
41
+ }
42
+
43
+ public static function login() {
44
+ if( !Security::hasLogin() ) {
45
+ return true;
46
+ }
47
+ $authType = GetGlobalData("restAuth");
48
+ if( $authType == REST_BASIC ) {
49
+ // Authorization: Basic <base64_encode(username:password)>
50
+ $username = "";
51
+ $password = "";
52
+ $username = $_SERVER["PHP_AUTH_USER"];
53
+ $password = $_SERVER["PHP_AUTH_PW"];
54
+ if( !$username ) {
55
+ $loginHeader = getHttpHeader('Authorization') . "";
56
+ if( substr( $loginHeader, 0, 6 ) !== 'Basic ' ) {
57
+ header( 'WWW-Authenticate: Basic realm="REST API"');
58
+ return false;
59
+ }
60
+ $token = base64_decode( substr( $loginHeader, 6) );
61
+ $colonPos = strpos( $token, ':' );
62
+ if( $colonPos === false ) {
63
+ return false;
64
+ }
65
+ $username = substr( $token, 0, $colonPos );
66
+ $password = substr( $token, $colonPos + 1 );
67
+ }
68
+ return Security::login( $username, $password, false, true );
69
+ }
70
+
71
+ if ( $authType == REST_APIKEY ) {
72
+ $APIkey = "";
73
+ if( isset( $_SERVER["HTTP_X_AUTH_TOKEN"] ) )
74
+ $APIkey = $_SERVER["HTTP_X_AUTH_TOKEN"];
75
+ else
76
+ $APIkey = postvalue("apikey");
77
+
78
+ if( !strlen( $APIkey ) )
79
+ return false;
80
+
81
+ if( Security::hardcodedLogin() ) {
82
+ if( GetGlobalData("APIkey", "") == $APIkey ) {
83
+ Security::createHardcodedSession();
84
+ return true;
85
+ }
86
+ return false;
87
+ }
88
+
89
+ $dataSource = getLoginDataSource();
90
+
91
+ $dc = new DsCommand();
92
+ $dc->filter = DataCondition::FieldEquals( GetGlobalData("APIkeyField"), $APIkey );
93
+ $rs = $dataSource->getSingle( $dc );
94
+ if( !$rs )
95
+ return false;
96
+
97
+ $loginSet = ProjectSettings::getForLogin();
98
+ $cipherer = RunnerCipherer::getForLogin( $loginSet );
99
+ $userData = $cipherer->DecryptFetchedArray( $rs->fetchAssoc() );
100
+
101
+ return Security::login( $userData[ Security::usernameField() ], $userData[ Security::passwordField() ], true, true );
102
+ }
103
+
104
+ return false;
105
+ }
106
+
107
+ public static function keysFromRequest( $pSet ) {
108
+ $keys = array();
109
+ foreach( $pSet->getTableKeys() as $i => $k ) {
110
+ $keys[ $k ] = postvalue( "editid" . ( $i + 1 ) );
111
+ }
112
+ return $keys;
113
+ }
114
+
115
+ public static function valuesFromRequest( $pSet ) {
116
+ $values = array();
117
+ foreach( $pSet->getFieldsList() as $f ) {
118
+ if( postvalue( $f ) || GetUploadedFileName( $f ) ) {
119
+ $values[ $f ] = API::processRequestValue( $f, postvalue( $f ), $pSet );
120
+ }
121
+ }
122
+
123
+ return $values;
124
+ }
125
+
126
+ protected static function processRequestValue( $fieldName, $value, $pSet ) {
127
+ if( IsBinaryType( $pSet->getFieldType( $fieldName ) ) ) {
128
+ if( $value && GetGlobalData("restAcceptEncodedBinary") ) {
129
+ $decodedValue = base64_decode_binary( $value );
130
+
131
+ // invalid base64 value passed
132
+ if( !$decodedValue ) {
133
+ API::sendError( "Unable to decode " . $fieldName . " value from base64" );
134
+ }
135
+
136
+ return $decodedValue;
137
+ }
138
+
139
+ // data passed as file
140
+ if( GetUploadedFileName( $fieldName ) ) {
141
+ return GetUploadedFileContents( $fieldName );
142
+ }
143
+ }
144
+
145
+ return $value;
146
+ }
147
+ }
148
+ ?>
api/v1.php ADDED
@@ -0,0 +1,278 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ $restApiCall = true;
4
+
5
+ require_once("../include/dbcommon.php");
6
+ add_nocache_headers();
7
+
8
+ storeJSONDataFromRequest();
9
+
10
+ require_once(getabspath( "api/api.php"));
11
+
12
+ if( !GetGlobalData("restCreate") ) {
13
+ return;
14
+ }
15
+
16
+ header("Content-Type: application/json");
17
+
18
+ if( !API::login() ) {
19
+ API::sendError( 'Access denied', 401 );
20
+ }
21
+
22
+ // dont' remember anything
23
+ session_destroy();
24
+
25
+ $table = findTable( postvalue("table") );
26
+ if( !$table ) {
27
+ API::sendError( 'Unknown table name', 403 );
28
+ }
29
+
30
+ $pSet = new ProjectSettings( $table );
31
+ $eventsObject = &getEventObject( $table );
32
+ $cipherer = new RunnerCipherer( $table, $pSet );
33
+
34
+ $action = postvalue("action");
35
+
36
+ if( $action === "list" ) {
37
+ if( !$pSet->pageTypeAvailable("list") ) {
38
+ API::sendError( "operation not supported" );
39
+ }
40
+ if( !Security::userCan( "S", $table ) ) {
41
+ API::sendError( "operation not allowed" );
42
+ }
43
+ $dataSource = getDataSource( $table, $pSet );
44
+ $srchObj = SearchClause::getSearchObject( $table );
45
+
46
+ $dc = new DsCommand();
47
+ $dc->filter = DataCondition::_And( array(
48
+ Security::SelectCondition( "S", $pSet ),
49
+ $srchObj->getSearchDataCondition()
50
+ ));
51
+
52
+ $order = postvalue("orderby");
53
+ if( $order ) {
54
+ $orderFields = explode( ";", $order );
55
+ $projectFields = $pSet->getFieldsList();
56
+ $dc->order[] = array();
57
+
58
+ foreach( $orderFields as $f ) {
59
+ $dir = substr( $f, 0, 1 ) == "d" ? "desc": "asc";
60
+ $field = trim( substr( $f, 1 ) );
61
+ if( in_array( $field, $projectFields ) ) {
62
+ $dc->order[] = array("column" => $field, "dir" => $dir);
63
+ }
64
+ }
65
+ }
66
+
67
+ if( postvalue( "skip" ) ) {
68
+ $dc->startRecord = (int)postvalue( "skip" );
69
+ }
70
+ if( postvalue( "records" ) ) {
71
+ $dc->reccount = (int)postvalue( "records" );
72
+ } else {
73
+ $dc->reccount = 200;
74
+ }
75
+ $rs = $dataSource->getList( $dc );
76
+ if( !$rs ) {
77
+ API::sendError( $dataSource->lastError() );
78
+ }
79
+ API::sendResponse( true, array("data" => API::readResult( $rs, $pSet, $dc->reccount ) ) );
80
+ }
81
+
82
+ if( $action === "view" ) {
83
+ if( !$pSet->pageTypeAvailable("view") ) {
84
+ API::sendError( "operation not supported" );
85
+ }
86
+ if( !Security::userCan( "S", $table ) ) {
87
+ API::sendError( "operation not allowed" );
88
+ }
89
+ $dataSource = getDataSource( $table, $pSet );
90
+ $dc = new DsCommand();
91
+ $dc->keys = API::keysFromRequest( $pSet );
92
+ $dc->filter = Security::SelectCondition( "S", $pSet );
93
+ $rs = $dataSource->getSingle( $dc );
94
+ if( !$rs ) {
95
+ API::sendError( $dataSource->lastError() );
96
+ }
97
+ API::sendResponse( true, array("data" => API::readRecord( $rs, $pSet ) ) );
98
+ }
99
+
100
+ if( $action === "update" ) {
101
+ if( !$pSet->pageTypeAvailable("edit") ) {
102
+ API::sendError( "operation not supported" );
103
+ }
104
+ if( !Security::userCan( "E", $table ) ) {
105
+ API::sendError( "operation not allowed" );
106
+ }
107
+
108
+ $dataSource = getDataSource( $table, $pSet );
109
+
110
+ $oldKeys = API::keysFromRequest( $pSet );
111
+ $newRecordData = API::valuesFromRequest( $pSet );
112
+
113
+ $oldRecordData = null;
114
+ if( $eventsObject->exists("BeforeEdit") || $eventsObject->exists("AfterEdit") ) {
115
+ $dc = new DsCommand();
116
+ $dc->filter = Security::SelectCondition( "E", $pSet );
117
+ $dc->keys = $oldKeys;
118
+ $fetchedArray = $dataSource->getSingle( $dc )->fetchAssoc();
119
+ $oldRecordData = $cipherer->DecryptFetchedArray( $fetchedArray );
120
+ }
121
+
122
+ $sqlValues = array();
123
+ if( $eventsObject->exists("BeforeEdit") ) {
124
+ $usermessage = "";
125
+ $keyWhereClause = KeyWhere( $oldKeys, $table );
126
+ $pageObj = null;
127
+
128
+ $beforeEdit = $eventsObject->BeforeEdit( $newRecordData,
129
+ $sqlValues,
130
+ $keyWhereClause,
131
+ $oldRecordData,
132
+ $oldKeys,
133
+ $usermessage,
134
+ false,
135
+ $pageObj );
136
+
137
+ if( !$beforeEdit ) {
138
+ API::sendResponse( false, array( "success" => false, "error" => $usermessage ) );
139
+ }
140
+ }
141
+
142
+ $dc = new DsCommand();
143
+ $dc->keys = $oldKeys;
144
+ $dc->filter = Security::SelectCondition( "E", $pSet );
145
+ $dc->values = $newRecordData;
146
+
147
+ $dc->advValues = array();
148
+ foreach( $sqlValues as $field => $sqlValue ) {
149
+ $dc->advValues[ $field ] = new DsOperand( dsotSQL, $sqlValue );
150
+ }
151
+
152
+ $ret = $dataSource->updateSingle( $dc );
153
+
154
+ if( $ret && $eventsObject->exists("AfterEdit") ) {
155
+ $keys = $oldKeys;
156
+ foreach( $newRecordData as $f => $v ) {
157
+ if( isset( $keys[ $f ] ) ) {
158
+ $keys[ $f ] = $v;
159
+ }
160
+ }
161
+
162
+ $keyWhereClause = KeyWhere( $keys, $table );
163
+ $pageObj = null;
164
+
165
+ $eventsObject->AfterEdit( $newRecordData,
166
+ $keyWhereClause,
167
+ $oldRecordData,
168
+ $keys,
169
+ false,
170
+ $pageObj );
171
+ }
172
+
173
+ if( $ret ) {
174
+ API::sendResponse( true, array( "success" => true ) );
175
+ } else {
176
+ API::sendResponse( false, array( "success" => false, "error" => $dataSource->lastError() ) );
177
+ }
178
+ API::sendResponse( $ret["success"], $ret );
179
+ }
180
+
181
+ if( $action === "insert" ) {
182
+ if( !$pSet->pageTypeAvailable("add") ) {
183
+ API::sendError( "operation not supported" );
184
+ }
185
+
186
+ if( !Security::userCan( "A", $table ) ) {
187
+ API::sendError( "operation not allowed" );
188
+ }
189
+
190
+ $newRecordData = API::valuesFromRequest( $pSet );
191
+
192
+ $sqlValues = array();
193
+ if( $eventsObject->exists("BeforeAdd") ) {
194
+ $usermessage = "";
195
+ $pageObj = null;
196
+
197
+ if( !$eventsObject->BeforeAdd( $newRecordData, $sqlValues, $usermessage, false, $pageObj ) ) {
198
+ API::sendResponse( false, array( "success" => false, "error" => $usermessage ) );
199
+ }
200
+ }
201
+
202
+ $dataSource = getDataSource( $table, $pSet );
203
+ $dc = new DsCommand();
204
+ $dc->values = $newRecordData;
205
+
206
+ $dc->advValues = array();
207
+ foreach( $sqlValues as $field => $sqlValue ) {
208
+ $dc->advValues[ $field ] = new DsOperand( dsotSQL, $sqlValue );
209
+ }
210
+
211
+ $ret = $dataSource->insertSingle( $dc );
212
+
213
+ if( $ret && $eventsObject->exists("AfterAdd") ) {
214
+ $pageObj = null;
215
+ $newRecordData = $ret;
216
+ $keys = array();
217
+ foreach( $pSet->getTableKeys() as $kf ) {
218
+ $keys[ $kf ] = $newRecordData[ $kf ];
219
+ }
220
+
221
+ $eventsObject->AfterAdd( $newRecordData, $keys, false, $pageObj );
222
+ }
223
+
224
+ if( $ret !== false ) {
225
+ API::sendResponse( true, array( "success" => true, "data" => $ret ) );
226
+ } else {
227
+ API::sendResponse( false, array( "success" => false, "error" => $dataSource->lastError() ) );
228
+ }
229
+ }
230
+
231
+ if( $action === "delete" ) {
232
+ if( !$pSet->pageTypeAvailable("list") ) {
233
+ API::sendError( "operation not supported" );
234
+ }
235
+ if( !Security::userCan( "D", $table ) ) {
236
+ API::sendError( "operation not allowed" );
237
+ }
238
+
239
+ $dataSource = getDataSource( $table, $pSet );
240
+ $dc = new DsCommand();
241
+ $dc->keys = API::keysFromRequest( $pSet );
242
+ $dc->filter = Security::SelectCondition( "D", $pSet );
243
+
244
+ $whereClause = "";
245
+ $deletedValues = array();
246
+ if( $eventsObject->exists("BeforeDelete") || $eventsObject->exists("AfterDelete") ) {
247
+ $deletedResult = $dataSource->getSingle( $dc );
248
+ if( $deletedResult )
249
+ $deletedValues = $cipherer->DecryptFetchedArray( $deletedResult->fetchAssoc() );
250
+
251
+ $whereClause = KeyWhere( $dc->keys, $table );
252
+ }
253
+
254
+ if( $eventsObject->exists("BeforeDelete") ) {
255
+ $userMessage = "";
256
+ $pageObj = null;
257
+ if( !$eventsObject->BeforeDelete( $whereClause, $deletedValues, $userMessage, $pageObj ) ) {
258
+ API::sendResponse( false, array( "success" => false, "error" => $userMessage ) );
259
+ }
260
+ }
261
+
262
+ $ret = $dataSource->deleteSingle( $dc );
263
+
264
+ if( $ret && $eventsObject->exists("AfterDelete") ) {
265
+ $userMessage = "";
266
+ $pageObj = null;
267
+ $eventsObject->AfterDelete( $whereClause, $deletedValues, $userMessage, $pageObj );
268
+ }
269
+
270
+ if( $ret ) {
271
+ API::sendResponse( true, array( "success" => true ) );
272
+ } else {
273
+ API::sendResponse( false, array( "success" => false, "error" => $dataSource->lastError() ) );
274
+ }
275
+ }
276
+
277
+ API::sendError( "unknown operation" );
278
+
appointments_add.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+
4
+ require_once("include/dbcommon.php");
5
+ require_once("classes/searchclause.php");
6
+ require_once("include/appointments_variables.php");
7
+ require_once('include/xtempl.php');
8
+ require_once('classes/addpage.php');
9
+ require_once('include/lookuplinks.php');
10
+
11
+ add_nocache_headers();
12
+
13
+ InitLookupLinks();
14
+
15
+ if( Security::hasLogin() ) {
16
+ if( !AddPage::processAddPageSecurity( $strTableName ) )
17
+ return;
18
+ }
19
+
20
+ AddPage::handleBrokenRequest();
21
+
22
+
23
+ $pageMode = AddPage::readAddModeFromRequest();
24
+
25
+ $xt = new Xtempl();
26
+
27
+ $id = postvalue_number("id");
28
+ $id = $id ? $id : 1;
29
+
30
+ //an array of AddPage constructor's params
31
+ $params = array();
32
+ $params["id"] = $id;
33
+ $params["xt"] = &$xt;
34
+ $params["mode"] = $pageMode;
35
+ $params["pageType"] = PAGE_ADD;
36
+ $params["tName"] = $strTableName;
37
+ $params["pageName"] = postvalue("page");
38
+ $params["action"] = postvalue("a");
39
+ $params["needSearchClauseObj"] = false;
40
+ $params["afterAdd_id"] = postvalue("afteradd");
41
+
42
+ $params["hostPageName"] = postvalue("hostPageName");
43
+ $params["listPage"] = postvalue("listPage");
44
+
45
+ $params["newRowId"] = postvalue("newRowId");
46
+
47
+ $params["masterTable"] = postvalue("mastertable");
48
+ if( $params["masterTable"] )
49
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
50
+
51
+
52
+
53
+ ;
54
+ $params["captchaName"] = "captcha_1209xre";
55
+ $params["captchaValue"] = postvalue("value_captcha_1209xre_" . $id);
56
+ $params["dashElementName"] = postvalue("dashelement");
57
+ $params["fromDashboard"] = postvalue("fromDashboard");
58
+ $params["dashTName"] = $params["fromDashboard"] ? $params["fromDashboard"] : postvalue("dashTName");
59
+ $params["dashPage"] = postvalue("dashPage");
60
+
61
+ $params["forSpreadsheetGrid"] = postvalue("spreadsheetGrid");
62
+
63
+ if ( $pageMode == ADD_POPUP ) {
64
+ $params["forListPageLookup"] = postvalue('forLookup');
65
+ }
66
+
67
+ if( $pageMode == ADD_DASHBOARD )
68
+ {
69
+ $params["dashElementName"] = postvalue("dashelement");
70
+ $params["dashTName"] = postvalue("table");
71
+ $params["dashPage"] = postvalue("dashPage");
72
+ }
73
+
74
+
75
+ if( $pageMode == ADD_INLINE )
76
+ {
77
+ // Inline add in a 'List page with search' lookup
78
+ $params["forListPageLookup"] = postvalue('forLookup');
79
+
80
+ $params["screenWidth"] = postvalue("screenWidth");
81
+ $params["screenHeight"] = postvalue("screenHeight");
82
+ $params["orientation"] = postvalue("orientation");
83
+
84
+ $params["masterPageType"] = postvalue("masterpagetype");
85
+ }
86
+
87
+
88
+ if( $pageMode == ADD_ONTHEFLY || ( $pageMode == ADD_INLINE || $pageMode == ADD_POPUP ) && postvalue('forLookup') )
89
+ {
90
+ //table where lookup is set
91
+ $params["lookupTable"] = postvalue("table");
92
+ //field with lookup is set
93
+ $params["lookupField"] = postvalue("field");
94
+ //the ptype od the page where lookup is set
95
+ $params["lookupPageType"] = postvalue("pageType");
96
+
97
+ if( postvalue('parentsExist') )
98
+ {
99
+ //the parent controls values data
100
+ $params["parentCtrlsData"] = my_json_decode( postvalue("parentCtrlsData") );
101
+ }
102
+ }
103
+
104
+ $pageObject = new AddPage($params);
105
+ $pageObject->init();
106
+
107
+ $pageObject->process();
108
+ ?>
appointments_edit.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ @ini_set("display_errors","1");
4
+ @ini_set("display_startup_errors","1");
5
+
6
+ require_once("include/dbcommon.php");
7
+ require_once("classes/searchclause.php");
8
+ require_once("include/appointments_variables.php");
9
+ require_once('include/xtempl.php');
10
+ require_once('classes/editpage.php');
11
+
12
+ add_nocache_headers();
13
+
14
+ if( Security::hasLogin() ) {
15
+ if( !EditPage::processEditPageSecurity( $strTableName ) )
16
+ return;
17
+ }
18
+
19
+ EditPage::handleBrokenRequest();
20
+
21
+ // render all necessary layouts
22
+
23
+
24
+ // parse control parameters
25
+ $pageMode = EditPage::readEditModeFromRequest();
26
+
27
+ $xt = new Xtempl();
28
+
29
+ $id = postvalue_number("id");
30
+ $id = intval($id) == 0 ? 1 : $id;
31
+
32
+
33
+ // $keys could not be set properly if editid params were no passed
34
+ $keys = array();
35
+ $keys["id"] = postvalue("editid1");
36
+
37
+ //array of params for classes
38
+ $params = array();
39
+ $params["id"] = $id;
40
+ $params["xt"] = &$xt;
41
+ $params["keys"] = $keys;
42
+ $params["mode"] = $pageMode;
43
+ $params["pageType"] = PAGE_EDIT;
44
+ $params["pageName"] = postvalue("page");
45
+ $params["tName"] = $strTableName;
46
+ $params["action"] = postvalue("a");
47
+ $params["selectedFields"] = postvalue("fields");
48
+
49
+ ;
50
+ $params["captchaName"] = "captcha_1209xre";
51
+ $params["captchaValue"] = postvalue("value_captcha_1209xre_" . $id);
52
+ $params["selection"] = postvalue("selection");
53
+ $params["rowIds"] = my_json_decode( postvalue("rowIds") );
54
+
55
+ $params["masterTable"] = postvalue("mastertable");
56
+ if( $params["masterTable"] )
57
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
58
+
59
+ // locking parameters
60
+ $params["lockingAction"] = postvalue("action");
61
+ $params["lockingSid"] = postvalue("sid");
62
+ $params["lockingKeys"] = postvalue("keys");
63
+ $params["lockingStart"] = postvalue("startEdit");
64
+
65
+ if( $pageMode == EDIT_INLINE )
66
+ {
67
+ $params["screenWidth"] = postvalue("screenWidth");
68
+ $params["screenHeight"] = postvalue("screenHeight");
69
+ $params["orientation"] = postvalue("orientation");
70
+ }
71
+
72
+ if( $pageMode == EDIT_DASHBOARD )
73
+ {
74
+ $params["dashElementName"] = postvalue("dashelement");
75
+ $params["dashTName"] = postvalue("table");
76
+ $params["dashPage"] = postvalue("dashPage");
77
+
78
+ if( postvalue("mapRefresh") )
79
+ {
80
+ $params["mapRefresh"] = true;
81
+ $params["vpCoordinates"] = my_json_decode( postvalue("vpCoordinates") );
82
+ }
83
+ }
84
+
85
+ if(( $pageMode == EDIT_POPUP || $pageMode == EDIT_INLINE ) && postvalue("dashTName"))
86
+ {
87
+ $params["dashTName"] = postvalue("dashTName");
88
+ $params["dashElementName"] = postvalue("dashelement");
89
+ $params["dashPage"] = postvalue("dashPage");
90
+ }
91
+
92
+ $params["forSpreadsheetGrid"] = postvalue("spreadsheetGrid");
93
+ $params["hostPageName"] = postvalue("hostPageName");
94
+ $params["listPage"] = postvalue("listPage");
95
+
96
+ $pageObject = EditPage::EditPageFactory($params);
97
+
98
+ if( $pageObject->isLockingRequest() )
99
+ {
100
+ $pageObject->doLockingAction();
101
+ exit();
102
+ }
103
+
104
+ $pageObject->init();
105
+
106
+ $pageObject->process();
107
+ ?>
appointments_export.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+ require_once("include/dbcommon.php");
5
+ header("Expires: Thu, 01 Jan 1970 00:00:01 GMT");
6
+
7
+ require_once("classes/searchclause.php");
8
+ require_once("classes/sql.php");
9
+
10
+ require_once("include/appointments_variables.php");
11
+
12
+ if( Security::hasLogin() ) {
13
+ if( !Security::processPageSecurity( $strtablename, 'P' ) )
14
+ return;
15
+ }
16
+
17
+
18
+ require_once("include/export_functions.php");
19
+ require_once("classes/exportpage.php");
20
+ require_once("include/xtempl.php");
21
+
22
+ $xt = new Xtempl();
23
+
24
+ //array of params for classes
25
+ $params = array();
26
+ $params["id"] = postvalue_number("id");
27
+ $params["xt"] = &$xt;
28
+ $params["tName"] = $strTableName;
29
+ $params["pageType"] = PAGE_EXPORT;
30
+ $params["pageName"] = postvalue("page");
31
+
32
+ $params["selectedFields"] = postvalue("exportFields");
33
+ $params["exportType"] = postvalue("type");
34
+
35
+ $params["allPagesMode"] = postvalue("records") == "all";
36
+ $params["currentPageMode"] = postvalue("records") == "page";
37
+ $params["selection"] = postvalue("selection");
38
+ $params["csvDelimiter"] = postvalue("delimiter");
39
+
40
+ if( postvalue("txtformatting") == "raw" )
41
+ $params["useRawValues"] = true;
42
+
43
+ $params["mode"] = ExportPage::readModeFromRequest();
44
+
45
+ $params["masterTable"] = postvalue("mastertable");
46
+ if( $params["masterTable"] )
47
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
48
+
49
+ $pageObject = new ExportPage( $params );
50
+ $pageObject->init();
51
+
52
+ $pageObject->process();
53
+ ?>
appointments_import.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+ require_once("include/dbcommon.php");
5
+ header("Expires: Thu, 01 Jan 1970 00:00:01 GMT");
6
+
7
+ set_time_limit(600);
8
+
9
+ require_once("include/appointments_variables.php");
10
+ require_once("include/import_functions.php");
11
+ require_once('classes/importpage.php');
12
+
13
+ if( Security::hasLogin() ) {
14
+ if( !Security::processPageSecurity( $strtablename, 'I' ) )
15
+ return;
16
+ }
17
+
18
+
19
+ require_once('include/xtempl.php');
20
+ $xt = new Xtempl();
21
+
22
+ //an array of params for ImportPage constructor
23
+ $params = array();
24
+ $params["id"] = postvalue_number("id");
25
+ $params["xt"] = &$xt;
26
+ $params["tName"] = $strTableName;
27
+ $params["action"] = postvalue("a");
28
+ $params["pageType"] = PAGE_IMPORT;
29
+ $params["pageName"] = postvalue("page");
30
+ $params["needSearchClauseObj"] = false;
31
+ $params["strOriginalTableName"] = $strOriginalTableName;
32
+
33
+ if( $params["action"] == "importPreview" )
34
+ {
35
+ $params["importType"] = postvalue("importType");
36
+ $params["importText"] = postvalue("importText");
37
+ $params["useXHR"] = postvalue("useXHR");
38
+ }
39
+ elseif( $params["action"] == "importData" )
40
+ {
41
+ $params["importData"] = my_json_decode( postvalue("importData") );
42
+ }
43
+
44
+ $params["masterTable"] = postvalue("mastertable");
45
+ if( $params["masterTable"] )
46
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
47
+
48
+ $pageObject = new ImportPage($params);
49
+ $pageObject->init();
50
+
51
+ $pageObject->process();
52
+
53
+ ?>
appointments_list.php ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ $requestTable = "public.appointments";
6
+ $requestPage = "list";
7
+
8
+ require_once("include/dbcommon.php");
9
+ add_nocache_headers();
10
+
11
+ require_once('include/xtempl.php');
12
+
13
+ require_once("classes/searchcontrol.php");
14
+ require_once("classes/searchclause.php");
15
+ require_once("classes/panelsearchcontrol.php");
16
+ require_once("include/appointments_variables.php");
17
+ require_once('classes/listpage.php');
18
+ require_once('include/lookuplinks.php');
19
+
20
+ // Check whether the page was called as a part of Lookup wizard - List page with search.
21
+ // Verify the eligibility of such a call.
22
+
23
+ InitLookupLinks();
24
+ if( Security::hasLogin() ) {
25
+ if( !ListPage::processListPageSecurity( $strTableName ) )
26
+ return;
27
+ }
28
+
29
+ if( ListPage::processSaveParams( $strTableName ) )
30
+ return;
31
+
32
+ $options = array();
33
+ //array of params for classes
34
+
35
+ // Include necessary files in accordance with the page displaying mode
36
+ $mode = ListPage::readListModeFromRequest();
37
+ if( $mode == LIST_SIMPLE )
38
+ {
39
+ require_once('classes/listpage_simple.php');
40
+ require_once("classes/searchpanelsimple.php");
41
+ }
42
+ elseif( $mode == LIST_AJAX )
43
+ {
44
+ require_once('classes/listpage_simple.php');
45
+ require_once('classes/listpage_ajax.php');
46
+ require_once("classes/searchpanelsimple.php");
47
+ }
48
+ elseif( $mode == LIST_LOOKUP )
49
+ {
50
+ require_once('classes/listpage_embed.php');
51
+ require_once('classes/listpage_lookup.php');
52
+
53
+ $options["mainTable"] = postvalue("table");
54
+ $options["mainField"] = postvalue("field");
55
+ $options["mainPageType"] = postvalue("pageType");
56
+
57
+ $options["mainRecordData"] = my_json_decode( postvalue('data') );
58
+ $options["mainRecordMasterTable"] = postvalue('mainRecordMasterTable');
59
+
60
+ if( postvalue("parentsExist") )
61
+ $options["parentCtrlsData"] = my_json_decode( postvalue("parentCtrlsData") );
62
+ }
63
+ elseif( $mode == LIST_POPUPDETAILS )
64
+ {
65
+ require_once('classes/listpage_embed.php');
66
+ require_once('classes/listpage_dpinline.php');
67
+ require_once('classes/listpage_dppopup.php');
68
+ }
69
+ elseif( $mode == LIST_DETAILS )
70
+ {
71
+ require_once('classes/listpage_embed.php');
72
+ require_once('classes/listpage_dpinline.php');
73
+ require_once('classes/listpage_dplist.php');
74
+ }
75
+ elseif( $mode == LIST_DASHDETAILS )
76
+ {
77
+ require_once('classes/listpage_embed.php');
78
+ require_once('classes/listpage_dashboard.php');
79
+ require_once('classes/listpage_dpdash.php');
80
+ }
81
+ elseif( $mode == LIST_DASHBOARD )
82
+ {
83
+ require_once('classes/listpage_embed.php');
84
+ require_once('classes/listpage_dashboard.php');
85
+ }
86
+ elseif( $mode == MAP_DASHBOARD )
87
+ {
88
+ require_once('classes/listpage_embed.php');
89
+ require_once('classes/listpage_dashboard.php');
90
+ require_once('classes/map_dashboard.php');
91
+ }
92
+
93
+ $xt = new Xtempl( $mode != LIST_SIMPLE ); //#9607 1. Temporary fix
94
+
95
+ $options["pageName"] = postvalue("page");
96
+ $options["pageType"] = PAGE_LIST;
97
+ $options["id"] = postvalue_number("id") ? postvalue_number("id") : 1;
98
+ $options["flyId"] = (int)postvalue("recordId");
99
+ $options["mode"] = $mode;
100
+ $options["xt"] = &$xt;
101
+ $options["firstTime"] = postvalue("firstTime");
102
+ $options["sortBy"] = postvalue("sortby");
103
+ $options["requestGoto"] = postvalue_number("goto");
104
+
105
+
106
+ $options["masterPageType"] = postvalue("masterpagetype");
107
+ $options["masterPage"] = postvalue("masterpage");
108
+ $options["masterId"] = postvalue("masterid");
109
+
110
+ $options["masterTable"] = postvalue("mastertable");
111
+ if( $options["masterTable"] )
112
+ $options["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
113
+
114
+
115
+ if( $mode == LIST_DASHBOARD && postvalue("nodata") && strlen($options["masterTable"]) )
116
+ $options["showNoData"] = true;
117
+
118
+ if( $mode != LIST_LOOKUP )
119
+ {
120
+ $options["dashElementName"] = postvalue("dashelement");
121
+ $options["dashTName"] = postvalue("table");
122
+ $options["dashPage"] = postvalue("dashPage");
123
+ }
124
+
125
+ if( postvalue("mapRefresh") )
126
+ {
127
+ $options["mapRefresh"] = true;
128
+ $options["vpCoordinates"] = my_json_decode( postvalue("vpCoordinates") );
129
+ }
130
+
131
+ if( postvalue("firstTime") )
132
+ $options["firstTime"] = true;
133
+
134
+ // Create $pageObject
135
+ $pageObject = ListPage::createListPage($strTableName, $options);
136
+
137
+ if( $pageObject->processSaveSearch() )
138
+ exit();
139
+
140
+ if( $pageObject->updateRowOrder() )
141
+ exit();
142
+
143
+ if ( $pageObject->processFieldFilter() )
144
+ exit();
145
+
146
+ if( $pageObject->processTotals() )
147
+ exit();
148
+
149
+ if( $mode != LIST_DETAILS && $mode != MAP_DASHBOARD && $mode != LIST_DASHBOARD )
150
+ {
151
+ //maps
152
+ }
153
+
154
+ unset($_SESSION["message_add"]);
155
+ unset($_SESSION["message_edit"]);
156
+
157
+ // prepare code for build page
158
+ $pageObject->prepareForBuildPage();
159
+
160
+ // show page depends of mode
161
+ $pageObject->showPage();
162
+
163
+ ?>
appointments_print.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ require_once("include/dbcommon.php");
6
+ require_once("classes/searchclause.php");
7
+ require_once('include/xtempl.php');
8
+ require_once('classes/printpage.php');
9
+ require_once('classes/printpage_details.php');
10
+ require_once('classes/reportpage.php');
11
+ require_once('classes/reportprintpage.php');
12
+
13
+ add_nocache_headers();
14
+
15
+ require_once("include/appointments_variables.php");
16
+
17
+ if( Security::hasLogin() ) {
18
+ if( !Security::processPageSecurity( $strtablename, 'P' ) )
19
+ return;
20
+ }
21
+
22
+
23
+ $xt = new Xtempl();
24
+
25
+ //array of params for classes
26
+ $params = array();
27
+ $params["id"] = postvalue_number("id");
28
+ $params["xt"] = &$xt;
29
+ $params["pageType"] = PAGE_PRINT;
30
+ $params["pageName"] = postvalue("page");
31
+ $params["tName"] = $strTableName;
32
+ $params["selection"] = postvalue("selection"); //PrintPage::readSelectedRecordsFromRequest( "public.appointments" );
33
+ $params["allPagesMode"] = postvalue("all");
34
+ $params["detailTables"] = postvalue("details");
35
+ $params["splitByRecords"] = postvalue("records");
36
+ $params["mode"] = postvalue( "pdfjson" ) ? PRINT_PDFJSON : PRINT_SIMPLE;
37
+ $params["pdfBackgroundImage"] = postvalue("pdfBackgroundImage");
38
+
39
+ $params["masterTable"] = postvalue("mastertable");
40
+ if( $params["masterTable"] )
41
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
42
+
43
+ $pageObject = new PrintPage($params);
44
+ $pageObject->init();
45
+ $pageObject->process();
46
+ ?>
appointments_search.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ require_once("include/dbcommon.php");
6
+ add_nocache_headers();
7
+
8
+ require_once("classes/searchclause.php");
9
+ require_once("include/appointments_variables.php");
10
+ require_once("classes/searchcontrol.php");
11
+ require_once("classes/advancedsearchcontrol.php");
12
+ require_once("classes/panelsearchcontrol.php");
13
+
14
+
15
+ Security::processLogoutRequest();
16
+
17
+ if( !isLogged() )
18
+ {
19
+ Security::saveRedirectURL();
20
+ redirectToLogin();
21
+ }
22
+
23
+ require_once( "include/reportfunctions.php" );
24
+ $cname = postvalue("cname");
25
+ $rname = postvalue("rname");
26
+ if( $rname || $cname ) {
27
+ $rpt_array = wrGetEntityArray(
28
+ $rname ? $rname : $cname,
29
+ $rname ? WR_REPORT : WR_CHART
30
+ );
31
+ $accessGranted = @$rpt_array['status'] != "private" || @$rpt_array['owner'] != Security::getUserName();
32
+ } else {
33
+ $accessGranted = CheckTablePermissions( $strTableName, "S" );
34
+ }
35
+ if(!$accessGranted)
36
+ {
37
+ HeaderRedirect("menu");
38
+ }
39
+
40
+
41
+ require_once('include/xtempl.php');
42
+ require_once('classes/searchpage.php');
43
+ require_once('classes/searchpage_dash.php');
44
+
45
+ $xt = new Xtempl();
46
+ $pageMode = SearchPage::readSearchModeFromRequest();
47
+
48
+ if( $pageMode == SEARCH_LOAD_CONTROL )
49
+ $layoutVersion = postvalue("layoutVersion");
50
+
51
+
52
+ $params = array();
53
+ $params['xt'] = &$xt;
54
+ $params['id'] = postvalue_number("id");
55
+ $params['mode'] = $pageMode;
56
+ $params['tName'] = $strTableName;
57
+ $params["pageName"] = postvalue("page");
58
+ $params['pageType'] = PAGE_SEARCH;
59
+ $params['chartName'] = $cname;
60
+ $params['reportName'] = $rname;
61
+ $params['templatefile'] = $templatefile;
62
+ $params['shortTableName'] = 'appointments';
63
+ $params['layoutVersion'] = $layoutVersion;
64
+
65
+ $params['searchControllerId'] = postvalue('searchControllerId') ? postvalue('searchControllerId') : $id;
66
+ $params['ctrlField'] = postvalue('ctrlField');
67
+
68
+ $params['needSettings'] = postvalue('isNeedSettings');
69
+
70
+ if( $pageMode == SEARCH_DASHBOARD )
71
+ {
72
+ $params["dashTName"] = postvalue("table");
73
+ $params["dashElementName"] = postvalue("dashelement");
74
+ $params["dashPage"] = postvalue("dashPage");
75
+ }
76
+
77
+ // e.g. crosstable params
78
+ $params["extraPageParams"] = SearchPage::getExtraPageParams();
79
+
80
+ $params["masterTable"] = postvalue("mastertable");
81
+ if( $params["masterTable"] )
82
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
83
+
84
+
85
+ $pageObject = new SearchPage($params);
86
+
87
+ if( $pageMode == SEARCH_LOAD_CONTROL )
88
+ {
89
+ $pageObject->displaySearchControl();
90
+ return;
91
+ }
92
+
93
+ $pageObject->init();
94
+ $pageObject->process();
95
+ ?>
appointments_view.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ require_once("include/dbcommon.php");
6
+ require_once("include/appointments_variables.php");
7
+ require_once('include/xtempl.php');
8
+ require_once('classes/viewpage.php');
9
+ require_once("classes/searchclause.php");
10
+
11
+ add_nocache_headers();
12
+
13
+ if( Security::hasLogin() ) {
14
+ if( !ViewPage::processEditPageSecurity( $strTableName ) )
15
+ return;
16
+ }
17
+
18
+ $pageMode = ViewPage::readViewModeFromRequest();
19
+
20
+ $xt = new Xtempl();
21
+
22
+ // $keys could not be set properly if editid params were no passed
23
+ $keys = array();
24
+ $keys["id"] = postvalue("editid1");
25
+
26
+ //array of params for classes
27
+ $params = array();
28
+ $params["id"] = postvalue_number("id");
29
+ $params["xt"] = &$xt;
30
+ $params["keys"] = $keys;
31
+ $params["mode"] = $pageMode;
32
+ $params["pageType"] = PAGE_VIEW;
33
+ $params["pageName"] = postvalue("page");
34
+ $params["tName"] = $strTableName;
35
+
36
+ $params["pdfMode"] = postvalue("pdf") !== "";
37
+
38
+ $params["masterTable"] = postvalue("mastertable");
39
+ if( $params["masterTable"] )
40
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
41
+
42
+ if( $pageMode == VIEW_DASHBOARD )
43
+ {
44
+ $params["dashElementName"] = postvalue("dashelement");
45
+ $params["dashTName"] = postvalue("table");
46
+ $params["dashPage"] = postvalue("dashPage");
47
+ if( postvalue("mapRefresh") )
48
+ {
49
+ $params["mapRefresh"] = true;
50
+ $params["vpCoordinates"] = my_json_decode( postvalue("vpCoordinates") );
51
+ }
52
+ }
53
+ if( $pageMode == VIEW_POPUP )
54
+ {
55
+ $params["dashElementName"] = postvalue("dashelement");
56
+ $params["dashTName"] = postvalue("dashTName");
57
+ $params["dashPage"] = postvalue("dashPage");
58
+ }
59
+
60
+ $params["pdfBackgroundImage"] = postvalue("pdfBackgroundImage");
61
+
62
+ $pageObject = new ViewPage($params);
63
+ $pageObject->init();
64
+
65
+ $pageObject->process();
66
+
67
+ ?>
autocomplete.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+
4
+ require_once("include/dbcommon.php");
5
+ header("Expires: Thu, 01 Jan 1970 00:00:01 GMT");
6
+
7
+ $shortTableName = postvalue("shortTName");
8
+ $table = GetTableByShort( $shortTableName );
9
+ if( !$table )
10
+ exit(0);
11
+
12
+
13
+ $field = postvalue("field");
14
+
15
+ $pageType = postvalue('pageType');
16
+ $pageName = postvalue('page');
17
+
18
+ if( !Security::userHasFieldPermissions( $table, $field, $pageType, $pageName, true ) )
19
+ return;
20
+
21
+ $cipherer = new RunnerCipherer( $table );
22
+ $pSet = new ProjectSettings( $table, $pageType, $pageName );
23
+
24
+ include_once getabspath("classes/controls/EditControlsContainer.php");
25
+ $editControls = new EditControlsContainer( null, $pSet, $pageType, $cipherer );
26
+ $control = $editControls->getControl( $field );
27
+
28
+
29
+ $contextParams = array();
30
+ $contextParams["data"] = my_json_decode( postvalue('data') );
31
+
32
+ $masterTable = postvalue('masterTable');
33
+ if ( $masterTable != "" && isset($_SESSION[ $masterTable . "_masterRecordData" ] ) || postvalue('masterData') )
34
+ {
35
+ $masterData = $_SESSION[ $masterTable . "_masterRecordData" ];
36
+ if( !is_array($masterData) ) {
37
+ $masterData = array();
38
+ }
39
+ $masterControlsData = my_json_decode( postvalue('masterData') );
40
+ foreach( $masterControlsData as $mField => $mValue )
41
+ {
42
+ $masterData[ $mField ] = $mValue;
43
+ }
44
+
45
+ $contextParams["masterData"] = $masterData;
46
+ }
47
+
48
+ RunnerContext::push( new RunnerContextItem( CONTEXT_ROW, $contextParams ) );
49
+
50
+
51
+ $parentCtrlsData = my_json_decode( postvalue('parentCtrlsData') );
52
+ $isExistParent = postvalue('isExistParent');
53
+ $mode = intval( postvalue('mode') );
54
+
55
+ $respObj = array( 'success' => true, 'data' => $control->getLookupContentToReload( $isExistParent === '1', $mode, $parentCtrlsData ) );
56
+ echo printJSON( $respObj );
57
+
58
+ RunnerContext::pop();
59
+ exit();
60
+ ?>
autofillfields.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+
4
+ require_once("include/dbcommon.php");
5
+ header("Expires: Thu, 01 Jan 1970 00:00:01 GMT");
6
+
7
+
8
+ $shortTableName = postvalue("shortTName");
9
+ $table = GetTableByShort( $shortTableName );
10
+ if( !$table )
11
+ exit(0);
12
+
13
+ $mainField = postvalue('mainField');
14
+ $linkFieldVal = postvalue('linkFieldVal');
15
+ $pageName = postvalue('page');
16
+ $pageType = postvalue('pageType');
17
+
18
+ if( !Security::userHasFieldPermissions( $table, $mainField, $pageType, $pageName, true ) )
19
+ return;
20
+
21
+ $cipherer = new RunnerCipherer( $table );
22
+ $pSet = new ProjectSettings( $table, $pageType, $pageName );
23
+
24
+ include_once getabspath("classes/controls/EditControlsContainer.php");
25
+ $editControls = new EditControlsContainer( null, $pSet, $pageType, $cipherer );
26
+ $control = $editControls->getControl( $mainField );
27
+
28
+
29
+ $contextParams = array();
30
+ $contextParams["data"] = my_json_decode( postvalue('data') );
31
+
32
+ $masterTable = postvalue('masterTable');
33
+ if ( $masterTable != "" && isset($_SESSION[ $masterTable . "_masterRecordData" ]) )
34
+ $contextParams["masterData"] = $_SESSION[ $masterTable . "_masterRecordData" ];
35
+
36
+ RunnerContext::push( new RunnerContextItem( CONTEXT_ROW, $contextParams ) );
37
+
38
+ echo printJSON( array( 'success'=> true, 'data' => $control->getAutoFillData( $linkFieldVal ) ) );
39
+
40
+ RunnerContext::pop();
41
+ exit();
42
+ ?>
buildpdf.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ require_once("include/dbcommon.php");
6
+ ?>
7
+ <!DOCTYPE html>
8
+ <html lang="en-US">
9
+ <head>
10
+ <title>PDF Building</title>
11
+ </head>
12
+ <body>
13
+ <div class="printpdf"></div>
14
+ <?php echo GetBaseScriptsForPage(false); ?>
15
+ <script type='text/javascript' src="<?php echo GetRootPathForResources("include/pdfnewwindow.js"); ?>"></script>
16
+ </body>
17
+ </html>
buttonhandler.php ADDED
@@ -0,0 +1,982 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ require_once("include/dbcommon.php");
6
+ require_once("classes/button.php");
7
+
8
+ // CSRF protection
9
+ if( !isPostRequest() )
10
+ return;
11
+
12
+ $params = (array)my_json_decode(postvalue('params'));
13
+
14
+ if( $params["_base64fields"] ) {
15
+ foreach( $params["_base64fields"] as $f ) {
16
+ $params[$f] = base64_str2bin( $params[$f] );
17
+ }
18
+ }
19
+
20
+ $buttId = $params['buttId'];
21
+ $eventId = postvalue('event');
22
+ $table = $params['table'];
23
+ if( !GetTableURL( $table ) ) {
24
+ exit;
25
+ }
26
+ $page = $params['page'];
27
+ if( !Security::userCanSeePage($table, $page ) ) {
28
+ exit;
29
+ }
30
+
31
+ $pSet = new ProjectSettings( $table, "", $page );
32
+ if( $buttId ) {
33
+ $pageButtons = $pSet->customButtons();
34
+ if( array_search( $buttId , $pageButtons ) === false ) {
35
+ exit;
36
+ }
37
+ }
38
+
39
+ $params["masterTable"] = postValue("masterTable");;
40
+ $params["masterKeys"] = array();
41
+ // RunnerPage::readMasterKeysFromRequest
42
+ $i = 1;
43
+ while( isset( $_REQUEST["masterkey".$i] ) ) {
44
+ $params["masterKeys"][ $i ] = $_REQUEST["masterkey".$i];
45
+ $i++;
46
+ }
47
+
48
+
49
+ if($buttId=='Add_Comment')
50
+ {
51
+ // for login page users table can be turned off
52
+ if( $table != GLOBAL_PAGES )
53
+ {
54
+ require_once("include/". GetTableURL( $table ) ."_variables.php");
55
+ $cipherer = new RunnerCipherer( $table );
56
+ }
57
+ buttonHandler_Add_Comment($params);
58
+ }
59
+ if($buttId=='Create_chart')
60
+ {
61
+ // for login page users table can be turned off
62
+ if( $table != GLOBAL_PAGES )
63
+ {
64
+ require_once("include/". GetTableURL( $table ) ."_variables.php");
65
+ $cipherer = new RunnerCipherer( $table );
66
+ }
67
+ buttonHandler_Create_chart($params);
68
+ }
69
+ if($buttId=='Send')
70
+ {
71
+ // for login page users table can be turned off
72
+ if( $table != GLOBAL_PAGES )
73
+ {
74
+ require_once("include/". GetTableURL( $table ) ."_variables.php");
75
+ $cipherer = new RunnerCipherer( $table );
76
+ }
77
+ buttonHandler_Send($params);
78
+ }
79
+ if($buttId=='New_Button')
80
+ {
81
+ // for login page users table can be turned off
82
+ if( $table != GLOBAL_PAGES )
83
+ {
84
+ require_once("include/". GetTableURL( $table ) ."_variables.php");
85
+ $cipherer = new RunnerCipherer( $table );
86
+ }
87
+ buttonHandler_New_Button($params);
88
+ }
89
+ if($buttId=='select_user_button')
90
+ {
91
+ // for login page users table can be turned off
92
+ if( $table != GLOBAL_PAGES )
93
+ {
94
+ require_once("include/". GetTableURL( $table ) ."_variables.php");
95
+ $cipherer = new RunnerCipherer( $table );
96
+ }
97
+ buttonHandler_select_user_button($params);
98
+ }
99
+ if($buttId=='New_Button1')
100
+ {
101
+ // for login page users table can be turned off
102
+ if( $table != GLOBAL_PAGES )
103
+ {
104
+ require_once("include/". GetTableURL( $table ) ."_variables.php");
105
+ $cipherer = new RunnerCipherer( $table );
106
+ }
107
+ buttonHandler_New_Button1($params);
108
+ }
109
+ if($buttId=='Audio')
110
+ {
111
+ // for login page users table can be turned off
112
+ if( $table != GLOBAL_PAGES )
113
+ {
114
+ require_once("include/". GetTableURL( $table ) ."_variables.php");
115
+ $cipherer = new RunnerCipherer( $table );
116
+ }
117
+ buttonHandler_Audio($params);
118
+ }
119
+ if($buttId=='stopAudio')
120
+ {
121
+ // for login page users table can be turned off
122
+ if( $table != GLOBAL_PAGES )
123
+ {
124
+ require_once("include/". GetTableURL( $table ) ."_variables.php");
125
+ $cipherer = new RunnerCipherer( $table );
126
+ }
127
+ buttonHandler_stopAudio($params);
128
+ }
129
+ if($buttId=='video_chat')
130
+ {
131
+ // for login page users table can be turned off
132
+ if( $table != GLOBAL_PAGES )
133
+ {
134
+ require_once("include/". GetTableURL( $table ) ."_variables.php");
135
+ $cipherer = new RunnerCipherer( $table );
136
+ }
137
+ buttonHandler_video_chat($params);
138
+ }
139
+ if($buttId=='clip')
140
+ {
141
+ // for login page users table can be turned off
142
+ if( $table != GLOBAL_PAGES )
143
+ {
144
+ require_once("include/". GetTableURL( $table ) ."_variables.php");
145
+ $cipherer = new RunnerCipherer( $table );
146
+ }
147
+ buttonHandler_clip($params);
148
+ }
149
+ if($buttId=='audiotest')
150
+ {
151
+ // for login page users table can be turned off
152
+ if( $table != GLOBAL_PAGES )
153
+ {
154
+ require_once("include/". GetTableURL( $table ) ."_variables.php");
155
+ $cipherer = new RunnerCipherer( $table );
156
+ }
157
+ buttonHandler_audiotest($params);
158
+ }
159
+
160
+ if( $eventId == 'select_provider' && "chat_settings" == $table )
161
+ {
162
+ require_once("include/chat_settings_variables.php");
163
+ $cipherer = new RunnerCipherer("chat_settings");
164
+ fieldEventHandler_select_provider( $params );
165
+ }
166
+ if( $eventId == 'check_video' && "chat_settings" == $table )
167
+ {
168
+ require_once("include/chat_settings_variables.php");
169
+ $cipherer = new RunnerCipherer("chat_settings");
170
+ fieldEventHandler_check_video( $params );
171
+ }
172
+ if( $eventId == 'tmp_file_event' && "chat_history" == $table )
173
+ {
174
+ require_once("include/chat_history_variables.php");
175
+ $cipherer = new RunnerCipherer("chat_history");
176
+ fieldEventHandler_tmp_file_event( $params );
177
+ }
178
+
179
+
180
+
181
+
182
+ // create table and non table handlers
183
+ function buttonHandler_Add_Comment($params)
184
+ {
185
+ global $strTableName;
186
+ $result = array();
187
+
188
+ // create new button object for get record data
189
+ $params["keys"] = (array)my_json_decode(postvalue('keys'));
190
+ $params["isManyKeys"] = postvalue('isManyKeys');
191
+ $params["location"] = postvalue('location');
192
+
193
+ $button = new Button($params);
194
+ $ajax = $button; // for examle from HELP
195
+ $keys = $button->getKeys();
196
+
197
+ $masterData = false;
198
+ if ( isset($params['masterData']) && count($params['masterData']) > 0 )
199
+ {
200
+ $masterData = $params['masterData'];
201
+ }
202
+ else if ( isset($params["masterTable"]) )
203
+ {
204
+ $masterData = $button->getMasterData($params["masterTable"]);
205
+ }
206
+
207
+ $contextParams = array();
208
+ if ( $params["location"] == PAGE_VIEW )
209
+ {
210
+ $contextParams["data"] = $button->getRecordData();
211
+ $contextParams["masterData"] = $masterData;
212
+ }
213
+ else if ( $params["location"] == PAGE_EDIT )
214
+ {
215
+ $contextParams["data"] = $button->getRecordData();
216
+ $contextParams["newData"] = $params['fieldsData'];
217
+ $contextParams["masterData"] = $masterData;
218
+ }
219
+ else if ( $params["location"] == "grid" )
220
+ {
221
+ $params["location"] = "list";
222
+ $contextParams["data"] = $button->getRecordData();
223
+ $contextParams["newData"] = $params['fieldsData'];
224
+ $contextParams["masterData"] = $masterData;
225
+ }
226
+ else
227
+ {
228
+ $contextParams["masterData"] = $masterData;
229
+ }
230
+
231
+ RunnerContext::push( new RunnerContextItem( $params["location"], $contextParams));
232
+ // Put your code here.
233
+ $result["txt"] = $params["txt"]." world!";
234
+ ;
235
+ RunnerContext::pop();
236
+ echo my_json_encode($result);
237
+ $button->deleteTempFiles();
238
+ }
239
+ function buttonHandler_Create_chart($params)
240
+ {
241
+ global $strTableName;
242
+ $result = array();
243
+
244
+ // create new button object for get record data
245
+ $params["keys"] = (array)my_json_decode(postvalue('keys'));
246
+ $params["isManyKeys"] = postvalue('isManyKeys');
247
+ $params["location"] = postvalue('location');
248
+
249
+ $button = new Button($params);
250
+ $ajax = $button; // for examle from HELP
251
+ $keys = $button->getKeys();
252
+
253
+ $masterData = false;
254
+ if ( isset($params['masterData']) && count($params['masterData']) > 0 )
255
+ {
256
+ $masterData = $params['masterData'];
257
+ }
258
+ else if ( isset($params["masterTable"]) )
259
+ {
260
+ $masterData = $button->getMasterData($params["masterTable"]);
261
+ }
262
+
263
+ $contextParams = array();
264
+ if ( $params["location"] == PAGE_VIEW )
265
+ {
266
+ $contextParams["data"] = $button->getRecordData();
267
+ $contextParams["masterData"] = $masterData;
268
+ }
269
+ else if ( $params["location"] == PAGE_EDIT )
270
+ {
271
+ $contextParams["data"] = $button->getRecordData();
272
+ $contextParams["newData"] = $params['fieldsData'];
273
+ $contextParams["masterData"] = $masterData;
274
+ }
275
+ else if ( $params["location"] == "grid" )
276
+ {
277
+ $params["location"] = "list";
278
+ $contextParams["data"] = $button->getRecordData();
279
+ $contextParams["newData"] = $params['fieldsData'];
280
+ $contextParams["masterData"] = $masterData;
281
+ }
282
+ else
283
+ {
284
+ $contextParams["masterData"] = $masterData;
285
+ }
286
+
287
+ RunnerContext::push( new RunnerContextItem( $params["location"], $contextParams));
288
+ /*global $loginKeyFields;
289
+ $userdata = Security::currentUserData();
290
+ $rs = DB::Query("select count(id) as cnt from chat_history where ownerid='".$userdata[$loginKeyFields[0]]."' and targetid='".$params["id"]."' and isread=0");
291
+ $data = $rs->fetchAssoc();
292
+ if($data["cnt"]==0){
293
+ DB::Exec("insert into chat_history (messages, created, isread, targetid, ownerid) values ('','".date("Y-m-d- h:i:s")."',0,".$params["id"].",'".$userdata[$loginKeyFields[0]]."')");
294
+ }
295
+ $result["id"] = $params["id"];*/;
296
+ RunnerContext::pop();
297
+ echo my_json_encode($result);
298
+ $button->deleteTempFiles();
299
+ }
300
+ function buttonHandler_Send($params)
301
+ {
302
+ global $strTableName;
303
+ $result = array();
304
+
305
+ // create new button object for get record data
306
+ $params["keys"] = (array)my_json_decode(postvalue('keys'));
307
+ $params["isManyKeys"] = postvalue('isManyKeys');
308
+ $params["location"] = postvalue('location');
309
+
310
+ $button = new Button($params);
311
+ $ajax = $button; // for examle from HELP
312
+ $keys = $button->getKeys();
313
+
314
+ $masterData = false;
315
+ if ( isset($params['masterData']) && count($params['masterData']) > 0 )
316
+ {
317
+ $masterData = $params['masterData'];
318
+ }
319
+ else if ( isset($params["masterTable"]) )
320
+ {
321
+ $masterData = $button->getMasterData($params["masterTable"]);
322
+ }
323
+
324
+ $contextParams = array();
325
+ if ( $params["location"] == PAGE_VIEW )
326
+ {
327
+ $contextParams["data"] = $button->getRecordData();
328
+ $contextParams["masterData"] = $masterData;
329
+ }
330
+ else if ( $params["location"] == PAGE_EDIT )
331
+ {
332
+ $contextParams["data"] = $button->getRecordData();
333
+ $contextParams["newData"] = $params['fieldsData'];
334
+ $contextParams["masterData"] = $masterData;
335
+ }
336
+ else if ( $params["location"] == "grid" )
337
+ {
338
+ $params["location"] = "list";
339
+ $contextParams["data"] = $button->getRecordData();
340
+ $contextParams["newData"] = $params['fieldsData'];
341
+ $contextParams["masterData"] = $masterData;
342
+ }
343
+ else
344
+ {
345
+ $contextParams["masterData"] = $masterData;
346
+ }
347
+
348
+ RunnerContext::push( new RunnerContextItem( $params["location"], $contextParams));
349
+ /*include_once("chat_functions.php");
350
+ global $loginKeyFields;
351
+ $mess = $params["msg"];
352
+ if(strlen($mess)>4000)
353
+ $mess = substr($mess,0,4000);
354
+ $userdata = Security::currentUserData();
355
+ $t = explode(" ",this_microtime());
356
+ $sql = DB::PrepareSQL("insert into chat_history (messages, created, isread, targetid, ownerid, status) values (':1',':2','0','".$_SESSION["targetid"]."','".$userdata[$loginKeyFields[0]]."','')", $mess, date("Y-m-d H:i:s",$t[1]).substr((string)$t[0],1,4));
357
+ //echo $sql;
358
+ DB::Exec($sql);
359
+ $_SESSION["message_id"] = DB::LastId();
360
+
361
+ **/;
362
+ RunnerContext::pop();
363
+ echo my_json_encode($result);
364
+ $button->deleteTempFiles();
365
+ }
366
+ function buttonHandler_New_Button($params)
367
+ {
368
+ global $strTableName;
369
+ $result = array();
370
+
371
+ // create new button object for get record data
372
+ $params["keys"] = (array)my_json_decode(postvalue('keys'));
373
+ $params["isManyKeys"] = postvalue('isManyKeys');
374
+ $params["location"] = postvalue('location');
375
+
376
+ $button = new Button($params);
377
+ $ajax = $button; // for examle from HELP
378
+ $keys = $button->getKeys();
379
+
380
+ $masterData = false;
381
+ if ( isset($params['masterData']) && count($params['masterData']) > 0 )
382
+ {
383
+ $masterData = $params['masterData'];
384
+ }
385
+ else if ( isset($params["masterTable"]) )
386
+ {
387
+ $masterData = $button->getMasterData($params["masterTable"]);
388
+ }
389
+
390
+ $contextParams = array();
391
+ if ( $params["location"] == PAGE_VIEW )
392
+ {
393
+ $contextParams["data"] = $button->getRecordData();
394
+ $contextParams["masterData"] = $masterData;
395
+ }
396
+ else if ( $params["location"] == PAGE_EDIT )
397
+ {
398
+ $contextParams["data"] = $button->getRecordData();
399
+ $contextParams["newData"] = $params['fieldsData'];
400
+ $contextParams["masterData"] = $masterData;
401
+ }
402
+ else if ( $params["location"] == "grid" )
403
+ {
404
+ $params["location"] = "list";
405
+ $contextParams["data"] = $button->getRecordData();
406
+ $contextParams["newData"] = $params['fieldsData'];
407
+ $contextParams["masterData"] = $masterData;
408
+ }
409
+ else
410
+ {
411
+ $contextParams["masterData"] = $masterData;
412
+ }
413
+
414
+ RunnerContext::push( new RunnerContextItem( $params["location"], $contextParams));
415
+ ;
416
+ RunnerContext::pop();
417
+ echo my_json_encode($result);
418
+ $button->deleteTempFiles();
419
+ }
420
+ function buttonHandler_select_user_button($params)
421
+ {
422
+ global $strTableName;
423
+ $result = array();
424
+
425
+ // create new button object for get record data
426
+ $params["keys"] = (array)my_json_decode(postvalue('keys'));
427
+ $params["isManyKeys"] = postvalue('isManyKeys');
428
+ $params["location"] = postvalue('location');
429
+
430
+ $button = new Button($params);
431
+ $ajax = $button; // for examle from HELP
432
+ $keys = $button->getKeys();
433
+
434
+ $masterData = false;
435
+ if ( isset($params['masterData']) && count($params['masterData']) > 0 )
436
+ {
437
+ $masterData = $params['masterData'];
438
+ }
439
+ else if ( isset($params["masterTable"]) )
440
+ {
441
+ $masterData = $button->getMasterData($params["masterTable"]);
442
+ }
443
+
444
+ $contextParams = array();
445
+ if ( $params["location"] == PAGE_VIEW )
446
+ {
447
+ $contextParams["data"] = $button->getRecordData();
448
+ $contextParams["masterData"] = $masterData;
449
+ }
450
+ else if ( $params["location"] == PAGE_EDIT )
451
+ {
452
+ $contextParams["data"] = $button->getRecordData();
453
+ $contextParams["newData"] = $params['fieldsData'];
454
+ $contextParams["masterData"] = $masterData;
455
+ }
456
+ else if ( $params["location"] == "grid" )
457
+ {
458
+ $params["location"] = "list";
459
+ $contextParams["data"] = $button->getRecordData();
460
+ $contextParams["newData"] = $params['fieldsData'];
461
+ $contextParams["masterData"] = $masterData;
462
+ }
463
+ else
464
+ {
465
+ $contextParams["masterData"] = $masterData;
466
+ }
467
+
468
+ RunnerContext::push( new RunnerContextItem( $params["location"], $contextParams));
469
+ ;
470
+ RunnerContext::pop();
471
+ echo my_json_encode($result);
472
+ $button->deleteTempFiles();
473
+ }
474
+ function buttonHandler_New_Button1($params)
475
+ {
476
+ global $strTableName;
477
+ $result = array();
478
+
479
+ // create new button object for get record data
480
+ $params["keys"] = (array)my_json_decode(postvalue('keys'));
481
+ $params["isManyKeys"] = postvalue('isManyKeys');
482
+ $params["location"] = postvalue('location');
483
+
484
+ $button = new Button($params);
485
+ $ajax = $button; // for examle from HELP
486
+ $keys = $button->getKeys();
487
+
488
+ $masterData = false;
489
+ if ( isset($params['masterData']) && count($params['masterData']) > 0 )
490
+ {
491
+ $masterData = $params['masterData'];
492
+ }
493
+ else if ( isset($params["masterTable"]) )
494
+ {
495
+ $masterData = $button->getMasterData($params["masterTable"]);
496
+ }
497
+
498
+ $contextParams = array();
499
+ if ( $params["location"] == PAGE_VIEW )
500
+ {
501
+ $contextParams["data"] = $button->getRecordData();
502
+ $contextParams["masterData"] = $masterData;
503
+ }
504
+ else if ( $params["location"] == PAGE_EDIT )
505
+ {
506
+ $contextParams["data"] = $button->getRecordData();
507
+ $contextParams["newData"] = $params['fieldsData'];
508
+ $contextParams["masterData"] = $masterData;
509
+ }
510
+ else if ( $params["location"] == "grid" )
511
+ {
512
+ $params["location"] = "list";
513
+ $contextParams["data"] = $button->getRecordData();
514
+ $contextParams["newData"] = $params['fieldsData'];
515
+ $contextParams["masterData"] = $masterData;
516
+ }
517
+ else
518
+ {
519
+ $contextParams["masterData"] = $masterData;
520
+ }
521
+
522
+ RunnerContext::push( new RunnerContextItem( $params["location"], $contextParams));
523
+ // Put your code here.
524
+ $result["txt"] = $params["txt"]." world!";
525
+ ;
526
+ RunnerContext::pop();
527
+ echo my_json_encode($result);
528
+ $button->deleteTempFiles();
529
+ }
530
+ function buttonHandler_Audio($params)
531
+ {
532
+ global $strTableName;
533
+ $result = array();
534
+
535
+ // create new button object for get record data
536
+ $params["keys"] = (array)my_json_decode(postvalue('keys'));
537
+ $params["isManyKeys"] = postvalue('isManyKeys');
538
+ $params["location"] = postvalue('location');
539
+
540
+ $button = new Button($params);
541
+ $ajax = $button; // for examle from HELP
542
+ $keys = $button->getKeys();
543
+
544
+ $masterData = false;
545
+ if ( isset($params['masterData']) && count($params['masterData']) > 0 )
546
+ {
547
+ $masterData = $params['masterData'];
548
+ }
549
+ else if ( isset($params["masterTable"]) )
550
+ {
551
+ $masterData = $button->getMasterData($params["masterTable"]);
552
+ }
553
+
554
+ $contextParams = array();
555
+ if ( $params["location"] == PAGE_VIEW )
556
+ {
557
+ $contextParams["data"] = $button->getRecordData();
558
+ $contextParams["masterData"] = $masterData;
559
+ }
560
+ else if ( $params["location"] == PAGE_EDIT )
561
+ {
562
+ $contextParams["data"] = $button->getRecordData();
563
+ $contextParams["newData"] = $params['fieldsData'];
564
+ $contextParams["masterData"] = $masterData;
565
+ }
566
+ else if ( $params["location"] == "grid" )
567
+ {
568
+ $params["location"] = "list";
569
+ $contextParams["data"] = $button->getRecordData();
570
+ $contextParams["newData"] = $params['fieldsData'];
571
+ $contextParams["masterData"] = $masterData;
572
+ }
573
+ else
574
+ {
575
+ $contextParams["masterData"] = $masterData;
576
+ }
577
+
578
+ RunnerContext::push( new RunnerContextItem( $params["location"], $contextParams));
579
+ // Put your code here.
580
+ $result["txt"] = $params["txt"]." world!";
581
+ ;
582
+ RunnerContext::pop();
583
+ echo my_json_encode($result);
584
+ $button->deleteTempFiles();
585
+ }
586
+ function buttonHandler_stopAudio($params)
587
+ {
588
+ global $strTableName;
589
+ $result = array();
590
+
591
+ // create new button object for get record data
592
+ $params["keys"] = (array)my_json_decode(postvalue('keys'));
593
+ $params["isManyKeys"] = postvalue('isManyKeys');
594
+ $params["location"] = postvalue('location');
595
+
596
+ $button = new Button($params);
597
+ $ajax = $button; // for examle from HELP
598
+ $keys = $button->getKeys();
599
+
600
+ $masterData = false;
601
+ if ( isset($params['masterData']) && count($params['masterData']) > 0 )
602
+ {
603
+ $masterData = $params['masterData'];
604
+ }
605
+ else if ( isset($params["masterTable"]) )
606
+ {
607
+ $masterData = $button->getMasterData($params["masterTable"]);
608
+ }
609
+
610
+ $contextParams = array();
611
+ if ( $params["location"] == PAGE_VIEW )
612
+ {
613
+ $contextParams["data"] = $button->getRecordData();
614
+ $contextParams["masterData"] = $masterData;
615
+ }
616
+ else if ( $params["location"] == PAGE_EDIT )
617
+ {
618
+ $contextParams["data"] = $button->getRecordData();
619
+ $contextParams["newData"] = $params['fieldsData'];
620
+ $contextParams["masterData"] = $masterData;
621
+ }
622
+ else if ( $params["location"] == "grid" )
623
+ {
624
+ $params["location"] = "list";
625
+ $contextParams["data"] = $button->getRecordData();
626
+ $contextParams["newData"] = $params['fieldsData'];
627
+ $contextParams["masterData"] = $masterData;
628
+ }
629
+ else
630
+ {
631
+ $contextParams["masterData"] = $masterData;
632
+ }
633
+
634
+ RunnerContext::push( new RunnerContextItem( $params["location"], $contextParams));
635
+ // Put your code here.
636
+ $result["txt"] = $params["txt"]." world!";
637
+ ;
638
+ RunnerContext::pop();
639
+ echo my_json_encode($result);
640
+ $button->deleteTempFiles();
641
+ }
642
+ function buttonHandler_video_chat($params)
643
+ {
644
+ global $strTableName;
645
+ $result = array();
646
+
647
+ // create new button object for get record data
648
+ $params["keys"] = (array)my_json_decode(postvalue('keys'));
649
+ $params["isManyKeys"] = postvalue('isManyKeys');
650
+ $params["location"] = postvalue('location');
651
+
652
+ $button = new Button($params);
653
+ $ajax = $button; // for examle from HELP
654
+ $keys = $button->getKeys();
655
+
656
+ $masterData = false;
657
+ if ( isset($params['masterData']) && count($params['masterData']) > 0 )
658
+ {
659
+ $masterData = $params['masterData'];
660
+ }
661
+ else if ( isset($params["masterTable"]) )
662
+ {
663
+ $masterData = $button->getMasterData($params["masterTable"]);
664
+ }
665
+
666
+ $contextParams = array();
667
+ if ( $params["location"] == PAGE_VIEW )
668
+ {
669
+ $contextParams["data"] = $button->getRecordData();
670
+ $contextParams["masterData"] = $masterData;
671
+ }
672
+ else if ( $params["location"] == PAGE_EDIT )
673
+ {
674
+ $contextParams["data"] = $button->getRecordData();
675
+ $contextParams["newData"] = $params['fieldsData'];
676
+ $contextParams["masterData"] = $masterData;
677
+ }
678
+ else if ( $params["location"] == "grid" )
679
+ {
680
+ $params["location"] = "list";
681
+ $contextParams["data"] = $button->getRecordData();
682
+ $contextParams["newData"] = $params['fieldsData'];
683
+ $contextParams["masterData"] = $masterData;
684
+ }
685
+ else
686
+ {
687
+ $contextParams["masterData"] = $masterData;
688
+ }
689
+
690
+ RunnerContext::push( new RunnerContextItem( $params["location"], $contextParams));
691
+ include_once("chat_functions.php");
692
+ global $loginKeyFields, $cDisplayNameField, $cUserNameField;
693
+ $result["message"] = "";
694
+ $rs = DB::Select("chat_history", array("isVideo"=>1,"ownerid"=>$userdata[$loginKeyFields[0]]));
695
+ if(!($data = $rs->fetchAssoc())){
696
+ if(!$cDisplayNameField)
697
+ $cDisplayNameField = $cUserNameField;
698
+ $userdata = Security::currentUserData();
699
+ $username = $userdata[$cDisplayNameField];
700
+ if(!$username)
701
+ $username = $userdata[$cUserNameField];
702
+ $t = explode(" ",this_microtime());
703
+ //--- create meeting
704
+ $values["name"] = "Video chat";
705
+ $values["schedule"] = date("Y-m-d H:i:s");
706
+ $values["password"] = "";
707
+
708
+ /*$rs = DB::Select("chat_settings");
709
+ $data = $rs->fetchAssoc();
710
+ $rs2 = DB::Select("chat_timezone", array("id"=>$data["timezone"]));
711
+ $data2 = $rs2->fetchAssoc();
712
+ $rctimezone = $data2["rc"];
713
+ $zoomtimezone = $data2["zoom"];*/
714
+
715
+ $rs = DB::Select("chat_settings");
716
+ $data = $rs->fetchAssoc();
717
+
718
+ $OAuoh = base64_encode($data["Z_APIKey"].":".$data["Z_APISecret"]);
719
+ $url = "https://zoom.us/oauth/token";
720
+ $headers = array("Authorization"=>" Basic ".$OAuoh, "Host"=>"zoom.us","Content-Type"=>"application/x-www-form-urlencoded");
721
+ $postFields = "grant_type=account_credentials&account_id=".$data["Z_Token"]."&redirect_uri=https://zoom.us";
722
+ $response = runner_http_request( $url, $postFields, "POST", $headers, true );
723
+ $arrresponse = my_json_decode($response["content"]);
724
+ if($arrresponse["message"]){
725
+ $result["message"] = $arrresponse["message"];
726
+ }
727
+ else{
728
+ $token = $arrresponse["access_token"];
729
+
730
+ $createAMeetingArray['topic'] = $values["name"];
731
+ $createAMeetingArray['agenda'] = "";
732
+ $dt = "";
733
+ if($values["schedule"]){
734
+ $datetime = date("Y-m-d\TH:i:s", strtotime($values["schedule"]));
735
+ $createAMeetingArray['type'] = 2;
736
+ $createAMeetingArray['start_time'] = $datetime;
737
+ $dt = date("m/d/Y H:i:s", strtotime($values["schedule"]));
738
+ }
739
+ else
740
+ $createAMeetingArray['type'] = 1;
741
+
742
+ //$createAMeetingArray['timezone'] = $zoomtimezone;
743
+ if($values["password"])
744
+ $createAMeetingArray['password'] = $values["password"];
745
+ else
746
+ $createAMeetingArray['password'] = "";
747
+ $createAMeetingArray['duration'] = 60;
748
+ $createAMeetingArray['settings'] = array(
749
+ 'join_before_host' => false,
750
+ 'host_video' => true,
751
+ 'participant_video' => true,
752
+ 'mute_upon_entry' => false,
753
+ 'enforce_login' => false,
754
+ 'alternative_hosts' => ""
755
+ );
756
+ if($data["saveInCloud"])
757
+ $createAMeetingArray['settings']['auto_recording'] = true;
758
+
759
+ $postFields = my_json_encode($createAMeetingArray);
760
+ $url = "https://api.zoom.us/v2/users/me/meetings";
761
+ $headers = array("authorization"=>" Bearer ".$token, "content-type"=>"application/json");
762
+ $response = runner_http_request( $url, $postFields, "POST", $headers, true );
763
+ $arrresponse = my_json_decode($response["content"]);
764
+ $result["createlink"] = "";
765
+ if($arrresponse["message"]){
766
+ $result["message"] = $arrresponse["message"];
767
+ }
768
+ else{
769
+ $values["createlink"] = $arrresponse["start_url"];
770
+ $values["joinlink"] = $arrresponse["join_url"];
771
+
772
+
773
+ $result["createlink"] = $values["createlink"];
774
+ DB::Insert("chat_history", array("messages"=>$values["joinlink"],"created"=>date("Y-m-d H:i:s",$t[1]).substr((string)$t[0],1,4),"isread"=>0,"targetid"=>$_SESSION["targetid"], "isVideo"=>1, "ownerid"=>$userdata[$loginKeyFields[0]]));
775
+ //DB::Insert("chat_history", array("messages"=>"<i>".$username." create video chat</i>","created"=>date("Y-m-d H:i:s",$t[1]).substr((string)$t[0],1,4),"isread"=>0,"targetid"=>$_SESSION["targetid"], "isVideo"=>0, "ownerid"=>$userdata[$loginKeyFields[0]]));
776
+ }
777
+ }
778
+ }
779
+
780
+ ;
781
+ RunnerContext::pop();
782
+ echo my_json_encode($result);
783
+ $button->deleteTempFiles();
784
+ }
785
+ function buttonHandler_clip($params)
786
+ {
787
+ global $strTableName;
788
+ $result = array();
789
+
790
+ // create new button object for get record data
791
+ $params["keys"] = (array)my_json_decode(postvalue('keys'));
792
+ $params["isManyKeys"] = postvalue('isManyKeys');
793
+ $params["location"] = postvalue('location');
794
+
795
+ $button = new Button($params);
796
+ $ajax = $button; // for examle from HELP
797
+ $keys = $button->getKeys();
798
+
799
+ $masterData = false;
800
+ if ( isset($params['masterData']) && count($params['masterData']) > 0 )
801
+ {
802
+ $masterData = $params['masterData'];
803
+ }
804
+ else if ( isset($params["masterTable"]) )
805
+ {
806
+ $masterData = $button->getMasterData($params["masterTable"]);
807
+ }
808
+
809
+ $contextParams = array();
810
+ if ( $params["location"] == PAGE_VIEW )
811
+ {
812
+ $contextParams["data"] = $button->getRecordData();
813
+ $contextParams["masterData"] = $masterData;
814
+ }
815
+ else if ( $params["location"] == PAGE_EDIT )
816
+ {
817
+ $contextParams["data"] = $button->getRecordData();
818
+ $contextParams["newData"] = $params['fieldsData'];
819
+ $contextParams["masterData"] = $masterData;
820
+ }
821
+ else if ( $params["location"] == "grid" )
822
+ {
823
+ $params["location"] = "list";
824
+ $contextParams["data"] = $button->getRecordData();
825
+ $contextParams["newData"] = $params['fieldsData'];
826
+ $contextParams["masterData"] = $masterData;
827
+ }
828
+ else
829
+ {
830
+ $contextParams["masterData"] = $masterData;
831
+ }
832
+
833
+ RunnerContext::push( new RunnerContextItem( $params["location"], $contextParams));
834
+ ;
835
+ RunnerContext::pop();
836
+ echo my_json_encode($result);
837
+ $button->deleteTempFiles();
838
+ }
839
+ function buttonHandler_audiotest($params)
840
+ {
841
+ global $strTableName;
842
+ $result = array();
843
+
844
+ // create new button object for get record data
845
+ $params["keys"] = (array)my_json_decode(postvalue('keys'));
846
+ $params["isManyKeys"] = postvalue('isManyKeys');
847
+ $params["location"] = postvalue('location');
848
+
849
+ $button = new Button($params);
850
+ $ajax = $button; // for examle from HELP
851
+ $keys = $button->getKeys();
852
+
853
+ $masterData = false;
854
+ if ( isset($params['masterData']) && count($params['masterData']) > 0 )
855
+ {
856
+ $masterData = $params['masterData'];
857
+ }
858
+ else if ( isset($params["masterTable"]) )
859
+ {
860
+ $masterData = $button->getMasterData($params["masterTable"]);
861
+ }
862
+
863
+ $contextParams = array();
864
+ if ( $params["location"] == PAGE_VIEW )
865
+ {
866
+ $contextParams["data"] = $button->getRecordData();
867
+ $contextParams["masterData"] = $masterData;
868
+ }
869
+ else if ( $params["location"] == PAGE_EDIT )
870
+ {
871
+ $contextParams["data"] = $button->getRecordData();
872
+ $contextParams["newData"] = $params['fieldsData'];
873
+ $contextParams["masterData"] = $masterData;
874
+ }
875
+ else if ( $params["location"] == "grid" )
876
+ {
877
+ $params["location"] = "list";
878
+ $contextParams["data"] = $button->getRecordData();
879
+ $contextParams["newData"] = $params['fieldsData'];
880
+ $contextParams["masterData"] = $masterData;
881
+ }
882
+ else
883
+ {
884
+ $contextParams["masterData"] = $masterData;
885
+ }
886
+
887
+ RunnerContext::push( new RunnerContextItem( $params["location"], $contextParams));
888
+ // Put your code here.
889
+ $result["txt"] = $params["txt"]." world!";
890
+ ;
891
+ RunnerContext::pop();
892
+ echo my_json_encode($result);
893
+ $button->deleteTempFiles();
894
+ }
895
+
896
+
897
+
898
+ function fieldEventHandler_select_provider( $params )
899
+ {
900
+ $params["keys"] = (array)my_json_decode(postvalue('keys'));
901
+ $params["isManyKeys"] = false;
902
+ $params["location"] = postvalue('pageType');
903
+
904
+ $button = new Button($params);
905
+ $keys = $button->getKeys();
906
+ $ajax = $button; // for examle from HELP
907
+ $result = array();
908
+
909
+ $pageType = postvalue("pageType");
910
+ $fieldsData = my_json_decode( postvalue("fieldsData") );
911
+
912
+ $contextParams = array(
913
+ "data" => $fieldsData,
914
+ "masterData" => $_SESSION[ $masterTable . "_masterRecordData" ]
915
+ );
916
+
917
+ RunnerContext::push( new RunnerContextItem( CONTEXT_ROW, $contextParams ) );
918
+ ;
919
+ RunnerContext::pop();
920
+
921
+ echo my_json_encode( $result );
922
+ $button->deleteTempFiles();
923
+ }
924
+ function fieldEventHandler_check_video( $params )
925
+ {
926
+ $params["keys"] = (array)my_json_decode(postvalue('keys'));
927
+ $params["isManyKeys"] = false;
928
+ $params["location"] = postvalue('pageType');
929
+
930
+ $button = new Button($params);
931
+ $keys = $button->getKeys();
932
+ $ajax = $button; // for examle from HELP
933
+ $result = array();
934
+
935
+ $pageType = postvalue("pageType");
936
+ $fieldsData = my_json_decode( postvalue("fieldsData") );
937
+
938
+ $contextParams = array(
939
+ "data" => $fieldsData,
940
+ "masterData" => $_SESSION[ $masterTable . "_masterRecordData" ]
941
+ );
942
+
943
+ RunnerContext::push( new RunnerContextItem( CONTEXT_ROW, $contextParams ) );
944
+
945
+ // Sample:
946
+ $result["upper"] = strtoupper( $params["value"] );
947
+ ;
948
+ RunnerContext::pop();
949
+
950
+ echo my_json_encode( $result );
951
+ $button->deleteTempFiles();
952
+ }
953
+ function fieldEventHandler_tmp_file_event( $params )
954
+ {
955
+ $params["keys"] = (array)my_json_decode(postvalue('keys'));
956
+ $params["isManyKeys"] = false;
957
+ $params["location"] = postvalue('pageType');
958
+
959
+ $button = new Button($params);
960
+ $keys = $button->getKeys();
961
+ $ajax = $button; // for examle from HELP
962
+ $result = array();
963
+
964
+ $pageType = postvalue("pageType");
965
+ $fieldsData = my_json_decode( postvalue("fieldsData") );
966
+
967
+ $contextParams = array(
968
+ "data" => $fieldsData,
969
+ "masterData" => $_SESSION[ $masterTable . "_masterRecordData" ]
970
+ );
971
+
972
+ RunnerContext::push( new RunnerContextItem( CONTEXT_ROW, $contextParams ) );
973
+
974
+ // Sample:
975
+ $result["upper"] = strtoupper( $params["value"] );
976
+ ;
977
+ RunnerContext::pop();
978
+
979
+ echo my_json_encode( $result );
980
+ $button->deleteTempFiles();
981
+ }
982
+ ?>
callVideo.mp3 ADDED
Binary file (61.3 kB). View file
 
chat_files_list.php ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ $requestTable = "chat_files";
6
+ $requestPage = "list";
7
+
8
+ require_once("include/dbcommon.php");
9
+ add_nocache_headers();
10
+
11
+ require_once('include/xtempl.php');
12
+
13
+ require_once("classes/searchcontrol.php");
14
+ require_once("classes/searchclause.php");
15
+ require_once("classes/panelsearchcontrol.php");
16
+ require_once("include/chat_files_variables.php");
17
+ require_once('classes/listpage.php');
18
+ require_once('include/lookuplinks.php');
19
+
20
+ // Check whether the page was called as a part of Lookup wizard - List page with search.
21
+ // Verify the eligibility of such a call.
22
+
23
+ InitLookupLinks();
24
+ if( Security::hasLogin() ) {
25
+ if( !ListPage::processListPageSecurity( $strTableName ) )
26
+ return;
27
+ }
28
+
29
+ if( ListPage::processSaveParams( $strTableName ) )
30
+ return;
31
+
32
+ $options = array();
33
+ //array of params for classes
34
+
35
+ // Include necessary files in accordance with the page displaying mode
36
+ $mode = ListPage::readListModeFromRequest();
37
+ if( $mode == LIST_SIMPLE )
38
+ {
39
+ require_once('classes/listpage_simple.php');
40
+ require_once("classes/searchpanelsimple.php");
41
+ }
42
+ elseif( $mode == LIST_AJAX )
43
+ {
44
+ require_once('classes/listpage_simple.php');
45
+ require_once('classes/listpage_ajax.php');
46
+ require_once("classes/searchpanelsimple.php");
47
+ }
48
+ elseif( $mode == LIST_LOOKUP )
49
+ {
50
+ require_once('classes/listpage_embed.php');
51
+ require_once('classes/listpage_lookup.php');
52
+
53
+ $options["mainTable"] = postvalue("table");
54
+ $options["mainField"] = postvalue("field");
55
+ $options["mainPageType"] = postvalue("pageType");
56
+
57
+ $options["mainRecordData"] = my_json_decode( postvalue('data') );
58
+ $options["mainRecordMasterTable"] = postvalue('mainRecordMasterTable');
59
+
60
+ if( postvalue("parentsExist") )
61
+ $options["parentCtrlsData"] = my_json_decode( postvalue("parentCtrlsData") );
62
+ }
63
+ elseif( $mode == LIST_POPUPDETAILS )
64
+ {
65
+ require_once('classes/listpage_embed.php');
66
+ require_once('classes/listpage_dpinline.php');
67
+ require_once('classes/listpage_dppopup.php');
68
+ }
69
+ elseif( $mode == LIST_DETAILS )
70
+ {
71
+ require_once('classes/listpage_embed.php');
72
+ require_once('classes/listpage_dpinline.php');
73
+ require_once('classes/listpage_dplist.php');
74
+ }
75
+ elseif( $mode == LIST_DASHDETAILS )
76
+ {
77
+ require_once('classes/listpage_embed.php');
78
+ require_once('classes/listpage_dashboard.php');
79
+ require_once('classes/listpage_dpdash.php');
80
+ }
81
+ elseif( $mode == LIST_DASHBOARD )
82
+ {
83
+ require_once('classes/listpage_embed.php');
84
+ require_once('classes/listpage_dashboard.php');
85
+ }
86
+ elseif( $mode == MAP_DASHBOARD )
87
+ {
88
+ require_once('classes/listpage_embed.php');
89
+ require_once('classes/listpage_dashboard.php');
90
+ require_once('classes/map_dashboard.php');
91
+ }
92
+
93
+ $xt = new Xtempl( $mode != LIST_SIMPLE ); //#9607 1. Temporary fix
94
+
95
+ $options["pageName"] = postvalue("page");
96
+ $options["pageType"] = PAGE_LIST;
97
+ $options["id"] = postvalue_number("id") ? postvalue_number("id") : 1;
98
+ $options["flyId"] = (int)postvalue("recordId");
99
+ $options["mode"] = $mode;
100
+ $options["xt"] = &$xt;
101
+ $options["firstTime"] = postvalue("firstTime");
102
+ $options["sortBy"] = postvalue("sortby");
103
+ $options["requestGoto"] = postvalue_number("goto");
104
+
105
+
106
+ $options["masterPageType"] = postvalue("masterpagetype");
107
+ $options["masterPage"] = postvalue("masterpage");
108
+ $options["masterId"] = postvalue("masterid");
109
+
110
+ $options["masterTable"] = postvalue("mastertable");
111
+ if( $options["masterTable"] )
112
+ $options["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
113
+
114
+
115
+ if( $mode == LIST_DASHBOARD && postvalue("nodata") && strlen($options["masterTable"]) )
116
+ $options["showNoData"] = true;
117
+
118
+ if( $mode != LIST_LOOKUP )
119
+ {
120
+ $options["dashElementName"] = postvalue("dashelement");
121
+ $options["dashTName"] = postvalue("table");
122
+ $options["dashPage"] = postvalue("dashPage");
123
+ }
124
+
125
+ if( postvalue("mapRefresh") )
126
+ {
127
+ $options["mapRefresh"] = true;
128
+ $options["vpCoordinates"] = my_json_decode( postvalue("vpCoordinates") );
129
+ }
130
+
131
+ if( postvalue("firstTime") )
132
+ $options["firstTime"] = true;
133
+
134
+ // Create $pageObject
135
+ $pageObject = ListPage::createListPage($strTableName, $options);
136
+
137
+ if( $pageObject->processSaveSearch() )
138
+ exit();
139
+
140
+ if( $pageObject->updateRowOrder() )
141
+ exit();
142
+
143
+ if ( $pageObject->processFieldFilter() )
144
+ exit();
145
+
146
+ if( $pageObject->processTotals() )
147
+ exit();
148
+
149
+ if( $mode != LIST_DETAILS && $mode != MAP_DASHBOARD && $mode != LIST_DASHBOARD )
150
+ {
151
+ //maps
152
+ }
153
+
154
+ unset($_SESSION["message_add"]);
155
+ unset($_SESSION["message_edit"]);
156
+
157
+ // prepare code for build page
158
+ $pageObject->prepareForBuildPage();
159
+
160
+ // show page depends of mode
161
+ $pageObject->showPage();
162
+
163
+ ?>
chat_files_search.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ require_once("include/dbcommon.php");
6
+ add_nocache_headers();
7
+
8
+ require_once("classes/searchclause.php");
9
+ require_once("include/chat_files_variables.php");
10
+ require_once("classes/searchcontrol.php");
11
+ require_once("classes/advancedsearchcontrol.php");
12
+ require_once("classes/panelsearchcontrol.php");
13
+
14
+
15
+ Security::processLogoutRequest();
16
+
17
+ if( !isLogged() )
18
+ {
19
+ Security::saveRedirectURL();
20
+ redirectToLogin();
21
+ }
22
+
23
+ require_once( "include/reportfunctions.php" );
24
+ $cname = postvalue("cname");
25
+ $rname = postvalue("rname");
26
+ if( $rname || $cname ) {
27
+ $rpt_array = wrGetEntityArray(
28
+ $rname ? $rname : $cname,
29
+ $rname ? WR_REPORT : WR_CHART
30
+ );
31
+ $accessGranted = @$rpt_array['status'] != "private" || @$rpt_array['owner'] != Security::getUserName();
32
+ } else {
33
+ $accessGranted = CheckTablePermissions( $strTableName, "S" );
34
+ }
35
+ if(!$accessGranted)
36
+ {
37
+ HeaderRedirect("menu");
38
+ }
39
+
40
+
41
+ require_once('include/xtempl.php');
42
+ require_once('classes/searchpage.php');
43
+ require_once('classes/searchpage_dash.php');
44
+
45
+ $xt = new Xtempl();
46
+ $pageMode = SearchPage::readSearchModeFromRequest();
47
+
48
+ if( $pageMode == SEARCH_LOAD_CONTROL )
49
+ $layoutVersion = postvalue("layoutVersion");
50
+
51
+
52
+ $params = array();
53
+ $params['xt'] = &$xt;
54
+ $params['id'] = postvalue_number("id");
55
+ $params['mode'] = $pageMode;
56
+ $params['tName'] = $strTableName;
57
+ $params["pageName"] = postvalue("page");
58
+ $params['pageType'] = PAGE_SEARCH;
59
+ $params['chartName'] = $cname;
60
+ $params['reportName'] = $rname;
61
+ $params['templatefile'] = $templatefile;
62
+ $params['shortTableName'] = 'chat_files';
63
+ $params['layoutVersion'] = $layoutVersion;
64
+
65
+ $params['searchControllerId'] = postvalue('searchControllerId') ? postvalue('searchControllerId') : $id;
66
+ $params['ctrlField'] = postvalue('ctrlField');
67
+
68
+ $params['needSettings'] = postvalue('isNeedSettings');
69
+
70
+ if( $pageMode == SEARCH_DASHBOARD )
71
+ {
72
+ $params["dashTName"] = postvalue("table");
73
+ $params["dashElementName"] = postvalue("dashelement");
74
+ $params["dashPage"] = postvalue("dashPage");
75
+ }
76
+
77
+ // e.g. crosstable params
78
+ $params["extraPageParams"] = SearchPage::getExtraPageParams();
79
+
80
+ $params["masterTable"] = postvalue("mastertable");
81
+ if( $params["masterTable"] )
82
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
83
+
84
+
85
+ $pageObject = new SearchPage($params);
86
+
87
+ if( $pageMode == SEARCH_LOAD_CONTROL )
88
+ {
89
+ $pageObject->displaySearchControl();
90
+ return;
91
+ }
92
+
93
+ $pageObject->init();
94
+ $pageObject->process();
95
+ ?>
chat_functions.php ADDED
@@ -0,0 +1,868 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function isGroupTarget($id){
3
+ if(substr($id,0,1) == "G")
4
+ return true;
5
+ else
6
+ return false;
7
+ }
8
+ function getGroupID($id){
9
+ return substr($id,1);
10
+ }
11
+ function getGroupIDs($targetid){
12
+ if(substr($targetid,0,1) == "G"){
13
+ $gid = str_replace("G","",$targetid);
14
+ $res = DB::DBLookup(DB::PrepareSQL("select ".AddFieldWrappers("ownerid")." from ".AddTableWrappers("chat_groups")." where ".AddFieldWrappers("id")."=:1",$gid));
15
+ if(!$res)
16
+ return 0;
17
+ $res = $res.",".DB::DBLookup(DB::PrepareSQL("select ".AddFieldWrappers("targetid")." from ".AddTableWrappers("chat_groups")." where ".AddFieldWrappers("id")."=:1",$gid));
18
+ return $res;
19
+ }
20
+ else
21
+ return $targetid;
22
+
23
+ }
24
+ function getGroupIDsIn($targetid){
25
+ global $loginKeyFields, $cLoginTable;
26
+ $res = array();
27
+ if(substr($targetid,0,1) == "G"){
28
+ $gid = str_replace("G","",$targetid);
29
+ $res[] = DB::DBLookup(DB::PrepareSQL("select ".AddFieldWrappers("ownerid")." from ".AddTableWrappers("chat_groups")." where ".AddFieldWrappers("id")."=:1",$gid));
30
+ if(!count($res))
31
+ return 0;
32
+ $arr = explode(",",DB::DBLookup(DB::PrepareSQL("select ".AddFieldWrappers("targetid")." from ".AddTableWrappers("chat_groups")." where ".AddFieldWrappers("id")."=:1",$gid)));
33
+ $res = array_merge($res,$arr);
34
+
35
+ /*$pSet = new ProjectSettings( $cLoginTable );
36
+ $ftype = $pSet->getFieldType( $loginKeyFields[0] );
37
+ if(NeedQuotes($ftype))
38
+ $out = "'".implode("','",$res)."'";
39
+ else
40
+ $out = implode(",",$res);*/
41
+ return $res;
42
+ }
43
+ else
44
+ return array($targetid);
45
+
46
+ }
47
+
48
+ function getGroupMenu(){
49
+ global $loginKeyFields;
50
+ $userdata = Security::currentUserData();
51
+ $countGroups = 0;
52
+ $groups = "";
53
+ $rs = DB::Select("chat_groups","");
54
+ while($data = $rs->fetchAssoc()){
55
+ $targetArr = explode(",",$data["targetid"]);
56
+ if($data["ownerid"] == $userdata[$loginKeyFields[0]]){
57
+ if($groups)
58
+ $groups.=",";
59
+ $groups.= $data["id"];
60
+ }
61
+ if(in_array($userdata[$loginKeyFields[0]],$targetArr)){
62
+ if($groups)
63
+ $groups.=",";
64
+ $groups.= $data["id"];
65
+ }
66
+
67
+ $countGroups++;
68
+ }
69
+ $_SESSION["countGroups"] = $countGroups;
70
+
71
+ $menu = "";
72
+ // create group menu
73
+ if($groups){
74
+ $menu.= "<table width=100% >";
75
+ $rs = DB::Select("chat_groups",AddFieldWrappers("id")." in (".$groups.")");
76
+ while($data = $rs->fetchAssoc()){
77
+ $author = $data["groupname"];
78
+ if(!$author)
79
+ $author = "Group chat";
80
+ $isType = 0;
81
+ $cnt_messages = 0;
82
+ $sql = DB::PrepareSQL("select * from ".AddTableWrappers("chat_history")." where ".AddFieldWrappers("ownerid")."<>':1' and ".AddFieldWrappers("targetid")."=':2'",$userdata[$loginKeyFields[0]],"G".$data["id"]);
83
+ $rs2 = DB::Query($sql);
84
+ while($data2 = $rs2->fetchAssoc()){
85
+ $arr = explode(",",$data2["isread"]);
86
+ if(!in_array($userdata[$loginKeyFields[0]],$arr))
87
+ $cnt_messages++;
88
+ }
89
+ if($cnt_messages>0)
90
+ $cnt_messages = "<div class='indicator'>".$cnt_messages."</div>";
91
+ else
92
+ $cnt_messages = "";
93
+ $avatar = "<span class='menu_typing isTypingG".$data["id"]."' id='searching-ellipsis' style='display:none;'><span>.</span><span>.</span><span>.</span></span>";
94
+ $display_author = $author;
95
+ if(strlen($display_author)>27)
96
+ $display_author = substr($display_author,0,24)."...";
97
+ $s = "";
98
+ if($_SESSION["targetid"] == "G".$data["id"])
99
+ $s = " td_users_selected";
100
+ $type_popup = "user";
101
+ if($data["ownerid"] == $userdata[$loginKeyFields[0]])
102
+ $type_popup = "admin";
103
+
104
+ $menu.= "<tr><td class='td_groups".$s."' userid='G".$data["id"]."'>".$avatar."<div style='display:inline-table' id='menuusernameG".$data["id"]."'>".$display_author."</div>".$cnt_messages;
105
+
106
+
107
+ if($data["ownerid"] == $userdata[$loginKeyFields[0]]){
108
+ $menu.= "<span class='caret_down_grchat_".$data["id"]."' rid='".$data["id"]."' owner='".$type_popup."'><svg xmlns='http://www.w3.org/2000/svg' width='11' height='11' fill='currentColor' class='bi bi-caret-down-fill' viewBox='0 0 16 16'>
109
+ <path class='_bi-caret' d='M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z'/>
110
+ </svg></span>";
111
+ $menu.= "<span class='caret_up_grchat_".$data["id"]."' rid='".$data["id"]."' owner='".$type_popup."'><svg xmlns='http://www.w3.org/2000/svg' width='11' height='11' fill='currentColor' class='bi bi-caret-right-fill' viewBox='0 0 16 16'>
112
+ <path class='_bi-caret' d='m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z'/>
113
+ </svg></span></td><td>".$typing."</td></tr>";
114
+ }
115
+ else{
116
+ $menu.= "<span class='caret_down_grchat_".$data["id"]."' rid='".$data["id"]."' owner='".$type_popup."'><svg width='1em' height='1em' viewBox='0 0 12 12' class='bi bi-x' fill='currentColor' xmlns='http://www.w3.org/2000/svg'>
117
+ <path class='_bi-caret' fill-rule='evenodd' d='M11.854 4.146a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708-.708l7-7a.5.5 0 0 1 .708 0z'/>
118
+ <path class='_bi-caret' fill-rule='evenodd' d='M4.146 4.146a.5.5 0 0 0 0 .708l7 7a.5.5 0 0 0 .708-.708l-7-7a.5.5 0 0 0-.708 0z'/>
119
+ </svg></span>";
120
+ $menu.= "<span class='caret_up_grchat_".$data["id"]."' rid='".$data["id"]."' owner='".$type_popup."'><svg width='1em' height='1em' viewBox='0 0 12 12' class='bi bi-x' fill='currentColor' xmlns='http://www.w3.org/2000/svg'>
121
+ <path class='_bi-caret' fill-rule='evenodd' d='M11.854 4.146a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708-.708l7-7a.5.5 0 0 1 .708 0z'/>
122
+ <path class='_bi-caret' fill-rule='evenodd' d='M4.146 4.146a.5.5 0 0 0 0 .708l7 7a.5.5 0 0 0 .708-.708l-7-7a.5.5 0 0 0-.708 0z'/>
123
+ </svg></span></td><td>".$typing."</td></tr>";
124
+ }
125
+ if(!$_SESSION["targetid"])
126
+ $_SESSION["targetid"] = "G".$data["id"];
127
+ }
128
+ $menu.= "</table>";
129
+ $menu = "<div class='div_users'>".$menu."</div>";
130
+ }
131
+
132
+ return $menu;
133
+ }
134
+
135
+
136
+ function getMenu(){
137
+ global $loginKeyFields, $cLoginTable,$cDisplayNameField, $cUserpicField, $cUserNameField;
138
+ if(!$cDisplayNameField)
139
+ $cDisplayNameField = $cUserNameField;
140
+ $userdata = Security::currentUserData();
141
+ $users = array();
142
+ if(!isGroupTarget($_SESSION["targetid"]) && $_SESSION["targetid"])
143
+ $users[] = $_SESSION["targetid"];
144
+ $sql = DB::PrepareSQL("select ".AddFieldWrappers("ownerid")." from ".AddTableWrappers("chat_history")." where ".AddFieldWrappers("targetid")."=':1' group by ".AddFieldWrappers("ownerid"),$userdata[$loginKeyFields[0]]);
145
+ $rs = DB::Query($sql);
146
+ $countUsers = 0;
147
+ while($data = $rs->fetchAssoc()){
148
+ if(!isGroupTarget($data["ownerid"])){
149
+ $users[] = $data["ownerid"];
150
+ $countUsers++;
151
+ }
152
+ }
153
+ $sql = DB::PrepareSQL("select ".AddFieldWrappers("targetid")." from ".AddTableWrappers("chat_history")." where ".AddFieldWrappers("ownerid")."=':1' group by ".AddFieldWrappers("targetid"),$userdata[$loginKeyFields[0]]);
154
+ $rs = DB::Query($sql);
155
+ while($data = $rs->fetchAssoc()){
156
+ if(!isGroupTarget($data["targetid"])){
157
+ $users[] = $data["targetid"];
158
+ $countUsers++;
159
+ }
160
+ }
161
+ $_SESSION["countUsers"] = $countUsers;
162
+ $menu = "";
163
+
164
+
165
+ $menu = "<div class='div_users'>";
166
+
167
+ // create menu
168
+ if(count($users)){
169
+ $menu.= "<table width=100% >";
170
+ $dc = new DsCommand();
171
+ $conditions = array();
172
+ $conditions[] = DataCondition::FieldIs( $loginKeyFields[0], dsopIN, $users );
173
+ $dc->filter = DataCondition::_And( $conditions );
174
+ $datasource = getLoginDataSource();
175
+ $rs = $datasource->getList( $dc );
176
+ while($data = $rs->fetchAssoc()){
177
+ $author = $data[$cDisplayNameField];
178
+ if(!$author)
179
+ $author = $data[$cUserNameField];
180
+ $rs2 = DB::Select("chat_users",array("userid"=>$data[$loginKeyFields[0]]));
181
+ $isType = 0;
182
+ if($data2 = $rs2->fetchAssoc()){
183
+ if(strtotime(date("Y-m-d H:i:s")) - strtotime($data2["lastaccess"]) > $_SESSION["loginTime"])
184
+ $cl = "offline";
185
+ else
186
+ $cl = "online";
187
+ $isType = $data2["isTyping"];
188
+ }
189
+ else
190
+ $cl = "offline";
191
+ $cnt_messages = "";
192
+ $sql = DB::PrepareSQL("select count(".AddFieldWrappers("id").") as cnt from ".AddTableWrappers("chat_history")." where ".AddFieldWrappers("isread")."='0' and ".AddFieldWrappers("ownerid")."=':1' and ".AddFieldWrappers("targetid")."=':2'",$data[$loginKeyFields[0]],$userdata[$loginKeyFields[0]]);
193
+ $rs2 = DB::Query($sql);
194
+ $data2 = $rs2->fetchAssoc();
195
+ if($data2["cnt"]>0)
196
+ $cnt_messages = "<div class='indicator'>".$data2["cnt"]."</div>";
197
+ $onoffline = "<div id='userIsOnline_".$data[$loginKeyFields[0]]."' class='".$cl." ind_state' align=center></div>";
198
+ $avatar = getAvatar($data,"",false)."<span class='menu_typing isTyping".$data[$loginKeyFields[0]]."' id='searching-ellipsis' style='display:none;'><span>.</span><span>.</span><span>.</span></span>";
199
+ $display_author = $author;
200
+ if(strlen($display_author)>27)
201
+ $display_author = substr($display_author,0,24)."...";
202
+ $s = "";
203
+ if($_SESSION["targetid"] == $data[$loginKeyFields[0]])
204
+ $s = " td_users_selected";
205
+ $menu.= "<tr><td class='td_users".$s."' userid='".$data[$loginKeyFields[0]]."'>".$onoffline.$avatar."<div style='display:inline-table' id='menuusername".$data[$loginKeyFields[0]]."'>".$display_author."</div>".$cnt_messages."</td><td>".$typing."</td></tr>";
206
+ if(!$_SESSION["targetid"])
207
+ $_SESSION["targetid"] = $data[$loginKeyFields[0]];
208
+ }
209
+
210
+ $menu.= "</table></div>";
211
+ }
212
+ return $menu;
213
+ }
214
+
215
+ function getAjaxMenu(){
216
+ $userdata = Security::currentUserData();
217
+ global $loginKeyFields, $cLoginTable,$cDisplayNameField, $cUserpicField, $cUserNameField;
218
+ if(!$cDisplayNameField)
219
+ $cDisplayNameField = $cUserNameField;
220
+
221
+ $users = array();
222
+ if(!isGroupTarget($_SESSION["targetid"]) && $_SESSION["targetid"])
223
+ $users[] = $_SESSION["targetid"];
224
+ $sql = DB::PrepareSQL("select ".AddFieldWrappers("ownerid")." from ".AddTableWrappers("chat_history")." where ".AddFieldWrappers("targetid")."=':1' group by ".AddFieldWrappers("ownerid"),$userdata[$loginKeyFields[0]]);
225
+ $rs = DB::Query($sql);
226
+ $countUsers = 0;
227
+ while($data = $rs->fetchAssoc()){
228
+ if(!isGroupTarget($data["ownerid"])){
229
+ $users[] = $data["ownerid"];
230
+ $countUsers++;
231
+ }
232
+ }
233
+ $sql = DB::PrepareSQL("select ".AddFieldWrappers("targetid")." from ".AddTableWrappers("chat_history")." where ".AddFieldWrappers("ownerid")."=':1' group by ".AddFieldWrappers("targetid"),$userdata[$loginKeyFields[0]]);
234
+ $rs = DB::Query($sql);
235
+ while($data = $rs->fetchAssoc()){
236
+ if(!isGroupTarget($data["targetid"])){
237
+ $users[] = $data["targetid"];
238
+ $countUsers++;
239
+ }
240
+ }
241
+ if($_SESSION["countUsers"] == $countUsers){
242
+ $arrMenu = array();
243
+ if(count($users)){
244
+ $dc = new DsCommand();
245
+ $conditions = array();
246
+ $conditions[] = DataCondition::FieldIs( $loginKeyFields[0], dsopIN, $users );
247
+ $dc->filter = DataCondition::_And( $conditions );
248
+ $datasource = getLoginDataSource();
249
+ $rs = $datasource->getList( $dc );
250
+ while($data = $rs->fetchAssoc()){
251
+ $elemMenu = array();
252
+ $rs2 = DB::Select("chat_users", array("userid"=>$data[$loginKeyFields[0]]));
253
+ $isType = 0;
254
+ if($data2 = $rs2->fetchAssoc()){
255
+ if(strtotime(date("Y-m-d H:i:s")) - strtotime($data2["lastaccess"]) > $_SESSION["loginTime"])
256
+ $cl = "offline";
257
+ else{
258
+ $cl = "online";
259
+ if(!isGroupTarget($data2["isTyping"]))
260
+ $isType = $data2["isTyping"];
261
+ }
262
+ }
263
+ else
264
+ $cl = "offline";
265
+
266
+ //$isType = $data2["isTyping"];
267
+
268
+
269
+ $cnt_messages = "";
270
+ $sql = DB::PrepareSQL("select count(".AddFieldWrappers("id").") as cnt from ".AddTableWrappers("chat_history")." where ".AddFieldWrappers("isread")."='0' and ".AddFieldWrappers("ownerid")."=':1' and ".AddFieldWrappers("targetid")."=':2'",$data[$loginKeyFields[0]],$userdata[$loginKeyFields[0]]);
271
+ $rs2 = DB::Query($sql);
272
+ $data2 = $rs2->fetchAssoc();
273
+ if($data2["cnt"]>0)
274
+ $cnt_messages = $data2["cnt"];
275
+ $elemMenu["notify"] = $cnt_messages;
276
+ $elemMenu["status"] = $cl;
277
+ $elemMenu["typing"] = $isType;
278
+ $elemMenu["username"] = $data[$cUserNameField];
279
+ $arrMenu[$data[$loginKeyFields[0]]] = $elemMenu;
280
+
281
+ if(!$_SESSION["targetid"])
282
+ $_SESSION["targetid"] = $data[$loginKeyFields[0]];
283
+
284
+ }
285
+ }
286
+ }
287
+ else{
288
+ $arrMenu["menu"] = getMenu();
289
+ $_SESSION["countUsers"] = $countUsers;
290
+ }
291
+ return $arrMenu;
292
+ }
293
+
294
+ function getGroupAjaxMenu(){
295
+ global $loginKeyFields;
296
+ $userdata = Security::currentUserData();
297
+ $countGroups = 0;
298
+ $groups = "";
299
+ $rs = DB::Select("chat_groups","");
300
+ while($data = $rs->fetchAssoc()){
301
+ if($data["ownerid"] == $userdata[$loginKeyFields[0]]){
302
+ if($groups)
303
+ $groups.=",";
304
+ $groups.= $data["id"];
305
+ $countGroups++;
306
+ }
307
+ $targetArr = explode(",",$data["targetid"]);
308
+ if(in_array($userdata[$loginKeyFields[0]],$targetArr) && $data["ownerid"] != $userdata[$loginKeyFields[0]]){
309
+ if($groups)
310
+ $groups.=",";
311
+ $groups.= $data["id"];
312
+ $countGroups++;
313
+ }
314
+ }
315
+ $arrMenu = array();
316
+ //$arrMenu["tmp"] = $_SESSION["countGroups"]."---".$countGroups;
317
+ if($_SESSION["countGroups"] == $countGroups){
318
+ // create group menu
319
+ if($groups){
320
+ $countGroups = 0;
321
+ $rs = DB::Select("chat_groups",AddFieldWrappers("id")." in (".$groups.")");
322
+ while($data = $rs->fetchAssoc()){
323
+ $elemMenu = array();
324
+ $isType = 0;
325
+ $rs2 = DB::Select("chat_users", array("isTyping"=>"G".$data["id"]));
326
+ $isType = 0;
327
+ if($data2 = $rs2->fetchAssoc()){
328
+ if(isGroupTarget($data2["isTyping"]) && $data2["userid"]!=$userdata[$loginKeyFields[0]])
329
+ $isType = $data2["isTyping"];
330
+ }
331
+ $cnt_messages = 0;
332
+ $sql = DB::PrepareSQL("select * from ".AddTableWrappers("chat_history")." where ".AddFieldWrappers("ownerid")."<>':1' and ".AddFieldWrappers("targetid")."=':2'",$userdata[$loginKeyFields[0]],"G".$data["id"]);
333
+ $rs2 = DB::Query($sql);
334
+ while($data2 = $rs2->fetchAssoc()){
335
+ $arr = explode(",",$data2["isread"]);
336
+ if(!in_array($userdata[$loginKeyFields[0]],$arr))
337
+ $cnt_messages++;
338
+ }
339
+ $elemMenu["notify"] = $cnt_messages;
340
+ $elemMenu["typing"] = $isType;
341
+ $elemMenu["name"] = $data["groupname"];
342
+ $arrMenu["G".$data["id"]] = $elemMenu;
343
+ $countGroups++;
344
+ }
345
+ if($_SESSION["countGroups"] != $countGroups){
346
+ $arrMenu["menu"] = getGroupMenu();
347
+ $_SESSION["countGroups"] = $countGroups;
348
+ }
349
+ }
350
+ }
351
+ else{
352
+ $arrMenu["menu"] = getGroupMenu();
353
+ $_SESSION["countGroups"] = $countGroups;
354
+ }
355
+
356
+ return $arrMenu;
357
+ }
358
+
359
+
360
+ function getUserStatus($targetid){
361
+
362
+ $rs2 = DB::Select("chat_users", array("userid"=>$targetid));
363
+ if($data2 = $rs2->fetchAssoc()){
364
+ if(strtotime(date("Y-m-d H:i:s")) - strtotime($data2["lastaccess"]) > $_SESSION["loginTime"]){
365
+ $cl = "offline_header";
366
+ }
367
+ else{
368
+ $cl = "online";
369
+ }
370
+ }
371
+ else
372
+ $cl = "offline_header";
373
+ return $cl;
374
+ }
375
+
376
+ function getUserStatusHeader($targetid){
377
+ $resArray = array();
378
+ if(isGroupTarget($targetid)){
379
+ $ids = getGroupIDs($targetid);
380
+ $usersArray = explode(",",$ids);
381
+ foreach($usersArray as $tid)
382
+ $resArray[] = getStatusUser($tid);
383
+ }
384
+ else{
385
+ $resArray[] = getStatusUser($targetid);
386
+ }
387
+ return $resArray;
388
+ }
389
+
390
+ function getStatusUser($targetid){
391
+ $rs2 = DB::Select("chat_users", array("userid"=>$targetid));
392
+ if($data2 = $rs2->fetchAssoc()){
393
+ if(strtotime(date("Y-m-d H:i:s")) - strtotime($data2["lastaccess"]) > $_SESSION["loginTime"]){
394
+ $resArray = array( $targetid => "offline_header");
395
+ }
396
+ else{
397
+ $resArray = array( $targetid => "online");
398
+ }
399
+ }
400
+ else
401
+ $resArray = array( $targetid => "offline_header");
402
+ return $resArray;
403
+ }
404
+
405
+ function getHeader(){
406
+ global $loginKeyFields, $cLoginTable,$cDisplayNameField,$cUserNameField;
407
+ if(!$cDisplayNameField)
408
+ $cDisplayNameField = $cUserNameField;
409
+ if(!$_SESSION["targetid"])
410
+ $_SESSION["targetid"]=0;
411
+ $hiddenInput = "<input type='hidden' id=search_input value=''><input type='hidden' id=save_anchor value='".$_SESSION["anchor"]."'><input type='hidden' id=searchanchor value=''>";
412
+ $userdata = Security::currentUserData();
413
+ if(isGroupTarget($_SESSION["targetid"])){
414
+ $currentUserName.= "<div class='currUserNameDiv'>";
415
+ $rs = DB::Select("chat_groups", array("id" => getGroupID($_SESSION["targetid"])));
416
+ $data = $rs->fetchAssoc();
417
+ $currentUserName.= "<div class='header_groupname'>".$data["groupname"]."</div>";
418
+ $type_popup = "user";
419
+ if($data["ownerid"] == $userdata[$loginKeyFields[0]])
420
+ $type_popup = "admin";
421
+ $currentUserName.= "<div class='header_groupname_edit' rid='".$data["id"]."' owner='".$type_popup."'><svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-pencil-square' viewBox='0 0 16 16'>
422
+ <path d='M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z'/>
423
+ <path fill-rule='evenodd' d='M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z'/>
424
+ </svg></div>";
425
+ $usersArray = explode(",",$data["targetid"]);
426
+ $usersArray[] = $data["ownerid"];
427
+ sort($usersArray);
428
+ foreach($usersArray as $users){
429
+ if($userdata[$loginKeyFields[0]] != $users){
430
+ DB::SetConnection(DB::ConnectionByTable($cLoginTable));
431
+ $rs2 = DB::Select( $cLoginTable, array( $loginKeyFields[0] => $users ) );
432
+ DB::SetConnection(DB::DefaultConnection());
433
+ if($data2 = $rs2->fetchAssoc()){
434
+ $avatar = getAvatar($data2,"",true);
435
+ $cl = getUserStatus($data2[$loginKeyFields[0]]);
436
+ $onoffline = "<div class='".$cl." ind_state_header_group' align=center id='headerstatus".$data2[$loginKeyFields[0]]."'></div>";
437
+ $uname = $data2[$cDisplayNameField];
438
+ if(!$uname)
439
+ $uname = $data2[$cUserNameField];
440
+ $currentUserName.= "<div style='padding-right:1px;padding-top:0px'>".$onoffline.$avatar." <span class='header_group'>".$uname."</span></div>";
441
+ }
442
+ }
443
+ }
444
+ $currentUserName.= "</div>";
445
+ /*$userdata = Security::currentUserData();
446
+ if($userdata[$loginKeyFields[0]] == $data["ownerid"])
447
+ $currentUserName.= "<div class='close_chat'><button id='delete_chat' class='btn btn-primary btn-xs'>".getCustomLabel("delete_chat")."</button></div>";
448
+ else
449
+ $currentUserName.= "<div class='close_chat'><a id='leave_chat' href='javascript:void(0);'>".getCustomLabel("leave_chat")."</a></div>";*/
450
+ }
451
+ else{
452
+ $currentUserName = "";
453
+ DB::SetConnection(DB::ConnectionByTable($cLoginTable));
454
+ $rs = DB::Select( $cLoginTable, array( $loginKeyFields[0] => $_SESSION["targetid"] ) );
455
+ DB::SetConnection(DB::DefaultConnection());
456
+ if($data = $rs->fetchAssoc()){
457
+ $avatar = getAvatar($data, "_message", false);
458
+ $cl = getUserStatus($data[$loginKeyFields[0]]);
459
+ $uname = $data[$cDisplayNameField];
460
+ if(!$uname)
461
+ $uname = $data[$cUserNameField];
462
+ $onoffline = "<div class='".$cl." ind_state_header' align=center id='headerstatus".$data[$loginKeyFields[0]]."'></div>";
463
+ $currentUserName = $onoffline.$avatar." <span class='header_name'>".$uname."</span>";
464
+ }
465
+ }
466
+ return $currentUserName.$hiddenInput;
467
+ }
468
+
469
+ function getMessageRecordSet(){
470
+ $userdata = Security::currentUserData();
471
+ global $loginKeyFields, $cLoginTable,$cDisplayNameField, $cUserpicField, $cUserNameField;
472
+ $dc = new DsCommand();
473
+ $conditions1 = array();
474
+ $conditions2 = array();
475
+ if(!isGroupTarget($_SESSION["targetid"])){
476
+ if(!$_SESSION["searchValue"]){
477
+ //$sqlGlobal = "select * from chat_history where targetid='".$userdata[$loginKeyFields[0]]."' and ownerid='".$_SESSION["targetid"]."' or targetid='".$_SESSION["targetid"]."' and ownerid='".$userdata[$loginKeyFields[0]]."' order by id";
478
+ $conditions1[] = DataCondition::FieldIs( "targetid", dsopEQUAL, $userdata[$loginKeyFields[0]] );
479
+ $conditions1[] = DataCondition::FieldIs( "ownerid", dsopEQUAL, $_SESSION["targetid"] );
480
+ $conditions2[] = DataCondition::FieldIs( "targetid", dsopEQUAL, $_SESSION["targetid"] );
481
+ $conditions2[] = DataCondition::FieldIs( "ownerid", dsopEQUAL, $userdata[$loginKeyFields[0]] );
482
+ $dc->filter = DataCondition::_Or( array(
483
+ DataCondition::_And( $conditions1 ),
484
+ DataCondition::_And( $conditions2 ),
485
+ ));
486
+ }
487
+ else{
488
+
489
+ //$sqlGlobal = "select * from chat_history where targetid='".$userdata[$loginKeyFields[0]]."'".$_SESSION["searchSQLValue"]." or ownerid='".$userdata[$loginKeyFields[0]]."'".$_SESSION["searchSQLValue"]." order by id";
490
+ $conditions1[] = DataCondition::FieldIs( "targetid", dsopEQUAL, $userdata[$loginKeyFields[0]] );
491
+ $conditions1[] = DataCondition::FieldIs( "messages", dsopCONTAIN, $_SESSION["searchValue"] );
492
+ $conditions2[] = DataCondition::FieldIs( "ownerid", dsopEQUAL, $userdata[$loginKeyFields[0]] );
493
+ $conditions2[] = DataCondition::FieldIs( "messages", dsopCONTAIN, $_SESSION["searchValue"] );
494
+ $dc->filter = DataCondition::_Or( array(
495
+ DataCondition::_And( $conditions1 ),
496
+ DataCondition::_And( $conditions2 ),
497
+ ));
498
+ }
499
+ }
500
+ else{
501
+ if(!$_SESSION["searchValue"]){
502
+ //$sqlGlobal = "select * from chat_history where targetid='".$_SESSION["targetid"]."' and ownerid in (".getGroupIDsIn($_SESSION["targetid"]).") order by id";
503
+ $conditions1[] = DataCondition::FieldIs( "targetid", dsopEQUAL, $_SESSION["targetid"] );
504
+ $conditions1[] = DataCondition::FieldIs( "ownerid", dsopIN, getGroupIDsIn($_SESSION["targetid"]) );
505
+ $dc->filter = DataCondition::_And( $conditions1 );
506
+ }
507
+ else{
508
+ //$sqlGlobal = "select * from chat_history where ownerid in (".getGroupIDsIn($_SESSION["targetid"]).")".$_SESSION["searchSQLValue"]." order by id";
509
+ $conditions1[] = DataCondition::FieldIs( "messages", dsopCONTAIN, $_SESSION["searchValue"] );
510
+ $conditions1[] = DataCondition::FieldIs( "ownerid", dsopIN, getGroupIDsIn($_SESSION["targetid"]) );
511
+ $dc->filter = DataCondition::_And( $conditions1 );
512
+ }
513
+ }
514
+ $dc->order = array(array( "column" => "id", "dir" => "ASC" ));
515
+ $datasource = getDataSource("chat_history");
516
+ $rs = $datasource->getList( $dc );
517
+ return $rs;
518
+ }
519
+
520
+ function getMessage($isStart){
521
+ $scrollStep = 14;
522
+ $userdata = Security::currentUserData();
523
+ global $loginKeyFields, $cLoginTable,$cDisplayNameField, $cUserpicField, $cUserNameField;
524
+ if(!$cDisplayNameField)
525
+ $cDisplayNameField = $cUserNameField;
526
+ $period = DB::DBLookup("select ".addFieldWrappers("timeperiod")." from ".addTableWrappers("chat_settings"));
527
+ $res_msg = "";
528
+ $rs = getMessageRecordSet();
529
+ $totalMessages = 0;
530
+ while($data = $rs->fetchAssoc()){
531
+ if(isAddMessage($data,$period,$isStart) && $data["status"]!="delete")
532
+ $totalMessages++;
533
+ }
534
+ $rs = getMessageRecordSet();
535
+ $counter = 0;
536
+ $counterTrue = 0;
537
+ $res_msg = array();
538
+ $firstID = "";
539
+ while($data = $rs->fetchAssoc()){
540
+ if(isAddMessage($data,$period,$isStart) && $data["status"]!="delete" && !$data["isVideo"]){
541
+ if(isCounter($counter,$totalMessages,$scrollStep,$data)){
542
+ DB::SetConnection(DB::ConnectionByTable($cLoginTable));
543
+ $rs2 = DB::Select($cLoginTable, array($loginKeyFields[0]=>$data["ownerid"]));
544
+ DB::SetConnection(DB::DefaultConnection());
545
+ $data2 = $rs2->fetchAssoc();
546
+ $avatar = getAvatar($data2,"_message", false);
547
+ $author = $data2[$cDisplayNameField];
548
+ if(!$author)
549
+ $author = $data2[$cUserNameField];
550
+ $timeArray = array();
551
+ $arrtmp = explode(" ",$data["created"]);
552
+ $arrtmp1 = explode("-",$arrtmp[0]);
553
+ $arrtmp2 = explode(":",$arrtmp[1]);
554
+ $timeArray[0] = $arrtmp1[0];
555
+ $timeArray[1] = $arrtmp1[1];
556
+ $timeArray[2] = $arrtmp1[2];
557
+ $timeArray[3] = $arrtmp2[0];
558
+ $timeArray[4] = $arrtmp2[1];
559
+ $timeArray[5] = "00";
560
+ $not_read = "";
561
+ if(!$firstID)
562
+ $firstID = $data["id"];
563
+ if($data["ownerid"]==$userdata[$loginKeyFields[0]]){ //// || isGroupTarget($_SESSION["targetid"])
564
+ if(!$data["isread"] || $data["isread"] == $data["ownerid"])
565
+ $not_read = '<span class="not_read'.$data["id"].'"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 18" width="14" height="18"><path fill="currentColor" d="M12.502 5.035l-.57-.444a.434.434 0 0 0-.609.076l-6.39 8.198a.38.38 0 0 1-.577.039l-2.614-2.556a.435.435 0 0 0-.614.007l-.505.516a.435.435 0 0 0 .007.614l3.887 3.8a.38.38 0 0 0 .577-.039l7.483-9.602a.435.435 0 0 0-.075-.609z"></path></svg></span>';
566
+ else{
567
+ if(!isGroupTarget($_SESSION["targetid"]))
568
+ $not_read = '<span class="not_read'.$data["id"].'" style="color:#48D1CC"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 18" width="14" height="18"><path fill="currentColor" d="M12.502 5.035l-.57-.444a.434.434 0 0 0-.609.076l-6.39 8.198a.38.38 0 0 1-.577.039l-2.614-2.556a.435.435 0 0 0-.614.007l-.505.516a.435.435 0 0 0 .007.614l3.887 3.8a.38.38 0 0 0 .577-.039l7.483-9.602a.435.435 0 0 0-.075-.609z"></path></svg></span>'; else{
569
+ $ids = getGroupIDs($_SESSION["targetid"]);
570
+ $arrayIDs = explode(",",$ids);
571
+ sort($arrayIDs);
572
+ $arrayRead = explode(",",$data["isread"]);
573
+ sort($arrayRead);
574
+ if($arrayIDs == $arrayRead)
575
+ $not_read = '<span class="not_read'.$data["id"].'" style="color:#48D1CC"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" width="18" height="18"><path fill="currentColor" d="M17.394 5.035l-.57-.444a.434.434 0 0 0-.609.076l-6.39 8.198a.38.38 0 0 1-.577.039l-.427-.388a.381.381 0 0 0-.578.038l-.451.576a.497.497 0 0 0 .043.645l1.575 1.51a.38.38 0 0 0 .577-.039l7.483-9.602a.436.436 0 0 0-.076-.609zm-4.892 0l-.57-.444a.434.434 0 0 0-.609.076l-6.39 8.198a.38.38 0 0 1-.577.039l-2.614-2.556a.435.435 0 0 0-.614.007l-.505.516a.435.435 0 0 0 .007.614l3.887 3.8a.38.38 0 0 0 .577-.039l7.483-9.602a.435.435 0 0 0-.075-.609z"></path></svg></span>';
576
+ else
577
+ $not_read = '<span class="not_read'.$data["id"].'" style="color:#48D1CC"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 18" width="14" height="18"><path fill="currentColor" d="M12.502 5.035l-.57-.444a.434.434 0 0 0-.609.076l-6.39 8.198a.38.38 0 0 1-.577.039l-2.614-2.556a.435.435 0 0 0-.614.007l-.505.516a.435.435 0 0 0 .007.614l3.887 3.8a.38.38 0 0 0 .577-.039l7.483-9.602a.435.435 0 0 0-.075-.609z"></path></svg></span>';
578
+ }
579
+ }
580
+ }
581
+ if(date("Y-m-d",strtotime($data["created"])) == date("Y-m-d"))
582
+ $current_date = str_format_time($timeArray);
583
+ else
584
+ $current_date = str_format_datetime($timeArray);
585
+ $current_date = str_replace(":00 "," ",$current_date);
586
+ $message_block_search = "";
587
+ if($_SESSION["searchValue"])
588
+ $message_box_search = " message_block_search";
589
+ $actpoint = "";
590
+ if($data["ownerid"] == $userdata[$loginKeyFields[0]])
591
+ $actpoint = " addpoint";
592
+ $search_class="";
593
+ if(postvalue("searchanchor") == $data["id"])
594
+ $search_class=" select_search_result";
595
+
596
+ $res_msg[$data["id"]] = "<div class='message_block".$message_box_search.$actpoint.$search_class."' anchor=".$data["id"]."><div>";
597
+ if($_SESSION["searchValue"]){
598
+ $targetid = $data["targetid"];
599
+ if($targetid == $userdata[$loginKeyFields[0]])
600
+ $targetid = $data["ownerid"];
601
+
602
+ if(!isGroupTarget($targetid)){
603
+ DB::SetConnection(DB::ConnectionByTable($cLoginTable));
604
+ $rslog = DB::Select($cLoginTable, array($loginKeyFields[0]=>$targetid));
605
+ DB::SetConnection(DB::DefaultConnection());
606
+ $datalog = $rslog->fetchAssoc();
607
+ $channel = $datalog[$cDisplayNameField];
608
+ if(!$channel)
609
+ $channel = $datalog[$cUserNameField];
610
+ }
611
+ else{
612
+ $id = getGroupID($targetid);
613
+ $rslog = DB::Select("chat_groups", array("id"=>$id));
614
+ $datalog = $rslog->fetchAssoc();
615
+ $channel = $datalog["groupname"];
616
+ }
617
+ $res_msg[$data["id"]].="<div class='message_search'>".$channel." - ".date("M dS,Y",strtotime($data["created"]));
618
+ if($_SESSION["searchValue"])
619
+ $res_msg[$data["id"]].="<a class='a_channel' href='#' onclick='clickAnchor(".$data["id"].",\"".$targetid."\");return false;'>".GetCustomLabel("view_in_channel")."</a>";
620
+ $res_msg[$data["id"]].="</div>";
621
+ }
622
+ $res_msg[$data["id"]].="<div class='message_avatar'>".$avatar."</div>";
623
+ $res_msg[$data["id"]].="<div class='message_header'><table><tr><td><b>".$author."</b> <span class='message_date'>".$current_date.$not_read."</span></td>";
624
+
625
+ $res_msg[$data["id"]].="</tr></table></div>";
626
+ $text = str_replace("\n","<br>",$data["messages"]);
627
+ if($_SESSION["searchValue"]){
628
+ $text = str_replace(postvalue("search"),"<span style='background:rgba(242,199,68,.4);'>".runner_htmlspecialchars(postvalue("search"))."</span>",$text);
629
+ }
630
+ if($data["soundRecord"]){
631
+ $arr = my_json_decode($data["soundRecord"]);
632
+ foreach($arr as $src)
633
+ $text.= "<div><audio class='' controls='controls' autobuffer='autobuffer'><source src='".$src."'></audio></div>";
634
+ }
635
+ $res_msg[$data["id"]].= "<div class='message_author'>".$text."</div>";
636
+ $strfiles = getAttachment($data);
637
+ if($strfiles)
638
+ $res_msg[$data["id"]].= "<div class='message_author'>".$strfiles."</div>";
639
+ $res_msg[$data["id"]].= "</div>";
640
+ $res_msg[$data["id"]].= "<div apid='".$data["id"]."' class='action_point'></div></div>";
641
+ $counterTrue++;
642
+ }
643
+ $counter++;
644
+ }
645
+
646
+ }
647
+ if($firstID)
648
+ $_SESSION["firstMessID"] = $firstID;
649
+ if(postvalue("searchanchor")){
650
+ $_SESSION["scroll_step"] = floor($counterTrue/$scrollStep);
651
+ }
652
+ if($counter == 0 && $isStart=="true")
653
+ $res_msg[0] = "<span class='nomessage'>".GetCustomLabel("nomessage_id")."</span>";
654
+
655
+ return $res_msg;
656
+ }
657
+ function getAttachment($data){
658
+ global $loginKeyFields, $cLoginTable,$cDisplayNameField, $cUserpicField, $cUserNameField;
659
+ if(!$cDisplayNameField)
660
+ $cDisplayNameField = $cUserNameField;
661
+ $rs2 = DB::Select("chat_files", array("messageid"=>$data["id"]));
662
+ $strfiles = "";
663
+ $data2 = $rs2->fetchAssoc();
664
+ $filesArray = my_json_decode($data2["files"]);
665
+ foreach($filesArray as $ind=>$val){
666
+ if($strfiles)
667
+ $strfiles.="&nbsp;&nbsp;&nbsp;";
668
+ $fileType = getContentTypeByExtension(substr($val["usrName"], strrpos($val["usrName"], '.')));
669
+ $icon = "<img src='images/icons/".getIconByFileType($fileType, $val["usrName"])."' />";
670
+ $p = strrpos($val["usrName"],".");
671
+ $ext = CheckImageExtension($val["usrName"]);
672
+ if( $ext ){
673
+ $strfiles.= "<div style='display:inline-block;vertical-align:top;padding-right:10px;' class='fname_preview'>".$val["usrName"]."</div>";
674
+ $file = file_get_contents(getabspath($val["name"]));
675
+ $src = "data:image/png;base64,".base64_encode($file);
676
+ $strfiles.= "<div style='display:none1'><a class='message_files' dir='LTR' href='javascript:void(0)' onclick='showPictureInPopup(\"".$val["usrName"]."\",".$data2["id"].");'><img width=200px src='".$src."'></a></div>";
677
+ }
678
+ else{
679
+ $fsize = $val["size"];
680
+ if($val["size"]<1000)
681
+ $fsize = $val["size"]." B";
682
+ else
683
+ $fsize = round($val["size"]/1000)." kB";
684
+ $fname = "<table><tr><td rowspan=2>".$icon."&nbsp;</td><td><b>".$val["usrName"]."</b></td></tr><tr><td>".$fsize."</td></tr></table>";
685
+ $strfiles.= "<div style='display:inline-block;vertical-align:top;padding-right:10px;' class='fname_preview'>".$val["usrName"]."</div>";
686
+ $strfiles.= "<div style='display:none1'><a class='message_files' href='mfhandler.php?file=".$val["usrName"]."&table=chat_files&field=files&pageType=list&page=list&key1=".$data2["id"]."'>";
687
+ $strfiles.= "<div class='files_border'>".$fname."</div>";
688
+ $strfiles.= "</a></div>";
689
+ }
690
+ }
691
+ return $strfiles;
692
+ }
693
+
694
+ function getAvatar($data, $cl = "", $needLetter = false){
695
+ global $loginKeyFields, $cLoginTable,$cDisplayNameField, $cUserpicField, $cUserNameField;
696
+ if(!$cDisplayNameField)
697
+ $cDisplayNameField = $cUserNameField;
698
+ if($data[$cUserpicField]){
699
+ DB::SetConnection(DB::ConnectionByTable($cLoginTable));
700
+ $rs2 = DB::Select($cLoginTable, array($loginKeyFields[0]=>$data[$loginKeyFields[0]]));
701
+ DB::SetConnection(DB::DefaultConnection());
702
+ $data2 = $rs2->fetchAssoc();
703
+ $src = "data:image/png;base64,".base64_encode($data2[$cUserpicField]);
704
+ $avatar = "<img id='menuAvatar".$data[$loginKeyFields[0]]."' class='menu_avatar".$cl."' src='".$src."' />";
705
+ }
706
+ else{
707
+ $letter = "";
708
+ if($needLetter){
709
+ if($data[$cDisplayNameField])
710
+ $letter = substr($data[$cDisplayNameField],0,1);
711
+ else
712
+ $letter = substr($data[$cUserNameField],0,1);
713
+ $letter = "<span class='user_letter usernamepopup'>".strtoupper($letter)."</span>";
714
+ }
715
+ $avatar = "<img class='menu_avatar".$cl." usernamepopup' src='images/no_avatar.jpg' />".$letter;
716
+ }
717
+ return $avatar;
718
+ }
719
+
720
+ function isAddMessage($data,$period,$isStart){
721
+ $t = explode(" ",this_microtime());
722
+ $now = date("Y-m-d H:i:s",$t[1]).substr((string)$t[0],1,4)."000";
723
+ if(strtotime($data["created"])>strtotime($now)-$period || $isStart=="true")
724
+ return true;
725
+ else
726
+ return false;
727
+
728
+ }
729
+
730
+ function isCounter($counter,$totalMessages,$scrollStep,$data){
731
+ if(postvalue("searchanchor")){
732
+ if($data["id"] >= postvalue("searchanchor"))
733
+ return true;
734
+ else
735
+ return false;
736
+ }
737
+ else{
738
+ if($counter>=$totalMessages-$scrollStep-$_SESSION["scroll_step"]*$scrollStep)
739
+ return true;
740
+ else
741
+ return false;
742
+ }
743
+ }
744
+
745
+ function getDeleteMessage(){
746
+ $res = array();
747
+ $period = DB::DBLookup("select ".AddFieldWrappers("timeperiod")." from ".AddTableWrappers("chat_settings"));
748
+ $rs = DB::Select("chat_history", array("status"=>"delete"));
749
+ while($data = $rs->fetchAssoc()){
750
+ $res[] = $data["id"];
751
+ if(strtotime(date("Y-m-d H:i:s")) - strtotime($data["status_created"])>=$period*2)
752
+ DB::Delete("chat_history", array("id"=>$data["id"]));
753
+ }
754
+ return $res;
755
+ }
756
+ function getEditMessage(){
757
+ $res = array();
758
+ $period = DB::DBLookup("select ".AddFieldWrappers("timeperiod")." from ".AddTableWrappers("chat_settings"));
759
+ $rs = DB::Select("chat_history", array("status"=>"edit"));
760
+ while($data = $rs->fetchAssoc()){
761
+ $res[] = $data["id"];
762
+ if(strtotime(date("Y-m-d H:i:s")) - strtotime($data["status_created"])>=$period*2)
763
+ DB::Delete("chat_history", array("id"=>$data["id"]));
764
+ }
765
+ return $res;
766
+ }
767
+ function updateIsRead(){
768
+ global $loginKeyFields, $cLoginTable;
769
+ $userdata = Security::currentUserData();
770
+ if($_SESSION["targetid"]){
771
+ if(strpos(postvalue("url"),"chat_history_add")>0 || strpos(postvalue("url"),"chat_history/add")>0){
772
+ if(!isGroupTarget($_SESSION["targetid"])){
773
+ DB::Update("chat_history",array("isread"=>$userdata[$loginKeyFields[0]]),array("ownerid"=>$_SESSION["targetid"],"targetid"=>$userdata[$loginKeyFields[0]]));
774
+ }
775
+ else{
776
+ $targetIDs = getGroupIDsIn($_SESSION["targetid"]);
777
+ /*$pSet = new ProjectSettings( $cLoginTable );
778
+ $ftype = $pSet->getFieldType( $loginKeyFields[0] );
779
+ $val = $userdata[$loginKeyFields[0]];
780
+ if(NeedQuotes($ftype))
781
+ $val = "'".$userdata[$loginKeyFields[0]]."'";
782
+ $rs2 = DB::Query("select * from chat_history where status<>'delete' and targetid='".$_SESSION["targetid"]."' and ".$val." in (".$targetIDs.")");*/
783
+
784
+ $dc = new DsCommand();
785
+ $conditions = array();
786
+ $conditions[] = DataCondition::FieldIs( "targetid", dsopEQUAL, $_SESSION["targetid"] );
787
+ //$conditions[] = DataCondition::FieldIs( $userdata[$loginKeyFields[0]], dsopIN, $targetIDs );
788
+ $conditions[] = DataCondition::_Not( DataCondition::FieldIs( "status", dsopEQUAL, 'delete' ) );
789
+ $dc->filter = DataCondition::_And( $conditions );
790
+ $datasource = getDataSource("chat_history");
791
+ $rs2 = $datasource->getList( $dc );
792
+
793
+ while($data2 = $rs2->fetchAssoc()){
794
+ if(in_array($userdata[$loginKeyFields[0]],$targetIDs)){
795
+ $arrayRead = array();
796
+ $arrayRead = explode(",",$data2["isread"]);
797
+ $key = array_search(0, $arrayRead);
798
+ if (false !== $key && $arrayRead[0]=="0")
799
+ unset($arrayRead[$key]);
800
+ if(!in_array($userdata[$loginKeyFields[0]],$arrayRead)){
801
+ $arrayRead[] = $userdata[$loginKeyFields[0]];
802
+ $isRead = implode(",",$arrayRead);
803
+ DB::Update("chat_history",array("isread"=>$isRead),"id=".$data2["id"]);
804
+ }
805
+ }
806
+ }
807
+ }
808
+ }
809
+ }
810
+ }
811
+
812
+ function getIsReadStatus(){
813
+ global $loginKeyFields;
814
+ $userdata = Security::currentUserData();
815
+ $isRead = array();
816
+ $rs = DB::Select("chat_history",array("targetid"=>$_SESSION["targetid"],"ownerid"=>$userdata[$loginKeyFields[0]]));
817
+ while($data = $rs->fetchAssoc()){
818
+ if($data["isread"] && $data["isread"] != $data["ownerid"] && $data["id"]>=$_SESSION["firstMessID"]){
819
+ if(!isGroupTarget($_SESSION["targetid"]))
820
+ $isRead[$data["id"]] = 2;
821
+ else{
822
+ $ids = getGroupIDs($_SESSION["targetid"]);
823
+ $arrayIDs = explode(",",$ids);
824
+ if(!in_array($userdata[$loginKeyFields[0]],$arrayIDs))
825
+ $arrayIDs[] = $userdata[$loginKeyFields[0]];
826
+ sort($arrayIDs);
827
+ $arrayRead = explode(",",$data["isread"]);
828
+ sort($arrayRead);
829
+ if($arrayIDs == $arrayRead)
830
+ $isRead[$data["id"]] = 3;
831
+ else
832
+ $isRead[$data["id"]] = 2;
833
+ }
834
+ }
835
+ }
836
+ return $isRead;
837
+ }
838
+
839
+ function getVideoCallData(){
840
+ global $loginKeyFields, $cLoginTable, $cUserpicField, $cUserNameField;
841
+ $userdata = Security::currentUserData();
842
+ $userid = $userdata[$loginKeyFields[0]];
843
+ $sql = DB::PrepareSQL("select * from ".AddTableWrappers("chat_history")." where ".AddFieldWrappers("targetid")."=:1 and ".AddFieldWrappers("isVideo").">0",$userid);
844
+ $rs = DB::Query($sql);
845
+ if($data = $rs->fetchAssoc()){
846
+ $_SESSION["targetid"] = $data["ownerid"];
847
+ DB::SetConnection(DB::ConnectionByTable($cLoginTable));
848
+ $rs2 = DB::Select( $cLoginTable, array( $loginKeyFields[0] => $data["ownerid"]) );
849
+ DB::SetConnection(DB::DefaultConnection());
850
+ $data2 = $rs2->fetchAssoc();
851
+
852
+ DB::Delete("chat_history", array("targetid"=>$userid, "isVideo"=>1));
853
+
854
+ if($data2[$cUserpicField])
855
+ $src = "data:image/png;base64,".base64_encode($data2[$cUserpicField]);
856
+ else
857
+ $src = "images/no_avatar.jpg";
858
+
859
+ return array("msg"=>$data["messages"],"avatar"=>$src, "name"=>$data2[$cUserNameField], "isVideo"=>$data["isVideo"]);
860
+ }
861
+ else
862
+ return array();
863
+ }
864
+
865
+ function this_microtime(){
866
+ return microtime();
867
+ }
868
+ ?>
chat_groups_add.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+
4
+ require_once("include/dbcommon.php");
5
+ require_once("classes/searchclause.php");
6
+ require_once("include/chat_groups_variables.php");
7
+ require_once('include/xtempl.php');
8
+ require_once('classes/addpage.php');
9
+ require_once('include/lookuplinks.php');
10
+
11
+ add_nocache_headers();
12
+
13
+ InitLookupLinks();
14
+
15
+ if( Security::hasLogin() ) {
16
+ if( !AddPage::processAddPageSecurity( $strTableName ) )
17
+ return;
18
+ }
19
+
20
+ AddPage::handleBrokenRequest();
21
+
22
+
23
+ $pageMode = AddPage::readAddModeFromRequest();
24
+
25
+ $xt = new Xtempl();
26
+
27
+ $id = postvalue_number("id");
28
+ $id = $id ? $id : 1;
29
+
30
+ //an array of AddPage constructor's params
31
+ $params = array();
32
+ $params["id"] = $id;
33
+ $params["xt"] = &$xt;
34
+ $params["mode"] = $pageMode;
35
+ $params["pageType"] = PAGE_ADD;
36
+ $params["tName"] = $strTableName;
37
+ $params["pageName"] = postvalue("page");
38
+ $params["action"] = postvalue("a");
39
+ $params["needSearchClauseObj"] = false;
40
+ $params["afterAdd_id"] = postvalue("afteradd");
41
+
42
+ $params["hostPageName"] = postvalue("hostPageName");
43
+ $params["listPage"] = postvalue("listPage");
44
+
45
+ $params["newRowId"] = postvalue("newRowId");
46
+
47
+ $params["masterTable"] = postvalue("mastertable");
48
+ if( $params["masterTable"] )
49
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
50
+
51
+
52
+
53
+ ;
54
+ $params["captchaName"] = "captcha_1209xre";
55
+ $params["captchaValue"] = postvalue("value_captcha_1209xre_" . $id);
56
+ $params["dashElementName"] = postvalue("dashelement");
57
+ $params["fromDashboard"] = postvalue("fromDashboard");
58
+ $params["dashTName"] = $params["fromDashboard"] ? $params["fromDashboard"] : postvalue("dashTName");
59
+ $params["dashPage"] = postvalue("dashPage");
60
+
61
+ $params["forSpreadsheetGrid"] = postvalue("spreadsheetGrid");
62
+
63
+ if ( $pageMode == ADD_POPUP ) {
64
+ $params["forListPageLookup"] = postvalue('forLookup');
65
+ }
66
+
67
+ if( $pageMode == ADD_DASHBOARD )
68
+ {
69
+ $params["dashElementName"] = postvalue("dashelement");
70
+ $params["dashTName"] = postvalue("table");
71
+ $params["dashPage"] = postvalue("dashPage");
72
+ }
73
+
74
+
75
+ if( $pageMode == ADD_INLINE )
76
+ {
77
+ // Inline add in a 'List page with search' lookup
78
+ $params["forListPageLookup"] = postvalue('forLookup');
79
+
80
+ $params["screenWidth"] = postvalue("screenWidth");
81
+ $params["screenHeight"] = postvalue("screenHeight");
82
+ $params["orientation"] = postvalue("orientation");
83
+
84
+ $params["masterPageType"] = postvalue("masterpagetype");
85
+ }
86
+
87
+
88
+ if( $pageMode == ADD_ONTHEFLY || ( $pageMode == ADD_INLINE || $pageMode == ADD_POPUP ) && postvalue('forLookup') )
89
+ {
90
+ //table where lookup is set
91
+ $params["lookupTable"] = postvalue("table");
92
+ //field with lookup is set
93
+ $params["lookupField"] = postvalue("field");
94
+ //the ptype od the page where lookup is set
95
+ $params["lookupPageType"] = postvalue("pageType");
96
+
97
+ if( postvalue('parentsExist') )
98
+ {
99
+ //the parent controls values data
100
+ $params["parentCtrlsData"] = my_json_decode( postvalue("parentCtrlsData") );
101
+ }
102
+ }
103
+
104
+ $pageObject = new AddPage($params);
105
+ $pageObject->init();
106
+
107
+ $pageObject->process();
108
+ ?>
chat_groups_edit.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ @ini_set("display_errors","1");
4
+ @ini_set("display_startup_errors","1");
5
+
6
+ require_once("include/dbcommon.php");
7
+ require_once("classes/searchclause.php");
8
+ require_once("include/chat_groups_variables.php");
9
+ require_once('include/xtempl.php');
10
+ require_once('classes/editpage.php');
11
+
12
+ add_nocache_headers();
13
+
14
+ if( Security::hasLogin() ) {
15
+ if( !EditPage::processEditPageSecurity( $strTableName ) )
16
+ return;
17
+ }
18
+
19
+ EditPage::handleBrokenRequest();
20
+
21
+ // render all necessary layouts
22
+
23
+
24
+ // parse control parameters
25
+ $pageMode = EditPage::readEditModeFromRequest();
26
+
27
+ $xt = new Xtempl();
28
+
29
+ $id = postvalue_number("id");
30
+ $id = intval($id) == 0 ? 1 : $id;
31
+
32
+
33
+ // $keys could not be set properly if editid params were no passed
34
+ $keys = array();
35
+ $keys["id"] = postvalue("editid1");
36
+
37
+ //array of params for classes
38
+ $params = array();
39
+ $params["id"] = $id;
40
+ $params["xt"] = &$xt;
41
+ $params["keys"] = $keys;
42
+ $params["mode"] = $pageMode;
43
+ $params["pageType"] = PAGE_EDIT;
44
+ $params["pageName"] = postvalue("page");
45
+ $params["tName"] = $strTableName;
46
+ $params["action"] = postvalue("a");
47
+ $params["selectedFields"] = postvalue("fields");
48
+
49
+ ;
50
+ $params["captchaName"] = "captcha_1209xre";
51
+ $params["captchaValue"] = postvalue("value_captcha_1209xre_" . $id);
52
+ $params["selection"] = postvalue("selection");
53
+ $params["rowIds"] = my_json_decode( postvalue("rowIds") );
54
+
55
+ $params["masterTable"] = postvalue("mastertable");
56
+ if( $params["masterTable"] )
57
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
58
+
59
+ // locking parameters
60
+ $params["lockingAction"] = postvalue("action");
61
+ $params["lockingSid"] = postvalue("sid");
62
+ $params["lockingKeys"] = postvalue("keys");
63
+ $params["lockingStart"] = postvalue("startEdit");
64
+
65
+ if( $pageMode == EDIT_INLINE )
66
+ {
67
+ $params["screenWidth"] = postvalue("screenWidth");
68
+ $params["screenHeight"] = postvalue("screenHeight");
69
+ $params["orientation"] = postvalue("orientation");
70
+ }
71
+
72
+ if( $pageMode == EDIT_DASHBOARD )
73
+ {
74
+ $params["dashElementName"] = postvalue("dashelement");
75
+ $params["dashTName"] = postvalue("table");
76
+ $params["dashPage"] = postvalue("dashPage");
77
+
78
+ if( postvalue("mapRefresh") )
79
+ {
80
+ $params["mapRefresh"] = true;
81
+ $params["vpCoordinates"] = my_json_decode( postvalue("vpCoordinates") );
82
+ }
83
+ }
84
+
85
+ if(( $pageMode == EDIT_POPUP || $pageMode == EDIT_INLINE ) && postvalue("dashTName"))
86
+ {
87
+ $params["dashTName"] = postvalue("dashTName");
88
+ $params["dashElementName"] = postvalue("dashelement");
89
+ $params["dashPage"] = postvalue("dashPage");
90
+ }
91
+
92
+ $params["forSpreadsheetGrid"] = postvalue("spreadsheetGrid");
93
+ $params["hostPageName"] = postvalue("hostPageName");
94
+ $params["listPage"] = postvalue("listPage");
95
+
96
+ $pageObject = EditPage::EditPageFactory($params);
97
+
98
+ if( $pageObject->isLockingRequest() )
99
+ {
100
+ $pageObject->doLockingAction();
101
+ exit();
102
+ }
103
+
104
+ $pageObject->init();
105
+
106
+ $pageObject->process();
107
+ ?>
chat_groups_list.php ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ $requestTable = "chat_groups";
6
+ $requestPage = "list";
7
+
8
+ require_once("include/dbcommon.php");
9
+ add_nocache_headers();
10
+
11
+ require_once('include/xtempl.php');
12
+
13
+ require_once("classes/searchcontrol.php");
14
+ require_once("classes/searchclause.php");
15
+ require_once("classes/panelsearchcontrol.php");
16
+ require_once("include/chat_groups_variables.php");
17
+ require_once('classes/listpage.php');
18
+ require_once('include/lookuplinks.php');
19
+
20
+ // Check whether the page was called as a part of Lookup wizard - List page with search.
21
+ // Verify the eligibility of such a call.
22
+
23
+ InitLookupLinks();
24
+ if( Security::hasLogin() ) {
25
+ if( !ListPage::processListPageSecurity( $strTableName ) )
26
+ return;
27
+ }
28
+
29
+ if( ListPage::processSaveParams( $strTableName ) )
30
+ return;
31
+
32
+ $options = array();
33
+ //array of params for classes
34
+
35
+ // Include necessary files in accordance with the page displaying mode
36
+ $mode = ListPage::readListModeFromRequest();
37
+ if( $mode == LIST_SIMPLE )
38
+ {
39
+ require_once('classes/listpage_simple.php');
40
+ require_once("classes/searchpanelsimple.php");
41
+ }
42
+ elseif( $mode == LIST_AJAX )
43
+ {
44
+ require_once('classes/listpage_simple.php');
45
+ require_once('classes/listpage_ajax.php');
46
+ require_once("classes/searchpanelsimple.php");
47
+ }
48
+ elseif( $mode == LIST_LOOKUP )
49
+ {
50
+ require_once('classes/listpage_embed.php');
51
+ require_once('classes/listpage_lookup.php');
52
+
53
+ $options["mainTable"] = postvalue("table");
54
+ $options["mainField"] = postvalue("field");
55
+ $options["mainPageType"] = postvalue("pageType");
56
+
57
+ $options["mainRecordData"] = my_json_decode( postvalue('data') );
58
+ $options["mainRecordMasterTable"] = postvalue('mainRecordMasterTable');
59
+
60
+ if( postvalue("parentsExist") )
61
+ $options["parentCtrlsData"] = my_json_decode( postvalue("parentCtrlsData") );
62
+ }
63
+ elseif( $mode == LIST_POPUPDETAILS )
64
+ {
65
+ require_once('classes/listpage_embed.php');
66
+ require_once('classes/listpage_dpinline.php');
67
+ require_once('classes/listpage_dppopup.php');
68
+ }
69
+ elseif( $mode == LIST_DETAILS )
70
+ {
71
+ require_once('classes/listpage_embed.php');
72
+ require_once('classes/listpage_dpinline.php');
73
+ require_once('classes/listpage_dplist.php');
74
+ }
75
+ elseif( $mode == LIST_DASHDETAILS )
76
+ {
77
+ require_once('classes/listpage_embed.php');
78
+ require_once('classes/listpage_dashboard.php');
79
+ require_once('classes/listpage_dpdash.php');
80
+ }
81
+ elseif( $mode == LIST_DASHBOARD )
82
+ {
83
+ require_once('classes/listpage_embed.php');
84
+ require_once('classes/listpage_dashboard.php');
85
+ }
86
+ elseif( $mode == MAP_DASHBOARD )
87
+ {
88
+ require_once('classes/listpage_embed.php');
89
+ require_once('classes/listpage_dashboard.php');
90
+ require_once('classes/map_dashboard.php');
91
+ }
92
+
93
+ $xt = new Xtempl( $mode != LIST_SIMPLE ); //#9607 1. Temporary fix
94
+
95
+ $options["pageName"] = postvalue("page");
96
+ $options["pageType"] = PAGE_LIST;
97
+ $options["id"] = postvalue_number("id") ? postvalue_number("id") : 1;
98
+ $options["flyId"] = (int)postvalue("recordId");
99
+ $options["mode"] = $mode;
100
+ $options["xt"] = &$xt;
101
+ $options["firstTime"] = postvalue("firstTime");
102
+ $options["sortBy"] = postvalue("sortby");
103
+ $options["requestGoto"] = postvalue_number("goto");
104
+
105
+
106
+ $options["masterPageType"] = postvalue("masterpagetype");
107
+ $options["masterPage"] = postvalue("masterpage");
108
+ $options["masterId"] = postvalue("masterid");
109
+
110
+ $options["masterTable"] = postvalue("mastertable");
111
+ if( $options["masterTable"] )
112
+ $options["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
113
+
114
+
115
+ if( $mode == LIST_DASHBOARD && postvalue("nodata") && strlen($options["masterTable"]) )
116
+ $options["showNoData"] = true;
117
+
118
+ if( $mode != LIST_LOOKUP )
119
+ {
120
+ $options["dashElementName"] = postvalue("dashelement");
121
+ $options["dashTName"] = postvalue("table");
122
+ $options["dashPage"] = postvalue("dashPage");
123
+ }
124
+
125
+ if( postvalue("mapRefresh") )
126
+ {
127
+ $options["mapRefresh"] = true;
128
+ $options["vpCoordinates"] = my_json_decode( postvalue("vpCoordinates") );
129
+ }
130
+
131
+ if( postvalue("firstTime") )
132
+ $options["firstTime"] = true;
133
+
134
+ // Create $pageObject
135
+ $pageObject = ListPage::createListPage($strTableName, $options);
136
+
137
+ if( $pageObject->processSaveSearch() )
138
+ exit();
139
+
140
+ if( $pageObject->updateRowOrder() )
141
+ exit();
142
+
143
+ if ( $pageObject->processFieldFilter() )
144
+ exit();
145
+
146
+ if( $pageObject->processTotals() )
147
+ exit();
148
+
149
+ if( $mode != LIST_DETAILS && $mode != MAP_DASHBOARD && $mode != LIST_DASHBOARD )
150
+ {
151
+ //maps
152
+ }
153
+
154
+ unset($_SESSION["message_add"]);
155
+ unset($_SESSION["message_edit"]);
156
+
157
+ // prepare code for build page
158
+ $pageObject->prepareForBuildPage();
159
+
160
+ // show page depends of mode
161
+ $pageObject->showPage();
162
+
163
+ ?>
chat_groups_search.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ require_once("include/dbcommon.php");
6
+ add_nocache_headers();
7
+
8
+ require_once("classes/searchclause.php");
9
+ require_once("include/chat_groups_variables.php");
10
+ require_once("classes/searchcontrol.php");
11
+ require_once("classes/advancedsearchcontrol.php");
12
+ require_once("classes/panelsearchcontrol.php");
13
+
14
+
15
+ Security::processLogoutRequest();
16
+
17
+ if( !isLogged() )
18
+ {
19
+ Security::saveRedirectURL();
20
+ redirectToLogin();
21
+ }
22
+
23
+ require_once( "include/reportfunctions.php" );
24
+ $cname = postvalue("cname");
25
+ $rname = postvalue("rname");
26
+ if( $rname || $cname ) {
27
+ $rpt_array = wrGetEntityArray(
28
+ $rname ? $rname : $cname,
29
+ $rname ? WR_REPORT : WR_CHART
30
+ );
31
+ $accessGranted = @$rpt_array['status'] != "private" || @$rpt_array['owner'] != Security::getUserName();
32
+ } else {
33
+ $accessGranted = CheckTablePermissions( $strTableName, "S" );
34
+ }
35
+ if(!$accessGranted)
36
+ {
37
+ HeaderRedirect("menu");
38
+ }
39
+
40
+
41
+ require_once('include/xtempl.php');
42
+ require_once('classes/searchpage.php');
43
+ require_once('classes/searchpage_dash.php');
44
+
45
+ $xt = new Xtempl();
46
+ $pageMode = SearchPage::readSearchModeFromRequest();
47
+
48
+ if( $pageMode == SEARCH_LOAD_CONTROL )
49
+ $layoutVersion = postvalue("layoutVersion");
50
+
51
+
52
+ $params = array();
53
+ $params['xt'] = &$xt;
54
+ $params['id'] = postvalue_number("id");
55
+ $params['mode'] = $pageMode;
56
+ $params['tName'] = $strTableName;
57
+ $params["pageName"] = postvalue("page");
58
+ $params['pageType'] = PAGE_SEARCH;
59
+ $params['chartName'] = $cname;
60
+ $params['reportName'] = $rname;
61
+ $params['templatefile'] = $templatefile;
62
+ $params['shortTableName'] = 'chat_groups';
63
+ $params['layoutVersion'] = $layoutVersion;
64
+
65
+ $params['searchControllerId'] = postvalue('searchControllerId') ? postvalue('searchControllerId') : $id;
66
+ $params['ctrlField'] = postvalue('ctrlField');
67
+
68
+ $params['needSettings'] = postvalue('isNeedSettings');
69
+
70
+ if( $pageMode == SEARCH_DASHBOARD )
71
+ {
72
+ $params["dashTName"] = postvalue("table");
73
+ $params["dashElementName"] = postvalue("dashelement");
74
+ $params["dashPage"] = postvalue("dashPage");
75
+ }
76
+
77
+ // e.g. crosstable params
78
+ $params["extraPageParams"] = SearchPage::getExtraPageParams();
79
+
80
+ $params["masterTable"] = postvalue("mastertable");
81
+ if( $params["masterTable"] )
82
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
83
+
84
+
85
+ $pageObject = new SearchPage($params);
86
+
87
+ if( $pageMode == SEARCH_LOAD_CONTROL )
88
+ {
89
+ $pageObject->displaySearchControl();
90
+ return;
91
+ }
92
+
93
+ $pageObject->init();
94
+ $pageObject->process();
95
+ ?>
chat_history_add.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+
4
+ require_once("include/dbcommon.php");
5
+ require_once("classes/searchclause.php");
6
+ require_once("include/chat_history_variables.php");
7
+ require_once('include/xtempl.php');
8
+ require_once('classes/addpage.php');
9
+ require_once('include/lookuplinks.php');
10
+
11
+ add_nocache_headers();
12
+
13
+ InitLookupLinks();
14
+
15
+ if( Security::hasLogin() ) {
16
+ if( !AddPage::processAddPageSecurity( $strTableName ) )
17
+ return;
18
+ }
19
+
20
+ AddPage::handleBrokenRequest();
21
+
22
+
23
+ $pageMode = AddPage::readAddModeFromRequest();
24
+
25
+ $xt = new Xtempl();
26
+
27
+ $id = postvalue_number("id");
28
+ $id = $id ? $id : 1;
29
+
30
+ //an array of AddPage constructor's params
31
+ $params = array();
32
+ $params["id"] = $id;
33
+ $params["xt"] = &$xt;
34
+ $params["mode"] = $pageMode;
35
+ $params["pageType"] = PAGE_ADD;
36
+ $params["tName"] = $strTableName;
37
+ $params["pageName"] = postvalue("page");
38
+ $params["action"] = postvalue("a");
39
+ $params["needSearchClauseObj"] = false;
40
+ $params["afterAdd_id"] = postvalue("afteradd");
41
+
42
+ $params["hostPageName"] = postvalue("hostPageName");
43
+ $params["listPage"] = postvalue("listPage");
44
+
45
+ $params["newRowId"] = postvalue("newRowId");
46
+
47
+ $params["masterTable"] = postvalue("mastertable");
48
+ if( $params["masterTable"] )
49
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
50
+
51
+
52
+
53
+ ;
54
+ $params["captchaName"] = "captcha_1209xre";
55
+ $params["captchaValue"] = postvalue("value_captcha_1209xre_" . $id);
56
+ $params["dashElementName"] = postvalue("dashelement");
57
+ $params["fromDashboard"] = postvalue("fromDashboard");
58
+ $params["dashTName"] = $params["fromDashboard"] ? $params["fromDashboard"] : postvalue("dashTName");
59
+ $params["dashPage"] = postvalue("dashPage");
60
+
61
+ $params["forSpreadsheetGrid"] = postvalue("spreadsheetGrid");
62
+
63
+ if ( $pageMode == ADD_POPUP ) {
64
+ $params["forListPageLookup"] = postvalue('forLookup');
65
+ }
66
+
67
+ if( $pageMode == ADD_DASHBOARD )
68
+ {
69
+ $params["dashElementName"] = postvalue("dashelement");
70
+ $params["dashTName"] = postvalue("table");
71
+ $params["dashPage"] = postvalue("dashPage");
72
+ }
73
+
74
+
75
+ if( $pageMode == ADD_INLINE )
76
+ {
77
+ // Inline add in a 'List page with search' lookup
78
+ $params["forListPageLookup"] = postvalue('forLookup');
79
+
80
+ $params["screenWidth"] = postvalue("screenWidth");
81
+ $params["screenHeight"] = postvalue("screenHeight");
82
+ $params["orientation"] = postvalue("orientation");
83
+
84
+ $params["masterPageType"] = postvalue("masterpagetype");
85
+ }
86
+
87
+
88
+ if( $pageMode == ADD_ONTHEFLY || ( $pageMode == ADD_INLINE || $pageMode == ADD_POPUP ) && postvalue('forLookup') )
89
+ {
90
+ //table where lookup is set
91
+ $params["lookupTable"] = postvalue("table");
92
+ //field with lookup is set
93
+ $params["lookupField"] = postvalue("field");
94
+ //the ptype od the page where lookup is set
95
+ $params["lookupPageType"] = postvalue("pageType");
96
+
97
+ if( postvalue('parentsExist') )
98
+ {
99
+ //the parent controls values data
100
+ $params["parentCtrlsData"] = my_json_decode( postvalue("parentCtrlsData") );
101
+ }
102
+ }
103
+
104
+ $pageObject = new AddPage($params);
105
+ $pageObject->init();
106
+
107
+ $pageObject->process();
108
+ ?>
chat_history_search.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ require_once("include/dbcommon.php");
6
+ add_nocache_headers();
7
+
8
+ require_once("classes/searchclause.php");
9
+ require_once("include/chat_history_variables.php");
10
+ require_once("classes/searchcontrol.php");
11
+ require_once("classes/advancedsearchcontrol.php");
12
+ require_once("classes/panelsearchcontrol.php");
13
+
14
+
15
+ Security::processLogoutRequest();
16
+
17
+ if( !isLogged() )
18
+ {
19
+ Security::saveRedirectURL();
20
+ redirectToLogin();
21
+ }
22
+
23
+ require_once( "include/reportfunctions.php" );
24
+ $cname = postvalue("cname");
25
+ $rname = postvalue("rname");
26
+ if( $rname || $cname ) {
27
+ $rpt_array = wrGetEntityArray(
28
+ $rname ? $rname : $cname,
29
+ $rname ? WR_REPORT : WR_CHART
30
+ );
31
+ $accessGranted = @$rpt_array['status'] != "private" || @$rpt_array['owner'] != Security::getUserName();
32
+ } else {
33
+ $accessGranted = CheckTablePermissions( $strTableName, "S" );
34
+ }
35
+ if(!$accessGranted)
36
+ {
37
+ HeaderRedirect("menu");
38
+ }
39
+
40
+
41
+ require_once('include/xtempl.php');
42
+ require_once('classes/searchpage.php');
43
+ require_once('classes/searchpage_dash.php');
44
+
45
+ $xt = new Xtempl();
46
+ $pageMode = SearchPage::readSearchModeFromRequest();
47
+
48
+ if( $pageMode == SEARCH_LOAD_CONTROL )
49
+ $layoutVersion = postvalue("layoutVersion");
50
+
51
+
52
+ $params = array();
53
+ $params['xt'] = &$xt;
54
+ $params['id'] = postvalue_number("id");
55
+ $params['mode'] = $pageMode;
56
+ $params['tName'] = $strTableName;
57
+ $params["pageName"] = postvalue("page");
58
+ $params['pageType'] = PAGE_SEARCH;
59
+ $params['chartName'] = $cname;
60
+ $params['reportName'] = $rname;
61
+ $params['templatefile'] = $templatefile;
62
+ $params['shortTableName'] = 'chat_history';
63
+ $params['layoutVersion'] = $layoutVersion;
64
+
65
+ $params['searchControllerId'] = postvalue('searchControllerId') ? postvalue('searchControllerId') : $id;
66
+ $params['ctrlField'] = postvalue('ctrlField');
67
+
68
+ $params['needSettings'] = postvalue('isNeedSettings');
69
+
70
+ if( $pageMode == SEARCH_DASHBOARD )
71
+ {
72
+ $params["dashTName"] = postvalue("table");
73
+ $params["dashElementName"] = postvalue("dashelement");
74
+ $params["dashPage"] = postvalue("dashPage");
75
+ }
76
+
77
+ // e.g. crosstable params
78
+ $params["extraPageParams"] = SearchPage::getExtraPageParams();
79
+
80
+ $params["masterTable"] = postvalue("mastertable");
81
+ if( $params["masterTable"] )
82
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
83
+
84
+
85
+ $pageObject = new SearchPage($params);
86
+
87
+ if( $pageMode == SEARCH_LOAD_CONTROL )
88
+ {
89
+ $pageObject->displaySearchControl();
90
+ return;
91
+ }
92
+
93
+ $pageObject->init();
94
+ $pageObject->process();
95
+ ?>
chat_peopletype_search.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ require_once("include/dbcommon.php");
6
+ add_nocache_headers();
7
+
8
+ require_once("classes/searchclause.php");
9
+ require_once("include/chat_peopletype_variables.php");
10
+ require_once("classes/searchcontrol.php");
11
+ require_once("classes/advancedsearchcontrol.php");
12
+ require_once("classes/panelsearchcontrol.php");
13
+
14
+
15
+ Security::processLogoutRequest();
16
+
17
+ if( !isLogged() )
18
+ {
19
+ Security::saveRedirectURL();
20
+ redirectToLogin();
21
+ }
22
+
23
+ require_once( "include/reportfunctions.php" );
24
+ $cname = postvalue("cname");
25
+ $rname = postvalue("rname");
26
+ if( $rname || $cname ) {
27
+ $rpt_array = wrGetEntityArray(
28
+ $rname ? $rname : $cname,
29
+ $rname ? WR_REPORT : WR_CHART
30
+ );
31
+ $accessGranted = @$rpt_array['status'] != "private" || @$rpt_array['owner'] != Security::getUserName();
32
+ } else {
33
+ $accessGranted = CheckTablePermissions( $strTableName, "S" );
34
+ }
35
+ if(!$accessGranted)
36
+ {
37
+ HeaderRedirect("menu");
38
+ }
39
+
40
+
41
+ require_once('include/xtempl.php');
42
+ require_once('classes/searchpage.php');
43
+ require_once('classes/searchpage_dash.php');
44
+
45
+ $xt = new Xtempl();
46
+ $pageMode = SearchPage::readSearchModeFromRequest();
47
+
48
+ if( $pageMode == SEARCH_LOAD_CONTROL )
49
+ $layoutVersion = postvalue("layoutVersion");
50
+
51
+
52
+ $params = array();
53
+ $params['xt'] = &$xt;
54
+ $params['id'] = postvalue_number("id");
55
+ $params['mode'] = $pageMode;
56
+ $params['tName'] = $strTableName;
57
+ $params["pageName"] = postvalue("page");
58
+ $params['pageType'] = PAGE_SEARCH;
59
+ $params['chartName'] = $cname;
60
+ $params['reportName'] = $rname;
61
+ $params['templatefile'] = $templatefile;
62
+ $params['shortTableName'] = 'chat_peopletype';
63
+ $params['layoutVersion'] = $layoutVersion;
64
+
65
+ $params['searchControllerId'] = postvalue('searchControllerId') ? postvalue('searchControllerId') : $id;
66
+ $params['ctrlField'] = postvalue('ctrlField');
67
+
68
+ $params['needSettings'] = postvalue('isNeedSettings');
69
+
70
+ if( $pageMode == SEARCH_DASHBOARD )
71
+ {
72
+ $params["dashTName"] = postvalue("table");
73
+ $params["dashElementName"] = postvalue("dashelement");
74
+ $params["dashPage"] = postvalue("dashPage");
75
+ }
76
+
77
+ // e.g. crosstable params
78
+ $params["extraPageParams"] = SearchPage::getExtraPageParams();
79
+
80
+ $params["masterTable"] = postvalue("mastertable");
81
+ if( $params["masterTable"] )
82
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
83
+
84
+
85
+ $pageObject = new SearchPage($params);
86
+
87
+ if( $pageMode == SEARCH_LOAD_CONTROL )
88
+ {
89
+ $pageObject->displaySearchControl();
90
+ return;
91
+ }
92
+
93
+ $pageObject->init();
94
+ $pageObject->process();
95
+ ?>
chat_settings_edit.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ @ini_set("display_errors","1");
4
+ @ini_set("display_startup_errors","1");
5
+
6
+ require_once("include/dbcommon.php");
7
+ require_once("classes/searchclause.php");
8
+ require_once("include/chat_settings_variables.php");
9
+ require_once('include/xtempl.php');
10
+ require_once('classes/editpage.php');
11
+
12
+ add_nocache_headers();
13
+
14
+ if( Security::hasLogin() ) {
15
+ if( !EditPage::processEditPageSecurity( $strTableName ) )
16
+ return;
17
+ }
18
+
19
+ EditPage::handleBrokenRequest();
20
+
21
+ // render all necessary layouts
22
+
23
+
24
+ // parse control parameters
25
+ $pageMode = EditPage::readEditModeFromRequest();
26
+
27
+ $xt = new Xtempl();
28
+
29
+ $id = postvalue_number("id");
30
+ $id = intval($id) == 0 ? 1 : $id;
31
+
32
+
33
+ // $keys could not be set properly if editid params were no passed
34
+ $keys = array();
35
+ $keys["id"] = postvalue("editid1");
36
+
37
+ //array of params for classes
38
+ $params = array();
39
+ $params["id"] = $id;
40
+ $params["xt"] = &$xt;
41
+ $params["keys"] = $keys;
42
+ $params["mode"] = $pageMode;
43
+ $params["pageType"] = PAGE_EDIT;
44
+ $params["pageName"] = postvalue("page");
45
+ $params["tName"] = $strTableName;
46
+ $params["action"] = postvalue("a");
47
+ $params["selectedFields"] = postvalue("fields");
48
+
49
+ ;
50
+ $params["captchaName"] = "captcha_1209xre";
51
+ $params["captchaValue"] = postvalue("value_captcha_1209xre_" . $id);
52
+ $params["selection"] = postvalue("selection");
53
+ $params["rowIds"] = my_json_decode( postvalue("rowIds") );
54
+
55
+ $params["masterTable"] = postvalue("mastertable");
56
+ if( $params["masterTable"] )
57
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
58
+
59
+ // locking parameters
60
+ $params["lockingAction"] = postvalue("action");
61
+ $params["lockingSid"] = postvalue("sid");
62
+ $params["lockingKeys"] = postvalue("keys");
63
+ $params["lockingStart"] = postvalue("startEdit");
64
+
65
+ if( $pageMode == EDIT_INLINE )
66
+ {
67
+ $params["screenWidth"] = postvalue("screenWidth");
68
+ $params["screenHeight"] = postvalue("screenHeight");
69
+ $params["orientation"] = postvalue("orientation");
70
+ }
71
+
72
+ if( $pageMode == EDIT_DASHBOARD )
73
+ {
74
+ $params["dashElementName"] = postvalue("dashelement");
75
+ $params["dashTName"] = postvalue("table");
76
+ $params["dashPage"] = postvalue("dashPage");
77
+
78
+ if( postvalue("mapRefresh") )
79
+ {
80
+ $params["mapRefresh"] = true;
81
+ $params["vpCoordinates"] = my_json_decode( postvalue("vpCoordinates") );
82
+ }
83
+ }
84
+
85
+ if(( $pageMode == EDIT_POPUP || $pageMode == EDIT_INLINE ) && postvalue("dashTName"))
86
+ {
87
+ $params["dashTName"] = postvalue("dashTName");
88
+ $params["dashElementName"] = postvalue("dashelement");
89
+ $params["dashPage"] = postvalue("dashPage");
90
+ }
91
+
92
+ $params["forSpreadsheetGrid"] = postvalue("spreadsheetGrid");
93
+ $params["hostPageName"] = postvalue("hostPageName");
94
+ $params["listPage"] = postvalue("listPage");
95
+
96
+ $pageObject = EditPage::EditPageFactory($params);
97
+
98
+ if( $pageObject->isLockingRequest() )
99
+ {
100
+ $pageObject->doLockingAction();
101
+ exit();
102
+ }
103
+
104
+ $pageObject->init();
105
+
106
+ $pageObject->process();
107
+ ?>
chat_settings_search.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ require_once("include/dbcommon.php");
6
+ add_nocache_headers();
7
+
8
+ require_once("classes/searchclause.php");
9
+ require_once("include/chat_settings_variables.php");
10
+ require_once("classes/searchcontrol.php");
11
+ require_once("classes/advancedsearchcontrol.php");
12
+ require_once("classes/panelsearchcontrol.php");
13
+
14
+
15
+ Security::processLogoutRequest();
16
+
17
+ if( !isLogged() )
18
+ {
19
+ Security::saveRedirectURL();
20
+ redirectToLogin();
21
+ }
22
+
23
+ require_once( "include/reportfunctions.php" );
24
+ $cname = postvalue("cname");
25
+ $rname = postvalue("rname");
26
+ if( $rname || $cname ) {
27
+ $rpt_array = wrGetEntityArray(
28
+ $rname ? $rname : $cname,
29
+ $rname ? WR_REPORT : WR_CHART
30
+ );
31
+ $accessGranted = @$rpt_array['status'] != "private" || @$rpt_array['owner'] != Security::getUserName();
32
+ } else {
33
+ $accessGranted = CheckTablePermissions( $strTableName, "S" );
34
+ }
35
+ if(!$accessGranted)
36
+ {
37
+ HeaderRedirect("menu");
38
+ }
39
+
40
+
41
+ require_once('include/xtempl.php');
42
+ require_once('classes/searchpage.php');
43
+ require_once('classes/searchpage_dash.php');
44
+
45
+ $xt = new Xtempl();
46
+ $pageMode = SearchPage::readSearchModeFromRequest();
47
+
48
+ if( $pageMode == SEARCH_LOAD_CONTROL )
49
+ $layoutVersion = postvalue("layoutVersion");
50
+
51
+
52
+ $params = array();
53
+ $params['xt'] = &$xt;
54
+ $params['id'] = postvalue_number("id");
55
+ $params['mode'] = $pageMode;
56
+ $params['tName'] = $strTableName;
57
+ $params["pageName"] = postvalue("page");
58
+ $params['pageType'] = PAGE_SEARCH;
59
+ $params['chartName'] = $cname;
60
+ $params['reportName'] = $rname;
61
+ $params['templatefile'] = $templatefile;
62
+ $params['shortTableName'] = 'chat_settings';
63
+ $params['layoutVersion'] = $layoutVersion;
64
+
65
+ $params['searchControllerId'] = postvalue('searchControllerId') ? postvalue('searchControllerId') : $id;
66
+ $params['ctrlField'] = postvalue('ctrlField');
67
+
68
+ $params['needSettings'] = postvalue('isNeedSettings');
69
+
70
+ if( $pageMode == SEARCH_DASHBOARD )
71
+ {
72
+ $params["dashTName"] = postvalue("table");
73
+ $params["dashElementName"] = postvalue("dashelement");
74
+ $params["dashPage"] = postvalue("dashPage");
75
+ }
76
+
77
+ // e.g. crosstable params
78
+ $params["extraPageParams"] = SearchPage::getExtraPageParams();
79
+
80
+ $params["masterTable"] = postvalue("mastertable");
81
+ if( $params["masterTable"] )
82
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
83
+
84
+
85
+ $pageObject = new SearchPage($params);
86
+
87
+ if( $pageMode == SEARCH_LOAD_CONTROL )
88
+ {
89
+ $pageObject->displaySearchControl();
90
+ return;
91
+ }
92
+
93
+ $pageObject->init();
94
+ $pageObject->process();
95
+ ?>
chat_timezone_search.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ require_once("include/dbcommon.php");
6
+ add_nocache_headers();
7
+
8
+ require_once("classes/searchclause.php");
9
+ require_once("include/chat_timezone_variables.php");
10
+ require_once("classes/searchcontrol.php");
11
+ require_once("classes/advancedsearchcontrol.php");
12
+ require_once("classes/panelsearchcontrol.php");
13
+
14
+
15
+ Security::processLogoutRequest();
16
+
17
+ if( !isLogged() )
18
+ {
19
+ Security::saveRedirectURL();
20
+ redirectToLogin();
21
+ }
22
+
23
+ require_once( "include/reportfunctions.php" );
24
+ $cname = postvalue("cname");
25
+ $rname = postvalue("rname");
26
+ if( $rname || $cname ) {
27
+ $rpt_array = wrGetEntityArray(
28
+ $rname ? $rname : $cname,
29
+ $rname ? WR_REPORT : WR_CHART
30
+ );
31
+ $accessGranted = @$rpt_array['status'] != "private" || @$rpt_array['owner'] != Security::getUserName();
32
+ } else {
33
+ $accessGranted = CheckTablePermissions( $strTableName, "S" );
34
+ }
35
+ if(!$accessGranted)
36
+ {
37
+ HeaderRedirect("menu");
38
+ }
39
+
40
+
41
+ require_once('include/xtempl.php');
42
+ require_once('classes/searchpage.php');
43
+ require_once('classes/searchpage_dash.php');
44
+
45
+ $xt = new Xtempl();
46
+ $pageMode = SearchPage::readSearchModeFromRequest();
47
+
48
+ if( $pageMode == SEARCH_LOAD_CONTROL )
49
+ $layoutVersion = postvalue("layoutVersion");
50
+
51
+
52
+ $params = array();
53
+ $params['xt'] = &$xt;
54
+ $params['id'] = postvalue_number("id");
55
+ $params['mode'] = $pageMode;
56
+ $params['tName'] = $strTableName;
57
+ $params["pageName"] = postvalue("page");
58
+ $params['pageType'] = PAGE_SEARCH;
59
+ $params['chartName'] = $cname;
60
+ $params['reportName'] = $rname;
61
+ $params['templatefile'] = $templatefile;
62
+ $params['shortTableName'] = 'chat_timezone';
63
+ $params['layoutVersion'] = $layoutVersion;
64
+
65
+ $params['searchControllerId'] = postvalue('searchControllerId') ? postvalue('searchControllerId') : $id;
66
+ $params['ctrlField'] = postvalue('ctrlField');
67
+
68
+ $params['needSettings'] = postvalue('isNeedSettings');
69
+
70
+ if( $pageMode == SEARCH_DASHBOARD )
71
+ {
72
+ $params["dashTName"] = postvalue("table");
73
+ $params["dashElementName"] = postvalue("dashelement");
74
+ $params["dashPage"] = postvalue("dashPage");
75
+ }
76
+
77
+ // e.g. crosstable params
78
+ $params["extraPageParams"] = SearchPage::getExtraPageParams();
79
+
80
+ $params["masterTable"] = postvalue("mastertable");
81
+ if( $params["masterTable"] )
82
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
83
+
84
+
85
+ $pageObject = new SearchPage($params);
86
+
87
+ if( $pageMode == SEARCH_LOAD_CONTROL )
88
+ {
89
+ $pageObject->displaySearchControl();
90
+ return;
91
+ }
92
+
93
+ $pageObject->init();
94
+ $pageObject->process();
95
+ ?>
chat_users_search.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ require_once("include/dbcommon.php");
6
+ add_nocache_headers();
7
+
8
+ require_once("classes/searchclause.php");
9
+ require_once("include/chat_users_variables.php");
10
+ require_once("classes/searchcontrol.php");
11
+ require_once("classes/advancedsearchcontrol.php");
12
+ require_once("classes/panelsearchcontrol.php");
13
+
14
+
15
+ Security::processLogoutRequest();
16
+
17
+ if( !isLogged() )
18
+ {
19
+ Security::saveRedirectURL();
20
+ redirectToLogin();
21
+ }
22
+
23
+ require_once( "include/reportfunctions.php" );
24
+ $cname = postvalue("cname");
25
+ $rname = postvalue("rname");
26
+ if( $rname || $cname ) {
27
+ $rpt_array = wrGetEntityArray(
28
+ $rname ? $rname : $cname,
29
+ $rname ? WR_REPORT : WR_CHART
30
+ );
31
+ $accessGranted = @$rpt_array['status'] != "private" || @$rpt_array['owner'] != Security::getUserName();
32
+ } else {
33
+ $accessGranted = CheckTablePermissions( $strTableName, "S" );
34
+ }
35
+ if(!$accessGranted)
36
+ {
37
+ HeaderRedirect("menu");
38
+ }
39
+
40
+
41
+ require_once('include/xtempl.php');
42
+ require_once('classes/searchpage.php');
43
+ require_once('classes/searchpage_dash.php');
44
+
45
+ $xt = new Xtempl();
46
+ $pageMode = SearchPage::readSearchModeFromRequest();
47
+
48
+ if( $pageMode == SEARCH_LOAD_CONTROL )
49
+ $layoutVersion = postvalue("layoutVersion");
50
+
51
+
52
+ $params = array();
53
+ $params['xt'] = &$xt;
54
+ $params['id'] = postvalue_number("id");
55
+ $params['mode'] = $pageMode;
56
+ $params['tName'] = $strTableName;
57
+ $params["pageName"] = postvalue("page");
58
+ $params['pageType'] = PAGE_SEARCH;
59
+ $params['chartName'] = $cname;
60
+ $params['reportName'] = $rname;
61
+ $params['templatefile'] = $templatefile;
62
+ $params['shortTableName'] = 'chat_users';
63
+ $params['layoutVersion'] = $layoutVersion;
64
+
65
+ $params['searchControllerId'] = postvalue('searchControllerId') ? postvalue('searchControllerId') : $id;
66
+ $params['ctrlField'] = postvalue('ctrlField');
67
+
68
+ $params['needSettings'] = postvalue('isNeedSettings');
69
+
70
+ if( $pageMode == SEARCH_DASHBOARD )
71
+ {
72
+ $params["dashTName"] = postvalue("table");
73
+ $params["dashElementName"] = postvalue("dashelement");
74
+ $params["dashPage"] = postvalue("dashPage");
75
+ }
76
+
77
+ // e.g. crosstable params
78
+ $params["extraPageParams"] = SearchPage::getExtraPageParams();
79
+
80
+ $params["masterTable"] = postvalue("mastertable");
81
+ if( $params["masterTable"] )
82
+ $params["masterKeysReq"] = RunnerPage::readMasterKeysFromRequest();
83
+
84
+
85
+ $pageObject = new SearchPage($params);
86
+
87
+ if( $pageMode == SEARCH_LOAD_CONTROL )
88
+ {
89
+ $pageObject->displaySearchControl();
90
+ return;
91
+ }
92
+
93
+ $pageObject->init();
94
+ $pageObject->process();
95
+ ?>
checkduplicates.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @ini_set("display_errors","1");
3
+ @ini_set("display_startup_errors","1");
4
+
5
+ require_once("include/dbcommon.php");
6
+ header("Expires: Thu, 01 Jan 1970 00:00:01 GMT");
7
+
8
+ $shortTableName = postvalue("tableName");
9
+ $table = GetTableByShort( $shortTableName );
10
+ if( !$table )
11
+ exit(0);
12
+
13
+ $pageType = postvalue("pageType");
14
+ $pageName = postvalue("page");
15
+ $fieldName = postvalue("fieldName");
16
+ $fieldControlType = postvalue("fieldControlType");
17
+ $value = postvalue("value");
18
+
19
+ if( !Security::userHasFieldPermissions( $table, $fieldName, $pageType, $pageName, true ) )
20
+ return;
21
+
22
+ $pSet = new ProjectSettings( $table, $pageType );
23
+ $denyChecking = $pSet->allowDuplicateValues( $fieldName );
24
+
25
+ $regEmailMode = false;
26
+ $regUsernameMode = false;
27
+ $userNameField = Security::usernameField();
28
+ if( Security::registerPage() && $table == Security::loginDataSource() ) {
29
+ $regEmailMode = $fieldName == Security::emailField();
30
+ $regUsernameMode = $fieldName == $userNameField;
31
+ $denyChecking = $denyChecking && $fieldName != $userNameField && $fieldName != Security::emailField();
32
+ }
33
+
34
+ if( $denyChecking ) {
35
+ $returnJSON = array( "success" => false, "error" => "Duplicated values are allowed" );
36
+ echo printJSON( $returnJSON) ;
37
+ return;
38
+ }
39
+
40
+ // set db connection
41
+ $_connection = $cman->byTable( $table );
42
+ $dataSource = getDataSource( $table, $pSet, $_connection );
43
+ $dc = new DsCommand();
44
+
45
+ $dc->totals = array();
46
+ $dc->totals[] = array(
47
+ "total" => "count",
48
+ "alias" => "count_".$fieldName,
49
+ "field" => $fieldName,
50
+ );
51
+
52
+ $dc->filter = DataCondition::FieldEquals( $fieldName, $value, 0, dsCASE_DEFAULT );
53
+
54
+ // emails should always be compared case-insensitively
55
+ if( $regEmailMode ) {
56
+ $dc->filter = DataCondition::FieldEquals( $fieldName, $value, 0, dsCASE_INSENSITIVE );
57
+ }
58
+ // username on register page
59
+ if( $regUsernameMode ) {
60
+ $where = $_connection->comparisonSQL( $fieldSQL, $value, Security::caseInsensitiveUsername() );
61
+ $dc->filter = DataCondition::FieldEquals( $fieldName, $value, 0,
62
+ Security::caseInsensitiveUsername() ? dsCASE_INSENSITIVE : dsCASE_STRICT );
63
+ }
64
+
65
+ $qResult = $dataSource->getTotals( $dc );
66
+ if( !$qResult ) {
67
+ $returnJSON = array( "success" => false, "error" => "Error: Wrong SQL query" );
68
+ echo printJSON( $returnJSON );
69
+ return;
70
+ }
71
+
72
+ $hasDuplicates = false;
73
+ $data = $qResult->fetchAssoc();
74
+ if( $data )
75
+ $hasDuplicates = $data[ "count_".$fieldName ] ? true : false;
76
+
77
+ $returnJSON = array( "success" => true, "hasDuplicates" => $hasDuplicates, "error" => "" );
78
+ echo printJSON( $returnJSON );
79
+ return;
80
+ ?>
classes/addpage.php ADDED
@@ -0,0 +1,1885 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class AddPage extends RunnerPage
3
+ {
4
+ /**
5
+ * The page's message type
6
+ * @type Number
7
+ */
8
+ public $messageType = MESSAGE_ERROR;
9
+
10
+ protected $auditObj = null;
11
+
12
+ /**
13
+ * The page's fields array
14
+ */
15
+ protected $addFields = array();
16
+
17
+ protected $readAddValues = false;
18
+
19
+ /**
20
+ * The record is being added through the 'List page with search' InlineAdd controls
21
+ */
22
+ protected $insertedSuccessfully = false;
23
+
24
+ protected $defvalues = array();
25
+
26
+ protected $newRecordData = array();
27
+
28
+ /**
29
+ * It could be set up in ADD_MASTER mode only
30
+ */
31
+ public $afterAdd_id = '';
32
+
33
+ /**
34
+ * The page's action
35
+ * @type String
36
+ */
37
+ public $action = "";
38
+
39
+ /**
40
+ * It's set up in inline add mode only
41
+ */
42
+ public $screenWidth = 0;
43
+
44
+ /**
45
+ * It's set up in inline add mode only
46
+ */
47
+ public $screenHeight = 0;
48
+
49
+ /**
50
+ * It's set up in inline add mode only
51
+ */
52
+ public $orientation = '';
53
+
54
+ /**
55
+ * It's equal to true when a record is added
56
+ * through the 'List page with search' InlineAdd controls
57
+ */
58
+ public $forListPageLookup = false;
59
+
60
+ /**
61
+ * The short lookup table name
62
+ * It's set up properly when a record is being added
63
+ * in a lookup 'Add new' popup
64
+ * or through the 'List page with search' InlineAdd controls
65
+ */
66
+ public $lookupTable = "";
67
+
68
+ /**
69
+ * It's set up properly when a record is being added
70
+ * in a lookup 'Add new' popup
71
+ * or through the 'List page with search' InlineAdd controls
72
+ */
73
+ public $lookupField = "";
74
+
75
+ /**
76
+ * It's set up properly when a record is being added
77
+ * in a lookup 'Add new' popup
78
+ * or through the 'List page with search' InlineAdd controls
79
+ */
80
+ public $lookupPageType = "";
81
+
82
+ /**
83
+ * @type Array
84
+ */
85
+ public $parentCtrlsData;
86
+
87
+
88
+ /**
89
+ * @type Number
90
+ */
91
+ protected $afterAddAction = null;
92
+
93
+ /**
94
+ *
95
+ */
96
+ public $fromDashboard = "";
97
+
98
+ public $forSpreadsheetGrid = false;
99
+ public $hostPageName = "";
100
+ public $newRowId;
101
+
102
+ public $listPage = "";
103
+
104
+ protected $sqlValues = array();
105
+
106
+ /**
107
+ * @constructor
108
+ */
109
+ function __construct(&$params)
110
+ {
111
+ parent::__construct($params);
112
+
113
+ $this->addFields = $this->getPageFields();
114
+ $this->auditObj = GetAuditObject($this->tName);
115
+
116
+ $this->headerForms = array( "top" );
117
+ $this->footerForms = array( "below-grid" );
118
+
119
+ if ( $this->isMultistepped() )
120
+ $this->bodyForms = array( "above-grid", "steps" );
121
+ else
122
+ $this->bodyForms = array( "above-grid", "grid" );
123
+
124
+ $this->addPageSettings();
125
+ }
126
+
127
+ function setSessionVariables() {
128
+ parent::setSessionVariables();
129
+ // don't use mastertable pre-stroed in session
130
+ if( !postvalue("mastertable")) {
131
+ $this->masterTable = "";
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Add js page settings
137
+ */
138
+ protected function addPageSettings()
139
+ {
140
+ if( $_SESSION[ $this->sessionPrefix . "_recordAdded" ] )
141
+ {
142
+ $this->setProxyValue( $this->shortTableName."_recordAdded", true );
143
+ unset( $_SESSION[ $this->sessionPrefix . "_recordAdded" ] );
144
+ }
145
+ else
146
+ $this->setProxyValue( $this->shortTableName."_recordAdded", false );
147
+
148
+ if( $this->mode != ADD_SIMPLE && $this->mode != ADD_POPUP )
149
+ return;
150
+
151
+ $afterAddAction = $this->getAfterAddAction();
152
+ $this->jsSettings["tableSettings"][ $this->tName ]["afterAddAction"] = $afterAddAction;
153
+
154
+ if ( $afterAddAction == AA_TO_DETAIL_LIST || $afterAddAction == AA_TO_DETAIL_ADD )
155
+ $this->jsSettings["tableSettings"][ $this->tName ]["afterAddActionDetTable"] = GetTableURL( $this->pSet->getAADetailTable() );
156
+
157
+ if( $this->listPage && $afterAddAction == AA_TO_LIST ) {
158
+ $this->pageData["listPage"] = $this->listPage;
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Get the correct after add action
164
+ * basing on the table settings
165
+ * @return Number
166
+ */
167
+ protected function getAfterAddAction()
168
+ {
169
+ if( isset( $this->afterAddAction ) && !is_null( $this->afterAddAction ) )
170
+ return $this->afterAddAction;
171
+
172
+ $action = $this->pSet->getAfterAddAction();
173
+
174
+ if( $this->mode == ADD_POPUP && $this->pSet->checkClosePopupAfterAdd()
175
+ || $action == AA_TO_VIEW && !$this->viewAvailable()
176
+ || $action == AA_TO_EDIT && !$this->editAvailable() )
177
+ {
178
+ $action = AA_TO_LIST;
179
+ }
180
+
181
+ if( $action == AA_TO_DETAIL_LIST || $action == AA_TO_DETAIL_ADD )
182
+ {
183
+ $dTName = $this->pSet->getAADetailTable();
184
+ $dPset = new ProjectSettings( $dTName );
185
+ $dPermissions = $this->getPermissions( $dTName );
186
+
187
+ $listPageAllowed = $dPset->hasListPage() && $dPermissions["search"];
188
+
189
+ if( !$dTName || $action == AA_TO_DETAIL_LIST && !$listPageAllowed
190
+ || $action == AA_TO_DETAIL_ADD && ( !$dPset->hasAddPage() || !$dPermissions["add"] && !$listPageAllowed ) )
191
+ {
192
+ $action = AA_TO_LIST;
193
+ }
194
+ }
195
+
196
+ $this->afterAddAction = $action;
197
+ return $this->afterAddAction;
198
+ }
199
+
200
+ /**
201
+ * Assign session prefix
202
+ */
203
+ protected function assignSessionPrefix()
204
+ {
205
+ if( $this->mode == ADD_DASHBOARD || $this->mode == ADD_MASTER_DASH
206
+ || ($this->mode == ADD_POPUP || $this->mode == ADD_INLINE || $this->fromDashboard != "" ) && $this->dashTName )
207
+ {
208
+ $this->sessionPrefix = $this->dashTName."_".$this->tName;
209
+ return;
210
+ }
211
+
212
+ parent::assignSessionPrefix();
213
+
214
+ if( $this->mode == ADD_ONTHEFLY )
215
+ $this->sessionPrefix.= "_add";
216
+ }
217
+
218
+ /**
219
+ * Set template file
220
+ */
221
+ public function setTemplateFile()
222
+ {
223
+ if( $this->mode == ADD_INLINE )
224
+ $this->templatefile = GetTemplateName($this->shortTableName, "inline_add");
225
+
226
+ parent::setTemplateFile();
227
+ }
228
+
229
+ /**
230
+ * Get the page's fields list
231
+ * @return Array
232
+ */
233
+ protected function getPageFields()
234
+ {
235
+ if( $this->mode == ADD_INLINE )
236
+ {
237
+ if( $this->masterTable && !$this->inlineAddAvailable() && $this->masterPageType == PAGE_ADD ) // #12518
238
+ {
239
+ return $this->pSet->getInlineAddFields();
240
+ }
241
+
242
+ return $this->pSet->getInlineAddFields();
243
+ }
244
+
245
+ return $this->pSet->getAddFields();
246
+ }
247
+
248
+ /**
249
+ * Process a broken request
250
+ */
251
+ public static function handleBrokenRequest()
252
+ {
253
+ if( sizeof($_POST) != 0 || !postvalue('submit') )
254
+ return;
255
+
256
+ if( postvalue("inline") )
257
+ {
258
+ $returnJSON = array();
259
+ $returnJSON['success'] = false;
260
+ $returnJSON['message'] = "Error occurred";
261
+ $returnJSON['fatalError'] = true;
262
+ echo printJSON($returnJSON);
263
+ exit();
264
+ }
265
+
266
+ if( postvalue("fly") )
267
+ {
268
+ echo -1;
269
+ exit();
270
+ }
271
+
272
+ $_SESSION["message_add"] = "<< "."Error occurred"." >>";
273
+ }
274
+
275
+ /**
276
+ * Redirect after details saved
277
+ */
278
+ public function redirectAfterAdd()
279
+ {
280
+ if( $_SESSION['after_add_data'] ) {
281
+ $aaData =& $_SESSION['after_add_data'];
282
+ } else {
283
+ $aaData = array();
284
+ }
285
+ if( isset($aaData[ $this->afterAdd_id ]) && $aaData[ $this->afterAdd_id ] )
286
+ {
287
+ $data = $aaData[ $this->afterAdd_id ];
288
+ $this->keys = $data['keys'];
289
+ $this->newRecordData = $data['avalues'];
290
+ }
291
+ if( $this->eventsObject->exists("AfterAdd") && isset($aaData[ $this->afterAdd_id ]) && $aaData[ $this->afterAdd_id ] )
292
+ {
293
+ $this->eventsObject->AfterAdd( $data['avalues'], $data['keys'], $data['inlineadd'], $this );
294
+
295
+ }
296
+ unset( $aaData[ $this->afterAdd_id ] );
297
+
298
+ foreach( $aaData as $k => $v)
299
+ {
300
+ if( !is_array($v) or !array_key_exists('time', $v) )
301
+ {
302
+ unset( $aaData[ $k ] );
303
+ continue;
304
+ }
305
+
306
+ if( $v['time'] < time() - 3600 )
307
+ unset($aaData[ $k ]);
308
+ }
309
+ $this->afterAddActionRedirect();
310
+ }
311
+
312
+ /**
313
+ * Process the page
314
+ */
315
+ public function process()
316
+ {
317
+ if( strlen($this->afterAdd_id) )
318
+ {
319
+ $this->redirectAfterAdd();
320
+ return;
321
+ }
322
+
323
+ // Before Process event
324
+ if( $this->eventsObject->exists("BeforeProcessAdd") )
325
+ $this->eventsObject->BeforeProcessAdd( $this );
326
+
327
+ if( $this->action == "added" )
328
+ {
329
+ // insert new record if we have to
330
+ $this->processDataInput();
331
+
332
+ $this->readAddValues = !$this->insertedSuccessfully;
333
+
334
+ if( $this->mode != ADD_SIMPLE && $this->mode != ADD_DASHBOARD && $this->mode != ADD_MASTER_DASH )
335
+ {
336
+ $this->reportSaveStatus();
337
+ return;
338
+ }
339
+
340
+ if( $this->insertedSuccessfully )
341
+ {
342
+ // VBScript fix! don't &&-join these two conditions
343
+ if( $this->afterAddActionRedirect() )
344
+ return;
345
+ }
346
+ }
347
+
348
+ if( $this->captchaExists() )
349
+ $this->displayCaptcha();
350
+
351
+ $this->prgReadMessage();
352
+
353
+ $this->prepareDefvalues();
354
+
355
+ if( $this->eventsObject->exists("ProcessValuesAdd") )
356
+ $this->eventsObject->ProcessValuesAdd( $this->defvalues, $this );
357
+
358
+ $this->prepareReadonlyFields();
359
+ $this->prepareEditControls();
360
+
361
+ $this->prepareButtons();
362
+ $this->prepareSteps();
363
+ $this->prepareDetailsTables();
364
+
365
+ // add button events if exist
366
+ if( $this->mode == ADD_SIMPLE || $this->mode == ADD_ONTHEFLY )
367
+ $this->addButtonHandlers();
368
+
369
+ $this->addCommonJs();
370
+
371
+ $this->doCommonAssignments();
372
+ $this->prepareBreadcrumbs();
373
+ $this->prepareCollapseButton();
374
+
375
+ $this->displayAddPage();
376
+ }
377
+
378
+ /**
379
+ * Insert a new record to db
380
+ */
381
+ protected function processDataInput()
382
+ {
383
+ if( $this->action != "added" )
384
+ return;
385
+
386
+ // CSRF protection
387
+ if( !isPostRequest() )
388
+ return;
389
+
390
+ $this->buildNewRecordData();
391
+
392
+ if( !$this->checkCaptcha() )
393
+ return;
394
+
395
+ if( !$this->recheckUserPermissions() )
396
+ return;
397
+
398
+ if( !$this->callBeforeAddEvent() )
399
+ return;
400
+
401
+ //add or set updated lat-lng values for all map fileds with 'UpdateLatLng' ticked
402
+ $this->setUpdatedLatLng( $this->newRecordData );
403
+
404
+ if( !$this->checkDeniedDuplicatedValues() )
405
+ return;
406
+
407
+ if( $this->callCustomAddEvent() )
408
+ {
409
+ $insertResult = $this->dataSource->insertSingle( $this->getInsertDataCommand() );
410
+ $this->insertedSuccessfully = $insertResult !== false;
411
+
412
+ if( !$this->insertedSuccessfully )
413
+ $this->setDatabaseError( $this->dataSource->lastError() );
414
+ else
415
+ {
416
+ $this->newRecordData = $insertResult;
417
+ // set up keys
418
+ foreach( $this->pSet->getTableKeys() as $kf ) {
419
+ if( isset( $this->newRecordData[ $kf ] ) )
420
+ $this->keys[ $kf ] = $this->newRecordData[ $kf ];
421
+ }
422
+
423
+ if ( count( $this->pSet->getTableKeys() ) != count( $this->keys ) )
424
+ $this->keys = array();
425
+ }
426
+ }
427
+
428
+ if( !$this->insertedSuccessfully )
429
+ return;
430
+
431
+ if( $this->getAfterAddAction() == AA_TO_ADD )
432
+ $_SESSION[ $this->sessionPrefix . "_recordAdded" ] = true;
433
+
434
+ $this->ProcessFiles();
435
+
436
+ if( $this->auditObj )
437
+ $this->auditObj->LogAdd( $this->tName, $this->newRecordData, $this->keys );
438
+
439
+ $this->callAfterSuccessfulSave();
440
+ $this->callAfterAddEvent();
441
+
442
+ $this->messageType = MESSAGE_INFO;
443
+ $this->setSuccessfulUpdateMessage();
444
+ }
445
+
446
+ /**
447
+ * Fill newRecordData properties
448
+ */
449
+ protected function buildNewRecordData()
450
+ {
451
+ $avalues = array();
452
+ $blobfields = array();
453
+ $afilename_values = array();
454
+
455
+ foreach($this->addFields as $f)
456
+ {
457
+ $control = $this->getControl( $f, $this->id );
458
+ $control->readWebValue($avalues, $blobfields, NULL, NULL, $afilename_values);
459
+ }
460
+
461
+ if( Security::advancedSecurityAvailable() ) {
462
+ $securityType = $this->pSet->getAdvancedSecurityType();
463
+ if( !$this->isAdminTable() && ($securityType == ADVSECURITY_EDIT_OWN || $securityType == ADVSECURITY_VIEW_OWN) )
464
+ {
465
+ $tableOwnerIdField = $this->pSet->getTableOwnerIdField();
466
+ // insert owner id value if it exists an It hasn't already set by user
467
+ if( $this->checkIfToAddOwnerIdValue( $tableOwnerIdField, $avalues[ $tableOwnerIdField ] ) )
468
+ $avalues[ $tableOwnerIdField ] = prepare_for_db( $tableOwnerIdField, $_SESSION["_".$this->tName."_OwnerID"] );
469
+ }
470
+ }
471
+ $masterTables = $this->pSet->getMasterTablesArr( );
472
+ // insert master key value if exists and if not specified
473
+ foreach( $masterTables as $mTableData )
474
+ {
475
+ if( $this->masterTable == $mTableData["mDataSourceTable"] )
476
+ {
477
+ foreach( $mTableData["detailKeys"] as $idx => $dk )
478
+ {
479
+ $masterkeyIdx = "masterkey".($idx + 1);
480
+ if( strlen( postvalue($masterkeyIdx) ) )
481
+ $_SESSION[ $this->sessionPrefix."_".$masterkeyIdx ] = postvalue($masterkeyIdx);
482
+
483
+ if( !isset( $avalues[ $dk ] ) || $avalues[ $dk ] == "" )
484
+ $avalues[ $dk ] = prepare_for_db( $dk, $_SESSION[ $this->sessionPrefix."_".$masterkeyIdx ] );
485
+ }
486
+ }
487
+ }
488
+
489
+ $this->addLookupFilterFieldValue( $avalues, $avalues );
490
+
491
+ foreach($afilename_values as $fileFName => $value)
492
+ {
493
+ $avalues[ $fileFName ] = $value;
494
+ }
495
+
496
+ // calculate order for the reorderRows feature
497
+ $listPSet = $this->getListPSet();
498
+ if( $listPSet->reorderRows() ) {
499
+ $order = postvalue("order");
500
+ if( $order ) {
501
+ $order = $this->getUniqueOrder( $listPSet, $order );
502
+ } else {
503
+ $order = $this->getMaxOrderValue( $listPSet ) + 1;
504
+ }
505
+ $avalues[ $listPSet->reorderRowsField() ] = $order;
506
+ }
507
+
508
+ $this->newRecordData = $avalues;
509
+ }
510
+
511
+ /**
512
+ * Add to the values array the data about lookup filter field
513
+ * if it hasn't been set yet
514
+ * @param Array recordData
515
+ * @param &Array values
516
+ */
517
+ protected function addLookupFilterFieldValue( $recordData, &$values )
518
+ {
519
+ $lookupPSet = getLookupMainTableSettings($this->tName, $this->lookupTable, $this->lookupField);
520
+ if( !$lookupPSet )
521
+ return;
522
+
523
+ if( $lookupPSet->useCategory( $this->lookupField ) )
524
+ {
525
+ foreach( $lookupPSet->getParentFieldsData( $this->lookupField ) as $cData )
526
+ {
527
+ if( isset( $this->parentCtrlsData[ $cData['main'] ]) && !isset( $recordData[ $cData['lookup'] ] ) )
528
+ $values[ $cData['lookup'] ]= $this->parentCtrlsData[ $cData['main'] ];
529
+ }
530
+ }
531
+ }
532
+
533
+ /**
534
+ * Check is captcha exists on current page
535
+ *
536
+ * @intellisense
537
+ */
538
+ function captchaExists()
539
+ {
540
+ if ( $this->mode == ADD_ONTHEFLY || $this->mode == ADD_INLINE )
541
+ {
542
+ return false;
543
+ }
544
+
545
+ return $this->pSet->hasCaptcha();
546
+ }
547
+
548
+ /**
549
+ * Get captcha field name
550
+ *
551
+ * @intellisense
552
+ */
553
+ function getCaptchaFieldName()
554
+ {
555
+ return $this->captchaName;
556
+ }
557
+
558
+ /**
559
+ * @return Boolean
560
+ */
561
+ protected function recheckUserPermissions()
562
+ {
563
+ if( CheckTablePermissions($this->tName, "A") )
564
+ return true;
565
+
566
+ return parent::recheckUserPermissions();
567
+ }
568
+
569
+ /**
570
+ * Execute before Add event
571
+ * @return Boolean
572
+ */
573
+ protected function callBeforeAddEvent()
574
+ {
575
+ if( !$this->eventsObject->exists("BeforeAdd") )
576
+ return true;
577
+
578
+ $this->sqlValues = array();
579
+ $usermessage = "";
580
+ $ret = $this->eventsObject->BeforeAdd( $this->newRecordData, $this->sqlValues, $usermessage, $this->mode == ADD_INLINE, $this );
581
+ if( $usermessage != "" )
582
+ $this->setMessage( $usermessage );
583
+
584
+ return $ret;
585
+ }
586
+
587
+ /**
588
+ * Check if some values are duplicated for the fields not allowing duplicates
589
+ * @return Boolean
590
+ */
591
+ public function checkDeniedDuplicatedValues()
592
+ {
593
+ $usermessage = "";
594
+ $ret = $this->hasDeniedDuplicateValues( $this->newRecordData, $usermessage );
595
+ if( $ret )
596
+ $this->setMessage( $usermessage );
597
+
598
+ return !$ret;
599
+ }
600
+
601
+ /**
602
+ * #7374
603
+ * @return Boolean
604
+ */
605
+ protected function callCustomAddEvent()
606
+ {
607
+ if( !$this->eventsObject->exists("CustomAdd") )
608
+ return true;
609
+
610
+ $keys = array();
611
+ $customAddError = "";
612
+ $ret = $this->eventsObject->CustomAdd( $this->newRecordData, $keys, $customAddError, $this->mode == ADD_INLINE, $this );
613
+
614
+ if( strlen( $customAddError ) > 0 )
615
+ {
616
+ $this->insertedSuccessfully = false;
617
+ $this->setMessage( $customAddError );
618
+ $this->keys = array();
619
+ return false;
620
+ }
621
+
622
+ // do standard Add processing
623
+ if( $ret )
624
+ return true;
625
+
626
+ $this->insertedSuccessfully = true;
627
+
628
+ // update keys and inserted data
629
+ $keyFields = $this->pSet->getTableKeys();
630
+
631
+ if( !is_array( $keys ) && count( $keyFields ) == 1 )
632
+ $keys = array( $keyFields[0] => $keys );
633
+
634
+ foreach( $keyFields as $kf ) {
635
+ if( strlen( $keys[ $kf ] ) )
636
+ $this->keys[ $kf ] = $kf;
637
+ else if( array_key_exists( $kf, $this->newRecordData ) )
638
+ $this->keys[ $kf ] = $this->newRecordData[ $kf ];
639
+ else
640
+ $this->keys[ $kf ] = $this->dataSource->lastAutoincValue( $kf );
641
+
642
+ $this->newRecordData[ $kf ] = $this->keys[ $kf ];
643
+ }
644
+
645
+ return false;
646
+ }
647
+
648
+ /**
649
+ * Give possibility to all edit controls to clean their data
650
+ */
651
+ protected function callAfterSuccessfulSave()
652
+ {
653
+ foreach($this->addFields as $f)
654
+ {
655
+ $this->getControl( $f, $this->id )->afterSuccessfulSave();
656
+ }
657
+ }
658
+
659
+ /**
660
+ * Execute After Add event or prepare all necessary data for its execution after redirect
661
+ */
662
+ protected function callAfterAddEvent()
663
+ {
664
+ if( !$this->eventsObject->exists("AfterAdd") )
665
+ return;
666
+
667
+ if( $this->mode != ADD_MASTER )
668
+ {
669
+ $this->eventsObject->AfterAdd( $this->newRecordData, $this->keys, $this->mode == ADD_INLINE, $this );
670
+ return;
671
+ }
672
+
673
+ $this->afterAdd_id = generatePassword(20);
674
+
675
+ if( !$_SESSION['after_add_data'] ) {
676
+ $_SESSION['after_add_data'] = array();
677
+ }
678
+ $_SESSION['after_add_data'][ $this->afterAdd_id ] = array(
679
+ 'avalues' => $this->newRecordData,
680
+ 'keys'=> $this->keys,
681
+ 'inlineadd' => $this->mode == ADD_INLINE,
682
+ 'time' => time()
683
+ );
684
+ }
685
+
686
+ /**
687
+ * Set a successful update message.
688
+ * Add the corresponding edit/view links to the info message
689
+ */
690
+ protected function setSuccessfulUpdateMessage()
691
+ {
692
+ if( $this->isMessageSet() )
693
+ return;
694
+
695
+ if( $this->mode == ADD_INLINE )
696
+ $infoMessage = ""."Record was added"."";
697
+ else
698
+ $infoMessage = "<strong><<< "."Record was added"." >>></strong>";
699
+
700
+ if( $this->mode != ADD_SIMPLE && $this->mode != ADD_MASTER || !$this->keys )
701
+ {
702
+ $this->setMessage( $infoMessage );
703
+ return;
704
+ }
705
+
706
+ $k = 0;
707
+ $keyParams = array();
708
+ $keysArray = array();
709
+ foreach( $this->keys as $idx => $val )
710
+ {
711
+ $keyParams[] = "editid".( ++$k )."=".runner_htmlspecialchars(rawurlencode(@$val));
712
+ $keysArray[] = $val;
713
+ }
714
+ $keylink = implode("&", $keyParams);
715
+
716
+ if ( count($keysArray) > 0 && $this->mode == ADD_SIMPLE )
717
+ {
718
+ $_SESSION["successKeys"] = $keysArray;
719
+ }
720
+ else
721
+ {
722
+ $infoMessage.= "<br>";
723
+
724
+ if( $this->editAvailable() )
725
+ $infoMessage.= "&nbsp;<a href='".GetTableLink( $this->pSet->getShortTableName(), "edit", $keylink )."'>"."Edit"."</a>&nbsp;";
726
+
727
+ if( $this->viewAvailable() )
728
+ $infoMessage.= "&nbsp;<a href='".GetTableLink( $this->pSet->getShortTableName(), "view", $keylink )."'>"."View"."</a>&nbsp;";
729
+ }
730
+
731
+ $this->setMessage( $infoMessage );
732
+ }
733
+
734
+ /**
735
+ * Print JSON containing a saved record data on ajax-like request
736
+ */
737
+ protected function reportSaveStatus()
738
+ {
739
+ echo printJSON( $this->getSaveStatusJSON() );
740
+ exit();
741
+ }
742
+
743
+ /**
744
+ * Get an array containing the record save status
745
+ * @return Array
746
+ */
747
+ protected function getSaveStatusJSON()
748
+ {
749
+ global $globalEvents;
750
+ $returnJSON = array();
751
+
752
+ if( $this->action != "added" || $this->mode == ADD_SIMPLE )
753
+ return $returnJSON;
754
+
755
+ $returnJSON['success'] = $this->insertedSuccessfully;
756
+ $returnJSON['message'] = $this->message;
757
+
758
+ if( !$this->isCaptchaOk )
759
+ {
760
+ $returnJSON['wrongCaptchaFieldName'] = $this->getCaptchaFieldName();
761
+ }
762
+ elseif( $this->mode == ADD_POPUP || $this->mode == ADD_MASTER || $this->mode == ADD_MASTER_POPUP || $this->mode == ADD_MASTER_DASH )
763
+ {
764
+ $sessPrefix = $this->tName . "_" . $this->pageType;
765
+ if( isset($_SESSION["count_passes_captcha"]) || $_SESSION["count_passes_captcha"] > 0 || $_SESSION["count_passes_captcha"] < 5 )
766
+ $returnJSON['hideCaptcha'] = true;
767
+ }
768
+
769
+
770
+ if( !$this->insertedSuccessfully )
771
+ return $returnJSON;
772
+
773
+ $jsKeys = array();
774
+ $keyFields = $this->pSet->getTableKeys();
775
+ if ( $this->keys ) {
776
+ foreach( $keyFields as $idx => $f) {
777
+ $jsKeys[ $idx ] = $this->keys[ $f ];
778
+ }
779
+ }
780
+
781
+ if( $this->mode == ADD_ONTHEFLY )
782
+ {
783
+ $lokupData = $this->getLookupData();
784
+ $returnJSON['linkValue'] = $lokupData['linkValue'];
785
+ $returnJSON['displayValue'] = $lokupData['displayValue'];
786
+ $returnJSON['vals'] = $lokupData['vals'];
787
+
788
+ $returnJSON['keys'] = $jsKeys;
789
+ $returnJSON['keyFields'] = $keyFields;
790
+
791
+ return $returnJSON;
792
+ }
793
+
794
+ // get current values and show edit controls
795
+ $data = array();
796
+ $haveData = true;
797
+
798
+ if( $this->keys )
799
+ $data = $this->getRecordData( $this->keys );
800
+
801
+ if( !$data )
802
+ {
803
+ $data = $this->newRecordData;
804
+ $haveData = false;
805
+ }
806
+
807
+ $keyParams = array();
808
+ foreach( $this->pSet->getTableKeys() as $i => $kf ) {
809
+ $keyParams[] = "key".($i + 1). "=". runner_htmlspecialchars( rawurlencode( @$data[ $kf ] ));
810
+ }
811
+ $keylink = "&" . implode("&", $keyParams);
812
+
813
+ $showValues = array();
814
+ $showFields = array();
815
+ $showRawValues = array();
816
+
817
+ $listPSet = $this->getListPSet();
818
+
819
+ $listViewControls = new ViewControlsContainer(
820
+ $listPSet,
821
+ $this->pageType,
822
+ $this
823
+ );
824
+
825
+ foreach( $this->pSet->getFieldsList() as $f )
826
+ {
827
+ $control = $listViewControls->getControl( $f );
828
+ $showValues[ $f ] = $control->showDBValue( $data, $keylink, true );
829
+ $showFields[] = $f;
830
+
831
+ if( IsBinaryType( $this->pSet->getFieldType( $f ) ) )
832
+ $showRawValues[ $f ] = "";
833
+ else
834
+ $showRawValues[ $f ] = runner_substr($data[ $f ], 0, 100);
835
+ }
836
+
837
+ // reorderRows stuff
838
+ if( $listPSet->reorderRows() ) {
839
+ $returnJSON['order'] = $data[ $listPSet->reorderRowsField() ];
840
+ }
841
+
842
+ $returnJSON['keys'] = $jsKeys;
843
+ $returnJSON['vals'] = $showValues;
844
+ $returnJSON['fields'] = $showFields;
845
+
846
+ $returnJSON['detKeys'] = $this->getShowDetailKeys( $data );
847
+
848
+ $dmapIconsData = $this->getDashMapsIconsData( $data );
849
+ if( !!$dmapIconsData )
850
+ $returnJSON['mapIconsData'] = $dmapIconsData;
851
+
852
+ $fieldsIconsData = $this->getFieldMapIconsData( $data );
853
+ if( !!$fieldsIconsData )
854
+ $returnJSON['fieldsMapIconsData'] = $fieldsIconsData;
855
+
856
+ //$isEditable = Security::userCan('E', $this->tName) || Security::userCan('D', $this->tName);
857
+ $isEditable = true;
858
+ if( $globalEvents->exists("IsRecordEditable", $this->tName) ) {
859
+ $isEditable = $globalEvents->IsRecordEditable( $data, $isEditable, $this->tName );
860
+ }
861
+
862
+ if( $this->forSpreadsheetGrid ) {
863
+ if( $haveData && $isEditable ) {
864
+ // new added grid row id
865
+ $newRowId = $this->newRowId ? $this->newRowId : $this->id;
866
+ $editPage = $this->getRelatedInlineEditPage( $this->hostPageName, $this->keys, $newRowId );
867
+
868
+ $returnJSON["editFields"] = $listPSet->getInlineEditFields();
869
+
870
+ // use "htmlControls" key no to interfire with dash html data
871
+ $returnJSON["htmlControls"] = array();
872
+ foreach( $listPSet->getInlineEditFields() as $fName ) {
873
+ $controls = $editPage->getContolMapData( $fName, $newRowId, $data, $editPage->editFields );
874
+ // set edit page controlsMap
875
+ $editPage->fillControlsMap( $controls );
876
+
877
+ if( $editPage->getEditFormat( $fName ) == EDIT_FORMAT_READONLY )
878
+ $editPage->readOnlyFields[ $fName ] = $this->showDBValue( $fName, $data );
879
+
880
+ $returnJSON["htmlControls"][ $fName ] = $editPage->getSpreadsheetControlMarkup( $fName, $newRowId, $data );
881
+ }
882
+
883
+ $returnJSON["pageId"] = $newRowId;
884
+
885
+ $editPage->fillSetCntrlMaps();
886
+ // contols map for spreadsheet inline edit controls
887
+ $returnJSON["spreadControlsMap"] = $editPage->controlsHTMLMap;
888
+ } else {
889
+ $returnJSON['nonEditable'] = true;
890
+ }
891
+ }
892
+
893
+
894
+ if( $this->mode == ADD_INLINE || $this->mode == ADD_POPUP || $this->mode == ADD_DASHBOARD ) {
895
+ $returnJSON['noKeys'] = !$haveData;
896
+ $returnJSON['keyFields'] = $keyFields;
897
+ $returnJSON['rawVals'] = $showRawValues;
898
+ $returnJSON['hrefs'] = $this->buildDetailGridLinks( $returnJSON['detKeys'] );
899
+ // add link and display value if list page is lookup with search
900
+ if( $this->forListPageLookup )
901
+ {
902
+ $linkAndDispVals = $this->getLookupData();
903
+ $returnJSON['linkValue'] = $linkAndDispVals['linkValue'];
904
+ $returnJSON['displayValue'] = $linkAndDispVals['displayValue'];
905
+ }
906
+ if( $globalEvents->exists("IsRecordEditable", $this->tName) ) {
907
+ if( !$isEditable )
908
+ $returnJSON['nonEditable'] = true;
909
+ }
910
+
911
+ return $returnJSON;
912
+ }
913
+
914
+ if( $this->mode == ADD_MASTER || $this->mode == ADD_MASTER_POPUP || $this->mode == ADD_MASTER_DASH )
915
+ {
916
+ $_SESSION["message_add"] = $this->message ? $this->message : "";
917
+ $returnJSON['afterAddId'] = $this->afterAdd_id;
918
+ $tData = array();
919
+ $returnJSON['mKeys'] = $this->getDetailTablesMasterKeys( $tData );
920
+
921
+ if( $this->mode == ADD_MASTER_POPUP || $this->mode == ADD_MASTER_DASH )
922
+ {
923
+ $returnJSON['noKeys'] = !$haveData;
924
+ $returnJSON['keyFields'] = $keyFields;
925
+ $returnJSON['rawVals'] = $showRawValues;
926
+ $returnJSON['hrefs'] = $this->buildDetailGridLinks( $returnJSON['detKeys'] );
927
+
928
+ if( $globalEvents->exists("IsRecordEditable", $this->tName) ) {
929
+ if( !$isEditable )
930
+ $returnJSON['nonEditable'] = true;
931
+ }
932
+ }
933
+
934
+ return $returnJSON;
935
+ }
936
+ }
937
+
938
+ /**
939
+ * @param &Array data
940
+ * @return Array
941
+ */
942
+ protected function getShowDetailKeys( &$data )
943
+ {
944
+ $showDetailKeys = array();
945
+ foreach( $this->pSet->getDetailTablesArr() as $dt )
946
+ {
947
+ foreach( $dt["masterKeys"] as $idx => $dk)
948
+ {
949
+ $showDetailKeys[ $dt['dDataSourceTable'] ][ "masterkey".($idx + 1) ] = $data[ $dk ];
950
+ }
951
+ }
952
+
953
+ if( $this->getAfterAddAction() == AA_TO_DETAIL_ADD )
954
+ {
955
+ $AAdTName = $this->pSet->getAADetailTable();
956
+ $dTUrl = GetTableUrl( $AAdTName );
957
+
958
+ if( !isset( $showDetailKeys[ $dTUrl ] ) )
959
+ $showDetailKeys[ $dTUrl ] = $showDetailKeys[ $AAdTName ];
960
+ }
961
+
962
+ return $showDetailKeys;
963
+ }
964
+
965
+ /**
966
+ * @return Array
967
+ */
968
+ protected function getDetailTablesMasterKeys( $data )
969
+ {
970
+ if( !$this->isShowDetailTables || $this->mobileTemplateMode() )
971
+ return array();
972
+
973
+ $data = $this->newRecordData;
974
+ if( $this->keys )
975
+ $data = $this->getRecordData( $this->keys ) ;
976
+
977
+ $dpParams = $this->getDetailsParams( $this->id );
978
+ $mKeysData = array();
979
+ for( $i = 0; $i < count( $dpParams['ids'] ); $i++ ) {
980
+ $mKeysData[ $dpParams['strTableNames'][$i] ] = $this->getMasterKeysData( $dpParams['strTableNames'][$i], $data);
981
+ }
982
+
983
+ return $mKeysData;
984
+ }
985
+
986
+ /**
987
+ * @param String dTableName
988
+ * @param &Array data
989
+ */
990
+ protected function getMasterKeysData( $dTableName, &$data )
991
+ {
992
+ $mKeyId = 1;
993
+ $mKeysData = array();
994
+
995
+ $mKeys = $this->pSet->getMasterKeysByDetailTable( $dTableName );
996
+ foreach($mKeys as $mk)
997
+ {
998
+ if( strlen( $data[ $mk ] ) )
999
+ $mKeysData[ 'masterkey'.$mKeyId++ ] = $data[ $mk ];
1000
+ else
1001
+ $mKeysData[ 'masterkey'.$mKeyId++ ] = '';
1002
+ }
1003
+
1004
+ return $mKeysData;
1005
+ }
1006
+
1007
+ /**
1008
+ * It redirects to a new page
1009
+ * according to the add page settings
1010
+ * @return Boolean
1011
+ */
1012
+ protected function afterAddActionRedirect()
1013
+ {
1014
+ if( $this->mode != ADD_SIMPLE )
1015
+ return false;
1016
+
1017
+ switch( $this->getAfterAddAction() )
1018
+ {
1019
+ case AA_TO_ADD:
1020
+ if ( $this->insertedSuccessfully )
1021
+ return $this->prgRedirect();
1022
+
1023
+ $getParams = array();
1024
+ if( $this->pageName )
1025
+ $getParams[] = "page=".$this->pageName;
1026
+ $getParams[] = $this->getStateUrlParams();
1027
+ HeaderRedirect($this->shortTableName, PAGE_ADD, implode( '&', $getParams ));
1028
+ return true;
1029
+
1030
+ case AA_TO_LIST:
1031
+ if( $this->pSet->hasListPage() ) {
1032
+ HeaderRedirect( $this->shortTableName, PAGE_LIST, "a=return&"
1033
+ .( $this->listPage ? "page=".$this->listPage."&" : "" ).$this->getStateUrlParams() );
1034
+ } else {
1035
+ HeaderRedirect("menu");
1036
+ }
1037
+ return true;
1038
+
1039
+ case AA_TO_VIEW:
1040
+ HeaderRedirect( $this->shortTableName, PAGE_VIEW, implode( '&', array( $this->getKeyParams(), $this->getStateUrlParams() ) ) );
1041
+ return true;
1042
+
1043
+ case AA_TO_EDIT:
1044
+ HeaderRedirect( $this->shortTableName, PAGE_EDIT, implode( '&', array( $this->getKeyParams(), $this->getStateUrlParams() ) ) );
1045
+ return true;
1046
+
1047
+ case AA_TO_DETAIL_LIST:
1048
+ $dTName = $this->pSet->getAADetailTable();
1049
+ HeaderRedirect( GetTableURL( $dTName ), PAGE_LIST, implode("&", $this->getNewRecordMasterKeys( $dTName ) ). "&mastertable=" .$this->tName );
1050
+ return true;
1051
+
1052
+ case AA_TO_DETAIL_ADD:
1053
+ $_SESSION["message_add"] = $this->message ? $this->message : "";
1054
+
1055
+ $dTName = $this->pSet->getAADetailTable();
1056
+ HeaderRedirect( GetTableURL( $dTName ), PAGE_ADD, implode("&", $this->getNewRecordMasterKeys( $dTName ) ). "&mastertable=" .$this->tName );
1057
+ return true;
1058
+
1059
+ default:
1060
+ return false;
1061
+ }
1062
+ }
1063
+
1064
+ function getNewRecordMasterKeys( $dTName )
1065
+ {
1066
+ $data = $this->getNewRecordData();
1067
+
1068
+ $mKeys = array();
1069
+ foreach($this->pSet->getMasterKeysByDetailTable( $dTName ) as $i => $mk)
1070
+ {
1071
+ $mKeys[] = "masterkey". ($i + 1) . "=" .$data[ $mk ];
1072
+ }
1073
+ return $mKeys;
1074
+ }
1075
+
1076
+
1077
+ /**
1078
+ * POST-REDIRECT-GET
1079
+ * Redirect after saving the data to avoid saving again on refresh.
1080
+ */
1081
+ protected function prgRedirect()
1082
+ {
1083
+ if( $this->stopPRG )
1084
+ return false;
1085
+ if( !$this->insertedSuccessfully || $this->mode != ADD_SIMPLE || !no_output_done() )
1086
+ return false;
1087
+ // saving message
1088
+ $_SESSION["message_add"] = $this->message ? $this->message : "";
1089
+ $_SESSION["message_add_type"] = $this->messageType;
1090
+ // redirect
1091
+
1092
+
1093
+ $getParams = array();
1094
+ if( $this->pageName )
1095
+ $getParams[] = "page=".$this->pageName;
1096
+
1097
+ $getParams[] = $this->getStateUrlParams();
1098
+
1099
+ HeaderRedirect( $this->pSet->getShortTableName(), $this->pageType, implode( '&', $getParams ) );
1100
+ // turned on output buffering, so we need to stop script
1101
+ return true;
1102
+ }
1103
+
1104
+ /**
1105
+ * POST-REDIRECT-GET
1106
+ * Read the saved message on the GET step.
1107
+ */
1108
+ protected function prgReadMessage()
1109
+ {
1110
+ // for PRG rule, to avoid POSTDATA resend. Saving mess in session
1111
+ if( $this->mode == ADD_SIMPLE && isset( $_SESSION["message_add"] ) )
1112
+ {
1113
+ $this->message = $_SESSION["message_add"];
1114
+ $this->messageType = $_SESSION["message_add_type"];
1115
+ unset( $_SESSION["message_add"] );
1116
+ }
1117
+ }
1118
+
1119
+ /**
1120
+ * @return Array
1121
+ */
1122
+ public function getCurrentRecord()
1123
+ {
1124
+ $data = array();
1125
+ if ( $this->masterTable && !!$this->masterKeysReq )
1126
+ {
1127
+ foreach ($this->detailKeysByM as $key => $detKey )
1128
+ {
1129
+ $data[$detKey] = $this->masterKeysReq[$key+1];
1130
+ }
1131
+ }
1132
+
1133
+ return $data;
1134
+ }
1135
+
1136
+ protected function replaceFileFieldsValuesWithCopies( &$defvalues ) {
1137
+ foreach( $this->addFields as $f ) {
1138
+ if( $this->pSet->getEditFormat( $f ) == EDIT_FORMAT_FILE ) //#10023
1139
+ $defvalues[ $f ] = $this->getControl( $f, $this->id )->getFieldValueCopy( $defvalues[ $f ] );
1140
+ }
1141
+ }
1142
+
1143
+ protected function getCopyKeys() {
1144
+ $copyKeys = array();
1145
+
1146
+ if( !array_key_exists( "copyid1", $_REQUEST ) && !array_key_exists( "editid1", $_REQUEST ) )
1147
+ return $copyKeys;
1148
+
1149
+ $prefix = array_key_exists( "copyid1", $_REQUEST ) ? "copyid" : "editid";
1150
+ foreach( $this->pSet->getTableKeys() as $idx => $k ) {
1151
+ $copyKeys[ $k ] = postvalue( $prefix . ($idx + 1) );
1152
+ }
1153
+
1154
+ return $copyKeys;
1155
+ }
1156
+
1157
+ /**
1158
+ * Set the defvalues property
1159
+ */
1160
+ protected function prepareDefvalues()
1161
+ {
1162
+ $copyKeys = $this->getCopyKeys();
1163
+
1164
+ if( $copyKeys && $this->mode != ADD_DASHBOARD )
1165
+ {
1166
+ // copy record
1167
+ $dc = $this->getDsCommand( $copyKeys );
1168
+ $prep = $this->dataSource->prepareSQL( $dc );
1169
+ $keyWhere = $prep["where"];
1170
+
1171
+ $fetchedArray = $this->dataSource->getSingle( $dc )->fetchAssoc();
1172
+ $this->defvalues = $this->cipherer->DecryptFetchedArray( $fetchedArray );
1173
+
1174
+ $this->replaceFileFieldsValuesWithCopies( $this->defvalues );
1175
+
1176
+ if( $this->eventsObject->exists("CopyOnLoad") ) {
1177
+ // call CopyOnLoad event
1178
+ $this->eventsObject->CopyOnLoad( $this->defvalues, $keyWhere, $this );
1179
+
1180
+ if( $keyWhere != $prep["where"] ) {
1181
+ $this->dataSource->overrideWhere( $dc, $keyWhere );
1182
+ $fetchedArray = $this->dataSource->getSingle( $dc )->fetchAssoc();
1183
+ $this->defvalues = $this->cipherer->DecryptFetchedArray( $fetchedArray );
1184
+
1185
+ $this->replaceFileFieldsValuesWithCopies( $this->defvalues );
1186
+ }
1187
+ }
1188
+ }
1189
+ else
1190
+ {
1191
+ foreach( $this->addFields as $f )
1192
+ {
1193
+ $defaultValue = GetDefaultValue($f, PAGE_ADD, $this->tName );
1194
+ if( strlen($defaultValue) )
1195
+ $this->defvalues[ $f ] = $defaultValue;
1196
+ }
1197
+ }
1198
+
1199
+ if( Security::advancedSecurityAvailable() ) {
1200
+ $securityType = $this->pSet->getAdvancedSecurityType();
1201
+ if( !$this->isAdminTable() && ($securityType == ADVSECURITY_EDIT_OWN || $securityType == ADVSECURITY_VIEW_OWN) )
1202
+ {
1203
+ $tableOwnerIdField = $this->pSet->getTableOwnerIdField();
1204
+ // insert default owner id value if exists
1205
+ if( $this->checkIfToAddOwnerIdValue( $tableOwnerIdField, '' ) )
1206
+ $this->defvalues[ $tableOwnerIdField ] = prepare_for_db( $tableOwnerIdField, $_SESSION["_".$this->tName."_OwnerID"] );
1207
+ }
1208
+ }
1209
+
1210
+ $masterTables = $this->pSet->getMasterTablesArr();
1211
+ // set default values for the foreign keys
1212
+ foreach( $masterTables as $mTableData )
1213
+ {
1214
+ if( $this->masterTable == $mTableData["mDataSourceTable"] )
1215
+ {
1216
+ foreach( $mTableData["detailKeys"] as $idx => $dk )
1217
+ {
1218
+ $masterkeyIdx = "masterkey".($idx + 1);
1219
+ if( strlen( postvalue($masterkeyIdx) ) )
1220
+ $_SESSION[ $this->sessionPrefix."_".$masterkeyIdx ] = postvalue($masterkeyIdx);
1221
+
1222
+ if( $this->masterPageType != PAGE_ADD )
1223
+ $this->defvalues[ $dk ] = @$_SESSION[ $this->sessionPrefix."_".$masterkeyIdx ];
1224
+ }
1225
+ }
1226
+ }
1227
+
1228
+ $this->addLookupFilterFieldValue( $this->newRecordData, $this->defvalues );
1229
+
1230
+ if( $this->readAddValues )
1231
+ {
1232
+ foreach( $this->addFields as $fName )
1233
+ {
1234
+ $editFormat = $this->pSet->getEditFormat($fName);
1235
+ if( $editFormat != EDIT_FORMAT_DATABASE_FILE && $editFormat != EDIT_FORMAT_DATABASE_IMAGE && $editFormat != EDIT_FORMAT_FILE )
1236
+ $this->defvalues[ $fName ] = @$this->newRecordData[ $fName ];
1237
+ }
1238
+ }
1239
+ }
1240
+
1241
+ /**
1242
+ * Set read-only fields
1243
+ */
1244
+ protected function prepareReadonlyFields()
1245
+ {
1246
+ foreach( $this->addFields as $f )
1247
+ {
1248
+ if( $this->pSet->getEditFormat( $f ) == EDIT_FORMAT_READONLY )
1249
+ $this->readOnlyFields[ $f ] = $this->showDBValue($f, $this->defvalues);
1250
+ }
1251
+ }
1252
+
1253
+ /**
1254
+ * Assign buttons xt variables
1255
+ */
1256
+ protected function prepareButtons()
1257
+ {
1258
+ if( $this->mode == ADD_INLINE )
1259
+ return;
1260
+
1261
+ $this->xt->assign("save_button", true);
1262
+
1263
+ $addStyle = "";
1264
+ if ( $this->isMultistepped() )
1265
+ {
1266
+ $addStyle = " style=\"display: none;\"";
1267
+ }
1268
+
1269
+ // legacy assignment used in the Invoice template
1270
+ $this->xt->assign("savebutton_attrs", "id=\"saveButton".$this->id."\"" . $addStyle );
1271
+
1272
+ if( $this->mode == ADD_DASHBOARD )
1273
+ {
1274
+ $this->xt->assign("reset_button", true);
1275
+ return;
1276
+ }
1277
+
1278
+ if( $this->mode != ADD_ONTHEFLY
1279
+ && $this->mode != ADD_POPUP
1280
+ && $this->mode != ADD_MASTER_DASH )
1281
+ {
1282
+ // add was successful
1283
+ if( isset( $_SESSION["successKeys"] ) )
1284
+ $this->xt->assign("message_back_button", true);
1285
+ if( $this->pSet->hasListPage() )
1286
+ $this->xt->assign("back_button", true);
1287
+ else if( $this->isShowMenu() )
1288
+ $this->xt->assign("backToMenu_button", true);
1289
+ }
1290
+ else
1291
+ $this->xt->assign("cancel_button", true);
1292
+
1293
+ if( $this->mode == ADD_SIMPLE )
1294
+ {
1295
+ // back to list/menu buttons
1296
+ if( $this->pSet->hasListPage() )
1297
+ {
1298
+ $this->xt->assign("backbutton_attrs", "id=\"backButton".$this->id."\"");
1299
+ }
1300
+ else if( $this->isShowMenu() )
1301
+ {
1302
+ $this->xt->assign("backbutton_attrs", "id=\"backToMenuButton".$this->id."\"");
1303
+ }
1304
+ }
1305
+
1306
+ if ( isset($_SESSION["successKeys"]) )
1307
+ {
1308
+ $keysArray = $_SESSION["successKeys"];
1309
+ $dataKeysAttr = 'data-keys="'.runner_htmlspecialchars( my_json_encode($keysArray) ).'"';
1310
+ unset($_SESSION["successKeys"]);
1311
+
1312
+ if( $this->viewAvailable() && $keysArray )
1313
+ {
1314
+ $this->xt->assign("view_page_button", true);
1315
+ $this->xt->assign("view_page_button_attrs", 'id="viewPageButton'.$this->id.'" '.$dataKeysAttr);
1316
+ }
1317
+
1318
+ if( $this->editAvailable() && $keysArray )
1319
+ {
1320
+ $this->xt->assign("edit_page_button", true);
1321
+ $this->xt->assign("edit_page_button_attrs", 'id="editPageButton'.$this->id.'" '.$dataKeysAttr);
1322
+ }
1323
+ }
1324
+ }
1325
+
1326
+ /**
1327
+ * Prepare edit controls
1328
+ */
1329
+ protected function prepareEditControls()
1330
+ {
1331
+ $controlFields = $this->addFields;
1332
+
1333
+ if( $this->mode == ADD_INLINE ) { //#9069
1334
+ $controlFields = $this->removeHiddenColumnsFromInlineFields(
1335
+ $controlFields,
1336
+ $this->screenWidth,
1337
+ $this->screenHeight,
1338
+ $this->orientation
1339
+ );
1340
+ }
1341
+
1342
+ foreach( $controlFields as $fName ) {
1343
+ $isDetKeyField = in_array( $fName, $this->detailKeysByM );
1344
+ if( $isDetKeyField ) {
1345
+ // to the ReadOnly control show the detail key control's value
1346
+ $this->readOnlyFields[ $fName ] = $this->showDBValue( $fName, $this->defvalues );
1347
+ }
1348
+
1349
+ $firstElementId = $this->getControl( $fName, $this->id )->getFirstElementId();
1350
+ if( $firstElementId )
1351
+ $this->xt->assign( "labelfor_" . GoodFieldName( $fName ), $firstElementId );
1352
+
1353
+ $parameters = $this->getEditContolParams( $fName, $this->id, $this->defvalues );
1354
+ $this->xt->assign_function( GoodFieldName( $fName )."_editcontrol", "xt_buildeditcontrol", $parameters );
1355
+
1356
+ $controls = $this->getContolMapData( $fName, $this->id, $this->defvalues, $controlFields );
1357
+ if ( in_array( $fName, $this->errorFields ) )
1358
+ $controls["controls"]["isInvalid"] = true;
1359
+
1360
+ $this->fillControlsMap( $controls );
1361
+ $this->fillControlFlags( $fName );
1362
+
1363
+ // fill special settings for a time picker
1364
+ if( $this->pSet->getEditFormat($fName) == "Time" )
1365
+ $this->fillTimePickSettings( $fName, @$this->defvalues[ $fName ] );
1366
+ }
1367
+ }
1368
+
1369
+ public function getContolMapData( $fName, $recId, &$data, $pageFields ) {
1370
+ $controls = array();
1371
+ $controls["controls"] = array();
1372
+ $controls["controls"]["id"] = $recId;
1373
+ $controls["controls"]["ctrlInd"] = 0;
1374
+ $controls["controls"]["fieldName"] = $fName;
1375
+
1376
+ //if richEditor for field
1377
+ if( $this->pSet->isUseRTE( $fName ) )
1378
+ $controls["controls"]["mode"] = "add";
1379
+ else
1380
+ $controls["controls"]["mode"] = $this->mode == ADD_INLINE ? "inline_add" : "add";
1381
+
1382
+ $isDetKeyField = in_array( $fName, $this->detailKeysByM );
1383
+ if( $isDetKeyField )
1384
+ $controls["controls"]["value"] = $data[ $fName ];
1385
+
1386
+ $preload = $this->fillPreload( $fName, $pageFields, $data );
1387
+ if( $preload !== false ) {
1388
+ $controls["controls"]["preloadData"] = $preload;
1389
+ if( !$data[ $fName ] && $preload["vals"] )
1390
+ $data[ $fName ] = $preload["vals"][0];
1391
+ }
1392
+
1393
+ return $controls;
1394
+ }
1395
+
1396
+ /**
1397
+ *
1398
+ */
1399
+ public function getEditContolParams( $fName, $recId, &$data ) {
1400
+ $parameters = array();
1401
+ $parameters["id"] = $recId;
1402
+ $parameters["ptype"] = PAGE_ADD;
1403
+ $parameters["field"] = $fName;
1404
+ $parameters["value"] = $data[ $fName ];
1405
+ $parameters["pageObj"] = $this;
1406
+
1407
+ if( $this->getEditFormat( $fName ) !== EDIT_FORMAT_READONLY ) {
1408
+ $parameters["validate"] = $this->pSet->getValidation( $fName );
1409
+
1410
+ if( $this->pSet->isUseRTE($fName) )
1411
+ $_SESSION[ $this->sessionPrefix."_".$fName."_rte" ] = $data[ $fName ];
1412
+ }
1413
+
1414
+ //if richEditor for field
1415
+ if( $this->pSet->isUseRTE( $fName ) )
1416
+ $parameters["mode"] = "add";
1417
+ else
1418
+ $parameters["mode"] = $this->mode == ADD_INLINE ? "inline_add" : "add";
1419
+
1420
+ return $parameters;
1421
+ }
1422
+
1423
+ public function getEditFormat( $field, $pSet = null ) {
1424
+ $isDetKeyField = in_array( $field, $this->detailKeysByM );
1425
+ if( $isDetKeyField ) {
1426
+ return EDIT_FORMAT_READONLY;
1427
+ }
1428
+ return parent::getEditFormat( $field, $pSet );
1429
+ }
1430
+
1431
+
1432
+ /**
1433
+ * Set details preview on the add master page
1434
+ */
1435
+ protected function prepareDetailsTables()
1436
+ {
1437
+ if( !$this->isShowDetailTables
1438
+ || $this->mode != ADD_SIMPLE && $this->mode != ADD_POPUP && $this->mode != ADD_DASHBOARD && $this->mode != ADD_MASTER_DASH
1439
+ || $this->mobileTemplateMode() )
1440
+ {
1441
+ return;
1442
+ }
1443
+
1444
+ $dpParams = $this->getDetailsParams( $this->id );
1445
+
1446
+ $this->jsSettings['tableSettings'][ $this->tName ]['isShowDetails'] = !!$dpParams;
1447
+ $this->jsSettings['tableSettings'][ $this->tName ]['dpParams'] = array('tableNames' => $dpParams['strTableNames'], 'ids' => $dpParams['ids']);
1448
+
1449
+ if( !$dpParams['ids'] )
1450
+ return;
1451
+
1452
+ $this->xt->assign("detail_tables", true);
1453
+
1454
+ for($d = 0; $d < count($dpParams['ids']); $d++)
1455
+ {
1456
+ $this->setDetailPreview( "list", $dpParams['strTableNames'][ $d ], $dpParams['ids'][ $d ], $this->defvalues );
1457
+ $this->displayDetailsButtons( $dpParams['type'][ $d ], $dpParams['strTableNames'][ $d ], $dpParams['ids'][ $d ] );
1458
+ }
1459
+ }
1460
+
1461
+ /**
1462
+ *
1463
+ */
1464
+ protected function displayDetailsButtons( $dpType, $dpTableName, $dpId )
1465
+ {
1466
+ if ( !CheckTablePermissions($dpTableName, "S") )
1467
+ return;
1468
+
1469
+ $listPageObject = $this->getDetailsPageObject( $dpTableName, $dpId );
1470
+ $listPageObject->assignButtonsOnMasterEdit( $this->xt );
1471
+ }
1472
+
1473
+ /**
1474
+ * Assign basic page's xt variables
1475
+ */
1476
+ protected function doCommonAssignments()
1477
+ {
1478
+ if ( $this->mode === ADD_SIMPLE )
1479
+ {
1480
+ $this->headerCommonAssign();
1481
+ }
1482
+ else
1483
+ {
1484
+ $this->xt->assign("menu_chiddenattr", "data-hidden" );
1485
+ }
1486
+
1487
+ $this->setLangParams();
1488
+
1489
+ $this->xt->assign("message_block", true);
1490
+
1491
+ if( $this->isMessageSet() )
1492
+ {
1493
+ $this->xt->assign("message", $this->message );
1494
+ $this->xt->assign("message_class", $this->messageType == MESSAGE_ERROR ? "alert alert-danger" : "alert alert-success" );
1495
+ }
1496
+ else
1497
+ {
1498
+ $this->hideElement("message");
1499
+ }
1500
+
1501
+ if( $this->mode != ADD_INLINE )
1502
+ $this->assignAddFieldsBlocksAndLabels();
1503
+
1504
+ if( $this->mode == ADD_SIMPLE )
1505
+ {
1506
+ $this->assignBody();
1507
+ $this->xt->assign("flybody", true);
1508
+ }
1509
+
1510
+ if( $this->mode == ADD_ONTHEFLY
1511
+ /*|| $this->mode == ADD_MASTER*/
1512
+ || $this->mode == ADD_POPUP
1513
+ || $this->mode == ADD_DASHBOARD
1514
+ || $this->mode == ADD_MASTER_DASH )
1515
+ {
1516
+ $this->xt->assign("body", true);
1517
+ $this->xt->assign("footer", false);
1518
+ $this->xt->assign("header", false);
1519
+ $this->xt->assign("flybody", $this->body);
1520
+ }
1521
+ }
1522
+
1523
+ /**
1524
+ * Assign add fields' blocks and labels variables
1525
+ */
1526
+ public function assignAddFieldsBlocksAndLabels()
1527
+ {
1528
+ foreach($this->addFields as $fName)
1529
+ {
1530
+ $gfName = GoodFieldName($fName);
1531
+
1532
+ $this->xt->assign($gfName."_fieldblock", true);
1533
+ $this->xt->assign($gfName."_tabfieldblock", true);
1534
+ }
1535
+ }
1536
+
1537
+ /**
1538
+ * Display the add page basing on its mode
1539
+ */
1540
+ protected function displayAddPage()
1541
+ {
1542
+ $templatefile = $this->templatefile;
1543
+
1544
+ if( $this->eventsObject->exists("BeforeShowAdd") )
1545
+ $this->eventsObject->BeforeShowAdd($this->xt, $templatefile, $this);
1546
+
1547
+ if( $this->mode != ADD_INLINE && $this->mode != ADD_ONTHEFLY )
1548
+ $this->displayMasterTableInfo();
1549
+ // invoked after displayMasterTableInfo to add master viewcontrols maps
1550
+ $this->fillSetCntrlMaps();
1551
+
1552
+ if( $this->mode == ADD_SIMPLE /*|| $this->mode ==ADD_MASTER */)
1553
+ {
1554
+ $this->display( $templatefile );
1555
+ return;
1556
+ }
1557
+
1558
+ if( $this->mode == ADD_ONTHEFLY || $this->mode == ADD_POPUP || $this->mode == ADD_DASHBOARD || $this->mode == ADD_MASTER_DASH )
1559
+ {
1560
+ $this->displayAJAX( $templatefile, $this->flyId + 1 );
1561
+ exit();
1562
+ }
1563
+
1564
+ if( $this->mode == ADD_INLINE )
1565
+ {
1566
+ $returnJSON = array();
1567
+
1568
+ $this->xt->load_template( $templatefile );
1569
+
1570
+ $returnJSON["htmlControls"] = array();
1571
+ foreach( $this->addFields as $fName ) {
1572
+ $returnJSON["htmlControls"][ $fName ] = $this->xt->fetchVar( GoodFieldName($fName)."_editcontrol" );
1573
+ }
1574
+
1575
+ $listPSet = $this->getListPSet();
1576
+ if( $listPSet->reorderRows() ) {
1577
+ // provisional order value, to be adjusted at the time of saving
1578
+ $returnJSON['order'] = $this->getMaxOrderValue( $listPSet ) + 1;
1579
+ }
1580
+
1581
+
1582
+ global $pagesData;
1583
+ $returnJSON["pagesData"] = $pagesData;
1584
+
1585
+ $returnJSON['settings'] = $this->jsSettings;
1586
+ $returnJSON['controlsMap'] = $this->controlsHTMLMap;
1587
+ $returnJSON['viewControlsMap'] = $this->viewControlsHTMLMap;
1588
+
1589
+ $returnJSON["additionalJS"] = $this->grabAllJsFiles();
1590
+ $returnJSON["additionalCSS"] = $this->grabAllCSSFiles();
1591
+
1592
+ echo printJSON($returnJSON);
1593
+ exit();
1594
+ }
1595
+ }
1596
+
1597
+ /**
1598
+ * Get extra JSON params to display the page on AJAX-like request
1599
+ * @return Array
1600
+ */
1601
+ protected function getExtraAjaxPageParams()
1602
+ {
1603
+ return $this->getSaveStatusJSON();
1604
+ }
1605
+
1606
+ /**
1607
+ * Return link and display field values after Add on the fly
1608
+ * @return array or false
1609
+ * "link" => <link field value>
1610
+ * "display" => <display field value>
1611
+ */
1612
+ protected function getNewLookupValues( $lookupPSet )
1613
+ {
1614
+ $linkFieldName = $lookupPSet->getLinkField( $this->lookupField );
1615
+ $dispFieldName = $lookupPSet->getDisplayField( $this->lookupField );
1616
+ if( $this->keys ) {
1617
+ $dc = new DsCommand();
1618
+ $dc->keys = $this->keys;
1619
+
1620
+ if( $lookupPSet->getCustomDisplay( $this->lookupField ) ) {
1621
+ $customField = new DsFieldData( $dispFieldName, generateAlias(), "" );
1622
+ $dispFieldName = $customField->alias;
1623
+ $dc->extraColumns[] = $customField;
1624
+ }
1625
+ $data = $this->cipherer->DecryptFetchedArray( $this->dataSource->getSingle( $dc )->fetchAssoc() );
1626
+ }
1627
+ if( !$data ) {
1628
+ $data = $this->newRecordData;
1629
+ }
1630
+ return array(
1631
+ "link" => $data[ $linkFieldName ],
1632
+ "display" => $data[ $dispFieldName ]
1633
+ );
1634
+ }
1635
+
1636
+ /**
1637
+ * Get lookup data from a record added
1638
+ * in 'add value On the Fly' mode
1639
+ * or in Inline Add mode on List page with search.
1640
+ * @return Array
1641
+ */
1642
+ public function getLookupData() {
1643
+ // get Project Settings object for $this->lookupTable
1644
+ $lookupPSet = getLookupMainTableSettings( $this->tName, $this->lookupTable, $this->lookupField, $this->lookupPageType );
1645
+ if( !$lookupPSet )
1646
+ return array();
1647
+
1648
+ $lvals = $this->getNewLookupValues( $lookupPSet );
1649
+ if( !$lvals )
1650
+ return array();
1651
+
1652
+ $linkField = $lookupPSet->getLinkField( $this->lookupField );
1653
+ $dispfield = $lookupPSet->getDisplayField( $this->lookupField );
1654
+
1655
+ $respData = array(
1656
+ $linkField => $lvals["link"],
1657
+ $dispfield => $lvals["display"]
1658
+ );
1659
+
1660
+ // format DATE or TIME value
1661
+ if( in_array( $lookupPSet->getViewFormat( $this->lookupField ), array(FORMAT_DATE_SHORT, FORMAT_DATE_LONG, FORMAT_DATE_TIME) ) ) {
1662
+ $viewContainer = new ViewControlsContainer( $lookupPSet, PAGE_LIST, null );
1663
+
1664
+ $ctrlData = array();
1665
+ $ctrlData[ $this->lookupField ] = $respData[ $linkField ];
1666
+
1667
+ $respData[ $dispfield ] = $viewContainer->getControl( $this->lookupField )->getTextValue( $ctrlData );
1668
+ }
1669
+
1670
+ return array(
1671
+ 'linkValue' => $respData[ $linkField ],
1672
+ 'displayValue' => $respData[ $dispfield ],
1673
+ 'vals' => $respData
1674
+ );
1675
+ }
1676
+
1677
+ /**
1678
+ * Check if to add session owner id value
1679
+ * @param String ownerField
1680
+ * @param String currentValue
1681
+ * @return Boolean
1682
+ */
1683
+ public function checkIfToAddOwnerIdValue( $ownerField, $currentValue )
1684
+ {
1685
+ return originalTableField( $ownerField, $this->pSet ) // legacy
1686
+ && !$this->isAutoincPrimaryKey( $ownerField )
1687
+ && ( !CheckTablePermissions($this->tName, 'M') || !strlen($currentValue) );
1688
+ }
1689
+
1690
+ /**
1691
+ * Check if field is auto-incremented primary key
1692
+ * @param String field
1693
+ * @return Boolean
1694
+ */
1695
+ protected function isAutoincPrimaryKey( $field )
1696
+ {
1697
+ $keyFields = $this->pSet->getTableKeys();
1698
+ return count($keyFields) == 1 && in_array($field, $keyFields) && $this->pSet->isAutoincField( $field );
1699
+ }
1700
+
1701
+ /**
1702
+ * Check if the page's message is set
1703
+ * @return Boolean
1704
+ */
1705
+ protected function isMessageSet()
1706
+ {
1707
+ return strlen( $this->message ) > 0;
1708
+ }
1709
+
1710
+ /**
1711
+ * Set a database error message
1712
+ * @param String message
1713
+ */
1714
+ public function setDatabaseError( $message )
1715
+ {
1716
+ if( $this->mode != ADD_INLINE )
1717
+ {
1718
+ $this->message = "<strong>&lt;&lt;&lt; "."Record was NOT added"."</strong> &gt;&gt;&gt;<br><br>".$message;
1719
+ }
1720
+ else
1721
+ {
1722
+ $this->message = "Record was NOT added".". ".$message;
1723
+ }
1724
+
1725
+ $this->messageType = MESSAGE_ERROR;
1726
+ }
1727
+
1728
+ /**
1729
+ * @return Array
1730
+ */
1731
+ public function getNewRecordData()
1732
+ {
1733
+ return $this->newRecordData;
1734
+ }
1735
+
1736
+
1737
+ /**
1738
+ * @param String fName
1739
+ * @return Boolean
1740
+ */
1741
+ protected function checkFieldOnPage( $fName )
1742
+ {
1743
+ if( $this->mode == ADD_INLINE )
1744
+ return $this->pSet->appearOnInlineAdd( $fName );
1745
+
1746
+ return $this->pSet->appearOnAddPage( $fName );
1747
+ }
1748
+
1749
+ /**
1750
+ * @param String table
1751
+ */
1752
+ public static function processAddPageSecurity( $table )
1753
+ {
1754
+ // user has necessary permissions
1755
+ if( Security::checkPagePermissions( $table, "A" ) )
1756
+ return true;
1757
+
1758
+ // display entered data. Give the user chance to relogin. Do nothing for now.
1759
+ if( postvalue("a") == "added" )
1760
+ return true;
1761
+
1762
+ // page can not be displayed. Redirect or return error
1763
+
1764
+ // return error if the page is requested by AJAX
1765
+ $pageMode = AddPage::readAddModeFromRequest();
1766
+ if( $pageMode != ADD_SIMPLE )
1767
+ {
1768
+ Security::sendPermissionError();
1769
+ return false;
1770
+ }
1771
+
1772
+ // The user is logged in but lacks necessary permissions
1773
+ // redirect to List page or Menu.
1774
+ if( isLogged() && !Security::isGuest() )
1775
+ {
1776
+ Security::redirectToList( $table );
1777
+ return false;
1778
+ }
1779
+
1780
+ redirectToLogin();
1781
+ return false;
1782
+ }
1783
+
1784
+ public static function readAddModeFromRequest()
1785
+ {
1786
+ $editType = postvalue("editType");
1787
+
1788
+ if( $editType == "inline" )
1789
+ return ADD_INLINE;
1790
+ elseif( $editType == ADD_POPUP )
1791
+ return ADD_POPUP;
1792
+ elseif( $editType == ADD_MASTER )
1793
+ return ADD_MASTER;
1794
+ elseif( $editType == ADD_MASTER_POPUP )
1795
+ return ADD_MASTER_POPUP;
1796
+ elseif( $editType == ADD_MASTER_DASH )
1797
+ return ADD_MASTER_DASH;
1798
+ elseif( $editType == ADD_ONTHEFLY )
1799
+ return ADD_ONTHEFLY;
1800
+ elseif( postvalue("mode") == "dashrecord" )
1801
+ return ADD_DASHBOARD;
1802
+ else
1803
+ return ADD_SIMPLE;
1804
+ }
1805
+
1806
+ function editAvailable() {
1807
+ return !$this->dashElementData && parent::editAvailable();
1808
+ }
1809
+
1810
+ function viewAvailable() {
1811
+ return !$this->dashElementData && parent::viewAvailable();
1812
+ }
1813
+
1814
+ /**
1815
+ * API
1816
+ */
1817
+ public function setMessageType( $type )
1818
+ {
1819
+ $this->messageType = $type;
1820
+ }
1821
+
1822
+ function element2Item( $name ) {
1823
+ if( $name == "message" ) {
1824
+ return array( "add_message" );
1825
+ }
1826
+ return parent::element2Item( $name );
1827
+ }
1828
+
1829
+ protected function checkShowBreadcrumbs()
1830
+ {
1831
+ return $this->mode == ADD_SIMPLE;
1832
+ }
1833
+
1834
+ function createProjectSettings() {
1835
+ $this->pSet = new ProjectSettings($this->tName, $this->pageType, $this->pageName, $this->pageTable );
1836
+
1837
+ if( $this->mode != ADD_INLINE && $this->pSet->getPageType() !== PAGE_ADD )
1838
+ {
1839
+ $this->pSet = new ProjectSettings($this->tName, $this->pageType, null, $this->pageTable );
1840
+ }
1841
+
1842
+ if( $this->mode == ADD_POPUP && $this->action == "added" ) {
1843
+ $this->pSet->setPageType( "list" );
1844
+ }
1845
+ }
1846
+
1847
+
1848
+ public function getInsertDataCommand() {
1849
+ $dc = new DsCommand();
1850
+ $dc->values = &$this->newRecordData;
1851
+
1852
+ $dc->advValues = array();
1853
+ foreach( $this->sqlValues as $field => $sqlValue ) {
1854
+ $dc->advValues[ $field ] = new DsOperand( dsotSQL, $sqlValue );
1855
+ }
1856
+ return $dc;
1857
+ }
1858
+
1859
+ public function getSecurityCondition() {
1860
+ return Security::SelectCondition( "S", $this->pSet );
1861
+ }
1862
+
1863
+ protected function getRecordData( $keys ) {
1864
+ $dc = $this->getDsCommand( $keys );
1865
+
1866
+ $fetchedArray = $this->dataSource->getSingle( $dc )->fetchAssoc();
1867
+ return $this->cipherer->DecryptFetchedArray( $fetchedArray );
1868
+ }
1869
+
1870
+ protected function getDsCommand( $keys ) {
1871
+ $dc = new DsCommand();
1872
+ $dc->keys = $keys;
1873
+ $dc->filter = $this->getSecurityCondition();
1874
+
1875
+ return $dc;
1876
+ }
1877
+
1878
+ protected function getListPSet() {
1879
+ if( !$this->listPagePSet ) {
1880
+ $this->listPagePSet = new ProjectSettings( $this->tName, PAGE_LIST, $this->hostPageName, $this->pageTable );
1881
+ }
1882
+ return $this->listPagePSet;
1883
+ }
1884
+ }
1885
+ ?>
classes/advancedsearchcontrol.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Search control builder class for advanced search
5
+ *
6
+ */
7
+ class AdvancedSearchControl extends SearchControl
8
+ {
9
+ function __construct($id, $tName, &$searchClauseObj, &$pageObj)
10
+ {
11
+ parent::__construct($id, $tName, $searchClauseObj, $pageObj);
12
+ $this->getSrchPanelAttrs['ctrlTypeComboStatus'] = true;
13
+ }
14
+
15
+ function getCtrlSearchTypeOptions($fName, $selOpt, $not, $flexible = false, $both = false)
16
+ {
17
+ if( $this->pageObj->isBootstrap() )
18
+ {
19
+ if( !$flexible && ($selOpt == EMPTY_SEARCH || $selOpt == NOT_EMPTY) )
20
+ return $this->getControl($fName)->buildSearchOptions(array(EMPTY_SEARCH, NOT_EMPTY), $selOpt, $not, true);
21
+
22
+ return $this->getControl($fName)->getSearchOptions($selOpt, $not, true);
23
+ }
24
+
25
+ $withNot = $both ? $not : false;
26
+ return parent::getCtrlSearchTypeOptions($fName, $selOpt, $withNot, false, $both);
27
+ }
28
+ }
29
+ ?>
classes/base32.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class RunnerBase32 {
3
+ public static function encode( $str ) {
4
+ $ret = "";
5
+ $n = 0;
6
+ while( "" !== ( $symbol = self::encodeChunk( $str, $n++ ) ) ) {
7
+ $ret .= $symbol;
8
+ }
9
+ return str_pad( $ret, strlen( $ret ) + strlen( $ret ) % 8 , '=' );
10
+ }
11
+
12
+ public static function decode( $str ) {
13
+ $ret = "";
14
+ $n = 0;
15
+ while( $n < strlen( $str ) && self::decodeChunk( $str[ $n ], $ret, $n ) ) {
16
+ ++$n;
17
+ }
18
+ return $ret;
19
+ }
20
+
21
+ /**
22
+ * decode synbol and write n-th 5-bit block to the string
23
+ */
24
+ protected static function decodeChunk( $encoded, &$str, $n ) {
25
+ if( $encoded == '=' ) {
26
+ // reached the end, stop processing
27
+ return false;
28
+ }
29
+ $fiveBits = array_search( $encoded, self::$table );
30
+ if( $fiveBits < 0 ) {
31
+ // wrong symbol, stop procesing
32
+ return false;
33
+ }
34
+
35
+ $charIdx = (int)floor( $n * 5 / 8 );
36
+ $bitOffset = ($n * 5) % 8;
37
+ if( $charIdx < strlen( $str ) ) {
38
+ $byte = ord( $str[ $charIdx ] );
39
+ } else {
40
+ $byte = 0;
41
+ $str .= ' ';
42
+ }
43
+
44
+ if( $bitOffset <= 3 ) {
45
+ $byte += $fiveBits << ( 3 - $bitOffset );
46
+ $str[ $charIdx ] = chr( $byte );
47
+ } else {
48
+ $byte += $fiveBits >> ( $bitOffset - 3 );
49
+ $str[ $charIdx ] = chr( $byte );
50
+
51
+ // if lowest ( $bitOffset - 3 ) bits are not 0, write them to the next byte
52
+ $mask = (1 << ( $bitOffset - 3 )) - 1;
53
+ $nextByte = ( $fiveBits & $mask ) << ( 8 - ( $bitOffset - 3 ) );
54
+ if( $nextByte !== 0 ) {
55
+ if( $charIdx + 1 >= strlen( $str ) ) {
56
+ $str .= chr( $nextByte );
57
+ }
58
+ }
59
+ }
60
+
61
+ return true;
62
+ }
63
+
64
+ /**
65
+ * read and encode n-th 5-bit block from the string
66
+ */
67
+ protected static function encodeChunk( &$str, $n ) {
68
+ $charIdx = (int)floor( $n * 5 / 8 );
69
+ $bitOffset = ($n * 5) % 8;
70
+ if( $charIdx >= strlen( $str ) ) {
71
+ return "";
72
+ }
73
+ $byte = ord( $str[ $charIdx ] );
74
+ if( $bitOffset <= 3 ) {
75
+ // read highest ($bitOffset + 5) bits and puth them into $fiveBits
76
+ $fiveBits = ( $byte >> ( 3 - $bitOffset ) ) & 31;
77
+ } else {
78
+ // read 8 - $bitoffset bits from the first byte
79
+ $mask = ( 1 << ( 8 - $bitOffset ) ) - 1;
80
+ $fiveBits = ( $byte & $mask ) << ( $bitOffset - 3 );
81
+ if( $charIdx < strlen( $str ) - 1 ) {
82
+ // read next ($bitOffset - 3) bits and put them in the lowest bits of $fiveBits
83
+ $nextByte = ord( $str[ $charIdx + 1 ] );
84
+ $fiveBits += $nextByte >> ( 8 - ($bitOffset - 3) );
85
+ }
86
+ }
87
+ $ret = self::$table[ $fiveBits ];
88
+ return $ret;
89
+ }
90
+ protected static $table = array(
91
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
92
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
93
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
94
+ 'Y', 'Z', '2', '3', '4', '5', '6', '7',
95
+ '='
96
+ );
97
+ }
98
+ ?>
classes/button.php ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Button
3
+ {
4
+ var $keys = array();
5
+
6
+ var $currentKeys = array();
7
+
8
+ var $selectedKeys = array();
9
+
10
+ var $isManyKeys = false;
11
+
12
+ var $location = "";
13
+
14
+ var $nextInd;
15
+
16
+ var $table;
17
+
18
+ var $page;
19
+
20
+ var $tempFileNames = array();
21
+
22
+ public $masterTable;
23
+ public $masterKeys;
24
+
25
+ function __construct(&$params)
26
+ {
27
+ RunnerApply($this, $params);
28
+
29
+ $this->nextInd = 0;
30
+ $this->modifyKeys();
31
+ $this->separateKeys();
32
+ }
33
+ /**
34
+ * Separate modified post keys to current and selected
35
+ */
36
+ function separateKeys()
37
+ {
38
+ if($this->location == 'grid')
39
+ {
40
+ if($this->isManyKeys)
41
+ {
42
+ $this->currentKeys = $this->keys[0];
43
+ for($i=1; $i<count($this->keys); $i++)
44
+ $this->selectedKeys[$i-1] = $this->keys[$i];
45
+ }
46
+ else
47
+ $this->currentKeys = $this->keys;
48
+ }
49
+ if($this->location == PAGE_LIST) {
50
+ $this->selectedKeys = $this->keys;
51
+ $this->currentKeys = $this->keys;
52
+ }
53
+
54
+ if($this->location == PAGE_EDIT || $this->location == PAGE_VIEW)
55
+ $this->currentKeys = $this->keys;
56
+ }
57
+ /**
58
+ * Modify post keys array to associative
59
+ */
60
+ function modifyKeys()
61
+ {
62
+ $pSet = new ProjectSettings( $this->table, "", $this->page );
63
+
64
+ $keys = array();
65
+
66
+ // if array of keys exists
67
+ if( $this->keys )
68
+ {
69
+ $tKeysNamesArr = $pSet->getTableKeys();
70
+ if($this->isManyKeys)
71
+ {
72
+ foreach ($this->keys as $ind => $value)
73
+ {
74
+ $keys[$ind] = array();
75
+ $recKeyArr = explode('&', $value);
76
+ for($j=0;$j<count($tKeysNamesArr);$j++)
77
+ {
78
+ if (isset($recKeyArr[$j])){
79
+ $keys[$ind][$tKeysNamesArr[$j]] = urldecode($recKeyArr[$j]);
80
+ }
81
+ }
82
+ }
83
+ }
84
+ else
85
+ {
86
+ $keysReady = true;
87
+ foreach( $tKeysNamesArr as $kf ) {
88
+ if( !isset( $this->keys[ $kf ] ) ) {
89
+ $keysReady = false;
90
+ break;
91
+ }
92
+ }
93
+
94
+ if( $keysReady )
95
+ return;
96
+
97
+ for($j=0;$j<count($tKeysNamesArr);$j++)
98
+ {
99
+ $keys[$tKeysNamesArr[$j]] = urldecode(@$this->keys[$j]);
100
+ }
101
+ }
102
+ }
103
+ $this->keys = $keys;
104
+ }
105
+ /**
106
+ * Get keys
107
+ * @return {array}
108
+ */
109
+ function getKeys() {
110
+ return $this->keys;
111
+ }
112
+
113
+ /**
114
+ * Get current record data
115
+ * @return {mixed} array of next record data or false
116
+ */
117
+ function getCurrentRecord() {
118
+ return $this->getRecordData();
119
+ }
120
+
121
+ /**
122
+ * Get next selected record
123
+ * @return {mixed} array of next record data or false
124
+ */
125
+ function getNextSelectedRecord() {
126
+ if( $this->nextInd < count( $this->selectedKeys ) ) {
127
+ $data = $this->getRecordData( $this->selectedKeys[ $this->nextInd ] );
128
+ $this->nextInd += 1;
129
+ return $data;
130
+ }
131
+
132
+ return false;
133
+ }
134
+
135
+ /**
136
+ * Read values from the database by keys
137
+ * @return {mixed} array of current record data or false
138
+ */
139
+ public function getRecordData( $keys = null ) {
140
+ global $cipherer;
141
+
142
+ if( !$keys )
143
+ $keys = $this->currentKeys;
144
+
145
+ $pSet = new ProjectSettings( $this->table, "", $this->page );
146
+
147
+ $dc = new DsCommand();
148
+ $dc->filter = Security::SelectCondition( "S", $pSet );
149
+ $dc->keys = $keys;
150
+
151
+ $dataSource = getDataSource( $this->table, $pSet );
152
+ $fetchedArray = $dataSource->getSingle( $dc )->fetchAssoc();
153
+ $data = $cipherer->DecryptFetchedArray( $fetchedArray );
154
+
155
+ return $data;
156
+ }
157
+
158
+
159
+ function getMasterData( $masterTable )
160
+ {
161
+ if ( isset($_SESSION[ $masterTable . "_masterRecordData" ]) )
162
+ {
163
+ return $_SESSION[ $masterTable . "_masterRecordData" ];
164
+ }
165
+
166
+ return false;
167
+ }
168
+
169
+ function saveTempFile( $contents ) {
170
+ $filename = tempnam("", "");
171
+ runner_save_file($filename, $contents);
172
+ $this->tempFileNames[] = $filename;
173
+ return $filename;
174
+ }
175
+
176
+ function deleteTempFiles() {
177
+ foreach( $this->tempFileNames as $f ) {
178
+ @unlink( $f );
179
+ }
180
+ }
181
+
182
+ public function getMasterRecord() {
183
+ if( !$this->masterTable )
184
+ return null;
185
+
186
+ $pSet = new ProjectSettings( $this->table, "", $this->page );
187
+ $mpSet = new ProjectSettings( $this->masterTable, PAGE_LIST );
188
+ $masterDs = getDataSource( $this->masterTable, $mpSet );
189
+
190
+ $filters = array();
191
+ foreach( $pSet->getMasterTablesArr() as $i => $masterTableInfo ) {
192
+ if( $this->masterTable != $masterTableInfo['mDataSourceTable'] )
193
+ continue;
194
+
195
+ foreach( $masterTableInfo['masterKeys'] as $j => $mKeyField ) {
196
+ $filters[] = DataCondition::FieldEquals( $mKeyField, $this->masterKeys[ $j + 1 ] );
197
+ }
198
+ }
199
+ $filters[] = Security::SelectCondition( "S", $mpSet );
200
+
201
+ $dc = new DsCommand;
202
+ $dc->filter = DataCondition::_And( $filters );
203
+ $dc->reccount = 1;
204
+
205
+ return $masterDs->getList( $dc )->fetchAssoc();
206
+ }
207
+ }
208
+ ?>
classes/chartpage.php ADDED
@@ -0,0 +1,374 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class ChartPage extends RunnerPage
3
+ {
4
+ /**
5
+ * show message block
6
+ */
7
+ public $show_message_block = false;
8
+
9
+ /**
10
+ * @constructor
11
+ */
12
+ function __construct(&$params = "")
13
+ {
14
+ parent::__construct($params);
15
+
16
+ $this->bodyForms = array( "grid" );
17
+
18
+ $this->jsSettings['tableSettings'][ $this->tName ]['simpleSearchActive'] = $this->searchClauseObj->simpleSearchActive;
19
+
20
+ if( $this->mode == CHART_DASHBOARD ) {
21
+ $this->pageData['detailsMasterKeys'] = $this->getStartMasterKeys();
22
+ }
23
+ $this->pageData['singleChartPage'] = $this->pSet->getChartCount() == 1;
24
+ }
25
+
26
+ /**
27
+ * Set the page's session prefix
28
+ */
29
+ protected function assignSessionPrefix()
30
+ {
31
+ if( $this->mode == CHART_DASHBOARD )
32
+ $this->sessionPrefix = $this->dashTName."_".$this->tName;
33
+ else
34
+ $this->sessionPrefix = $this->tName;
35
+ }
36
+
37
+ /**
38
+ * Process the page
39
+ */
40
+ public function process()
41
+ {
42
+ if( $this->mode == CHART_DASHDETAILS
43
+ || $this->mode == CHART_DETAILS && ( $this->masterPageType == PAGE_LIST || $this->masterPageType == PAGE_REPORT ))
44
+ $this->updateDetailsTabTitles();
45
+
46
+
47
+ // Before Process event
48
+ if( $this->eventsObject->exists("BeforeProcessChart") )
49
+ $this->eventsObject->BeforeProcessChart( $this );
50
+
51
+
52
+ // build tabs and set current
53
+ $this->processGridTabs();
54
+
55
+ $this->doCommonAssignments();
56
+ $this->addButtonHandlers();
57
+ $this->addCommonJs();
58
+ $this->commonAssign();
59
+
60
+ if( $this->mode != CHART_DASHBOARD ) {
61
+ $this->buildSearchPanel();
62
+ $this->assignSimpleSearch();
63
+ }
64
+
65
+ // to restore correctly within a chart class
66
+ $_SESSION[ $this->sessionPrefix.'_advsearch' ] = serialize( $this->searchClauseObj );
67
+
68
+ // display the 'Back to Master' link and master table info
69
+ $this->displayMasterTableInfo();
70
+
71
+ $this->showPage();
72
+ }
73
+
74
+ function callBeforeQueryEvent( $dc ) {
75
+ if( !$this->eventsObject->exists("BeforeQueryChart") ) {
76
+ return;
77
+ }
78
+ $prep = $this->dataSource->prepareSQL( $dc );
79
+ $where = $prep["where"];
80
+ $order = $prep["order"];
81
+ $sql = $prep["sql"];
82
+ $this->eventsObject->BeforeQueryChart($sql, $where, $order );
83
+
84
+ if( $sql != $prep["sql"] )
85
+ $this->dataSource->overrideSQL( $dc, $sql );
86
+ else {
87
+ if( $where != $prep["where"] )
88
+ $this->dataSource->overrideWhere( $dc, $where );
89
+ if( $order != $prep["order"] )
90
+ $this->dataSource->overrideOrder( $dc, $order );
91
+ }
92
+ }
93
+
94
+
95
+
96
+ function getMasterCondition() {
97
+ if( $this->mode == CHART_DASHBOARD )
98
+ return null;
99
+
100
+ return parent::getMasterCondition();
101
+ }
102
+
103
+ /**
104
+ * Get started master keys
105
+ * @return Array
106
+ */
107
+ public function getStartMasterKeys()
108
+ {
109
+ $detailTablesData = $this->pSet->getDetailTablesArr();
110
+ if( !$detailTablesData ) {
111
+ return array();
112
+ }
113
+
114
+ $dc = $this->getSubsetDataCommand();
115
+ $dc->reccount = 1;
116
+
117
+ $rs = $this->dataSource->getList( $dc );
118
+ if( !$rs ) {
119
+ showError( $this->dataSource->lastError() );
120
+ }
121
+
122
+ $data = $this->cipherer->DecryptFetchedArray( $rs->fetchAssoc() );
123
+
124
+ $masterKeysArr = array();
125
+ foreach ( $detailTablesData as $detailId => $detail ) {
126
+ foreach( $detail['masterKeys'] as $idx => $mk ) {
127
+ $masterKeysArr[ $detail['dDataSourceTable'] ] = array( 'masterkey'.($idx + 1) => $data[$mk] );
128
+ }
129
+ }
130
+
131
+ return $masterKeysArr;
132
+ }
133
+
134
+ /**
135
+ *
136
+ */
137
+ public function doCommonAssignments()
138
+ {
139
+
140
+ //set the Search panel
141
+ $this->xt->assign("searchPanel", true);
142
+
143
+ if( $this->isShowMenu() )
144
+ $this->xt->assign("menu_block", true);
145
+
146
+ $this->setLangParams();
147
+
148
+ $this->xt->assign("chart_block", true);
149
+ $this->xt->assign("asearch_link", true);
150
+ $this->xt->assign("exportpdflink_attrs", "onclick='chart.saveAsPDF();'");
151
+ $this->xt->assign("advsearchlink_attrs", "id=\"advButton".$this->id."\"");
152
+
153
+ if( !GetChartXML( $this->shortTableName ) )
154
+ $this->xt->assign("chart_block", false);
155
+
156
+ $this->xt->assign("message_block", true);
157
+
158
+ if( ($this->mode == CHART_SIMPLE || $this->mode == CHART_DASHBOARD) && $this->pSet->noRecordsOnFirstPage() && !$this->searchClauseObj->isSearchFunctionalityActivated() )
159
+ {
160
+ $this->show_message_block = true;
161
+ $this->hideElement("chart");
162
+ $this->xt->assign("chart_block", false);
163
+
164
+ $this->xt->assign("message", $this->noRecordsMessage());
165
+ $this->xt->assign( "message_class", "alert-warning");
166
+ }
167
+
168
+ if( !$this->show_message_block )
169
+ $this->hideElement("message");
170
+
171
+ if( $this->mobileTemplateMode() )
172
+ $this->xt->assign('tableinfomobile_block', true);
173
+
174
+
175
+ $this->assignChartElement();
176
+
177
+ $this->body['begin'].= GetBaseScriptsForPage( $this->isDisplayLoading );
178
+ if( !$this->isDashboardElement() && !$this->mobileTemplateMode() )
179
+ $this->body['begin'].= "<div id=\"search_suggest\" class=\"search_suggest\"></div>";
180
+
181
+ // assign body end
182
+ $this->body['end'] = XTempl::create_method_assignment( "assignBodyEnd", $this);
183
+
184
+ $this->xt->assignbyref('body', $this->body);
185
+ }
186
+
187
+ /**
188
+ * Set the chart xt variable
189
+ */
190
+ public function assignChartElement()
191
+ {
192
+ }
193
+
194
+ /**
195
+ *
196
+ */
197
+ public function prepareDetailsForEditViewPage()
198
+ {
199
+ $this->addButtonHandlers();
200
+
201
+ $this->xt->assign("body", $this->body);
202
+ $this->xt->assign("chart_block", true);
203
+ $this->xt->assign("message_block", true);
204
+ }
205
+
206
+ protected function getExtraAjaxPageParams()
207
+ {
208
+ $returnJSON = array();
209
+ if( $this->mode == REPORT_DETAILS )
210
+ {
211
+ $returnJSON['headerCont'] = $this->getProceedLink() . $returnJSON['headerCont'];
212
+ }
213
+
214
+ return $returnJSON;
215
+ }
216
+
217
+ public function beforeShowChart()
218
+ {
219
+ if( $this->eventsObject->exists("BeforeShowChart") )
220
+ $this->eventsObject->BeforeShowChart($this->xt, $this->templatefile, $this);
221
+ }
222
+
223
+ public function showPage()
224
+ {
225
+ $this->beforeShowChart();
226
+
227
+ if( $this->mode == CHART_DETAILS || $this->mode == CHART_DASHBOARD || $this->mode == CHART_DASHDETAILS )
228
+ {
229
+ $this->addControlsJSAndCSS();
230
+ $this->fillSetCntrlMaps();
231
+
232
+ $this->xt->assign("header", false);
233
+ $this->xt->assign("footer", false);
234
+
235
+ $this->body["begin"] = "";
236
+ $this->body["end"] = "";
237
+ $this->xt->assign("body", $this->body);
238
+
239
+ $this->displayAJAX($this->templatefile, $this->id + 1);
240
+ exit();
241
+ }
242
+
243
+ if( $this->mode == CHART_POPUPDETAILS ) //currently unused
244
+ {
245
+ $this->xt->assign("header", false);
246
+ $this->xt->assign("footer", false);
247
+ $this->body["begin"] = '';
248
+ $this->body["end"] = '';
249
+
250
+ $this->xt->prepare_template($this->templatefile);
251
+ $respArr = array();
252
+ $respArr['success'] = true;
253
+ $respArr['body'] = $this->xt->fetch_loaded("body");
254
+ $respArr['counter'] = postvalue('counter');
255
+ $this->xt->assign("container_master", false);
256
+
257
+ echo printJSON($respArr);
258
+ exit();
259
+ }
260
+
261
+ $this->display( $this->templatefile );
262
+ }
263
+
264
+ /**
265
+ *
266
+ */
267
+ function processGridTabs()
268
+ {
269
+ $ctChanged = parent::processGridTabs();
270
+ $_SESSION[ $this->sessionPrefix . "_chartTabWhere" ] = $this->getCurrentTabWhere();
271
+
272
+ return $ctChanged;
273
+ }
274
+
275
+ function gridTabsAvailable() {
276
+ return true;
277
+ }
278
+
279
+ function displayTabsInPage()
280
+ {
281
+ return $this->simpleMode()
282
+ || ( $this->mode == CHART_DETAILS && ($this->masterPageType == PAGE_VIEW || $this->masterPageType == PAGE_EDIT))
283
+ || $this->mode == CHART_DASHBOARD && $this->dashElementData["tabLocation"] == "body";
284
+ }
285
+
286
+ protected function getBodyMarkup( $templatefile )
287
+ {
288
+ if( $this->mode == CHART_DASHBOARD && $this->dashElementData["tabLocation"] == "body" )
289
+ return $this->fetchBlocksList( array( "above-grid_block", "grid_tabs", "grid_block" ) );
290
+
291
+ return parent::getBodyMarkup( $templatefile );
292
+ }
293
+
294
+ function element2Item( $name ) {
295
+ if( $name == "message" ) {
296
+ return array( "grid_message" );
297
+ }
298
+ if( $name == "chart" ) {
299
+ return array( "chart" );
300
+ }
301
+ return parent::element2Item( $name );
302
+ }
303
+
304
+ public function prepareDisplayDetails()
305
+ {
306
+ $resizeChart = true;
307
+ if( $this->mode == CHART_SIMPLE ||
308
+ $this->mode == CHART_DASHBOARD ||
309
+ $this->mode == CHART_DETAILS && ( $this->masterPageType == PAGE_VIEW || $this->masterPageType == PAGE_EDIT ) )
310
+ $resizeChart = false;
311
+
312
+ //set params for the 'xt_showchart' method showing the chart
313
+ $chartXtParams = array(
314
+ "id" => $this->id,
315
+ "table" => $this->tName,
316
+ "ctype" => $this->pSet->getChartType(),
317
+ "resize" => $resizeChart,
318
+ "chartName" => $this->shortTableName,
319
+ "chartPreview" => $this->mode !== CHART_SIMPLE && $this->mode != CHART_DASHBOARD
320
+ );
321
+
322
+ if( $this->mode == CHART_DASHBOARD || $this->mode == CHART_DASHDETAILS )
323
+ {
324
+ $chartXtParams["refreshTime"] = $this->dashElementData["reload"];
325
+ }
326
+
327
+ $this->prepareCharts();
328
+ $forms = array( "grid" );
329
+ $bodyContents = $this->fetchForms($forms);
330
+ $this->renderedBody = '<div id="detailPreview'.$this->id.'">'.$bodyContents.'</div>';
331
+ return;
332
+ }
333
+
334
+ public function showGridOnly()
335
+ {
336
+ echo $this->renderedBody;
337
+ }
338
+
339
+ function prepareCharts()
340
+ {
341
+ $chartXtParams = array(
342
+ "id" => $this->id,
343
+ // it shows if chart show details
344
+ "chartPreview" => $this->mode !== CHART_SIMPLE && $this->mode != CHART_DASHBOARD,
345
+ "stateLink" => $this->getStateUrlParams()
346
+ );
347
+
348
+ if( $this->dashTName && $this->mode == CHART_DASHBOARD )
349
+ {
350
+ $chartXtParams["dash"] = true;
351
+ $chartXtParams["dashTName"] = $this->dashTName;
352
+ $chartXtParams["dashElementName"] = $this->dashElementName;
353
+ $chartXtParams["dashPage"] = $this->dashPage;
354
+ }
355
+
356
+ $this->xt->assign_function("chart", "xt_showpdchart", $chartXtParams);
357
+ }
358
+
359
+ public static function readChartModeFromRequest()
360
+ {
361
+ $mode = postvalue("mode");
362
+ if( $mode == "listdetails" )
363
+ return CHART_DETAILS;
364
+ elseif( $mode == "listdetailspopup" )
365
+ return CHART_POPUPDETAILS;
366
+ elseif( $mode == "dashchart" )
367
+ return CHART_DASHBOARD;
368
+ elseif( $mode == "dashdetails" )
369
+ return CHART_DASHDETAILS;
370
+ else
371
+ return CHART_SIMPLE;
372
+ }
373
+ }
374
+ ?>
classes/chartpage_master.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class for list page with mode simple
4
+ *
5
+ */
6
+ class ChartPage_Master extends ChartPage
7
+ {
8
+ /**
9
+ * Constructor, set initial params
10
+ *
11
+ * @param array $params
12
+ */
13
+ function __construct(&$params)
14
+ {
15
+ // call parent constructor
16
+ parent::__construct($params);
17
+ }
18
+
19
+ public function getMasterHeading()
20
+ {
21
+ $this->xt->assign( "masterlist_title", true );
22
+ return $this->xt->fetch_loaded( "masterlist_title" );
23
+ }
24
+
25
+ public function preparePage()
26
+ {
27
+ if( !$this->masterRecordData || !$this->masterRecordData )
28
+ return;
29
+
30
+ $this->xt->assign("chart_block", true);
31
+ $this->assignChartElement();
32
+
33
+ $this->xt->assign("pagetitlelabel", $this->getPageTitle( $this->pageType, GoodFieldName($this->tName), $this->masterRecordData ));
34
+
35
+ $tKeys = $this->pSet->getTableKeys();
36
+ $keylink = "";
37
+
38
+
39
+ for($i = 0; $i < count($tKeys); $i ++) {
40
+ $keylink.= "&key".($i + 1)."=".runner_htmlspecialchars(rawurlencode(@$this->masterRecordData[$tKeys[$i]]));
41
+ }
42
+
43
+ $fields = $this->pSet->getMasterListFields();
44
+ $fields = array_merge( $fields, $tKeys);
45
+ foreach( $fields as $f )
46
+ {
47
+ $fieldClassStr = $this->fieldClass($f);
48
+ $this->xt->assign( GoodFieldName( $f ) . "_mastervalue", "<span class='". $fieldClassStr ."'>".$this->showDBValue( $f, $this->masterRecordData, $keylink)."</span>");
49
+ $this->xt->assign( GoodFieldName( $f ) . "_class", $fieldClassStr); // add class for field header as field value
50
+ }
51
+
52
+ if( $this->pageLayout )
53
+ $this->xt->assign("pageattrs", 'class="'.$this->pageLayout->style." page-".$this->pageLayout->name.'"');
54
+
55
+ if( $this->pageLayout )
56
+ $this->xt->assign("pageattrs", 'class="'.$this->pageLayout->style." page-".$this->pageLayout->name.'"');
57
+ }
58
+
59
+ public function showMaster( $params )
60
+ {
61
+ if( !$this->masterRecordData || !$this->masterRecordData )
62
+ return;
63
+
64
+ $this->xt->load_template( $this->templatefile );
65
+
66
+ $this->xt->assign( "masterlist_title", false );
67
+ $this->xt->display_loaded();
68
+ }
69
+ }
70
+
71
+ ?>
classes/charts.php ADDED
@@ -0,0 +1,2033 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chart
3
+ {
4
+ protected $header;
5
+ protected $footer;
6
+
7
+ protected $y_axis_label;
8
+
9
+ protected $strLabel;
10
+
11
+ protected $arrDataLabels = array();
12
+ protected $arrDataSeries = array();
13
+
14
+ protected $chrt_array = array();
15
+ public $webchart;
16
+ protected $cname;
17
+
18
+ protected $table_type;
19
+
20
+ protected $cipherer = null;
21
+ protected $pSet = null;
22
+ protected $searchClauseObj = null;
23
+
24
+ protected $sessionPrefix = "";
25
+
26
+ protected $detailTablesData = array();
27
+
28
+ protected $pageId;
29
+
30
+ /**
31
+ * A flag helping to detect if to apply
32
+ * 'details' functionality to the chart
33
+ */
34
+ protected $showDetails = true;
35
+
36
+ /**
37
+ * Flag if the chart in master or details preview mode
38
+ * @type Boolean
39
+ */
40
+ protected $chartPreview = false;
41
+
42
+ /**
43
+ * It indicates if chart is shown on a dashboard
44
+ */
45
+ protected $dashChart = false;
46
+
47
+ /**
48
+ * It indicates if first point selected
49
+ */
50
+ protected $dashChartFirstPointSelected = false;
51
+
52
+ protected $detailMasterKeys = "";
53
+
54
+ /**
55
+ * Dashboard table name
56
+ * It's set up if chart is shown on a dashboard only
57
+ */
58
+ protected $dashTName = "";
59
+
60
+ /**
61
+ * Dashboard element name
62
+ * It's set up if chart is shown on a dashboard only
63
+ */
64
+ protected $dashElementName = "";
65
+
66
+ /**
67
+ * @type Connection
68
+ */
69
+ protected $connection;
70
+
71
+ /**
72
+ *
73
+ */
74
+ protected $_2d;
75
+
76
+ /**
77
+ *
78
+ */
79
+ protected $noRecordsFound = false;
80
+
81
+ /**
82
+ *
83
+ */
84
+ protected $singleSeries = false;
85
+
86
+ protected $masterKeysReq;
87
+ protected $masterTable;
88
+
89
+ /**
90
+ * DataSource
91
+ */
92
+ protected $dataSource = null;
93
+ protected $tName = "";
94
+
95
+
96
+ function __construct( &$ch_array, $param )
97
+ {
98
+ global $strTableName;
99
+
100
+ $this->webchart = $param["webchart"];
101
+
102
+ if( $this->webchart )
103
+ $this->chrt_array = Convert_Old_Chart($ch_array);
104
+ else
105
+ $this->chrt_array = $ch_array;
106
+
107
+ $this->tName = $this->chrt_array['tables'][0];
108
+
109
+ // #10461, $this->setConnection(); needs to be called after value is assigned to $this->webchart
110
+ $this->setConnection();
111
+
112
+ $this->pSet = new ProjectSettings( $this->tName, PAGE_CHART );
113
+ $this->showDetails = $param['showDetails'];
114
+ if( $this->showDetails )
115
+ {
116
+ $this->detailTablesData = $this->pSet->getDetailTablesArr();
117
+ for($i = 0; $i < count($this->detailTablesData); $i ++)
118
+ {
119
+ $strPerm = GetUserPermissions($this->detailTablesData[$i]['dDataSourceTable']);
120
+ if ( strpos($strPerm, "S") === false )
121
+ unset($this->detailTablesData[$i]);
122
+ }
123
+ }
124
+
125
+ $this->table_type = $this->chrt_array["table_type"];
126
+ if( !$this->table_type )
127
+ $this->table_type = "project";
128
+
129
+ if( $this->table_type == "project" ) {
130
+ // project table
131
+ $this->dataSource = getDataSource( $this->tName, $this->pSet, $this->connection );
132
+ } else {
133
+ // db-table-based webchart
134
+ $this->dataSource = getWebDataSource( $this->chrt_array );
135
+ }
136
+
137
+ $this->pageId = $param["pageId"];
138
+ $this->chrt_array["appearance"]["autoupdate"] = false;
139
+
140
+
141
+ $this->cname = $param["cname"];
142
+
143
+ $this->sessionPrefix = $this->chrt_array['tables'][0];
144
+
145
+ $this->masterTable = $param["masterTable"];
146
+ $this->masterKeysReq = $param["masterKeysReq"];
147
+
148
+ // true if chart has master
149
+ $this->chartPreview = $param["chartPreview"];
150
+ $this->dashChart = $param["dashChart"];
151
+
152
+ if( $this->dashChart )
153
+ {
154
+ $this->dashTName = $param["dashTName"];
155
+ $this->dashElementName = $param["dashElementName"];
156
+ $this->sessionPrefix = $this->dashTName."_".$this->sessionPrefix;
157
+ }
158
+
159
+ if( !$this->webchart && !$this->chartPreview && isset( $_SESSION[ $this->sessionPrefix.'_advsearch' ] ) )
160
+ $this->searchClauseObj = SearchClause::UnserializeObject( $_SESSION[ $this->sessionPrefix.'_advsearch' ] );
161
+
162
+ if( $this->searchClauseObj )
163
+ RunnerContext::pushSearchContext( $this->searchClauseObj );
164
+
165
+ if( $this->isProjectDB() ) {
166
+ $this->cipherer = new RunnerCipherer( $this->tName );
167
+ }
168
+
169
+ $this->setBasicChartProp();
170
+
171
+ if( tableEventExists("UpdateChartSettings", $strTableName) )
172
+ {
173
+ $eventObj = getEventObject( $strTableName );
174
+ $eventObj->UpdateChartSettings( $this );
175
+ }
176
+ }
177
+
178
+ /**
179
+ * @param Array params
180
+ */
181
+ protected function setSpecParams( $params )
182
+ {
183
+ if( $params['name'] == "" )
184
+ return;
185
+
186
+ if( $this->table_type != "db" )
187
+ $this->arrDataSeries[] = $params['agr_func'] ? $params['label'] : $params['name'];
188
+ else {
189
+ $this->arrDataSeries[] = $params['table']."_".$params['name'];
190
+ // $this->arrDataSeries[] = $params['name'];
191
+ }
192
+ }
193
+
194
+ /**
195
+ * @param Array params
196
+ * @param String gTableName
197
+ */
198
+ protected function setDataLabels( $params, $gTableName )
199
+ {
200
+ $chartType = $this->chrt_array["chart_type"]["type"];
201
+ if( $this->table_type == "project" && !$this->webchart )
202
+ {
203
+ if( $chartType != "candlestick" && $chartType != "ohlc" )
204
+ $this->arrDataLabels[] = GetFieldLabel( $gTableName, GoodFieldName($params['name']) );
205
+ else
206
+ $this->arrDataLabels[] = GetFieldLabel( $gTableName, GoodFieldName($params['ohlcOpen']) ) ;
207
+ }
208
+ else
209
+ {
210
+ if( !$params['label'] )
211
+ {
212
+ if( $chartType != "candlestick" && $chartType != "ohlc" )
213
+ $this->arrDataLabels[] = $params['name'];
214
+ else
215
+ $this->arrDataLabels[] = $params['ohlcOpen'];
216
+ }
217
+ else
218
+ $this->arrDataLabels[] = $params['label'];
219
+ }
220
+ }
221
+
222
+ /**
223
+ *
224
+ */
225
+ protected function setBasicChartProp()
226
+ {
227
+ $this->header = $this->chrt_array['appearance']['head'];
228
+ $this->header = $this->header ? $this->header : '';
229
+
230
+ $this->footer = $this->chrt_array['appearance']['foot'];
231
+ $this->footer = $this->footer ? $this->footer : '';
232
+
233
+ for ( $i = 0; $i<count($this->chrt_array['parameters']) - 1; $i++)
234
+ {
235
+ $this->setSpecParams( $this->chrt_array['parameters'][$i] );
236
+ $this->setDataLabels( $this->chrt_array['parameters'][$i], GoodFieldName( $this->chrt_array['tables'][0] ) );
237
+ }
238
+
239
+ if( $this->chrt_array["chart_type"]["type"] != "gauge" )
240
+ {
241
+ $chartParams = $this->chrt_array['parameters'];
242
+ $params = $chartParams[ count($chartParams) - 1 ];
243
+
244
+ if( $this->table_type != "db" )
245
+ $this->strLabel = $params['name'];
246
+ else {
247
+ // $this->strLabel = $params['name'];
248
+ $this->strLabel = $params['agr_func'] ? $params['agr_func']."_".$params['table']."_".$params['name']: $params['table']."_".$params['name'];
249
+ }
250
+ }
251
+
252
+ if( count( $this->arrDataLabels ) == 1 )
253
+ $this->y_axis_label = $this->arrDataLabels[0];
254
+ else
255
+ $this->y_axis_label = $this->chrt_array['appearance']['y_axis_label'];
256
+ }
257
+
258
+
259
+ protected function getMasterCondition() {
260
+ if( $this->dashChart )
261
+ return null;
262
+
263
+ $detailKeysByM = $this->pSet->getDetailKeysByMasterTable( $this->masterTable );
264
+ if( !$detailKeysByM )
265
+ return null;
266
+
267
+ $conditions = array();
268
+ for( $i = 0; $i < count( $detailKeysByM ); ++$i ) {
269
+ $conditions[] = DataCondition::FieldEquals( $detailKeysByM[ $i ], $this->masterKeysReq[ $i + 1 ] );
270
+ }
271
+
272
+ return DataCondition::_And( $conditions );
273
+ }
274
+
275
+ /**
276
+ * Get datasource command
277
+ */
278
+ public function getSubsetDataCommand( $ignoreFilterField = "" ) {
279
+ $dc = new DsCommand();
280
+
281
+ $dc->filter = DataCondition::_And( array(
282
+ Security::SelectCondition( "S", $this->pSet ),
283
+ $this->getMasterCondition()
284
+ ));
285
+
286
+ if( !$this->chartPreview && $this->searchClauseObj ) {
287
+ $search = $this->searchClauseObj->getSearchDataCondition();
288
+ $filter = $this->searchClauseObj->getFilterCondition( $this->pSet );
289
+
290
+ $dc->filter = DataCondition::_And( array( $dc->filter, $search, $filter ) );
291
+ }
292
+
293
+ // where tabs
294
+ if( $_SESSION[ $this->sessionPrefix . "_chartTabWhere" ] ) {
295
+ $dc->filter = DataCondition::_And( array(
296
+ $dc->filter,
297
+ DataCondition::SQLCondition( $_SESSION[ $this->sessionPrefix . "_chartTabWhere" ] )
298
+ ));
299
+ }
300
+
301
+ require_once( getabspath('classes/orderclause.php') );
302
+ $orderObject = new OrderClause( $this->pSet, $this->cipherer, $this->sessionPrefix, $this->connection );
303
+ $dc->order = $orderObject->getOrderFields();
304
+
305
+ if( $this->pSet->getRecordsLimit() )
306
+ $dc->reccount = $this->pSet->getRecordsLimit();
307
+
308
+ if( $this->pSet->groupChart() )
309
+ $dc->totals = $this->getGroupChartCommandTotals();
310
+
311
+ return $dc;
312
+ }
313
+
314
+ /**
315
+ * Get ds command totals
316
+ * total fields appear in the same order
317
+ they do in an original orderby clause
318
+ * @return array
319
+ */
320
+ protected function getGroupChartCommandTotals() {
321
+ $totals = array();
322
+ // label field
323
+ $totals[] = array(
324
+ "alias" => $this->pSet->chartLabelField(),
325
+ "field" => $this->pSet->chartLabelField(),
326
+ "modifier" => $this->pSet->chartLabelInterval()
327
+ );
328
+
329
+ $series = $this->pSet->chartSeries();
330
+ foreach( $series as $s ) {
331
+ $totals[] = array(
332
+ "alias" => $s["field"],
333
+ "field" => $s["field"],
334
+ "total" => strtolower( $s["total"] )
335
+ );
336
+ }
337
+
338
+ $orderInfo = $this->pSet->getOrderIndexes();
339
+ if( !$orderInfo )
340
+ return $totals;
341
+
342
+ $fields = array();
343
+ foreach( $orderInfo as $o ) {
344
+ $fields[] = $this->pSet->GetFieldByIndex( $o[0] );
345
+ }
346
+
347
+ foreach( $totals as $idx => $t ) {
348
+ if( !in_array( $t["field"], $fields ) )
349
+ $fields[] = $t["field"];
350
+
351
+ foreach( $orderInfo as $o ) {
352
+ $fieldIdx = $this->pSet->getFieldIndex( $t["field"] );
353
+ if( $fieldIdx == $o[0] ) {
354
+ $totals[ $idx ]["direction"] = $o[1];
355
+ break;
356
+ }
357
+ }
358
+ }
359
+
360
+ $_totals = array();
361
+ foreach( $fields as $field ) {
362
+ foreach( $totals as $t ) {
363
+ if( $t["field"] == $field ) {
364
+ $_totals[] = $t;
365
+ }
366
+ }
367
+ }
368
+
369
+ return $_totals;
370
+ }
371
+
372
+ /**
373
+ * Check for a web chart if it's based on the project table
374
+ * @return Boolean
375
+ */
376
+ protected function isProjectDB()
377
+ {
378
+ if( !$this->webchart )
379
+ return true;
380
+
381
+ if("public.kbarticles" == $this->chrt_array['tables'][0])
382
+ return true;
383
+ if("public.kbcategories" == $this->chrt_array['tables'][0])
384
+ return true;
385
+ if("public.kbcomments" == $this->chrt_array['tables'][0])
386
+ return true;
387
+ if("public.kbusers" == $this->chrt_array['tables'][0])
388
+ return true;
389
+ if("public.kbarticles" == $this->chrt_array['tables'][0])
390
+ return true;
391
+ if("public.faicons" == $this->chrt_array['tables'][0])
392
+ return true;
393
+ if("public.kbcomments" == $this->chrt_array['tables'][0])
394
+ return true;
395
+ if("public.fasis_chat_history" == $this->chrt_array['tables'][0])
396
+ return true;
397
+ if("public.diamondprice" == $this->chrt_array['tables'][0])
398
+ return true;
399
+ if("public.products" == $this->chrt_array['tables'][0])
400
+ return true;
401
+ if("public.items" == $this->chrt_array['tables'][0])
402
+ return true;
403
+ if("public.appointments" == $this->chrt_array['tables'][0])
404
+ return true;
405
+ if("public.chat_history" == $this->chrt_array['tables'][0])
406
+ return true;
407
+ if("public.chat_users" == $this->chrt_array['tables'][0])
408
+ return true;
409
+ if("public.chat_settings" == $this->chrt_array['tables'][0])
410
+ return true;
411
+ if("public.chat_files" == $this->chrt_array['tables'][0])
412
+ return true;
413
+ if("public.chat_groups" == $this->chrt_array['tables'][0])
414
+ return true;
415
+ if("public.chat_peopletype" == $this->chrt_array['tables'][0])
416
+ return true;
417
+ if("public.chat_timezone" == $this->chrt_array['tables'][0])
418
+ return true;
419
+ return false;
420
+ }
421
+
422
+ /**
423
+ * Set the 'connection' property #9875
424
+ */
425
+ protected function setConnection()
426
+ {
427
+ global $cman;
428
+
429
+ if($this->isProjectDB())
430
+ $this->connection = $cman->byTable( $this->tName );
431
+ else
432
+ $this->connection = $cman->getDefault();
433
+ }
434
+
435
+ public function setFooter($name)
436
+ {
437
+ $this->footer = $name;
438
+ }
439
+
440
+ public function getFooter()
441
+ {
442
+ return $this->footer;
443
+ }
444
+
445
+ public function setHeader($name)
446
+ {
447
+ $this->header = $name;
448
+ }
449
+
450
+ public function getHeader()
451
+ {
452
+ return $this->header;
453
+ }
454
+
455
+ public function setLabelField($name)
456
+ {
457
+ $this->strLabel = $name;
458
+ }
459
+
460
+ public function getLabelField()
461
+ {
462
+ return $this->strLabel;
463
+ }
464
+
465
+ /**
466
+ * @return String
467
+ */
468
+ protected function getDetailedTooltipMessage()
469
+ {
470
+ if( !$this->showDetails || !$this->detailTablesData )
471
+ return "";
472
+
473
+ $showClickHere = true;
474
+
475
+ if( $this->dashChart )
476
+ {
477
+ $showClickHere = false;
478
+
479
+ $pDSet = new ProjectSettings( $this->dashTName );
480
+ $arrDElem = $pDSet->getDashboardElements();
481
+ foreach($arrDElem as $elem)
482
+ {
483
+ if( $elem["table"] == $this->chrt_array['tables'][0] && !!$elem["details"] )
484
+ $showClickHere = true;
485
+ }
486
+ }
487
+
488
+ if( $showClickHere )
489
+ {
490
+ $tableCaption = GetTableCaption( $this->detailTablesData[0]['dDataSourceTable'] );
491
+ $tableCaption = $tableCaption ? $tableCaption : $this->detailTablesData[0]['dDataSourceTable'];
492
+
493
+ return "\nClick here to see ".$tableCaption." details";
494
+ }
495
+
496
+ return "";
497
+ }
498
+
499
+ /**
500
+ * @return String
501
+ */
502
+ protected function getNoDataMessage()
503
+ {
504
+ if( !$this->noRecordsFound )
505
+ return "";
506
+
507
+ if( !$this->searchClauseObj )
508
+ return "No data yet.";
509
+
510
+ if( $this->searchClauseObj->isSearchFunctionalityActivated() )
511
+ return "No results found.";
512
+
513
+ return "No data yet.";
514
+ }
515
+
516
+ /**
517
+ *
518
+ */
519
+ public function write()
520
+ {
521
+ $data = array();
522
+ $chart = array();
523
+
524
+ $this->setTypeSpecChartSettings( $chart );
525
+ if ( @$this->chrt_array["appearance"]["color71"] != "" || @$this->chrt_array["appearance"]["color91"] != "" )
526
+ $chart["background"] = array();
527
+ if ( @$this->chrt_array["appearance"]["color71"] != "" )
528
+ $chart["background"]["fill"] = "#".$this->chrt_array["appearance"]["color71"];
529
+
530
+ if ( @$this->chrt_array["appearance"]["color91"] != "" )
531
+ $chart["background"]["stroke"] = "#".$this->chrt_array["appearance"]["color91"];
532
+
533
+ if( $this->noRecordsFound )
534
+ {
535
+ $data["noDataMessage"] = $this->getNoDataMessage();
536
+ echo my_json_encode( $data );
537
+ return;
538
+ }
539
+
540
+ // animation
541
+ if( $this->chrt_array["appearance"]["sanim"] == "true" && $this->chrt_array["appearance"]["autoupdate"] != "true" ) // update?
542
+ $chart["animation"] = array("enabled" => "true", "duration" => 1000);
543
+
544
+ // legend
545
+ if( $this->chrt_array['appearance']['slegend'] == "true" && !$this->chartPreview )
546
+ $chart["legend"] = array("enabled" => "true");
547
+ else
548
+ $chart["legend"] = array("enabled" => false);
549
+
550
+ $chart["credits"] = false;
551
+ // title/header
552
+ $chart["title"] = array("enabled" => "true", "text" => $this->header);
553
+ if ( @$this->chrt_array["appearance"]["color101"] != "" )
554
+ $chart["title"]["fontColor"] = "#".$this->chrt_array["appearance"]["color101"];
555
+
556
+ // assign and display
557
+ $data["chart"] = $chart;
558
+ echo my_json_encode( $data );
559
+ }
560
+
561
+ /**
562
+ * A stub
563
+ * @param &Array chart
564
+ */
565
+ protected function setTypeSpecChartSettings( &$chart )
566
+ {
567
+ }
568
+
569
+ /**
570
+ * @return Array
571
+ */
572
+ protected function getGrids()
573
+ {
574
+ $grids = array();
575
+
576
+ if($this->chrt_array["appearance"]["sgrid"] == "true")
577
+ {
578
+ $stroke = @$this->chrt_array["appearance"]["color121"] != "" ? "#" . $this->chrt_array["appearance"]["color121"] : "#ddd";
579
+
580
+ $grid0 = array(
581
+ "enabled" => true,
582
+ "drawLastLine" => false,
583
+ "stroke" => $stroke,
584
+ "scale" => 0,
585
+ "axis" => 0
586
+ );
587
+
588
+ if ( @$this->chrt_array["appearance"]["color81"] != "" )
589
+ {
590
+ $dataPlotBackgroundColor = "#" . $this->chrt_array["appearance"]["color81"];
591
+ $grid0["oddFill"] = $dataPlotBackgroundColor;
592
+ $grid0["evenFill"] = $dataPlotBackgroundColor;
593
+ }
594
+
595
+ $grids[] = $grid0;
596
+
597
+ $grids[] = array(
598
+ "enabled" => true,
599
+ "drawLastLine" => false,
600
+ "stroke" => $stroke,
601
+ "axis" => 1
602
+ );
603
+ }
604
+
605
+ return $grids;
606
+ }
607
+
608
+ /**
609
+ * @param String fieldName
610
+ * @param Array data
611
+ * @return String
612
+ */
613
+ protected function labelFormat($fieldName, $data, $truncated = true)
614
+ {
615
+ if( !$fieldName )
616
+ return "";
617
+
618
+ if( $this->table_type == "db" && !!$this->chrt_array['customLabels'] )
619
+ $fieldName = $this->chrt_array['customLabels'][ $fieldName ];
620
+
621
+ include_once getabspath('classes/controls/ViewControlsContainer.php');
622
+ $viewControls = new ViewControlsContainer( $this->pSet, PAGE_CHART );
623
+ if( $this->pSet->groupChart() ) {
624
+ $interval = $this->pSet->chartLabelInterval();
625
+ if( $interval ) {
626
+ $fType = $this->pSet->getFieldType( $fieldName );
627
+ return RunnerPage::formatGroupValueStatic( $fieldName, $interval, $data[ $fieldName ], $this->pSet, $viewControls, false );
628
+ }
629
+ }
630
+ $value = $viewControls->showDBValue( $fieldName, $data, "", "", false );
631
+
632
+ if( $truncated && strlen($value) > 50 )
633
+ $value = runner_substr($value, 0, 47)."...";
634
+
635
+ return $value;
636
+ }
637
+
638
+ protected function beforeQueryEvent( &$dc ) {
639
+ $eventsObject = getEventObject( $this->pSet->getTableName() );
640
+
641
+ // ASP conversion requires these checks be separate
642
+ if( !$eventsObject )
643
+ return;
644
+ if( !$eventsObject->exists("BeforeQueryChart") ) {
645
+ return;
646
+ }
647
+
648
+ $prep = $this->dataSource->prepareSQL( $dc );
649
+ $where = $prep["where"];
650
+ $sql = $prep["sql"];
651
+ $order = $prep["order"];
652
+
653
+ // call Before Query event
654
+ $eventsObject->BeforeQueryChart( $sql, $where, $order );
655
+
656
+ if( $sql != $prep["sql"] )
657
+ $this->dataSource->overrideSQL( $dc, $sql );
658
+ else {
659
+ if( $where != $prep["where"] )
660
+ $this->dataSource->overrideWhere( $dc, $where );
661
+ if( $order != $prep["order"] )
662
+ $this->dataSource->overrideOrder( $dc, $order );
663
+ }
664
+ }
665
+
666
+ /**
667
+ * @return Array
668
+ */
669
+ public function get_data()
670
+ {
671
+ $data = array();
672
+ $clickdata = array();
673
+ for ( $i = 0; $i < count($this->arrDataSeries); $i++ )
674
+ {
675
+ $data[$i] = array();
676
+ $clickdata[$i] = array();
677
+ }
678
+
679
+ $dc = $this->getSubsetDataCommand();
680
+ $this->beforeQueryEvent( $dc );
681
+
682
+ if( $this->pSet->groupChart() ) {
683
+ $rs = $this->dataSource->getTotals( $dc );
684
+ } else {
685
+ $rs = $this->dataSource->getList( $dc );
686
+ }
687
+ if( !$rs ) {
688
+ showError( $this->dataSource->lastError() );
689
+ }
690
+
691
+ $row = $rs->fetchAssoc();
692
+ if( $this->cipherer )
693
+ $row = $this->cipherer->DecryptFetchedArray( $row );
694
+
695
+ if( !$row )
696
+ $this->noRecordsFound = true;
697
+
698
+ while ($row)
699
+ {
700
+ for ( $i = 0; $i < count($this->arrDataSeries); $i++ )
701
+ {
702
+ $data[$i][] = $this->getPoint($i, $row);
703
+
704
+ $strLabelFormat = $this->labelFormat( $this->strLabel, $row );
705
+ $clickdata[$i][] = $this->getActions( $row , $this->arrDataSeries[$i], $strLabelFormat );
706
+ }
707
+
708
+ $row = $rs->fetchAssoc();
709
+ if( $this->cipherer )
710
+ $row = $this->cipherer->DecryptFetchedArray( $row );
711
+ }
712
+
713
+ $series = array();
714
+ for ( $i = 0; $i < count($this->arrDataSeries); $i++ )
715
+ {
716
+ $series[] = $this->getSeriesData( $this->arrDataLabels[$i], $data[$i], $clickdata[$i], $i, count($this->arrDataSeries) > 1 );
717
+ }
718
+
719
+ return $series;
720
+ }
721
+
722
+ /**
723
+ * @param Number seriesNumber
724
+ * @param Array row
725
+ * @return Array
726
+ */
727
+ protected function getPoint( $seriesNumber, $row ) {
728
+ $strLabelFormat = $this->labelFormat( $this->strLabel, $row );
729
+
730
+ include_once getabspath('classes/controls/ViewControlsContainer.php');
731
+ $viewControls = new ViewControlsContainer( $this->pSet, PAGE_CHART );
732
+
733
+ if( $this->table_type != "db" || !$this->chrt_array['customLabels'] ) {
734
+ $strDataSeries = $row[ $this->arrDataSeries[ $seriesNumber ] ];
735
+ $fieldName = $this->arrDataSeries[ $seriesNumber ];
736
+ $formattedValue = $viewControls->showDBValue( $fieldName, $row, "", "", false );
737
+ } else {
738
+ $strDataSeries = $row[ $this->chrt_array['customLabels'][ $this->arrDataSeries[ $seriesNumber ] ] ];
739
+ $fieldName = $this->chrt_array['customLabels'][ $this->arrDataSeries[ $seriesNumber ] ];
740
+ $formattedValue = $viewControls->showDBValue( $fieldName, $row, "", "", false );
741
+ }
742
+
743
+ return array(
744
+ "x" => $strLabelFormat,
745
+ "value" => (double)str_replace(",", ".", $strDataSeries),
746
+ "viewAsValue" => $formattedValue
747
+ );
748
+ }
749
+
750
+ /**
751
+ * @param String name
752
+ * @param Array pointsData
753
+ * @param Array clickData
754
+ * @param Number seriesNumber
755
+ * @param Boolean multiSeries (optional)
756
+ * @return Array
757
+ */
758
+ protected function getSeriesData( $name, $pointsData, $clickData, $seriesNumber, $multiSeries = true )
759
+ {
760
+ $data = array(
761
+ "name" => $name,
762
+ "data" => $pointsData,
763
+ "xScale" => "0",
764
+ "yScale" => "1",
765
+ "seriesType" => $this->getSeriesType($seriesNumber)
766
+ );
767
+
768
+ $data["labels"] = array(
769
+ "enabled" => $this->chrt_array["appearance"]["sval"] == "true",
770
+ "format" => "{%viewAsValue}"
771
+ );
772
+
773
+ if ( @$this->chrt_array["appearance"]["color61"] != "" )
774
+ $data["labels"]["fontColor"] = "#".$this->chrt_array["appearance"]["color61"];
775
+
776
+ if( $clickData && $this->detailTablesData )
777
+ $data["clickData"] = $clickData;
778
+
779
+ $data["tooltip"] = $this->getSeriesTooltip( $multiSeries );
780
+
781
+ return $data;
782
+ }
783
+
784
+ /**
785
+ * @param Boolean $multiSeries
786
+ * @return Array
787
+ */
788
+ protected function getSeriesTooltip( $multiSeries ) {
789
+ return array(
790
+ "enabled" => true,
791
+ "format" => "{%seriesName}: {%viewAsValue}". $this->getDetailedTooltipMessage(),
792
+ );
793
+ }
794
+
795
+ /**
796
+ * @return String
797
+ */
798
+ protected function getSeriesType($seriesNumber)
799
+ {
800
+ return "column";
801
+ }
802
+
803
+ /**
804
+ * @deprecated
805
+ * @param String str
806
+ * @return String
807
+ */
808
+ protected function chart_xmlencode($str)
809
+ {
810
+ return str_replace(array("&","<",">","\""),array("&amp;","&lt;","&gt;","&quot;"),$str);
811
+ }
812
+
813
+ /**
814
+ * Get a 'point click' action data
815
+ * @param Array data
816
+ * @param Number seriesId
817
+ * @param Number pointId
818
+ * @return Array
819
+ */
820
+ protected function getActions( $data, $seriesId, $pointId )
821
+ {
822
+ global $strTableName;
823
+
824
+ if( !$this->detailTablesData )
825
+ return null;
826
+
827
+ if ( $this->dashChart )
828
+ {
829
+ $masterKeysArr = array();
830
+ foreach ( $this->detailTablesData as $detailId => $detail )
831
+ {
832
+ foreach( $detail['masterKeys'] as $idx => $mk )
833
+ {
834
+ $masterKeysArr[ $detail['dDataSourceTable'] ] = array( 'masterkey'.($idx + 1) => $data[ $mk ] );
835
+ }
836
+ }
837
+
838
+ if (!$this->dashChartFirstPointSelected)
839
+ {
840
+ $this->dashChartFirstPointSelected = true;
841
+ $this->detailMasterKeys = my_json_encode( $masterKeysArr );
842
+ }
843
+
844
+ return array( "masterKeys" => $masterKeysArr, "seriesId" => $seriesId, "pointId" => $pointId );
845
+ }
846
+
847
+ // The one detail table is allowed for a chart page only
848
+ $detailTableData = $this->detailTablesData[0];
849
+ $masterquery = "mastertable=".rawurlencode( $strTableName );
850
+ foreach( $detailTableData['masterKeys'] as $idx => $mk )
851
+ {
852
+ $masterquery.= "&masterkey".($idx + 1)."=".rawurlencode( $data[ $mk ] );
853
+ }
854
+
855
+ return array( "url" => GetTableLink( $detailTableData['dShortTable'], $detailTableData['dType'], $masterquery ) );
856
+ }
857
+
858
+ protected function getLogarithm()
859
+ {
860
+ if( $this->chrt_array["appearance"]["slog"] == "true" )
861
+ return true;
862
+ return false;
863
+ }
864
+ }
865
+
866
+
867
+ class Chart_Bar extends Chart
868
+ {
869
+ protected $stacked;
870
+ protected $bar;
871
+
872
+ function __construct( &$ch_array, $param )
873
+ {
874
+ parent::__construct( $ch_array, $param );
875
+
876
+ $this->stacked = $param["stacked"];
877
+ $this->_2d = $param["2d"];
878
+ $this->bar = $param["bar"];
879
+ }
880
+
881
+ /**
882
+ * @return String
883
+ */
884
+ protected function getSeriesType($seriesNumber)
885
+ {
886
+ if($this->bar)
887
+ return "bar";
888
+ else
889
+ return "column";
890
+ }
891
+
892
+ /**
893
+ * @param &Array chart
894
+ */
895
+ protected function setTypeSpecChartSettings( &$chart )
896
+ {
897
+ $chart["series"] = $this->get_data();
898
+
899
+ $chart["scales"] = $this->getScales();
900
+ $chart["logarithm"] = parent::getLogarithm();
901
+
902
+ if( $this->bar )
903
+ $chart["type"] = "bar";
904
+ else
905
+ $chart["type"] = "column";
906
+
907
+ if( !$this->_2d )
908
+ $chart["type"] .= "-3d";
909
+
910
+ $chart["xScale"] = 0;
911
+ $chart["yScale"] = 1;
912
+
913
+ // grid
914
+ $chart["grids"] = $this->getGrids();
915
+
916
+
917
+ // Y-axis label
918
+ $chart["yAxes"] = array(
919
+ array(
920
+ "enabled" => "true",
921
+ "title" => $this->y_axis_label
922
+ ));
923
+
924
+ // X-axis label
925
+ $chart["xAxes"] = array(
926
+ array(
927
+ "enabled" => "true",
928
+ "title" => array( 'text' => $this->footer ),
929
+ "labels" => array( "enabled" => $this->chrt_array["appearance"]["sname"] == "true" )
930
+ ));
931
+
932
+ if ( @$this->chrt_array["appearance"]["color51"] != "" )
933
+ $chart["xAxes"][0]["labels"]["fontColor"] = "#".$this->chrt_array["appearance"]["color51"];
934
+
935
+ if ( @$this->chrt_array["appearance"]["color111"] != "" )
936
+ $chart["xAxes"][0]["title"]["fontColor"] = "#".$this->chrt_array["appearance"]["color111"];
937
+
938
+ if ( @$this->chrt_array["appearance"]["color131"] != "" )
939
+ $chart["xAxes"][0]["stroke"] = "#".$this->chrt_array["appearance"]["color131"];
940
+
941
+ if ( @$this->chrt_array["appearance"]["color141"] != "" )
942
+ $chart["yAxes"][0]["stroke"] = "#".$this->chrt_array["appearance"]["color141"];
943
+ }
944
+
945
+ /**
946
+ * "scales"
947
+ * @return Array
948
+ */
949
+ protected function getScales()
950
+ {
951
+ if($this->stacked || $this->chrt_array["appearance"]["slog"] == "true")
952
+ {
953
+ $arr = array();
954
+ if( $this->stacked )
955
+ $arr["stackMode"] = "value";
956
+
957
+ if( $this->chrt_array["appearance"]["slog"] == "true" )
958
+ {
959
+ $arr["logBase"] = 10;
960
+ $arr["type"] = "log";
961
+ };
962
+
963
+ return array(
964
+ array("names" => array()),
965
+ $arr
966
+ );
967
+ }
968
+
969
+ return array();
970
+ }
971
+ }
972
+
973
+ class Chart_Line extends Chart
974
+ {
975
+ protected $type_line;
976
+
977
+
978
+ function __construct( &$ch_array, $param )
979
+ {
980
+ parent::__construct( $ch_array, $param );
981
+
982
+ $this->type_line = $param["type_line"];
983
+ }
984
+
985
+ /**
986
+ * @param &Array chart
987
+ */
988
+ protected function setTypeSpecChartSettings( &$chart )
989
+ {
990
+ $chart["series"] = $this->get_data();
991
+ $chart["type"] = "line";
992
+
993
+ $chart["xScale"] = 0;
994
+ $chart["yScale"] = 1;
995
+ $chart["grids"] = $this->getGrids();
996
+ $chart["logarithm"] = parent::getLogarithm();
997
+ $chart["tooltip"] = array("displayMode" => "single");
998
+
999
+ $chart["yAxes"] = array(
1000
+ array( "enabled" => "true", "title" => $this->y_axis_label )
1001
+ );
1002
+
1003
+ $chart["xAxes"] = array(
1004
+ array(
1005
+ "enabled" => "true",
1006
+ "title" => array( 'text' => $this->footer ),
1007
+ "labels" => array( "enabled" => $this->chrt_array["appearance"]["sname"] == "true" )
1008
+ ));
1009
+
1010
+ if ( @$this->chrt_array["appearance"]["color51"] != "" )
1011
+ $chart["xAxes"][0]["labels"]["fontColor"] = "#".$this->chrt_array["appearance"]["color51"];
1012
+
1013
+ if ( @$this->chrt_array["appearance"]["color111"] != "" )
1014
+ $chart["xAxes"][0]["title"]["fontColor"] = "#".$this->chrt_array["appearance"]["color111"];
1015
+
1016
+ if ( @$this->chrt_array["appearance"]["color131"] != "" )
1017
+ $chart["xAxes"][0]["stroke"] = "#".$this->chrt_array["appearance"]["color131"];
1018
+
1019
+ if ( @$this->chrt_array["appearance"]["color141"] != "" )
1020
+ $chart["yAxes"][0]["stroke"] = "#".$this->chrt_array["appearance"]["color141"];
1021
+ }
1022
+
1023
+ /**
1024
+ * @return String
1025
+ */
1026
+ protected function getSeriesType($seriesNumber)
1027
+ {
1028
+ switch( $this->type_line )
1029
+ {
1030
+ case "line":
1031
+ return "line";
1032
+ case "spline":
1033
+ return "spline";
1034
+ case "step_line":
1035
+ return "stepLine";
1036
+ default:
1037
+ return "line";
1038
+ }
1039
+ }
1040
+ }
1041
+
1042
+ class Chart_Area extends Chart
1043
+ {
1044
+ protected $stacked;
1045
+
1046
+
1047
+ function __construct( &$ch_array, $param )
1048
+ {
1049
+ parent::__construct( $ch_array, $param );
1050
+
1051
+ $this->stacked = $param["stacked"];
1052
+ }
1053
+
1054
+ /**
1055
+ * @param &Array chart
1056
+ */
1057
+ protected function setTypeSpecChartSettings( &$chart )
1058
+ {
1059
+ $chart["series"] = $this->get_data();
1060
+
1061
+ if( $this->stacked )
1062
+ $chart["scales"] = $this->getScales();
1063
+ $chart["type"] = "area";
1064
+ $chart["xScale"] = 0;
1065
+ $chart["yScale"] = 1;
1066
+ $chart["logarithm"] = parent::getLogarithm();
1067
+ $chart["grids"] = $this->getGrids();
1068
+
1069
+ $chart["tooltip"] = array("displayMode" => "single");
1070
+
1071
+ $chart["yAxes"] = array(
1072
+ array( "enabled" => "true", "title" => $this->y_axis_label )
1073
+ );
1074
+
1075
+ $chart["xAxes"] = array(
1076
+ array(
1077
+ "enabled" => "true",
1078
+ "title" => array( 'text' => $this->footer ),
1079
+ "labels" => array( "enabled" => $this->chrt_array["appearance"]["sname"] == "true" )
1080
+ ));
1081
+
1082
+ if ( @$this->chrt_array["appearance"]["color51"] != "" )
1083
+ $chart["xAxes"][0]["labels"]["fontColor"] = "#".$this->chrt_array["appearance"]["color51"];
1084
+
1085
+ if ( @$this->chrt_array["appearance"]["color111"] != "" )
1086
+ $chart["xAxes"][0]["title"]["fontColor"] = "#".$this->chrt_array["appearance"]["color111"];
1087
+
1088
+ if ( @$this->chrt_array["appearance"]["color131"] != "" )
1089
+ $chart["xAxes"][0]["stroke"] = "#".$this->chrt_array["appearance"]["color131"];
1090
+
1091
+ if ( @$this->chrt_array["appearance"]["color141"] != "" )
1092
+ $chart["yAxes"][0]["stroke"] = "#".$this->chrt_array["appearance"]["color141"];
1093
+ }
1094
+
1095
+ /**
1096
+ * @return String
1097
+ */
1098
+ protected function getSeriesType($seriesNumber)
1099
+ {
1100
+ return "area";
1101
+ }
1102
+
1103
+ /**
1104
+ * "scales"
1105
+ * @return Array
1106
+ */
1107
+ protected function getScales()
1108
+ {
1109
+ if( $this->stacked )
1110
+ {
1111
+ $arr = array();
1112
+ $arr["stackMode"] = "value";
1113
+
1114
+ if( $this->chrt_array["appearance"]["sstacked"] == "true" )
1115
+ {
1116
+ $arr["stackMode"] = "percent";
1117
+ $arr["maximumGap"] = "10";
1118
+ $arr["maximum"] = "100";
1119
+ };
1120
+
1121
+ return array(
1122
+ array( "names"=> array() ),
1123
+ $arr
1124
+ );
1125
+ }
1126
+
1127
+ return array();
1128
+ }
1129
+ }
1130
+
1131
+ /**
1132
+ * A single series chart
1133
+ */
1134
+ class Chart_Pie extends Chart
1135
+ {
1136
+ protected $pie;
1137
+
1138
+
1139
+ function __construct( &$ch_array, $param )
1140
+ {
1141
+ parent::__construct( $ch_array, $param );
1142
+
1143
+ $this->pie = $param["pie"];
1144
+ $this->_2d = $param["2d"];
1145
+ $this->singleSeries = true;
1146
+ }
1147
+
1148
+ /**
1149
+ * @param &Array chart
1150
+ */
1151
+ protected function setTypeSpecChartSettings( &$chart )
1152
+ {
1153
+ $series = $this->get_data();
1154
+
1155
+ $chart["data"] = $series[0]["data"];
1156
+ $chart["clickData"] = $series[0]["clickData"];
1157
+ $chart["singleSeries"] = true;
1158
+ $chart["tooltip"] = $series[0]["tooltip"];
1159
+ $chart["logarithm"] = false;
1160
+ if( $this->_2d )
1161
+ $chart["type"] = "pie";
1162
+ else
1163
+ $chart["type"] = "pie-3d";
1164
+
1165
+ if( !$this->pie )
1166
+ $chart["innerRadius"] = "30%";
1167
+
1168
+ if( $this->chrt_array['appearance']['slegend'] == "true" && !$this->chartPreview )
1169
+ {
1170
+ $chart["legend"] = array("enabled" => "true");
1171
+ }
1172
+
1173
+ $chart["labels"] = array( "enabled" => $this->chrt_array["appearance"]["sval"] == "true" || $this->chrt_array["appearance"]["sname"] == "true" );
1174
+
1175
+ if ( @$this->chrt_array["appearance"]["color51"] != "" )
1176
+ {
1177
+ if ( $this->chrt_array["appearance"]["sval"] )
1178
+ {
1179
+ $chart["labels"]["fontColor"] = "#".$this->chrt_array["appearance"]["color61"];
1180
+ }
1181
+ else if ( $this->chrt_array["appearance"]["sname"] )
1182
+ {
1183
+ $chart["labels"]["fontColor"] = "#".$this->chrt_array["appearance"]["color51"];
1184
+ }
1185
+ }
1186
+
1187
+ }
1188
+ }
1189
+
1190
+ class Chart_Combined extends Chart
1191
+ {
1192
+ function __construct( &$ch_array, $param )
1193
+ {
1194
+ parent::__construct( $ch_array, $param );
1195
+ }
1196
+
1197
+ /**
1198
+ * @param &Array chart
1199
+ */
1200
+ protected function setTypeSpecChartSettings( &$chart )
1201
+ {
1202
+ $chart["series"] = $this->get_data();
1203
+ $chart["type"] = "column";
1204
+ $chart["logarithm"] = parent::getLogarithm();
1205
+ $chart["xScale"] = 0;
1206
+ $chart["yScale"] = 1;
1207
+ $chart["grids"] = $this->getGrids();
1208
+ $chart["yAxes"] = array(
1209
+ array( "enabled" => "true", "title" => $this->y_axis_label )
1210
+ );
1211
+
1212
+ $chart["xAxes"] = array(
1213
+ array(
1214
+ "enabled" => "true",
1215
+ "title" => array( 'text' => $this->footer ),
1216
+ "labels" => array( "enabled" => $this->chrt_array["appearance"]["sname"] == "true" )
1217
+ ));
1218
+
1219
+ if ( @$this->chrt_array["appearance"]["color51"] != "" )
1220
+ $chart["xAxes"][0]["labels"]["fontColor"] = "#".$this->chrt_array["appearance"]["color51"];
1221
+
1222
+ if ( @$this->chrt_array["appearance"]["color111"] != "" )
1223
+ $chart["xAxes"][0]["title"]["fontColor"] = "#".$this->chrt_array["appearance"]["color111"];
1224
+
1225
+ if ( @$this->chrt_array["appearance"]["color131"] != "" )
1226
+ $chart["xAxes"][0]["stroke"] = "#".$this->chrt_array["appearance"]["color131"];
1227
+
1228
+ if ( @$this->chrt_array["appearance"]["color141"] != "" )
1229
+ $chart["yAxes"][0]["stroke"] = "#".$this->chrt_array["appearance"]["color141"];
1230
+ }
1231
+
1232
+ /**
1233
+ * @return String
1234
+ */
1235
+ protected function getSeriesType($seriesNumber)
1236
+ {
1237
+ switch ($seriesNumber) {
1238
+ case 0:
1239
+ return "spline";
1240
+ break;
1241
+ case 1:
1242
+ return "splineArea";
1243
+ break;
1244
+ default:
1245
+ return "column";
1246
+ }
1247
+ }
1248
+ protected function getLogarithm()
1249
+ {
1250
+ if( $this->chrt_array["appearance"]["slog"] == "true" )
1251
+ return true;
1252
+ return false;
1253
+ }
1254
+ }
1255
+
1256
+ /**
1257
+ * A single series chart
1258
+ */
1259
+ class Chart_Funnel extends Chart
1260
+ {
1261
+ protected $inver;
1262
+
1263
+
1264
+ function __construct( &$ch_array, $param )
1265
+ {
1266
+ parent::__construct( $ch_array, $param );
1267
+
1268
+ $this->inver = $param["funnel_inv"];
1269
+ $this->singleSeries = true;
1270
+ }
1271
+
1272
+ /**
1273
+ * @param &Array chart
1274
+ */
1275
+ protected function setTypeSpecChartSettings( &$chart )
1276
+ {
1277
+ $series = $this->get_data();
1278
+ $chart["type"] = "pyramid";
1279
+
1280
+ $chart["data"] = $series[0]["data"];
1281
+ $chart["clickData"] = $series[0]["clickData"];
1282
+ $chart["singleSeries"] = true;
1283
+ $chart["tooltip"] = $series[0]["tooltip"];
1284
+ $chart["logarithm"] = false;
1285
+ if( $this->inver )
1286
+ $chart["reversed"] = true;
1287
+
1288
+ $chart["labels"] = array( "enabled" => $this->chrt_array["appearance"]["sname"] == "true" );
1289
+
1290
+ if ( @$this->chrt_array["appearance"]["color51"] != "" )
1291
+ $chart["labels"]["fontColor"] = "#".$this->chrt_array["appearance"]["color51"];
1292
+ }
1293
+ }
1294
+
1295
+ class Chart_Bubble extends Chart
1296
+ {
1297
+ protected $arrDataSize = array();
1298
+
1299
+
1300
+ function __construct( &$ch_array, $param )
1301
+ {
1302
+ parent::__construct( $ch_array, $param );
1303
+
1304
+ $this->_2d = $param["2d"];
1305
+ }
1306
+
1307
+ /**
1308
+ * @param Array params
1309
+ */
1310
+ protected function setSpecParams( $params )
1311
+ {
1312
+ parent::setSpecParams( $params );
1313
+
1314
+ if( $params['name'] != "" )
1315
+ {
1316
+ if( $this->table_type != "db" )
1317
+ $this->arrDataSize[] = $params['size'];
1318
+ else
1319
+ $this->arrDataSize[] = $params['table']."_".$params['size'];
1320
+ }
1321
+ }
1322
+
1323
+ /**
1324
+ * @param &Array chart
1325
+ */
1326
+ protected function setTypeSpecChartSettings( &$chart )
1327
+ {
1328
+ $chart["series"] = $this->get_data();
1329
+ $chart["type"] = "cartesian";
1330
+ $chart["grids"] = $this->getGrids();
1331
+ $chart["logarithm"] = parent::getLogarithm();
1332
+ $chart["yAxes"] = array(
1333
+ array(
1334
+ "enabled" => true,
1335
+ "title" => $this->y_axis_label,
1336
+ "labels" => array( "enabled" => $this->chrt_array["appearance"]["sval"] == "true" )
1337
+ ));
1338
+
1339
+ if ( @$this->chrt_array["appearance"]["color61"] != "" )
1340
+ $chart["yAxes"][0]["labels"]["fontColor"] = "#".$this->chrt_array["appearance"]["color61"];
1341
+
1342
+ $chart["xAxes"] = array(
1343
+ array(
1344
+ "enabled" => "true",
1345
+ "title" => array( 'text' => $this->footer ),
1346
+ "labels" => array( "enabled" => $this->chrt_array["appearance"]["sname"] == "true" )
1347
+ ));
1348
+
1349
+ if ( @$this->chrt_array["appearance"]["color51"] != "" )
1350
+ $chart["xAxes"][0]["labels"]["fontColor"] = "#".$this->chrt_array["appearance"]["color51"];
1351
+
1352
+ if ( @$this->chrt_array["appearance"]["color111"] != "" )
1353
+ $chart["xAxes"][0]["title"]["fontColor"] = "#".$this->chrt_array["appearance"]["color111"];
1354
+
1355
+ if ( @$this->chrt_array["appearance"]["color131"] != "" )
1356
+ $chart["xAxes"][0]["stroke"] = "#".$this->chrt_array["appearance"]["color131"];
1357
+
1358
+ if ( @$this->chrt_array["appearance"]["color141"] != "" )
1359
+ $chart["yAxes"][0]["stroke"] = "#".$this->chrt_array["appearance"]["color141"];
1360
+ }
1361
+
1362
+ /**
1363
+ * @return String
1364
+ */
1365
+ protected function getSeriesType($seriesNumber)
1366
+ {
1367
+ return "bubble";
1368
+ }
1369
+
1370
+ /**
1371
+ * @param Number seriesNumber
1372
+ * @param Array row
1373
+ * @return Array
1374
+ */
1375
+ protected function getPoint( $seriesNumber, $row )
1376
+ {
1377
+ $pointData = parent::getPoint( $seriesNumber, $row );
1378
+ $pointData["size"] = (double)str_replace(",", ".", $row[ $this->arrDataSize[ $seriesNumber ] ]);
1379
+
1380
+ return $pointData;
1381
+ }
1382
+ }
1383
+
1384
+ class Chart_Gauge extends Chart
1385
+ {
1386
+ protected $arrGaugeColor = array();
1387
+ protected $gaugeType = "";
1388
+ protected $layout = "";
1389
+
1390
+ function __construct( &$ch_array, $param )
1391
+ {
1392
+ parent::__construct( $ch_array, $param );
1393
+
1394
+ $this->gaugeType = $param["gaugeType"];
1395
+ $this->layout = $param["layout"];
1396
+ }
1397
+
1398
+ /**
1399
+ * @param Array params
1400
+ */
1401
+ protected function setSpecParams( $params )
1402
+ {
1403
+ parent::setSpecParams( $params );
1404
+
1405
+ if ( $params['name'] != "" )
1406
+ {
1407
+ for ($k = 0; is_array( $params["gaugeColorZone"] ) && $k < count( $params["gaugeColorZone"] ); $k++ )
1408
+ {
1409
+ $beginColor = (float)@$params["gaugeColorZone"][ $k ]["gaugeBeginColor"];
1410
+ $endColor = (float)@$params["gaugeColorZone"][ $k ]["gaugeEndColor"];
1411
+ $gColor = "#".@$params["gaugeColorZone"][ $k ]["gaugeColor"];
1412
+
1413
+ $this->arrGaugeColor[ count($this->arrDataSeries) - 1 ][] = array($beginColor, $endColor, $gColor);
1414
+ }
1415
+ }
1416
+ }
1417
+
1418
+ /**
1419
+ *
1420
+ */
1421
+ public function write()
1422
+ {
1423
+ $data = array();
1424
+
1425
+ for($i = 0; $i < count($this->arrDataSeries); $i++)
1426
+ {
1427
+ $chart = array();
1428
+
1429
+ if( $this->chrt_array["appearance"]["sanim"] == "true" )
1430
+ $chart["animation"] = array("enabled" => "true", "duration" => 1000);
1431
+
1432
+ $this->setGaugeSpecChartSettings( $chart, $i );
1433
+
1434
+ if ( @$this->chrt_array["appearance"]["color71"] != "" || @$this->chrt_array["appearance"]["color91"] != "" )
1435
+ $chart["background"] = array();
1436
+ if ( @$this->chrt_array["appearance"]["color71"] != "" )
1437
+ $chart["background"]["fill"] = "#".$this->chrt_array["appearance"]["color71"];
1438
+
1439
+ if ( @$this->chrt_array["appearance"]["color91"] != "" )
1440
+ $chart["background"]["stroke"] = "#".$this->chrt_array["appearance"]["color91"];
1441
+
1442
+ if( $this->noRecordsFound )
1443
+ {
1444
+ $data["noDataMessage"] = $this->getNoDataMessage();
1445
+ echo my_json_encode( $data );
1446
+ return;
1447
+ }
1448
+
1449
+ $data[] = array( "gauge" => $chart );
1450
+ }
1451
+
1452
+ echo my_json_encode( array( "gauge" => $data, "header" => $this->header, "footer" => $this->footer ) );
1453
+ }
1454
+
1455
+ /**
1456
+ * @param &Array chart
1457
+ * @param Number seriesNumber
1458
+ */
1459
+ protected function setGaugeSpecChartSettings( &$chart, $seriesNumber )
1460
+ {
1461
+ $series = $this->get_data();
1462
+ $chart["data"] = $series[ $seriesNumber ]["data"];
1463
+
1464
+ $chart["type"] = $this->gaugeType;
1465
+ $chart["layout"] = $this->layout;
1466
+ $chart["axes"] = array( $this->getAxesSettings( $seriesNumber ) );
1467
+ $chart["credits"] = false;
1468
+ $chart["chartLabels"] = $this->getCircularGaugeLabel( $seriesNumber, $chart["data"][0] );
1469
+ if( $this->gaugeType == "circular-gauge" )
1470
+ {
1471
+ $chart["needles"] = array( array("enabled" => true) );
1472
+ $chart["ranges"] = $this->getColorRanges( $seriesNumber );
1473
+ }
1474
+ else
1475
+ {
1476
+ $hasColorZones = count( $this->arrGaugeColor ) > 0 && array_key_exists($seriesNumber, $this->arrGaugeColor );
1477
+
1478
+ $chart["pointers"] = array(
1479
+ array(
1480
+ "enabled" => true,
1481
+ "pointerType" => "marker",
1482
+ "type" => $this->layout == "horizontal" ? "triangleUp" : "triangleLeft",
1483
+ "name" => "",
1484
+ "offset" => $hasColorZones ? "20%" : "10%",
1485
+ "dataIndex" => 0,
1486
+ )
1487
+ );
1488
+
1489
+ if( $hasColorZones )
1490
+ {
1491
+ foreach( $this->arrGaugeColor[ $seriesNumber ] as $ind => $val )
1492
+ {
1493
+ $chart["pointers"][] = array(
1494
+ "enabled" => true,
1495
+ "pointerType" => "rangeBar",
1496
+ "name" => "",
1497
+ "offset" => "10%",
1498
+ "dataIndex" => $ind + 1, // 0 is an index of the db point then range bars coords go
1499
+ "color" => $val[2]
1500
+ );
1501
+ }
1502
+ }
1503
+
1504
+ $scalesData = $this->getGaugeScales( $seriesNumber );
1505
+
1506
+ $chart["scale"] = 0;
1507
+ $chart["scales"] = array(
1508
+ array(
1509
+ "maximum" => $scalesData["max"],
1510
+ "minimum" => $scalesData["min"],
1511
+ "ticks" => array( "interval"=> $scalesData["interval"] ),
1512
+ "minorTicks" => array( "interval"=> $scalesData["interval"] / 2 )
1513
+ )
1514
+ );
1515
+ }
1516
+ }
1517
+
1518
+ /**
1519
+ * @param Number seriesNumber
1520
+ * @param Array pointData
1521
+ * @return Array
1522
+ */
1523
+ protected function getCircularGaugeLabel( $seriesNumber, $pointData )
1524
+ {
1525
+ $label = array(
1526
+ "enabled" => true,
1527
+ "vAlign" => "center",
1528
+ "hAlign" => "center",
1529
+ "text" => $this->getChartLabelText( $seriesNumber, $pointData["value"] )
1530
+ );
1531
+
1532
+ if( $this->gaugeType == "circular-gauge" )
1533
+ {
1534
+ $label["offsetY"] = -150; //fix it
1535
+ $label["anchor"] = "center";
1536
+
1537
+ $label["background"] = array(
1538
+ "enabled" => true,
1539
+ "fill" => "#fff",
1540
+ "cornerType" => "round",
1541
+ "corner" => 0
1542
+ );
1543
+
1544
+ $label["padding"] = array(
1545
+ "top" => 15,
1546
+ "right" => 20,
1547
+ "bottom" => 15,
1548
+ "left" => 20
1549
+ );
1550
+ }
1551
+
1552
+ return array( $label );
1553
+ }
1554
+
1555
+ /**
1556
+ * @param Number seriesNumber
1557
+ * @return Array
1558
+ */
1559
+ protected function getColorRanges( $seriesNumber )
1560
+ {
1561
+ $ranges = array();
1562
+ if( count( $this->arrGaugeColor ) > 0 && array_key_exists($seriesNumber, $this->arrGaugeColor ) )
1563
+ {
1564
+ foreach( $this->arrGaugeColor[ $seriesNumber ] as $ind => $val )
1565
+ {
1566
+ $ranges[] = array(
1567
+ "radius" => 70,
1568
+ "from" => $val[0],
1569
+ "to" => $val[1],
1570
+ "fill" => $val[2],
1571
+ "endSize" => "10%",
1572
+ "startSize" => "10%"
1573
+ );
1574
+ }
1575
+ }
1576
+
1577
+ return $ranges;
1578
+ }
1579
+
1580
+ /**
1581
+ * @param Number seriesNumber
1582
+ * @return Array
1583
+ */
1584
+ protected function getAxesSettings( $seriesNumber )
1585
+ {
1586
+ $axes = array();
1587
+
1588
+ if( $this->gaugeType == "circular-gauge" )
1589
+ {
1590
+ $axes["startAngle"] = -150;
1591
+ $axes["sweepAngle"] = 300;
1592
+
1593
+ $scalesData = $this->getGaugeScales( $seriesNumber );
1594
+
1595
+ $axes["scale"] = array(
1596
+ "maximum" => $scalesData["max"],
1597
+ "minimum" => $scalesData["min"],
1598
+ "ticks" => array( "interval"=> $scalesData["interval"] ),
1599
+ "minorTicks" => array( "interval" => $scalesData["interval"] / 2 )
1600
+ );
1601
+
1602
+ $axes["ticks"] = array(
1603
+ "type" => "trapezoid",
1604
+ "interval" => $scalesData["interval"]
1605
+ );
1606
+
1607
+ $axes["minorTicks"] = array(
1608
+ "enabled" => true,
1609
+ "length" => 2
1610
+ );
1611
+
1612
+ if ( @$this->chrt_array["appearance"]["color131"] != "" )
1613
+ $axes["fill"] = "#".$this->chrt_array["appearance"]["color131"];
1614
+ }
1615
+
1616
+ $axes["enabled"] = true;
1617
+ $axes["labels"] = array( "enabled" => $this->chrt_array["appearance"]["sval"] == "true" );
1618
+
1619
+ if ( @$this->chrt_array["appearance"]["color61"] != "" )
1620
+ $axes["labels"]["fontColor"] = "#".$this->chrt_array["appearance"]["color61"];
1621
+
1622
+ return $axes;
1623
+ }
1624
+
1625
+ /**
1626
+ * @param Number seriesNumber
1627
+ * @return Array
1628
+ */
1629
+ protected function getGaugeScales( $seriesNumber )
1630
+ {
1631
+ $min = $this->chrt_array["parameters"][ $seriesNumber ]["gaugeMinValue"];
1632
+ $max = $this->chrt_array["parameters"][ $seriesNumber ]["gaugeMaxValue"];
1633
+
1634
+ if( !is_numeric( $min ) )
1635
+ $min = 0;
1636
+
1637
+ if( !is_numeric( $max ) )
1638
+ $max = 100;
1639
+
1640
+ $diff = $max - $min;
1641
+ $slog = floor( log10( $diff ) );
1642
+ $interval = pow(10, $slog - 2);
1643
+ $muls = array(1,2,3,5,10);
1644
+
1645
+ while(true)
1646
+ {
1647
+ foreach($muls as $m)
1648
+ {
1649
+ if( $diff / ($interval * $m) <= 10 )
1650
+ {
1651
+ $interval*= $m;
1652
+ break;
1653
+ }
1654
+ }
1655
+ if( $diff / ($interval) <= 10 )
1656
+ break;
1657
+
1658
+ $interval*= 10;
1659
+ }
1660
+
1661
+ return array(
1662
+ "min" => $min,
1663
+ "max" => $max,
1664
+ "interval" => $interval
1665
+ );
1666
+ }
1667
+
1668
+
1669
+ public function getSubsetDataCommand( $ignoreFilterField = "" ) {
1670
+ $dc = parent::getSubsetDataCommand();
1671
+
1672
+ if( $this->table_type == "project" ) {
1673
+ require_once( getabspath('classes/orderclause.php') );
1674
+
1675
+ $orderObject = new OrderClause( $this->pSet, $this->cipherer, $this->sessionPrefix, $this->connection );
1676
+ $order = $orderObject->getOrderFields();
1677
+ $revertedOrder = array();
1678
+
1679
+ foreach( $order as $o ) {
1680
+ $ro = $o;
1681
+ $ro['dir'] = $ro['dir'] == "ASC" ? "DESC" : "ASC";
1682
+
1683
+ $revertedOrder[] = $ro;
1684
+ }
1685
+
1686
+ $dc->order = $revertedOrder;
1687
+ }
1688
+
1689
+ return $dc;
1690
+ }
1691
+
1692
+ /**
1693
+ *
1694
+ */
1695
+ public function get_data()
1696
+ {
1697
+ $data = array();
1698
+
1699
+ $dc = $this->getSubsetDataCommand();
1700
+ $this->beforeQueryEvent( $dc );
1701
+
1702
+ $rs = $this->dataSource->getList( $dc );
1703
+ if( !$rs ) {
1704
+ showError( $this->dataSource->lastError() );
1705
+ }
1706
+
1707
+ $row = $rs->fetchAssoc();
1708
+ if( $this->cipherer )
1709
+ $row = $this->cipherer->DecryptFetchedArray( $row );
1710
+
1711
+ if( !$row )
1712
+ $this->noRecordsFound = true;
1713
+
1714
+ for($i = 0; $i < count($this->arrDataSeries); $i++)
1715
+ {
1716
+ if( $row )
1717
+ {
1718
+ $data[$i] = array();
1719
+ $data[$i][] = $this->getPoint($i, $row);
1720
+ }
1721
+ }
1722
+
1723
+ $series = array();
1724
+ for ( $i = 0; $i < count($this->arrDataSeries); $i++ )
1725
+ {
1726
+ $series[] = $this->getSeriesData( $this->arrDataLabels[$i], $data[$i], $clickdata[$i], $i, count($this->arrDataSeries) > 1 );
1727
+ }
1728
+
1729
+ return $series;
1730
+ }
1731
+
1732
+ /**
1733
+ * @param String name
1734
+ * @param Array pointsData
1735
+ * @param Array clickData
1736
+ * @param Number seriesNumber
1737
+ * @param Boolean multiSeries (optional)
1738
+ * @return Array
1739
+ */
1740
+ protected function getSeriesData( $name, $pointsData, $clickData, $seriesNumber, $multiSeries = true )
1741
+ {
1742
+ if( $this->gaugeType == "linearGauge" && count( $this->arrGaugeColor ) > 0 && array_key_exists( $seriesNumber, $this->arrGaugeColor ) )
1743
+ {
1744
+ foreach( $this->arrGaugeColor[ $seriesNumber ] as $ind => $val )
1745
+ {
1746
+ $pointsData[] = array(
1747
+ "low" => $val[0],
1748
+ "high" => $val[1]
1749
+ );
1750
+ }
1751
+ }
1752
+
1753
+ return array(
1754
+ "data" => $pointsData,
1755
+ "labelText" => $this->getChartLabelText( $seriesNumber, $pointsData[0]["value"] )
1756
+ );
1757
+ }
1758
+
1759
+ /**
1760
+ * @param Number seriesNumber
1761
+ * @param String value
1762
+ * @return String
1763
+ */
1764
+ protected function getChartLabelText( $seriesNumber, $value )
1765
+ {
1766
+ if( $this->table_type == "project" && !$this->webchart )
1767
+ {
1768
+ $fieldName = $this->arrDataSeries[ $seriesNumber ];
1769
+
1770
+ include_once getabspath('classes/controls/ViewControlsContainer.php');
1771
+ $viewControls = new ViewControlsContainer($this->pSet, PAGE_CHART);
1772
+
1773
+ $data = array( $fieldName => $value );
1774
+ $viewValue = $viewControls->showDBValue( $fieldName, $data, "", "", false );
1775
+
1776
+ return $this->arrDataLabels[ $seriesNumber ].": ". $viewValue;
1777
+ }
1778
+
1779
+ return $this->arrDataLabels[ $seriesNumber ].": ". $value;
1780
+ }
1781
+ }
1782
+
1783
+ class Chart_Ohlc extends Chart
1784
+ {
1785
+ protected $ohcl_type;
1786
+
1787
+ protected $arrOHLC_high = array();
1788
+ protected $arrOHLC_low = array();
1789
+ protected $arrOHLC_open = array();
1790
+ protected $arrOHLC_close = array();
1791
+
1792
+ function __construct( &$ch_array, $param )
1793
+ {
1794
+ parent::__construct( $ch_array, $param );
1795
+
1796
+ $this->ohcl_type = $param["ohcl_type"];
1797
+ }
1798
+
1799
+ /**
1800
+ * @param Array params
1801
+ */
1802
+ protected function setSpecParams( $params )
1803
+ {
1804
+ if($this->table_type != "db")
1805
+ {
1806
+ $this->arrOHLC_open[] = $params['ohlcOpen'];
1807
+ $this->arrOHLC_high[] = $params['ohlcHigh'];
1808
+ $this->arrOHLC_low[] = $params['ohlcLow'];
1809
+ $this->arrOHLC_close[] = $params['ohlcClose'];
1810
+ return;
1811
+ }
1812
+
1813
+ if( $params['agr_func'] )
1814
+ {
1815
+ $this->arrOHLC_open[] = $params['agr_func']."_".$params['table']."_".$params['ohlcOpen'];
1816
+ $this->arrOHLC_high[] = $params['agr_func']."_".$params['table']."_".$params['ohlcHigh'];
1817
+ $this->arrOHLC_low[] = $params['agr_func']."_".$params['table']."_".$params['ohlcLow'];
1818
+ $this->arrOHLC_close[] = $params['agr_func']."_".$params['table']."_".$params['ohlcClose'];
1819
+ }
1820
+ else
1821
+ {
1822
+ $this->arrOHLC_open[] = $params['table']."_".$params['ohlcOpen'];
1823
+ $this->arrOHLC_high[] = $params['table']."_".$params['ohlcHigh'];
1824
+ $this->arrOHLC_low[] = $params['table']."_".$params['ohlcLow'];
1825
+ $this->arrOHLC_close[] = $params['table']."_".$params['ohlcClose'];
1826
+ }
1827
+ }
1828
+
1829
+ /**
1830
+ *
1831
+ */
1832
+ public function write()
1833
+ {
1834
+ $data = array();
1835
+ $chart = array();
1836
+
1837
+ $this->setTypeSpecChartSettings( $chart );
1838
+ if ( @$this->chrt_array["appearance"]["color71"] != "" || @$this->chrt_array["appearance"]["color91"] != "" )
1839
+ $chart["background"] = array();
1840
+ if ( @$this->chrt_array["appearance"]["color71"] != "" )
1841
+ $chart["background"]["fill"] = "#".$this->chrt_array["appearance"]["color71"];
1842
+
1843
+ if ( @$this->chrt_array["appearance"]["color91"] != "" )
1844
+ $chart["background"]["stroke"] = "#".$this->chrt_array["appearance"]["color91"];
1845
+
1846
+ $chart["credits"] = false;
1847
+ $chart["title"] = array("enabled" => "true", "text" => $this->header);
1848
+ if ( @$this->chrt_array["appearance"]["color101"] != "" )
1849
+ $chart["title"]["fontColor"] = "#".$this->chrt_array["appearance"]["color101"];
1850
+
1851
+ if( $this->chrt_array['appearance']['slegend'] == "true" && !$this->chartPreview )
1852
+ $chart["legend"] = array("enabled" => "true");
1853
+
1854
+ $data["chart"] = $chart;
1855
+ echo my_json_encode( $data );
1856
+ }
1857
+
1858
+ /**
1859
+ * @param &Array chart
1860
+ */
1861
+ protected function setTypeSpecChartSettings( &$chart )
1862
+ {
1863
+ $chart["series"] = $this->get_data();
1864
+ foreach ($this->chrt_array["parameters"] as $seriesNum => $params) {
1865
+ if ( @$params["ohlcColor"] != "" )
1866
+ {
1867
+ $chart["series"][$seriesNum]["fallingStroke"] = "#".$params["ohlcColor"];
1868
+ $chart["series"][$seriesNum]["fallingFill"] = "#".$params["ohlcColor"];
1869
+ if ( $this->ohcl_type == "ohcl" )
1870
+ {
1871
+ $chart["series"][$seriesNum]["risingStroke"] = "#".$params["ohlcColor"];
1872
+ $chart["series"][$seriesNum]["risingFill"] = "#".$params["ohlcColor"];
1873
+ }
1874
+ }
1875
+ if ( @$params["ohlcCandleColor"] != "" && $this->ohcl_type != "ohcl" )
1876
+ {
1877
+ $chart["series"][$seriesNum]["risingStroke"] = "#".$params["ohlcCandleColor"];
1878
+ $chart["series"][$seriesNum]["risingFill"] = "#".$params["ohlcCandleColor"];
1879
+ }
1880
+ }
1881
+
1882
+ $chart["grids"] = $this->getGrids();
1883
+ $chart["logarithm"] = parent::getLogarithm();
1884
+ $chart["type"] = "financial";
1885
+ $chart["xScale"] = 0;
1886
+ $chart["yScale"] = 1;
1887
+
1888
+ $chart["yAxes"] = array(
1889
+ array(
1890
+ "enabled" => "true",
1891
+ "title" => $this->y_axis_label,
1892
+ "labels" => array("enabled" => $this->chrt_array["appearance"]["sval"] == "true")
1893
+ ));
1894
+
1895
+ if ( @$this->chrt_array["appearance"]["color61"] != "" )
1896
+ $chart["yAxes"][0]["labels"]["fontColor"] = "#".$this->chrt_array["appearance"]["color61"];
1897
+
1898
+ $chart["xAxes"] = array(
1899
+ array(
1900
+ "enabled" => "true",
1901
+ "title" => array( 'text' => $this->footer ),
1902
+ "labels" => array("enabled" => $this->chrt_array["appearance"]["sname"] == "true" )
1903
+ ));
1904
+
1905
+ if ( @$this->chrt_array["appearance"]["color51"] != "" )
1906
+ $chart["xAxes"][0]["labels"]["fontColor"] = "#".$this->chrt_array["appearance"]["color51"];
1907
+
1908
+ if ( @$this->chrt_array["appearance"]["color111"] != "" )
1909
+ $chart["xAxes"][0]["title"]["fontColor"] = "#".$this->chrt_array["appearance"]["color111"];
1910
+
1911
+ if ( @$this->chrt_array["appearance"]["color131"] != "" )
1912
+ $chart["xAxes"][0]["stroke"] = "#".$this->chrt_array["appearance"]["color131"];
1913
+
1914
+ if ( @$this->chrt_array["appearance"]["color141"] != "" )
1915
+ $chart["yAxes"][0]["stroke"] = "#".$this->chrt_array["appearance"]["color141"];
1916
+
1917
+ if( $this->chrt_array["appearance"]["slog"] == "true" )
1918
+ {
1919
+ $chart["scales"] = array(
1920
+ array( "names" => array() ),
1921
+ array( "logBase" => 10, "type" => "log" )
1922
+ );
1923
+ }
1924
+ }
1925
+
1926
+ /**
1927
+ * @return Array
1928
+ */
1929
+ public function get_data()
1930
+ {
1931
+ $data = array();
1932
+ $clickdata = array();
1933
+
1934
+ for ( $i = 0; $i < count( $this->arrOHLC_open ); $i++ )
1935
+ {
1936
+ $data[$i] = array();
1937
+ $clickdata[$i] = array();
1938
+ }
1939
+
1940
+ $dc = $this->getSubsetDataCommand();
1941
+ $this->beforeQueryEvent( $dc );
1942
+
1943
+ $rs = $this->dataSource->getList( $dc );
1944
+ if( !$rs ) {
1945
+ showError( $this->dataSource->lastError() );
1946
+ }
1947
+
1948
+ $row = $rs->fetchAssoc();
1949
+ if( $this->cipherer )
1950
+ $row = $this->cipherer->DecryptFetchedArray( $row );
1951
+
1952
+ if( !$row )
1953
+ $this->noRecordsFound = true;
1954
+
1955
+ while( $row )
1956
+ {
1957
+ for ( $i = 0; $i < count( $this->arrOHLC_open ); $i++ )
1958
+ {
1959
+ $data[$i][] = $this->getPoint( $i, $row );
1960
+
1961
+ $strLabelFormat = $this->labelFormat( $this->strLabel, $row );
1962
+ $clickdata[$i][] = $this->getActions( $row , $this->arrDataSeries[$i], $strLabelFormat );
1963
+ }
1964
+
1965
+ $row = $rs->fetchAssoc();
1966
+ if( $this->cipherer )
1967
+ $row = $this->cipherer->DecryptFetchedArray( $row );
1968
+ }
1969
+
1970
+ $series = array();
1971
+ for ( $i = 0; $i < count( $this->arrOHLC_open ); $i++ )
1972
+ {
1973
+ $series[] = $this->getSeriesData( $this->arrDataLabels[$i], $data[$i], $clickdata[$i], $i );
1974
+ }
1975
+
1976
+ return $series;
1977
+ }
1978
+
1979
+ /**
1980
+ * @return String
1981
+ */
1982
+ protected function getSeriesType($seriesNumber)
1983
+ {
1984
+ if( $this->ohcl_type == "ohcl" )
1985
+ return "ohlc";
1986
+
1987
+ return "candlestick";
1988
+ }
1989
+
1990
+ /**
1991
+ * @param Boolean $multiSeries
1992
+ * @return Array
1993
+ */
1994
+ protected function getSeriesTooltip( $multiSeries ) {
1995
+ $tooltipSettings = array(
1996
+ "enabled" => true
1997
+ );
1998
+
1999
+ return $tooltipSettings;
2000
+ }
2001
+
2002
+ /**
2003
+ * @param Number seriesNumber
2004
+ * @param Array row
2005
+ * @return Array
2006
+ */
2007
+ protected function getPoint( $seriesNumber, $row )
2008
+ {
2009
+ if( $this->table_type!="db" || !$this->chrt_array['customLabels'] )
2010
+ {
2011
+ $high = $row[ $this->arrOHLC_high[ $seriesNumber ] ];
2012
+ $low = $row[ $this->arrOHLC_low[ $seriesNumber ] ];
2013
+ $open = $row[ $this->arrOHLC_open[ $seriesNumber ] ];
2014
+ $close = $row[ $this->arrOHLC_close[ $seriesNumber ] ];
2015
+ }
2016
+ else
2017
+ {
2018
+ $high = $row[ $this->chrt_array['customLabels'][ $this->arrOHLC_high[ $seriesNumber ] ] ];
2019
+ $low = $row[ $this->chrt_array['customLabels'][ $this->arrOHLC_low[ $seriesNumber ] ] ];
2020
+ $open = $row[ $this->chrt_array['customLabels'][ $this->arrOHLC_open[ $seriesNumber ] ] ];
2021
+ $close = $row[ $this->chrt_array['customLabels'][ $this->arrOHLC_close[ $seriesNumber ] ] ];
2022
+ }
2023
+
2024
+ return array(
2025
+ "x" => $this->labelFormat( $this->strLabel, $row ),
2026
+ "open" => (double)$open,
2027
+ "high" => (double)$high,
2028
+ "low" => (double)$low,
2029
+ "close" => (double)str_replace(",", ".", $close)
2030
+ );
2031
+ }
2032
+ }
2033
+ ?>
classes/cipherer.php ADDED
@@ -0,0 +1,341 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class RunnerCipherer
3
+ {
4
+ public $key = '';
5
+ public $alg = '';
6
+ public $mode = '';
7
+
8
+ protected $strTableName = '';
9
+
10
+ /**
11
+ * Instance of RunnerCiphererES class for code-based ciphering
12
+ */
13
+ protected $ESFunctions = null;
14
+
15
+ /**
16
+ * Instance of ProjectSettings class
17
+ */
18
+ protected $pSet = null;
19
+
20
+ /**
21
+ * Array of fields which encrypted status already determined
22
+ */
23
+ protected $encryptedFields = array();
24
+
25
+ /**
26
+ * @type Connection
27
+ */
28
+ protected $connection;
29
+
30
+
31
+ function __construct($strTableName, $pSet = null)
32
+ {
33
+
34
+ $this->strTableName = $strTableName;
35
+
36
+ $this->setConnection();
37
+
38
+ if( $this->connection->dbBased() ) {
39
+ $this->key = $this->connection->_encryptInfo["key"];
40
+ $this->alg = $this->connection->_encryptInfo["alg"];
41
+ $this->mode = $this->connection->_encryptInfo["mode"];
42
+ }
43
+
44
+ if($pSet != null)
45
+ $this->pSet = $pSet;
46
+ else
47
+ $this->pSet = new ProjectSettings($strTableName);
48
+ }
49
+
50
+ /**
51
+ * Set the 'connection' property
52
+ */
53
+ protected function setConnection()
54
+ {
55
+ global $cman;
56
+
57
+ if( $this->strTableName != GLOBAL_PAGES )
58
+ $this->connection = $cman->byTable( $this->strTableName );
59
+ else
60
+ $this->connection = getDefaultConnection();
61
+
62
+ if ( $this->connection->dbType == nDATABASE_MSSQLServer && $this->connection->_encryptInfo["alg"] == ENCRYPTION_ALG_AES && $this->connection->_encryptInfo["mode"] == ENCRYPTION_DB )
63
+ {
64
+ $symmetricSql = mysprintf("OPEN SYMMETRIC KEY [%s] DECRYPTION BY CERTIFICATE [%s];", array($this->connection->_encryptInfo["slqserverkey"], $this->connection->_encryptInfo["slqservercert"]));
65
+ $this->connection->setInitializingSQL($symmetricSql);
66
+ }
67
+ }
68
+
69
+ function isEncryptionByPHPEnabled()
70
+ {
71
+ return $this->connection->isEncryptionByPHPEnabled();
72
+ }
73
+
74
+ /**
75
+ * DecryptFetchedArray
76
+ * Fetching record from sql result, looking through array of fetched values and decrypted all encrypted fields
77
+ * @param {array} fetchedArray
78
+ * @return {array} decrypted array
79
+ */
80
+ public function DecryptFetchedArray( $fetchedArray )
81
+ {
82
+ $result = array();
83
+
84
+ if($fetchedArray)
85
+ {
86
+ if( !$this->pSet->hasEncryptedFields() || !$this->connection->isEncryptionByPHPEnabled() )
87
+ return $fetchedArray;
88
+
89
+ foreach ($fetchedArray as $fieldName => $fieldValue)
90
+ {
91
+ $result[ $fieldName ] = $this->DecryptField($fieldName, $fieldValue);
92
+ }
93
+ }
94
+
95
+ return $result;
96
+ }
97
+
98
+ /**
99
+ * @param String field
100
+ * @param String
101
+ */
102
+ public function isFieldEncrypted($field)
103
+ {
104
+ $table = $this->strTableName;
105
+
106
+ if( array_key_exists($table, $this->encryptedFields) && array_key_exists($field, $this->encryptedFields[ $table ]) )
107
+ return $this->encryptedFields[ $table ][ $field ];
108
+
109
+ if( !array_key_exists($table, $this->encryptedFields) )
110
+ $this->encryptedFields[ $table ] = array();
111
+
112
+ $this->encryptedFields[ $table ][ $field ] = $this->pSet->isFieldEncrypted($field);
113
+ return $this->encryptedFields[ $table ][ $field ];
114
+ }
115
+
116
+ /**
117
+ * @param String field
118
+ * @return Boolean
119
+ */
120
+ public function isFieldPHPEncrypted($field)
121
+ {
122
+ return $this->connection->isEncryptionByPHPEnabled() && $this->isFieldEncrypted($field);
123
+ }
124
+
125
+ /**
126
+ * @param String field
127
+ * @param Mixed value
128
+ * @param String controltype (optional)
129
+ * @param Boolean phpEncryptionOnly (optional)
130
+ */
131
+ public function MakeDBValue($field, $value, $controltype = "", $phpEncryptionOnly = false)
132
+ {
133
+ $ret = prepare_for_db($field, $value, $controltype, "", $this->strTableName);
134
+ if( $ret === false )
135
+ return $ret;
136
+
137
+ $ret = add_db_quotes($field, $this->EncryptField($field, $ret), $this->strTableName );
138
+
139
+ if( $phpEncryptionOnly )
140
+ return $ret;
141
+
142
+ return $this->EncryptValueByDB($field, $ret);
143
+ }
144
+
145
+ /**
146
+ * @param String field
147
+ * @param Mixed value
148
+ */
149
+ public function AddDBQuotes($field, $value)
150
+ {
151
+ return $this->EncryptValueByDB( $field, add_db_quotes($field, $this->EncryptField($field, $value), $this->strTableName) );
152
+ }
153
+
154
+
155
+ /**
156
+ * GetFieldName
157
+ * Add to field name decryption function if field is encrypted by database
158
+ * @param {string} field name
159
+ * @param {string} alias of field name
160
+ * @param {bool} shows if 'as' construction needed
161
+ * @return {string}
162
+ */
163
+ public function GetFieldName($field, $alias = null, $addAs = false)
164
+ {
165
+ if($this->connection->isEncryptionByPHPEnabled() || !$this->isFieldEncrypted($alias != null ? $alias : $field))
166
+ return $field;
167
+
168
+ return $this->GetEncryptedFieldName($field, $alias, $addAs);
169
+ }
170
+
171
+ /**
172
+ * Get an SQL expression retriving the encrypted field's value
173
+ * Please note, when changing this function you should make appropriate changes in wizard method (dynamic permissions --> add new user) #8923
174
+ * @param {string} field
175
+ * @param {string} alias
176
+ * @param {string} addAs
177
+ * @return {string}
178
+ */
179
+ public function GetEncryptedFieldName($field, $alias = null, $addAs = false)
180
+ {
181
+ $result = "";
182
+ if ( $this->connection->_encryptInfo["alg"] == ENCRYPTION_ALG_DES)
183
+ {
184
+ if( $this->connection->dbType == nDATABASE_Oracle )
185
+ $result = "utl_raw.cast_to_varchar2(DBMS_CRYPTO.DECRYPT(utl_raw.cast_to_raw(%s), 4353, utl_raw.cast_to_raw('%s')))";
186
+ elseif( $this->connection->dbType == nDATABASE_MSSQLServer )
187
+ $result = "CAST(DecryptByPassPhrase(N'%s', %s) as nvarchar)";
188
+ elseif( $this->connection->dbType == nDATABASE_MySQL )
189
+ $result = "cast(DES_DECRYPT(unhex(%s), '%s') as char)";
190
+ elseif( $this->connection->dbType == nDATABASE_PostgreSQL )
191
+ $result = "pgp_sym_decrypt(CAST(%s as bytea), '%s')";
192
+ }
193
+ else if ( $this->connection->_encryptInfo["alg"] == ENCRYPTION_ALG_AES)
194
+ {
195
+ if( $this->connection->dbType == nDATABASE_Oracle )
196
+ {
197
+ $result = "utl_raw.cast_to_varchar2(DBMS_CRYPTO.DECRYPT(utl_raw.cast_to_raw(%s), 4358, utl_raw.cast_to_raw('%s')))";
198
+ $this->key = substr($this->key, 0, 16);
199
+ }
200
+ elseif( $this->connection->dbType == nDATABASE_MSSQLServer )
201
+ {
202
+ $result = "CAST(DecryptByKey(%s) as nvarchar(4000))";
203
+ $this->key = $field; // for use in first as parametr in mysprintf func
204
+ }
205
+ elseif( $this->connection->dbType == nDATABASE_MySQL )
206
+ $result = "cast(AES_DECRYPT(unhex(%s), '%s') as char)";
207
+ elseif( $this->connection->dbType == nDATABASE_PostgreSQL )
208
+ $result = "pgp_sym_decrypt(CAST(%s as bytea), '%s', 'cipher-algo=aes128')";
209
+ }
210
+
211
+ if($result == "")
212
+ return $field;
213
+
214
+ if( $this->connection->dbType == nDATABASE_MSSQLServer )
215
+ $result = mysprintf($result, array($this->key, $field));
216
+ else
217
+ $result = mysprintf($result, array($field, $this->key));
218
+
219
+ return $addAs ? $result." as ".$this->connection->addFieldWrappers($alias != null ? $alias : $field) : $result;
220
+ }
221
+
222
+ /**
223
+ * EncryptValueByDB
224
+ * Add to field name encryption function if field is encrypted by database
225
+ * Please note, when changing this function you should make appropriate changes in wizard method (dynamic permissions --> add new user) #8923
226
+ * @param {string} field name
227
+ * @param {mixed} value
228
+ * @return {string}
229
+ */
230
+ public function EncryptValueByDB($field, $value)
231
+ {
232
+ if( !$this->isFieldEncrypted($field) || $this->connection->isEncryptionByPHPEnabled() )
233
+ return $value;
234
+
235
+ $result = "";
236
+
237
+ if ( $this->connection->_encryptInfo["alg"] == ENCRYPTION_ALG_DES)
238
+ {
239
+ if( $this->connection->dbType == nDATABASE_Oracle )
240
+ $result = "utl_raw.cast_to_varchar2(DBMS_CRYPTO.ENCRYPT(utl_raw.cast_to_raw(%s), 4353, utl_raw.cast_to_raw('%s')))";
241
+ elseif( $this->connection->dbType == nDATABASE_MSSQLServer )
242
+ $result = "EncryptByPassPhrase(N'%s', %s)";
243
+ elseif( $this->connection->dbType == nDATABASE_MySQL )
244
+ $result = "hex(DES_ENCRYPT(%s, '%s'))";
245
+ elseif( $this->connection->dbType == nDATABASE_PostgreSQL )
246
+ $result = "pgp_sym_encrypt(%s, '%s')";
247
+ }
248
+ else if ( $this->connection->_encryptInfo["alg"] == ENCRYPTION_ALG_AES)
249
+ {
250
+ if( $this->connection->dbType == nDATABASE_Oracle )
251
+ {
252
+ $result = "utl_raw.cast_to_varchar2(DBMS_CRYPTO.ENCRYPT(utl_raw.cast_to_raw(%s), 4358, utl_raw.cast_to_raw('%s')))";
253
+ $this->key = substr($this->key, 0, 16);
254
+ }
255
+ elseif( $this->connection->dbType == nDATABASE_MSSQLServer )
256
+ {
257
+ $result = "EncryptByKey(Key_GUID('%s'), %s)";
258
+ $this->key = $this->connection->_encryptInfo["slqserverkey"];
259
+ }
260
+ elseif( $this->connection->dbType == nDATABASE_MySQL )
261
+ $result = "hex(AES_ENCRYPT(%s, '%s'))";
262
+ elseif( $this->connection->dbType == nDATABASE_PostgreSQL )
263
+ $result = "pgp_sym_encrypt(%s, '%s', 'cipher-algo=aes128')";
264
+ }
265
+
266
+ if($result != "")
267
+ {
268
+ if( $this->connection->dbType == nDATABASE_MSSQLServer )
269
+ $result = mysprintf($result, array($this->key, $value));
270
+ else
271
+ $result = mysprintf($result, array($value, $this->key));
272
+ }
273
+ else
274
+ $result = $value;
275
+
276
+ return $result;
277
+ }
278
+
279
+ /**
280
+ * EncryptField
281
+ * Determine if field need to be encrypted and encrypt value if it so
282
+ * @param {string} field name
283
+ * @param {string} value
284
+ * @return {string} encrypted or plain value
285
+ */
286
+ public function EncryptField($field, $value)
287
+ {
288
+ if( $this->isFieldEncrypted($field) && $this->connection->isEncryptionByPHPEnabled() )
289
+ {
290
+ if( is_null($this->ESFunctions) )
291
+ $this->ESFunctions = $this->getESFunctions();
292
+
293
+ return $this->ESFunctions->Encrypt($value);
294
+ }
295
+
296
+ return $value;
297
+ }
298
+
299
+ /**
300
+ * DecryptField
301
+ * Determine if field encrypted and decrypt value if it so
302
+ * Please note, when changing this function you should make appropriate changes in wizard method (dynamic permissions --> add new user) #8923
303
+ * @param {string} field name
304
+ * @param {string} value
305
+ * @return {string} decrypted or plain value
306
+ */
307
+ public function DecryptField($field, $value)
308
+ {
309
+ if($this->isFieldEncrypted($field) && $this->connection->isEncryptionByPHPEnabled())
310
+ {
311
+ if(is_null($this->ESFunctions))
312
+ $this->ESFunctions = $this->getESFunctions();
313
+
314
+ return $this->ESFunctions->Decrypt($value);
315
+ }
316
+ return $value;
317
+ }
318
+
319
+ function getESFunctions()
320
+ {
321
+ if ( $this->connection->_encryptInfo["alg"] == ENCRYPTION_ALG_DES )
322
+ return new RunnerCiphererDES($this->key);
323
+ if ( $this->connection->_encryptInfo["alg"] == ENCRYPTION_ALG_AES )
324
+ return new RunnerCiphererAES($this->key);
325
+ if ( $this->connection->_encryptInfo["alg"] == ENCRYPTION_ALG_AES_256 )
326
+ return new RunnerCiphererAES($this->key, true);
327
+ }
328
+
329
+ /**
330
+ * @param Mixed loginSet (optional)
331
+ * @return Mixed
332
+ */
333
+ public static function getForLogin( $loginSet = null )
334
+ {
335
+ if( !!Security::loginTable() ) {
336
+ return new RunnerCipherer( "public.kbusers", $loginSet);
337
+ }
338
+ return new RunnerCipherer( GLOBAL_PAGES, null);
339
+ }
340
+ }
341
+ ?>
classes/context.php ADDED
@@ -0,0 +1,623 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class RunnerContextItem
3
+ {
4
+ /**
5
+ * define('CONTEXT_GLOBAL', 0); // global context
6
+ * define('CONTEXT_PAGE', 1); // page where pageObject is available
7
+ * define('CONTEXT_BUTTON', 2); // button or other AJAX event
8
+ * define('CONTEXT_LOOKUP', 3); // dependent lookup
9
+ * define('CONTEXT_ROW', 4); // processing grid row on multiple-records page (list)
10
+ * define('CONTEXT_COMMAND', 5); // DsCommand context
11
+ * define('CONTEXT_SEARCH', 6); // Search object context
12
+ * define('CONTEXT_MASTER', 7); // Search object context
13
+ */
14
+ public $type;
15
+
16
+ public $pageObj;
17
+ public $data;
18
+ public $oldData;
19
+ public $newData;
20
+ public $detailsKeys;
21
+ public $dc;
22
+ public $searchClause;
23
+ public $masterData;
24
+
25
+ function __construct( $type, $params )
26
+ {
27
+ RunnerApply($this, $params);
28
+ $this->type = $type;
29
+ }
30
+
31
+ public function getType()
32
+ {
33
+ return $this->type;
34
+ }
35
+
36
+ /**
37
+ * @return Array
38
+ */
39
+ public function getValues()
40
+ {
41
+ if( $this->data )
42
+ return $this->data;
43
+
44
+ if( $this->dc ) {
45
+ return $this->dc->values;
46
+ }
47
+
48
+ if( $this->pageObj )
49
+ return $this->pageObj->getCurrentRecord();
50
+
51
+ return array();
52
+ }
53
+
54
+ /**
55
+ * @param String field
56
+ * @return Mixed
57
+ */
58
+ public function getFieldValue( $field )
59
+ {
60
+ $data = $this->getValues();
61
+ return getArrayElementNC( $data, $field );
62
+ }
63
+
64
+ public function getSearchValue( $field ) {
65
+ return $this->searchClause->_getFieldValue( $field, null, false, true );
66
+ }
67
+
68
+ public function getAllSearchValue() {
69
+ return $this->searchClause->getAllFieldsSearchValue();
70
+ }
71
+
72
+ /**
73
+ * @return Array
74
+ */
75
+ public function getOldValues()
76
+ {
77
+ if( $this->oldData )
78
+ return $this->oldData;
79
+
80
+ if( $this->pageObj )
81
+ return $this->pageObj->getOldRecordData();
82
+
83
+ return array();
84
+ }
85
+
86
+ public function getKeyValue( $field ) {
87
+ if( $this->dc ) {
88
+ return $this->dc->keys[ $field ];
89
+ }
90
+ return null;
91
+ }
92
+
93
+ public function getOrderValue( $key ) {
94
+ if( !$this->dc ) {
95
+ return null;
96
+ }
97
+ $idx = 0;
98
+ if( substr( $key, 0, 5) == "field" ) {
99
+ $param = "field";
100
+ $idx = (int)substr( $key, 5);
101
+ } else if( substr( $key, 0, 3 ) == "dir" ) {
102
+ $param = "dir";
103
+ $idx = (int)substr( $key, 3);
104
+ }
105
+ if( !$idx || $idx < 1 ) {
106
+ return null;
107
+ }
108
+ if( count( $this->dc->order ) <= $idx ) {
109
+ return null;
110
+ }
111
+ $order = $this->dc->order[ $idx - 1 ];
112
+ if( $param == "field") {
113
+ return $order["column"];
114
+ }
115
+ if( $param == "dir") {
116
+ return $order["dir"];
117
+ }
118
+ return null;
119
+ }
120
+
121
+
122
+ public function getFilterValue( $field ) {
123
+ if( $this->dc ) {
124
+ return $this->dc->findFieldFilterValue( $field );
125
+ }
126
+ }
127
+
128
+ public function getLimitValue( $key ) {
129
+ if( !$this->dc ) {
130
+ return "";
131
+ }
132
+ if( $key == "record_from" ) {
133
+ return $this->dc->startRecord + 1;
134
+ }
135
+ if( $key == "record_to" ) {
136
+ return $this->dc->startRecord + $this->dc->reccount;
137
+ }
138
+ if( $key == "record_count" ) {
139
+ return $this->dc->reccount;
140
+ }
141
+ if( $key == "record_offset" ) {
142
+ return $this->dc->startRecord;
143
+ }
144
+ }
145
+
146
+
147
+ /**
148
+ * @param String field
149
+ * @return Mixed
150
+ */
151
+ public function getOldFieldValue( $field )
152
+ {
153
+ $oldData = $this->getOldValues();
154
+ return getArrayElementNC( $oldData, $field );
155
+ }
156
+
157
+ /**
158
+ * @param String field
159
+ * @return Mixed
160
+ */
161
+ public function getNewFieldValue( $field )
162
+ {
163
+ if ( $this->newData )
164
+ return getArrayElementNC( $this->newData, $field );
165
+ if( $this->dc ) {
166
+ return getArrayElementNC( $this->dc->values, $field );
167
+ }
168
+
169
+ return $this->getFieldValue( $field );
170
+ }
171
+
172
+
173
+
174
+ /**
175
+ * @return Array
176
+ */
177
+ public function getMasterValues()
178
+ {
179
+ if( $this->masterData )
180
+ return $this->masterData;
181
+
182
+ if( $this->pageObj )
183
+ return $this->pageObj->getMasterRecord();
184
+
185
+ return array();
186
+ }
187
+
188
+ /**
189
+ * @param String field
190
+ * @return Mixed
191
+ */
192
+ public function getMasterFieldValue( $field )
193
+ {
194
+ $masterData = $this->getMasterValues();
195
+ if( !$masterData ) {
196
+ return "";
197
+ }
198
+ return getArrayElementNC( $masterData, $field );
199
+
200
+ }
201
+
202
+ /**
203
+ * @param String key
204
+ * @return String
205
+ */
206
+ public function getUserValue( $key )
207
+ {
208
+ return getArrayElementNC( Security::currentUserData(), $key );
209
+ }
210
+
211
+ /**
212
+ * @param String key
213
+ * @return Mixed
214
+ */
215
+ public function getSessionValue( $key )
216
+ {
217
+ return getSessionElementNC( $key );
218
+ }
219
+
220
+ public function getDetailsKeyValue( $key ) {
221
+ return $this->detailsKeys[ $key ];
222
+ }
223
+
224
+
225
+ /**
226
+ * Returns true if context must serve this scope, and search must stop here.
227
+ * For example, when page context is found, it must serve the 'master' and 'details' scopes even if no master-detail is in effect.
228
+ * @param String - scope like 'keys', 'master', 'details'
229
+ * @return Boolean
230
+ */
231
+ public function hasScope( $scope ) {
232
+ if( $scope == "master" )
233
+ return $this->masterData || $this->type == CONTEXT_PAGE;
234
+
235
+ if( $scope == "session" )
236
+ return true;
237
+
238
+ if( $scope == "user" )
239
+ return true;
240
+
241
+ if( $scope == "old" )
242
+ return $this->oldData || $this->type == CONTEXT_PAGE;
243
+
244
+ if( $scope == "keys" )
245
+ return $this->type == CONTEXT_COMMAND;
246
+
247
+ if( $scope == "order" )
248
+ return $this->type == CONTEXT_COMMAND;
249
+
250
+
251
+ if( $scope == "new" )
252
+ return $this->newData || $this->type == CONTEXT_PAGE || $this->type == CONTEXT_COMMAND;
253
+
254
+ if ( $scope == "global" )
255
+ return true;
256
+
257
+ if( $scope == "details" )
258
+ return $this->type == CONTEXT_PAGE || $this->type == CONTEXT_MASTER;
259
+
260
+ if ( $scope == "values" )
261
+ return !!$this->data || $this->type == CONTEXT_PAGE || $this->type == CONTEXT_COMMAND;
262
+
263
+ if( $scope == "search" )
264
+ return $this->type == CONTEXT_SEARCH;
265
+
266
+ if( $scope == "filter" )
267
+ return $this->type == CONTEXT_COMMAND;
268
+
269
+ if( $scope == "request" )
270
+ return true;
271
+
272
+ if( $scope == "limit" )
273
+ return $this->type == CONTEXT_COMMAND;
274
+
275
+ if( $scope == "all_field_search" )
276
+ return $this->type == CONTEXT_SEARCH;
277
+ }
278
+
279
+ /**
280
+ * @param String key
281
+ * @return Mixed
282
+ */
283
+ public function getContextValue( $scope, $key )
284
+ {
285
+
286
+ if( $scope == "master" )
287
+ return $this->getMasterFieldValue( $key );
288
+
289
+ if( $scope == "session" )
290
+ return $this->getSessionValue( $key );
291
+
292
+ if( $scope == "user" )
293
+ return $this->getUserValue( $key );
294
+
295
+ if( $scope == "old" )
296
+ return $this->getOldFieldValue( $key );
297
+
298
+ if( $scope == "keys" )
299
+ return $this->getKeyValue( $key );
300
+
301
+ if( $scope == "order" )
302
+ return $this->getOrderValue( $key );
303
+
304
+ if( $scope == "new" )
305
+ return $this->getNewFieldValue( $key );
306
+
307
+ if ( $scope == "global" && $key == "language" )
308
+ return mlang_getcurrentlang();
309
+
310
+ if( $scope == "details" ) {
311
+ if( $this->type == CONTEXT_PAGE )
312
+ return $this->pageObj->getDetailsKeyValue( $key );
313
+ if( $this->type == CONTEXT_MASTER )
314
+ return $this->getDetailsKeyValue( $key );
315
+ }
316
+
317
+ if( $scope == "values" )
318
+ return $this->getFieldValue( $key );
319
+
320
+ if( $scope == "search" )
321
+ return $this->getSearchValue( $key );
322
+
323
+ if( $scope == "filter" )
324
+ return $this->getFilterValue( $key );
325
+
326
+ if( $scope == "request" )
327
+ return postvalue( $key );
328
+
329
+ if( $scope == "limit" )
330
+ return $this->getLimitValue( $key );
331
+
332
+ if( $scope == "all_field_search" )
333
+ return $this->getAllSearchValue();
334
+
335
+ return false;
336
+ }
337
+ }
338
+
339
+ /**
340
+ * Singletone. All public functions are static
341
+ */
342
+ class RunnerContext
343
+ {
344
+ protected $stack = array();
345
+
346
+ public function __construct( )
347
+ {
348
+ $context = new RunnerContextItem( CONTEXT_GLOBAL, array() );
349
+ $this->stack[ count($this->stack) ] = $context;
350
+ }
351
+
352
+ public static function push( $context )
353
+ {
354
+ global $contextStack;
355
+ $contextStack->stack[ count($contextStack->stack) ] = $context;
356
+ }
357
+
358
+ public static function current( )
359
+ {
360
+ global $contextStack;
361
+ return $contextStack->stack[ count($contextStack->stack) - 1 ];
362
+ }
363
+
364
+ public static function pop( )
365
+ {
366
+ global $contextStack;
367
+
368
+ // this sometimes happens during the error reporting
369
+ if( !$contextStack->stack )
370
+ return null;
371
+
372
+ $context = $contextStack->stack[ count($contextStack->stack) - 1 ];
373
+ unset( $contextStack->stack[ count($contextStack->stack) - 1 ] );
374
+
375
+ return $context;
376
+ }
377
+
378
+ // Utility functions
379
+ /**
380
+ * Shortcut for adding page-based context
381
+ */
382
+ public static function pushPageContext( $pageObj ) {
383
+ RunnerContext::push( new RunnerContextItem( CONTEXT_PAGE, array( "pageObj" => $pageObj ) ) );
384
+ }
385
+ /**
386
+ * Shortcut for adding record-based context
387
+ */
388
+ public static function pushRecordContext( $record, $pageObj ) {
389
+ RunnerContext::push( new RunnerContextItem( CONTEXT_ROW, array( "pageObj" => $pageObj, "data" => $record ) ) ); //?
390
+ }
391
+
392
+ public static function pushDataCommandContext( $dc ) {
393
+ RunnerContext::push( new RunnerContextItem( CONTEXT_COMMAND, array( "dc" => $dc ) ) );
394
+ }
395
+
396
+ public static function pushSearchContext( $searchClause ) {
397
+ RunnerContext::push( new RunnerContextItem( CONTEXT_SEARCH, array( "searchClause" => $searchClause ) ) );
398
+ }
399
+
400
+ public static function pushMasterContext( $detailsKeys ) {
401
+ RunnerContext::push( new RunnerContextItem(
402
+ CONTEXT_MASTER,
403
+ array(
404
+ "detailsKeys" => $detailsKeys,
405
+ ) ) );
406
+ }
407
+
408
+
409
+ public static function getMasterValues() {
410
+ $ctx = RunnerContext::current();
411
+ return $ctx->getMasterValues();
412
+ }
413
+
414
+ public static function getValues() {
415
+ $ctx = RunnerContext::current();
416
+ return $ctx->getValues();
417
+ }
418
+
419
+ /**
420
+ * @return String
421
+ */
422
+ public static function PrepareRest( $str, $urlenc = true ) {
423
+ $context = RunnerContext::current();
424
+ $tokens = DB::scanTokenString($str);
425
+
426
+ $replacements = array();
427
+ // build array of replacements in this format:
428
+ // "offset" => position in the string where replacement should be done
429
+ // "len" => length of original substring to cut out
430
+ // "insert" => string to insert in place of cut out
431
+
432
+ foreach ($tokens["matches"] as $i => $match) {
433
+ $offset = $tokens["offsets"][$i];
434
+ $token = $tokens["tokens"][$i];
435
+
436
+ $repl = array(
437
+ "offset" => $offset,
438
+ "len" => strlen($match)
439
+ );
440
+ $val = "";
441
+ if (is_numeric($token) && count( $args ) > $token) {
442
+ $val = $args[(int)$token];
443
+ } else {
444
+ $val = RunnerContext::getValue($token);
445
+ }
446
+ if( $urlenc )
447
+ $val = rawurlencode($val);
448
+ $repl["insert"] = $val;
449
+
450
+ $replacements[] = $repl;
451
+ }
452
+ // do replacements
453
+ return RunnerContext::doReplacements( $str, $replacements );
454
+ }
455
+
456
+ /**
457
+ * locate all <? - ?> snippets in a string
458
+ * @param String str
459
+ * @return Array of array(
460
+ * "offset" => integer - offset of the opening bracket in the original string
461
+ * "len" => integer - length includes opening and closing brackets: <? - ?>
462
+ * )
463
+ */
464
+ protected static function getOptionalBlocks( $str ) {
465
+ if( !is_string( $str ) )
466
+ return array();
467
+
468
+ $snippetStack = array();
469
+ $snippets = array();
470
+ $pos = strpos( $str, '<?' );
471
+ if( $pos === false )
472
+ return array();
473
+
474
+ while( true ) {
475
+ $snippetStack[] = $pos;
476
+ $newPos = strpos( $str, '<?', $pos + 1 );
477
+
478
+ /* locate all ?> before the next <? or end of string*/
479
+ $tailLen = ( $newPos !== false ? $newPos : strlen( $str ) ) - $pos;
480
+ $tail = substr( $str, $pos, $tailLen );
481
+ $endPos = 0;
482
+ while( ($endPos = strpos( $tail, '?>', $endPos+1 ) ) !== false && count( $snippetStack ) ) {
483
+ $stackIdx = count( $snippetStack ) - 1;
484
+ $snippets[] = array( "offset" => $snippetStack[ $stackIdx ], "len" => $endPos + $pos + 2 - $snippetStack[ $stackIdx ] );
485
+ $snippetStack = array_slice( $snippetStack, 0, $stackIdx );
486
+ }
487
+ if( $newPos === false )
488
+ break;
489
+ $pos = $newPos;
490
+ }
491
+ return $snippets;
492
+ }
493
+
494
+ /**
495
+ * do actual replacements
496
+ * @param String $str - source string
497
+ * @param Array $replacements - Array of Array(
498
+ * "offset" => Integer, position in the source tring
499
+ * "len" => Integer, length of the source string portion to be replaced
500
+ * "insert" => String, value to insert instead of replaced
501
+ * )
502
+ */
503
+ public static function doReplacements( $str, $replacements ) {
504
+ if( !is_string( $str ) )
505
+ return $str;
506
+
507
+ $snippets = RunnerContext::getOptionalBlocks( $str );
508
+ /* snippets with 0 non-empty requirements must be deleted from the string */
509
+ /* mark empty snippets */
510
+ for( $i=0; $i < count( $snippets ); ++$i ) {
511
+ $s = &$snippets[$i];
512
+ $s["empty"] = true;
513
+ foreach ($replacements as $r) {
514
+ /* replacement inside snippet */
515
+ if( $r["offset"] > $s["offset"] && $r["offset"] < $s["offset"] + $s["len"] ) {
516
+ if( $r["insert"] != "" ) {
517
+ $s["empty"] = false;
518
+ break;
519
+ }
520
+ }
521
+ }
522
+ }
523
+
524
+ /* do replacements */
525
+ $offsetShift = 0;
526
+ foreach ($replacements as $r) {
527
+ $str = substr_replace($str, $r["insert"], $r["offset"] + $offsetShift, $r["len"]);
528
+ $offsetDelta = strlen($r["insert"]) - $r["len"];
529
+ // update all $snippets
530
+ RunnerContext::updateOptionalBlockOffset( $snippets, $r["offset"], $offsetDelta );
531
+ $offsetShift += $offsetDelta;
532
+ }
533
+
534
+ /* process optional blocks - delete or remove brackets */
535
+ for( $i=0; $i < count( $snippets ); ++$i ) {
536
+ $s = &$snippets[$i];
537
+ if( $s["empty"]) {
538
+ $str = substr_replace($str, "", $s["offset"], $s["len"] );
539
+ $offsetDelta = -$s["len"];
540
+ } else {
541
+ $str = substr_replace($str,
542
+ substr( $str, $s["offset"] + 2, $s["len"] - 4 ),
543
+ $s["offset"],
544
+ $s["len"]
545
+ );
546
+ $offsetDelta = -4;
547
+ }
548
+ RunnerContext::updateOptionalBlockOffset( $snippets, $s["offset"], $offsetDelta );
549
+ }
550
+ return $str;
551
+ }
552
+
553
+ protected static function updateOptionalBlockOffset( &$snippets, $offset, $delta ) {
554
+ for( $i=0; $i < count( $snippets ); ++$i ) {
555
+ $s = &$snippets[$i];
556
+ if( $s["offset"] > $offset ) {
557
+ $s["offset"] += $delta;
558
+ } else {
559
+ if( $s["offset"] + $s["len"] > $offset ) {
560
+ $s["len"] += $delta;
561
+ }
562
+ }
563
+ }
564
+ }
565
+
566
+
567
+ public static function getValue( $key ) {
568
+ $prefix = "";
569
+ $dotPos = strpos( $key, ".");
570
+ if( $dotPos !== FALSE )
571
+ {
572
+ $scope = strtolower( substr( $key, 0, $dotPos ) );
573
+ $key = substr( $key, $dotPos + 1 );
574
+ } else {
575
+ if( $key === "language" ) {
576
+ $scope = "global";
577
+ } else if( $key == "all_field_search") {
578
+ $scope = $key;
579
+ } else {
580
+ $scope = "values";
581
+ }
582
+
583
+ }
584
+ return RunnerContext::_getValue( $scope, $key );
585
+ }
586
+
587
+
588
+ /**
589
+ * Search got requested value in the stack of contexts
590
+ * @param String - scope like 'keys', 'master', 'details'
591
+ * @param String - key. 'details.teamId' is translated to context=details, key=teamId
592
+ * @return String or false if value is not found
593
+ */
594
+ protected static function _getValue( $scope, $key )
595
+ {
596
+ global $contextStack;
597
+ $idx = count( $contextStack->stack );
598
+ while( $idx > 0 ) {
599
+ $ctx = $contextStack->stack[ --$idx ];
600
+ if( $ctx->hasScope( $scope ) ) {
601
+ return $ctx->getContextValue( $scope, $key );
602
+ }
603
+ }
604
+ return false;
605
+ }
606
+
607
+ }
608
+
609
+ /**
610
+ * Push context in constructor and pop in destructor
611
+ */
612
+ class TempContext
613
+ {
614
+ function __construct( $context ) {
615
+ RunnerContext::push( $context );
616
+ }
617
+
618
+ function __destruct() {
619
+ RunnerContext::pop();
620
+ }
621
+ }
622
+
623
+ ?>
classes/controls/CheckboxField.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class CheckboxField extends EditControl
3
+ {
4
+ function __construct($field, $pageObject, $id, $connection)
5
+ {
6
+ parent::__construct($field, $pageObject, $id, $connection);
7
+ $this->format = EDIT_FORMAT_CHECKBOX;
8
+ }
9
+
10
+ function buildControl($value, $mode, $fieldNum, $validate, $additionalCtrlParams, $data)
11
+ {
12
+ parent::buildControl($value, $mode, $fieldNum, $validate, $additionalCtrlParams, $data);
13
+ if($mode == MODE_ADD || $mode == MODE_INLINE_ADD || $mode == MODE_EDIT || $mode == MODE_INLINE_EDIT)
14
+ {
15
+ $checked = "";
16
+
17
+ if( $this->connection->dbType == nDATABASE_PostgreSQL
18
+ && ($value === "t" || $value != "f" && $value != "" && $value != 0 )
19
+ || $this->connection->dbType != nDATABASE_PostgreSQL && ($value != "" && $value != 0 )) {
20
+
21
+ $checked=" checked";
22
+ }
23
+
24
+ if ( $this->connection->dbType == nDATABASE_PostgreSQL ) {
25
+ $reservedBoolean = 'data-true="t" data-false="f"';
26
+ }
27
+
28
+ echo '<span class="checkbox r-checkbox-control"><label>';
29
+
30
+ echo '<input id="'.$this->ctype.'" type="hidden" name="'.$this->ctype.'" value="checkbox">';
31
+ echo '<input id="'.$this->cfield.'" type="Checkbox" '
32
+ .(($mode == MODE_INLINE_EDIT || $mode == MODE_INLINE_ADD) && $this->is508==true ? 'alt="'.$this->strLabel.'" ' : '')
33
+ .'name="'.$this->cfield.'" '.$checked.' '.$reservedBoolean.'>';
34
+
35
+ echo '</label></span>';
36
+ }
37
+ else
38
+ {
39
+ echo '<input id="'.$this->ctype.'" type="hidden" name="'.$this->ctype.'" value="checkbox">';
40
+ echo '<select id="'.$this->cfield.'" '.(($mode == MODE_INLINE_EDIT || $mode == MODE_INLINE_ADD) && $this->is508==true ? 'alt="'
41
+ .$this->strLabel.'" ' : '').'name="'.$this->cfield.'" class="form-control">';
42
+
43
+ $options = array( "", "on", "off" );
44
+ $possibleOptions = array( "" => array(), "on" => array("on", "1"), "off" => array("off", "0") );
45
+ $labels = array("", "True", "False");
46
+
47
+ foreach( $options as $key => $optValue )
48
+ {
49
+ $selected = in_array( $value, $possibleOptions[ $optValue ] ) ? " selected" : "";
50
+ echo '<option value="' . $optValue . '"' . $selected.'>' . $labels[ $key ] . '</option>';
51
+ }
52
+
53
+ echo "</select>";
54
+ }
55
+ $this->buildControlEnd($validate, $mode);
56
+ }
57
+
58
+ function getFirstElementId()
59
+ {
60
+ return $this->cfield;
61
+ }
62
+
63
+ /**
64
+ * Get 'equal to on/off' condition
65
+ */
66
+ public static function getFieldCondition( $field, $searchFor ) {
67
+ if( $searchFor == "none" || $searchFor != "on" && $searchFor != "off" )
68
+ return null;
69
+
70
+ $offCondition = DataCondition::_Or( array(
71
+ DataCondition::FieldIs( $field, dsopEQUAL, '0', false, 0, null, false ),
72
+ DataCondition::FieldIs( $field, dsopEMPTY, '', false, 0, null, false )
73
+ ));
74
+
75
+ if( $searchFor == "off" )
76
+ return $offCondition;
77
+
78
+ return DataCondition::_Not( $offCondition );
79
+ }
80
+
81
+ /**
82
+ * Returns basic condition
83
+ */
84
+ public function getBasicFieldCondition( $searchFor, $strSearchOption, $searchFor2 = "", $etype = "" ) {
85
+ if( $strSearchOption != EQUALS )
86
+ return null;
87
+
88
+ return CheckboxField::getFieldCondition( $this->field, $searchFor );
89
+ }
90
+ }
91
+ ?>
classes/controls/Control.php ADDED
@@ -0,0 +1,790 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EditControl
3
+ {
4
+ /**
5
+ * Reference to RunnerPage (or its descendant) instance
6
+ */
7
+ public $pageObject = null;
8
+ /**
9
+ * Reference to EditControlsContainer instance
10
+ */
11
+ public $container = null;
12
+
13
+ public $id = "";
14
+ public $field = "";
15
+ public $goodFieldName = "";
16
+ public $format = "";
17
+ /**
18
+ * Field name prefix
19
+ * @var {string}
20
+ */
21
+ public $cfieldname = "";
22
+ /**
23
+ * Value field name
24
+ * @var {string}
25
+ */
26
+ public $cfield = "";
27
+ /**
28
+ * Type field name
29
+ * @var {string}
30
+ */
31
+ public $ctype = "";
32
+ /**
33
+ * A flag indicating whether the support for section 508 is on
34
+ * @var {bool}
35
+ */
36
+ public $is508 = false;
37
+ public $strLabel = "";
38
+ public $type = "";
39
+ public $inputStyle = "";
40
+ public $iquery = "";
41
+ public $keylink = "";
42
+ public $webValue = null;
43
+ public $webType = null;
44
+
45
+ /**
46
+ * Storage for control settings. It fills in the init() function.
47
+ * @var {array}
48
+ */
49
+ public $settings = array();
50
+
51
+ //Search params
52
+ public $isOracle = false;
53
+ public $ismssql = false;
54
+ public $isdb2 = false;
55
+ public $btexttype = false;
56
+ public $isMysql = false;
57
+ public $like = "like";
58
+
59
+ public $searchOptions = array();
60
+
61
+ public $searchPanelControl = false;
62
+ public $data = array();
63
+
64
+ /**
65
+ * @type Connection
66
+ */
67
+ protected $connection;
68
+
69
+ public $forSpreadsheetGrid;
70
+
71
+
72
+ function __construct($field, $pageObject, $id, $connection)
73
+ {
74
+ $this->field = $field;
75
+ $this->goodFieldName = GoodFieldName($field);
76
+ $this->setID($id);
77
+ $this->connection = $connection;
78
+
79
+ $this->pageObject = $pageObject;
80
+
81
+ $this->is508 = isEnableSection508();
82
+
83
+ $this->strLabel = $pageObject->pSetEdit->label($field);
84
+ $this->type = $pageObject->pSetEdit->getFieldType($this->field);
85
+
86
+ if( $this->connection->dbType == nDATABASE_Oracle )
87
+ $this->isOracle = true;
88
+
89
+ if( $this->connection->dbType == nDATABASE_MSSQLServer )
90
+ $this->ismssql=true;
91
+
92
+ if( $this->connection->dbType == nDATABASE_DB2 )
93
+ $this->isdb2=true;
94
+
95
+ if( $this->connection->dbType == nDATABASE_MySQL )
96
+ $this->isMysql = true;
97
+
98
+ if( $this->connection->dbType == nDATABASE_PostgreSQL )
99
+ $this->like = "ilike";
100
+
101
+ $this->searchOptions[CONTAINS] = "Contains";
102
+ $this->searchOptions[EQUALS] = "Equals";
103
+ $this->searchOptions[STARTS_WITH] = "Starts with";
104
+ $this->searchOptions[MORE_THAN] = "More than";
105
+ $this->searchOptions[LESS_THAN] = "Less than";
106
+ $this->searchOptions[BETWEEN] = "Between";
107
+ $this->searchOptions[EMPTY_SEARCH] = "Empty";
108
+ $this->searchOptions[NOT_CONTAINS] = "Doesn't contain";
109
+ $this->searchOptions[NOT_EQUALS] = "Doesn't equal";
110
+ $this->searchOptions[NOT_STARTS_WITH] = "Doesn't start with";
111
+ $this->searchOptions[NOT_MORE_THAN] = "Is not more than";
112
+ $this->searchOptions[NOT_LESS_THAN] = "Is not less than";
113
+ $this->searchOptions[NOT_BETWEEN] = "Is not between";
114
+ $this->searchOptions[NOT_EMPTY] = "Is not empty";
115
+
116
+ $this->init();
117
+ }
118
+
119
+ function setID($id)
120
+ {
121
+ $this->id = $id;
122
+ $this->cfieldname = $this->goodFieldName."_".$id;
123
+ $this->cfield = "value_".$this->goodFieldName."_".$id;
124
+ $this->ctype = "type_".$this->goodFieldName."_".$id;
125
+ }
126
+
127
+ /**
128
+ * addJSFiles
129
+ * Add control JS files to page object
130
+ */
131
+ function addJSFiles()
132
+ {
133
+ //example
134
+ // $this->pageObject->AddJSFile("include/mupload.js");
135
+ }
136
+
137
+ /**
138
+ * addCSSFiles
139
+ * Add control CSS files to page object
140
+ */
141
+ function addCSSFiles()
142
+ {
143
+ //example
144
+ // $this->pageObject->AddCSSFile("include/mupload.css");
145
+ }
146
+
147
+ function getSetting($key)
148
+ {
149
+ return $this->pageObject->pSetEdit->getFieldData($this->field, $key);
150
+ }
151
+
152
+ function addJSSetting($key, $value)
153
+ {
154
+ $this->pageObject->jsSettings['tableSettings'][ $this->pageObject->tName ]['fieldSettings'][ $this->field ][ $this->container->pageType ][ $key ] = $value;
155
+ }
156
+
157
+ function buildControl($value, $mode, $fieldNum, $validate, $additionalCtrlParams, $data)
158
+ {
159
+ $this->searchPanelControl = $this->isSearchPanelControl( $mode, $additionalCtrlParams );
160
+ $this->inputStyle = $this->getInputStyle( $mode );
161
+
162
+ if($fieldNum)
163
+ {
164
+ $this->cfield="value".$fieldNum."_".$this->goodFieldName."_".$this->id;
165
+ $this->ctype="type".$fieldNum."_".$this->goodFieldName."_".$this->id;
166
+ }
167
+
168
+ $this->iquery = "field=".rawurlencode($this->field);
169
+
170
+ $arrKeys = $this->pageObject->pSetEdit->getTableKeys();
171
+ for ($j = 0; $j < count($arrKeys); $j++)
172
+ {
173
+ $this->keylink .= "&key".($j+1)."=".rawurlencode( $data[ $arrKeys[$j] ] );
174
+ }
175
+ $this->iquery .= $this->keylink;
176
+
177
+ $isHidden = (isset($additionalCtrlParams['hidden']) && $additionalCtrlParams['hidden']);
178
+
179
+ $additionalClass = "";
180
+ if( $this->pageObject->isBootstrap() )
181
+ {
182
+ if( $this->pageObject->isPD() ) {
183
+ $additionalClass.= "bs-ctrlspan ";
184
+ } else {
185
+ $additionalClass.= "bs-ctrlspan rnr-nowrap ";
186
+ }
187
+ if( $this->format == EDIT_FORMAT_READONLY )
188
+ $additionalClass.= "form-control-static ";
189
+
190
+ if( $validate['basicValidate'] && array_search('IsRequired', $validate['basicValidate']) !== false )
191
+ $additionalClass.= "bs-inlinerequired";
192
+ }
193
+ else
194
+ {
195
+ $additionalClass.= "rnr-nowrap ";
196
+ }
197
+
198
+ echo '<span id="edit'.$this->id.'_'.$this->goodFieldName.'_'.$fieldNum.'" class="'.$additionalClass.'"'.($isHidden ? ' style="display:none"' : '').'>';
199
+ }
200
+
201
+ function getFirstElementId()
202
+ {
203
+ return false;
204
+ }
205
+
206
+ /**
207
+ * Check if the control belongs to the Search Panel
208
+ * @param Number mode
209
+ * @param Array additionalCtrlParams
210
+ * @return Boolean
211
+ */
212
+ function isSearchPanelControl( $mode, $additionalCtrlParams )
213
+ {
214
+ return $mode == MODE_SEARCH && isset( $additionalCtrlParams['searchPanelControl'] ) && $additionalCtrlParams['searchPanelControl'] && !$this->pageObject->mobileTemplateMode();
215
+ }
216
+
217
+ function buildControlEnd($validate, $mode)
218
+ {
219
+ if( $this->pageObject->isBootstrap() )
220
+ echo '</span>';
221
+ else if( $validate['basicValidate'] && array_search('IsRequired', $validate['basicValidate'])!==false)
222
+ echo'&nbsp;<font color="red">*</font></span>';
223
+ else
224
+ echo '</span>';
225
+ }
226
+
227
+ function getPostValueAndType()
228
+ {
229
+ $this->webValue = postvalue("value_".$this->goodFieldName."_".$this->id);
230
+ $this->webType = postvalue("type_".$this->goodFieldName."_".$this->id);
231
+ }
232
+
233
+ function getWebValue()
234
+ {
235
+ return $this->webValue;
236
+ }
237
+
238
+ function readWebValue(&$avalues, &$blobfields, $legacy1, $legacy2, &$filename_values)
239
+ {
240
+ $this->getPostValueAndType();
241
+
242
+ if (FieldSubmitted($this->goodFieldName."_".$this->id))
243
+ $this->webValue = prepare_for_db($this->field, $this->webValue, $this->webType);
244
+ else
245
+ $this->webValue = false;
246
+
247
+ if($this->pageObject->pageType == PAGE_EDIT && $this->pageObject->getEditFormat( $this->field) === EDIT_FORMAT_READONLY )
248
+ {
249
+ // ??
250
+ if( $this->pageObject->pSetEdit->getAutoUpdateValue($this->field) )
251
+ $this->webValue = $this->pageObject->pSetEdit->getAutoUpdateValue($this->field);
252
+ else if( !originalTableField( $this->field, $this->pageObject->pSetEdit ) ){
253
+ $this->webValue = false;
254
+ }
255
+ }
256
+
257
+ if(!($this->webValue===false))
258
+ {
259
+ if( $this->connection->dbType == nDATABASE_Informix )
260
+ {
261
+ if(IsTextType($this->pageObject->pSetEdit->getFieldType($this->field)))
262
+ $blobfields[] = $this->field;
263
+ }
264
+ $avalues[ $this->field ] = $this->webValue;
265
+ }
266
+ }
267
+
268
+ /**
269
+ * Get the substitute columns list for the SELECT Clause and the FORM clause part
270
+ * that will be joined to the basic page's FROM clause
271
+ * @param String searchFor
272
+ * @param String searchOpt
273
+ * @param Boolean isSuggest
274
+ * @return Array
275
+ */
276
+ public function getSelectColumnsAndJoinFromPart($searchFor, $searchOpt, $isSuggest)
277
+ {
278
+ return array(
279
+ "selectColumns"=> $this->getFieldSQLDecrypt(),
280
+ "joinFromPart"=> ""
281
+ );
282
+ }
283
+
284
+ /**
285
+ * @param String strSearchOption
286
+ * @return Boolean
287
+ */
288
+ public function checkIfDisplayFieldSearch( $strSearchOption )
289
+ {
290
+ return false;
291
+ }
292
+
293
+ /**
294
+ * Form the control's search options markup basing on user's search options settings
295
+ * @param Array optionsArray Control specified search options
296
+ * @param String selOpt The control selected search option
297
+ * @param Boolean not It indicates if the search option passed should be inverted ($selOpt should be considered as "NOT ".$selOpt)
298
+ * @param Boolean both It indicates if control needs both positive and negative("NOT ...") search options
299
+ * @return String
300
+ */
301
+ function buildSearchOptions($optionsArray, $selOpt, $not, $both)
302
+ {
303
+ $userSearchOptions = $this->pageObject->pSetEdit->getSearchOptionsList( $this->field );
304
+
305
+ $currentOption = $not ? 'NOT '.$selOpt : $selOpt;
306
+ if( $userSearchOptions && isset( $this->searchOptions[ $currentOption ] ) )
307
+ $userSearchOptions[] = $currentOption;
308
+
309
+ if( !!$userSearchOptions )
310
+ $optionsArray = array_intersect($optionsArray, $userSearchOptions);
311
+
312
+ $defaultOption = $this->pageObject->pSetEdit->getDefaultSearchOption( $this->field );
313
+ if( !$defaultOption )
314
+ $defaultOption = $optionsArray[0];
315
+
316
+ $result = '';
317
+ foreach($optionsArray as $option)
318
+ {
319
+ if( !isset( $this->searchOptions[ $option ] ) || !$both && substr($option, 0, 4) == 'NOT ' )
320
+ continue;
321
+
322
+ $selected = $currentOption == $option ? 'selected' : '';
323
+ $dataAttr = $defaultOption == $option ? ' data-default-option="true"' : '';
324
+ $result.= '<option value="'.$option.'" '.$selected.$dataAttr.'>'.$this->searchOptions[ $option ].'</option>';
325
+ }
326
+ return $result;
327
+ }
328
+
329
+ /**
330
+ * Form the control specified search options array and built the control's search options markup
331
+ * @param String selOpt The search option value
332
+ * @param Boolean not It indicates if the search option negation is set
333
+ * @param Boolean both It indicates if the control needs 'NOT'-options
334
+ * @return String A string containing options markup
335
+ */
336
+ function getSearchOptions($selOpt, $not, $both)
337
+ {
338
+ return $this->buildSearchOptions(array(EQUALS, NOT_EQUALS), $selOpt, $not, $both);
339
+ }
340
+
341
+ /**
342
+ * Fill the response array with the suggest values
343
+ *
344
+ * @param String value
345
+ * Note: value is preceeded with "_"
346
+ * @param String searchFor
347
+ * @param &Array response
348
+ * @param &Array row
349
+ */
350
+ function suggestValue($value, $searchFor, &$response, &$row)
351
+ {
352
+ $suggestStringSize = GetGlobalData("suggestStringSize", 40);
353
+
354
+ if( $suggestStringSize <= runner_strlen($searchFor) )
355
+ {
356
+ $response[ "_".$searchFor ] = $searchFor;
357
+ return;
358
+ }
359
+
360
+ $viewFormat = $this->pageObject->pSetEdit->getViewFormat($this->field);
361
+ if( $viewFormat == FORMAT_NUMBER )
362
+ {
363
+ $dotPosition = strpos($value, '.');
364
+ if($dotPosition !== FALSE)
365
+ {
366
+ for($i = strlen($value) - 1; $i > $dotPosition; $i--)
367
+ {
368
+ if(substr($value, $i, 1) != '0')
369
+ {
370
+ if($i < strlen($value) - 1)
371
+ $value = substr($value, 0, $i + 1);
372
+ break;
373
+ }
374
+ if($i == $dotPosition + 1 && $dotPosition > 0)
375
+ {
376
+ $value = substr($value, 0, $dotPosition);
377
+ break;
378
+ }
379
+ }
380
+ }
381
+ }
382
+
383
+ $realValue = $value;
384
+
385
+ if( $viewFormat == FORMAT_HTML )
386
+ {
387
+ // declarate patterns for regex
388
+ $html_tags = '/<.*?>/i'.($useUTF8 ? 'u':'');
389
+ $get_text = '/(.*<.*>|^.*?)([.]*'.preg_quote($searchFor, "/").'.*?)(<.*>|$)/i'.($useUTF8 ? 'u':'');
390
+
391
+ // decode html entity and delete all html tags from value
392
+ $value = preg_replace($html_tags, '', runner_html_entity_decode($value));
393
+
394
+ // if not searchFor in value return
395
+ if (stristr($value, $searchFor) === false)
396
+ return;
397
+
398
+ // get realValue (string between html tags)
399
+ if (preg_match($get_text, $realValue, $match))
400
+ $realValue = $match[2];
401
+ else
402
+ $realValue = $value;
403
+ }
404
+
405
+ // if large string cut value and add dots
406
+ if( $suggestStringSize < runner_strlen($value) )
407
+ {
408
+ $startPos = 0;
409
+ $valueLength = 0;
410
+ $suggestValues = $this->cutSuggestString( $value, $searchFor );
411
+ if( $suggestValues ) {
412
+ if( $viewFormat == FORMAT_HTML ) {
413
+ $suggestValues["search"] = $realValue;
414
+ }
415
+ $response[ $suggestValues["display"] ] = $suggestValues["search"];
416
+ }
417
+ } else {
418
+ $response[ $value ] = $realValue;
419
+ }
420
+ }
421
+
422
+ /**
423
+ * Reduce long field value to leave only the text relevant to search suggest
424
+ * ( "There was a time when Mary had a little lamb", "Mary" ) => "when Mary had"
425
+ * @return Array - array of (
426
+ * "search" => "when Mary had" - value that will be used for searching
427
+ * "display" => "...when Mary had..." - value to show to the user in the suggest list
428
+ * )
429
+ * Returns false if anything went wrong
430
+ */
431
+ function cutSuggestString( $_value, $searchFor )
432
+ {
433
+ $suggestStringSize = GetGlobalData("suggestStringSize", 40);
434
+ $caseIns = $this->pageObject->pSetEdit->getNCSearch();
435
+
436
+ // split to lines. Line breaks shouldn't appear in the suggested values
437
+ $lines = explode( "\n", $_value );
438
+ $value = "";
439
+ for( $lineIdx = 0; $lineIdx< count( $lines); ++$lineIdx ) {
440
+ $line = $lines[ $lineIdx ];
441
+ if( $caseIns )
442
+ {
443
+ // case-insensitive search
444
+ $startPos = stripos($line, $searchFor);
445
+ if( $startPos )
446
+ $startPos = runner_strlen( substr($line, 0 , $startPos) ); //UTF-8 support
447
+ }
448
+ else
449
+ {
450
+ $startPos = runner_strpos($line, $searchFor);
451
+ }
452
+ if( $startPos !== false )
453
+ {
454
+ $value = $line;
455
+ break;
456
+ }
457
+ }
458
+ if( $startPos === false ) {
459
+ return false;
460
+ }
461
+
462
+ // cut a chunk of the $value around the $searchFor.
463
+ // Paddings are parts of the chunk before and after $searchFor
464
+ // There are two "gray zones" at the begining and end of the chunk.
465
+ // If there are stop symbols ( spaces, commas ) in the gray zone, cut it up to them
466
+ // "tion of the next occu" => "of the next"
467
+
468
+ $grayZoneLength = 5;
469
+
470
+ $leftPaddingLength = min( $suggestStringSize / 2, $startPos );
471
+ $leftPadding = runner_substr( $value, $startPos - $leftPaddingLength, $leftPaddingLength );
472
+ $leftGrayZoneLength = $leftPaddingLength < $suggestStringSize / 2
473
+ ? 0
474
+ : $grayZoneLength;
475
+
476
+ $rightPaddingLength = min( $suggestStringSize - $leftPaddingLength, runner_strlen( $value ) - $startPos - runner_strlen( $searchFor ) );
477
+ $rightPadding = runner_substr( $value, $startPos + runner_strlen( $searchFor ), $rightPaddingLength );
478
+ $rightGrayZoneLength = $rightPaddingLength < $suggestStringSize / 2
479
+ ? 0
480
+ : $grayZoneLength;
481
+
482
+ $leftGrayZone = runner_substr( $leftPadding, 0, $leftGrayZoneLength );
483
+ $stopPos = $this->findFirstStop( $leftGrayZone, true );
484
+ if( $stopPos !== false ) {
485
+ $leftPadding = runner_substr( $leftPadding, $stopPos );
486
+ }
487
+
488
+ $rightGrayZone = runner_substr( $rightPadding, $rightPaddingLength - $rightGrayZoneLength );
489
+ $stopPos = $this->findFirstStop( $rightGrayZone );
490
+ if( $stopPos !== false ) {
491
+ $rightPadding = runner_substr( $rightPadding, 0, runner_strlen( $rightPadding ) - $rightGrayZoneLength + $stopPos );
492
+ }
493
+
494
+ $leftEllipsis = $lineIdx > 0 || runner_strlen( $leftPadding ) < $startPos
495
+ ? "... "
496
+ : "";
497
+ $rightEllipsis = $lineIdx < count( $lines) - 1 || runner_strlen( $rightPadding ) < runner_strlen( $value ) - $startPos - runner_strlen( $searchFor )
498
+ ? " ..."
499
+ : "";
500
+
501
+ $searchValue = $leftPadding . runner_substr( $value, $startPos, runner_strlen( $searchFor )) . $rightPadding;
502
+ return array(
503
+ "search" => $searchValue,
504
+ "display" => $leftEllipsis . $searchValue . $rightEllipsis
505
+ );
506
+ }
507
+
508
+ function findFirstStop( $str, $reverse = false ) {
509
+ $stopSymbols = " .,;:\"'?!|\\/=(){}[]*-+\n\r";
510
+ $length = runner_strlen( $str);
511
+ for( $i = 0; $i < $length; ++$i ) {
512
+ $idx = $reverse ? $length - $i - 1 : $i;
513
+ $c = runner_substr( $str, $idx, 1 );
514
+ if( runner_strpos( $stopSymbols, $c ) !== false )
515
+ return $idx;
516
+ }
517
+ return false;
518
+ }
519
+
520
+ /**
521
+ * This function ivokes after successful saving of added/edited record
522
+ */
523
+ function afterSuccessfulSave()
524
+ {
525
+ }
526
+
527
+ /**
528
+ * Control settings filling
529
+ */
530
+ function init()
531
+ {
532
+ }
533
+
534
+ /**
535
+ * Is the search string valid for LIKE search
536
+ */
537
+ function isStringValidForLike($str)
538
+ {
539
+ if(!IsCharType($this->type) && hasNonAsciiSymbols($str))
540
+ return false;
541
+
542
+ return true;
543
+ }
544
+
545
+ /**
546
+ * Get the displayed control elemnt's style attribute string
547
+ * @return String
548
+ */
549
+ function getInputStyle( $mode )
550
+ {
551
+ return "";
552
+ if( $this->pageObject->isBootstrap()
553
+ && ($this->pageObject->pageType != PAGE_ADD || $this->pageObject->mode != ADD_INLINE)
554
+ && ($this->pageObject->pageType != PAGE_EDIT || $this->pageObject->mode != EDIT_INLINE) )
555
+ {
556
+ return "";
557
+ }
558
+
559
+ $width = $this->searchPanelControl ? 150 : $this->pageObject->pSetEdit->getControlWidth( $this->field );
560
+ $style = $this->makeWidthStyle( $width );
561
+
562
+ return 'style="'.$style.'"';
563
+ }
564
+
565
+ /**
566
+ * Create a CSS rule specifying the control's width
567
+ * @param Number widthPx
568
+ */
569
+ function makeWidthStyle( $widthPx )
570
+ {
571
+ return "";
572
+ /*
573
+ if( 0 == $widthPx )
574
+ return "";
575
+
576
+ return "width: ".$widthPx."px;";
577
+ */
578
+ }
579
+
580
+ public function loadLookupContent( $parentValuesData, $childVal = "", $doCategoryFilter = true, $initialLoad = true )
581
+ {
582
+ return ""; // .net compatibility
583
+ }
584
+
585
+ public function getLookupContentToReload( $isExistParent, $mode, $parentCtrlsData )
586
+ {
587
+ return ""; // .net compatibility
588
+ }
589
+
590
+ /**
591
+ * A stub
592
+ */
593
+ public function getFieldValueCopy( $value )
594
+ {
595
+ return $value;
596
+ }
597
+
598
+ public function getFieldSQLDecrypt()
599
+ {
600
+ return RunnerPage::_getFieldSQLDecrypt( $this->field, $this->connection, $this->pageObject->pSetEdit, $this->pageObject->cipherer );
601
+ }
602
+
603
+ /**
604
+ * @return String
605
+ */
606
+ protected function getPlaceholderAttr()
607
+ {
608
+ if( !$this->searchPanelControl && $this->container->pageType != PAGE_SEARCH )
609
+ return ' placeholder="'.runner_htmlspecialchars(GetFieldPlaceHolder( GoodFieldname( $this->pageObject->tName ), GoodFieldname( $this->field ) )).'"';
610
+
611
+ return "";
612
+ }
613
+
614
+ /**
615
+ *
616
+ */
617
+ public function getConnection()
618
+ {
619
+ return $this->connection();
620
+ }
621
+
622
+ /**
623
+ * Returns basic condition, where first operand is field itself
624
+ */
625
+ public function getBasicFieldCondition( $svalue, $strSearchOption, $svalue2 = "", $etype = "" ) {
626
+ $searchFor = $this->processControlValue( $svalue, $etype );
627
+ $searchFor2 = $this->processControlValue( $svalue2, $etype );
628
+ $caseInsensitive = $this->pageObject->pSetEdit->getNCSearch() ? dsCASE_INSENSITIVE : dsCASE_DEFAULT;
629
+ if( $strSearchOption == EQUALS ) {
630
+ return DataCondition::FieldEquals( $this->field, $searchFor, 0, $caseInsensitive );
631
+ } else if( $strSearchOption == STARTS_WITH ) {
632
+ return DataCondition::FieldIs( $this->field, dsopSTART, $searchFor, $caseInsensitive );
633
+ } else if( $strSearchOption == CONTAINS ) {
634
+ return DataCondition::FieldIs( $this->field, dsopCONTAIN, $searchFor, $caseInsensitive );
635
+ } else if( $strSearchOption == MORE_THAN ) {
636
+ return DataCondition::FieldIs( $this->field, dsopMORE, $searchFor, $caseInsensitive );
637
+ } else if( $strSearchOption == LESS_THAN ) {
638
+ return DataCondition::FieldIs( $this->field, dsopLESS, $searchFor, $caseInsensitive );
639
+ } else if( $strSearchOption == BETWEEN && ( $searchFor != "" || $searchFor2 != "") ) {
640
+ if( $searchFor == "" ) {
641
+ return $this->getSearchCondition( $svalue2, NOT_MORE_THAN, "", $etype );
642
+ }
643
+ if( $searchFor2 == "" ) {
644
+ return $this->getSearchCondition( $svalue, NOT_LESS_THAN, "", $etype );
645
+ }
646
+ return DataCondition::FieldBetween( $this->field, $searchFor, $searchFor2, $caseInsensitive );
647
+ } else if( $strSearchOption == EMPTY_SEARCH ) {
648
+ return DataCondition::FieldIs( $this->field, dsopEMPTY, $searchFor );
649
+ }
650
+ return null;
651
+ }
652
+
653
+ public function getSearchCondition( $searchFor, $strSearchOption, $searchFor2 = "", $not = false, $etype = "" )
654
+ {
655
+ if( substr( $strSearchOption, 0, 4) == "NOT " ) {
656
+ $strSearchOption = substr( $strSearchOption, 4 );
657
+ $not = true;
658
+ }
659
+ $cond = $this->getBasicFieldCondition( $searchFor, $strSearchOption, $searchFor2, $etype );
660
+
661
+ if( $not ) {
662
+ $cond = DataCondition::_Not( $cond );
663
+ }
664
+ return $cond;
665
+ }
666
+
667
+ /**
668
+ * Reduce value passed from web to standard format using controlType
669
+ * Currently is used for Date and Time controls only
670
+ */
671
+ public function processControlValue( $value, $controlType ) {
672
+
673
+ if(substr($controlType, 0, 4) == "date")
674
+ {
675
+ $dformat = substr($controlType, 4);
676
+ if($dformat == EDIT_DATE_SIMPLE || $dformat == EDIT_DATE_SIMPLE_INLINE || $dformat == EDIT_DATE_SIMPLE_DP)
677
+ {
678
+ $time = localdatetime2db($value);
679
+ if($time == "null")
680
+ return "";
681
+ return $time;
682
+ }
683
+ else if($dformat == EDIT_DATE_DD || $dformat == EDIT_DATE_DD_INLINE || $dformat == EDIT_DATE_DD_DP)
684
+ {
685
+ $a = explode("-",$value);
686
+ if(count($a) < 3)
687
+ return "";
688
+ else
689
+ {
690
+ $y = $a[0];
691
+ $m = $a[1];
692
+ $d = $a[2];
693
+ }
694
+ if($y < 100)
695
+ {
696
+ if($y < 70)
697
+ $y += 2000;
698
+ else
699
+ $y += 1900;
700
+ }
701
+ return mysprintf("%04d-%02d-%02d",array($y,$m,$d));
702
+ }
703
+ else
704
+ return "";
705
+ }
706
+ else if($controlType == "time")
707
+ {
708
+ if(!strlen($value))
709
+ return "";
710
+ $ret = localtime2db($value);
711
+ if( IsDateFieldType( $this->type ) )
712
+ $ret = "2000-01-01 ".$ret;
713
+ return $ret;
714
+
715
+ }
716
+
717
+ return $value;
718
+ }
719
+
720
+ /**
721
+ *
722
+ * @returgn String
723
+ */
724
+ public function getControlMarkup( &$params, $data ) {
725
+ $fieldNum = 0;
726
+ if( $params["fieldNum"] )
727
+ $fieldNum = $params["fieldNum"];
728
+
729
+ $validate = array();
730
+ if( $params["validate"] )
731
+ $validate = $params["validate"];
732
+
733
+ $additionalCtrlParams = array();
734
+ if( $params["additionalCtrlParams"] )
735
+ $additionalCtrlParams = $params["additionalCtrlParams"];
736
+
737
+ ob_start();
738
+
739
+ $this->buildControl( $data[ $this->field ], $params["mode"], $fieldNum, $validate, $additionalCtrlParams, $data );
740
+ $markup = ob_get_contents() ;
741
+
742
+ ob_end_clean();
743
+ return $markup;
744
+ }
745
+
746
+ /**
747
+ * @return DsCommand - create data command for search suggest
748
+ */
749
+ public function getSuggestCommand( $searchFor, $searchOpt, $numberOfSuggests )
750
+ {
751
+ $dc = new DsCommand();
752
+ $dc->filter = DataCondition::_And( array(
753
+ $this->getSearchCondition( $searchFor, $searchOpt ),
754
+ Security::SelectCondition( "S", $this->pageObject->pSetEdit )
755
+ ));
756
+ $dc->totals[] = array(
757
+ "field" => $this->field,
758
+ "total" => "distinct"
759
+ );
760
+ $dc->skipAggregated = true;
761
+ $dc->reccount = $numberOfSuggests;
762
+ return $dc;
763
+ }
764
+
765
+ /**
766
+ * Get the field's content
767
+ * @param &Array data
768
+ * @param Array
769
+ * @return String
770
+ */
771
+ public function getDisplayValue( &$data )
772
+ {
773
+ $fName = $this->field;
774
+ $htmlType = $this->pageObject->pSetEdit->getHTML5InputType( $fName );
775
+ $value = $data[ $fName ];
776
+ if( $this->format !== EDIT_FORMAT_READONLY ) {
777
+ if( IsFloatType( $this->type ) && !is_null( $value ) ) {
778
+ if( $htmlType == "number" ) {
779
+ // no thousand delimiters, only dot as decimal delimiter
780
+ $value = formatNumberForHTML5( $value );
781
+ } else {
782
+ $value = formatNumberForEdit( $value );
783
+ }
784
+ }
785
+ }
786
+ return $value;
787
+ }
788
+
789
+ }
790
+ ?>
classes/controls/DatabaseFileField.php ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class DatabaseFileField extends EditControl
3
+ {
4
+ function __construct($field, $pageObject, $id, $connection)
5
+ {
6
+ parent::__construct($field, $pageObject, $id, $connection);
7
+ $this->format = $pageObject->pSetEdit->getEditFormat($field);
8
+ }
9
+
10
+ /**
11
+ * addJSFiles
12
+ * Add control JS files to page object
13
+ */
14
+ function addJSFiles()
15
+ {
16
+ }
17
+
18
+ /**
19
+ * addCSSFiles
20
+ * Add control CSS files to page object
21
+ */
22
+ function addCSSFiles()
23
+ {
24
+ }
25
+
26
+ function buildControl($value, $mode, $fieldNum, $validate, $additionalCtrlParams, $data)
27
+ {
28
+ parent::buildControl($value, $mode, $fieldNum, $validate, $additionalCtrlParams, $data);
29
+
30
+ $disp = "";
31
+ $strfilename = "";
32
+
33
+ if($mode == MODE_EDIT || $mode == MODE_INLINE_EDIT)
34
+ {
35
+ $value = $this->connection->stripSlashesBinary( $value );
36
+ $itype = SupposeImageType($value);
37
+
38
+ if($itype)
39
+ {
40
+ if( $this->format == EDIT_FORMAT_DATABASE_IMAGE && !$this->pageObject->pSetEdit->showThumbnail( $this->field ) )
41
+ {
42
+ // show real db image instead of icon
43
+ $src = GetTableLink( "file", "", "filename=file.jpg&table=".rawurlencode( $this->container->tName )
44
+ ."&field=".rawurlencode( $this->field )
45
+ ."&nodisp=1"
46
+ .$this->keylink."&fileHash=".fileAttrHash( $this->keylink, strlen_bin( $value ) ) );
47
+
48
+ $imgWidth = $this->container->pSetEdit->getImageWidth( $this->field );
49
+ $imgHeight = $this->container->pSetEdit->getImageHeight( $this->field );
50
+
51
+ $style = '';
52
+ if( $imgWidth )
53
+ $style.= 'max-width:'.$imgWidth.'px;';
54
+ if( $imgHeight )
55
+ $style.= 'max-height:'.$imgHeight.'px;';
56
+
57
+ $imageId = generatePassword( 10 );
58
+ if( $style != "" ) {
59
+ // don't use id attribute since this it should be possible to override this size in other CSS
60
+ $style = '<style> @media screen and (min-width: 768px) { [data-imageid="'. $imageId . '"] { '
61
+ . $style . '} } </style>';
62
+ }
63
+
64
+ $disp = $style.'<img class="" data-imageid="'.$imageId.'" id="image_'.GoodFieldName( $this->field ).'_'.$this->id.'" name="'.$this->cfield.'"';
65
+ if( $this->is508 )
66
+ $disp.= ' alt="Image from DB"';
67
+ $disp.= ' border=0 src="'.$src.'">';
68
+ }
69
+ else if( $this->pageObject->pSetEdit->showThumbnail($this->field) )
70
+ {
71
+ $disp = "<a target=_blank";
72
+
73
+ $disp.=" href=\"".
74
+ GetTableLink("imager", "",
75
+ "page=".$this->pageObject->pageName.
76
+ "&table=".GetTableURL($this->pageObject->tName).
77
+ "&".$this->iquery.
78
+ "&rndVal=".rand(0,32768))."\" >";
79
+ $disp.= "<img class=\"mupload-preview-img\" id=\"image_".GoodFieldName($this->field)."_".$this->id."\" name=\"".$this->cfield."\" border=0";
80
+ if($this->is508)
81
+ $disp .= " alt=\"Image from DB\"";
82
+
83
+ // show thumbnail or fullsize image
84
+ $displayField = $this->pageObject->pSetEdit->getStrThumbnail($this->field);
85
+ if( !strlen( $data[ $displayField ]) ) {
86
+ $displayField = $this->field;
87
+ }
88
+
89
+ $disp .= " src=\"".
90
+ GetTableLink("imager", "",
91
+ "page=".$this->pageObject->pageName.
92
+ "&table=".GetTableURL($this->pageObject->tName).
93
+ "&field=".rawurlencode( $displayField ).
94
+ $this->keylink.
95
+ "&rndVal=".rand(0,32768))."\">";
96
+ $disp.= "</a>";
97
+ }
98
+ else
99
+ {
100
+ $disp='<img class="mupload-preview-img" id="image_'.GoodFieldName($this->field).'_'.$this->id.'" name="'.$this->cfield.'"';
101
+ if($this->is508)
102
+ $disp.= ' alt="Image from DB"';
103
+ $disp.=' border=0 src="'.
104
+ GetTableLink("imager", "",
105
+ 'table='.GetTableURL($this->pageObject->tName).
106
+ "&page=".$this->pageObject->pageName.
107
+ '&'.$this->iquery."&src=1&rndVal=".rand(0,32768)).'">';
108
+ }
109
+ }
110
+ else
111
+ {
112
+ if(strlen($value))
113
+ {
114
+ $disp = '<img class="mupload-preview-img" id="image_'.GoodFieldName($this->field).'_'.$this->id.'" name="'.$this->cfield.'" border=0 ';
115
+ if($this->is508)
116
+ $disp .= ' alt="file"';
117
+ $disp .= ' src="'.GetRootPathForResources("images/file.gif").'">';
118
+ }
119
+ }
120
+ // filename
121
+ if($this->format == EDIT_FORMAT_DATABASE_FILE && !$itype && strlen($value))
122
+ {
123
+ if(!($filename = @$data[$this->pageObject->pSetEdit->getFilenameField($this->field)]))
124
+ $filename = "file.bin";
125
+
126
+ $disp = '<a href="'.GetTableLink("getfile", "", 'table='.GetTableURL( $this->pageObject->tName ).'&filename='.runner_htmlspecialchars( $filename )
127
+ .'&pagename='.runner_htmlspecialchars( $this->pageObject->pSetEdit->pageName() )
128
+ .'&'.$this->iquery).'".>'.$disp.'</a>';
129
+ }
130
+ // filename edit
131
+ if($this->format == EDIT_FORMAT_DATABASE_FILE && $this->pageObject->pSetEdit->getFilenameField($this->field))
132
+ {
133
+ if(!($filename = @$data[$this->pageObject->pSetEdit->getFilenameField($this->field)]))
134
+ $filename = "";
135
+ if($mode == MODE_INLINE_EDIT)
136
+ {
137
+ $strfilename = '<br><label for="filename_'.$this->cfieldname.'">'."Filename"
138
+ .'</label>&nbsp;&nbsp;<input type="text" '.$this->inputStyle.' id="filename_'.$this->cfieldname
139
+ .'" name="filename_'.$this->cfieldname.'" size="20" maxlength="50" value="'.runner_htmlspecialchars($filename).'">';
140
+ }
141
+ else
142
+ {
143
+ $strfilename = '<br><label for="filename_'.$this->cfieldname.'">'."Filename"
144
+ .'</label>&nbsp;&nbsp;<input type="text" '.$this->inputStyle.' id="filename_'.$this->cfieldname.'" name="filename_'
145
+ .$this->cfieldname.'" size="20" maxlength="50" value="'.runner_htmlspecialchars($filename).'">';
146
+ }
147
+ }
148
+ if(strlen($value)) {
149
+ $strtype = '<br><input id="'.$this->ctype.'_keep" type="Radio" name="'.$this->ctype.'" value="file0" checked class="rnr-uploadtype">'."Keep";
150
+
151
+ if(strlen($value) && !$this->pageObject->pSetEdit->isRequired($this->field))
152
+ {
153
+ $strtype .= '<input id="'.$this->ctype.'_delete" type="Radio" name="'.$this->ctype.'" value="file1" class="rnr-uploadtype">'."Delete";
154
+ }
155
+ $strtype .= '<input id="'.$this->ctype.'_update" type="Radio" name="'.$this->ctype.'" value="file2" class="rnr-uploadtype">'."Update";
156
+ } else {
157
+ $strtype = '<input id="'.$this->ctype.'_update" type="hidden" name="'.$this->ctype.'" value="file2" class="rnr-uploadtype">';
158
+ }
159
+ }
160
+ else
161
+ {
162
+ // if Add mode
163
+ $strtype = '<input id="'.$this->ctype.'" type="hidden" name="'.$this->ctype.'" value="file2">';
164
+ if($this->format == EDIT_FORMAT_DATABASE_FILE && $this->pageObject->pSetEdit->getFilenameField($this->field))
165
+ {
166
+ $strfilename = '<br><label for="filename_'.$this->cfieldname.'">'."Filename"
167
+ .'</label>&nbsp;&nbsp;<input type="text" '.$this->inputStyle.' id="filename_'.$this->cfieldname.'" name="filename_'
168
+ .$this->cfieldname.'" size="20" maxlength="50">';
169
+ }
170
+ }
171
+
172
+ if($mode == MODE_INLINE_EDIT && $this->format == EDIT_FORMAT_DATABASE_FILE)
173
+ $disp = "";
174
+ echo $disp.$strtype;
175
+ if (($mode == MODE_EDIT || $mode==MODE_INLINE_EDIT) && (strlen($value)))
176
+ {
177
+ echo '<br>';
178
+ }
179
+ echo '<input type="File" '.$this->inputStyle.' id="'.$this->cfield.'" '
180
+ .'accept="'.$this->pageObject->pSetEdit->getAcceptFileTypesHtml($this->field).'" '
181
+ .(($mode==MODE_INLINE_EDIT || $mode==MODE_INLINE_ADD) && $this->is508 ? 'alt="'.$this->strLabel.'" ' : '').' name="'
182
+ .$this->cfield.'" >'.$strfilename;
183
+ echo '<input type="Hidden" id="notempty_'.$this->cfieldname.'" value="'.(strlen($value) ? 1 : 0).'">';
184
+ $this->buildControlEnd($validate, $mode);
185
+ }
186
+
187
+ /**
188
+ * Create CSS code for specifying control's width
189
+ */
190
+ function makeWidthStyle($widthPx)
191
+ {
192
+ if(0 == $widthPx)
193
+ return "";
194
+ return "min-width: ".$widthPx."px";
195
+ }
196
+
197
+ function readWebValue(&$avalues, &$blobfields, $legacy1, $legacy2, &$filename_values)
198
+ {
199
+ $filename = "";
200
+ $this->getPostValueAndType();
201
+ if (FieldSubmitted($this->goodFieldName."_".$this->id))
202
+ {
203
+ $fileNameForPrepareFunc = securityCheckFileName(postvalue("filename_".$this->goodFieldName."_".$this->id));
204
+ if( $this->pageObject->pageType != PAGE_EDIT && $this->pageObject->pageType != PAGE_USERINFO )
205
+ {
206
+ $prepearedFile = prepare_file($this->webValue, $this->field, "file2", $fileNameForPrepareFunc, $this->id);
207
+ if($prepearedFile !== false)
208
+ {
209
+ $this->webValue = $prepearedFile["value"];
210
+ $filename = $prepearedFile["filename"];
211
+ }
212
+ else
213
+ $this->webValue = false;
214
+ }
215
+ else
216
+ {
217
+ if(substr($this->webType, 0, 4) == "file")
218
+ {
219
+ $prepearedFile = prepare_file($this->webValue, $this->field, $this->webType, $fileNameForPrepareFunc, $this->id);
220
+ if($prepearedFile !== false)
221
+ {
222
+ $this->webValue = $prepearedFile["value"];
223
+ $filename = $prepearedFile["filename"];
224
+ }
225
+ else
226
+ $this->webValue = false;
227
+ }
228
+ else if(substr($this->webType, 0, 6) == "upload")
229
+ {
230
+ if($this->webType == "upload1")
231
+ {
232
+ // file deletion, read filename from the database
233
+ $oldValues = $this->pageObject->getOldRecordData();
234
+ $fileNameForPrepareFunc = $oldValues[$this->field];
235
+ }
236
+ $this->webValue = prepare_upload($this->field, $this->webType, $fileNameForPrepareFunc, $this->webValue, "", $this->id, $this->pageObject);
237
+ }
238
+ else
239
+ $this->webValue = false;
240
+ }
241
+ }
242
+ else
243
+ $this->webValue = false;
244
+
245
+ if(!($this->webValue === false))
246
+ {
247
+ if($this->webValue)
248
+ {
249
+ if($this->pageObject->pSetEdit->getCreateThumbnail($this->field))
250
+ {
251
+ $ext = CheckImageExtension(GetUploadedFileName("value_".$this->goodFieldName."_".$this->id));
252
+ if( $ext ) {
253
+ $thumb = CreateThumbnail($this->webValue, $this->pageObject->pSetEdit->getThumbnailSize($this->field), $ext);
254
+ $blobfields[] = $this->pageObject->pSetEdit->getStrThumbnail($this->field);
255
+ $avalues[$blobfields[count($blobfields) - 1]] = $thumb;
256
+ }
257
+ }
258
+ // resize on upload
259
+ $resizeImageSize = 0;
260
+ if( $this->pageObject->pSetEdit->getResizeOnUpload($this->field) ) {
261
+ $resizeImageSize = $this->pageObject->pSetEdit->getNewImageSize($this->field);
262
+ } else if( $this->fieldIsUserpic() ) {
263
+ $resizeImageSize = 400;
264
+ }
265
+ if( $resizeImageSize ) {
266
+ $ext = CheckImageExtension( GetUploadedFileName("value_".$this->goodFieldName."_".$this->id) );
267
+ $this->webValue = CreateThumbnail($this->webValue, $resizeImageSize, $ext);
268
+ }
269
+ }
270
+ else if($this->pageObject->pageType == PAGE_EDIT && $this->pageObject->pSetEdit->getCreateThumbnail($this->field))
271
+ {
272
+ $blobfields[] = $this->pageObject->pSetEdit->getStrThumbnail($this->field);
273
+ $avalues[$blobfields[count($blobfields) - 1]] = "";
274
+ }
275
+ $blobfields[] = $this->field;
276
+ $avalues[$this->field] = $this->webValue;
277
+ }
278
+ if($filename && $this->pageObject->pSetEdit->getStrFilename($this->field))
279
+ $filename_values[$this->pageObject->pSetEdit->getStrFilename($this->field)] = $filename;
280
+ }
281
+
282
+ protected function fieldIsUserpic() {
283
+ return $this->field === Security::userpicField()
284
+ && $this->container->tName === Security::loginTable();
285
+ }
286
+ }
287
+ ?>
classes/controls/DateField.php ADDED
@@ -0,0 +1,293 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once getabspath('classes/controls/DateTimeControl.php');
3
+ class DateField extends DateTimeControl
4
+ {
5
+ function __construct($field, $pageObject, $id, $connection)
6
+ {
7
+ EditControl::__construct($field, $pageObject, $id, $connection);
8
+ $this->format = EDIT_FORMAT_DATE;
9
+ }
10
+
11
+ function addCSSFiles() {
12
+ $this->pageObject->AddCSSFile("include/bootstrap/css/bootstrap-datetimepicker.min.css");
13
+ }
14
+
15
+ function getProjectSettings()
16
+ {
17
+ if($this->pageObject->pageType == PAGE_LIST)
18
+ return new ProjectSettings($this->pageObject->tName, PAGE_SEARCH);
19
+ else
20
+ return $this->pageObject->pSetEdit;
21
+ }
22
+
23
+ function getDateEditType( $pSet = null )
24
+ {
25
+ if( !$pSet )
26
+ $pSet = $this->getProjectSettings();
27
+
28
+ $dateEditType = $pSet->getDateEditType($this->field);
29
+
30
+ // search panel control
31
+ if( !$this->forSpreadsheetGrid
32
+ && ( ( $this->pageObject->pageType == PAGE_LIST || $this->pageObject->pageType == PAGE_CHART || $this->pageObject->pageType == PAGE_REPORT)
33
+ || $this->pageObject->pageType == PAGE_SEARCH && $this->pageObject->mode == SEARCH_LOAD_CONTROL) )
34
+ {
35
+ if( $dateEditType == EDIT_DATE_DD )
36
+ return EDIT_DATE_SIMPLE;
37
+ if( $dateEditType == EDIT_DATE_DD_DP )
38
+ return EDIT_DATE_SIMPLE_DP;
39
+ if( $dateEditType == EDIT_DATE_DD_INLINE )
40
+ return EDIT_DATE_SIMPLE_INLINE;
41
+ }
42
+
43
+ return $dateEditType;
44
+ }
45
+
46
+ function buildControl($value, $mode, $fieldNum, $validate, $additionalCtrlParams, $data)
47
+ {
48
+ global $locale_info;
49
+ parent::buildControl($value, $mode, $fieldNum, $validate, $additionalCtrlParams, $data);
50
+
51
+ if($fieldNum)
52
+ $this->cfield = "value".$fieldNum."_".GoodFieldName($this->field).'_'.$this->id;
53
+
54
+ $pSet = $this->getProjectSettings();
55
+
56
+ $dateEditType = $this->getDateEditType( $pSet );
57
+
58
+ //if( $this->pageObject->pageType == PAGE_LIST ) //
59
+ echo '<input id="'.$this->ctype.'" type="hidden" name="'.$this->ctype.'" value="date'
60
+ .$dateEditType.'">';
61
+
62
+ $tvalue = $value;
63
+
64
+ $time = db2time($tvalue);
65
+ if( !$time )
66
+ $time = array(0, 0, 0, 0, 0, 0);
67
+
68
+ $classString = ' form-control';
69
+
70
+ $dp = 0;
71
+ $hasImgCal = true;
72
+ $showTime = $pSet->dateEditShowTime($this->field);
73
+ switch( $dateEditType )
74
+ {
75
+ case EDIT_DATE_SIMPLE_INLINE:
76
+ $hasImgCal = false;
77
+ case EDIT_DATE_SIMPLE_DP:
78
+ $ovalue = $value;
79
+
80
+ if($locale_info["LOCALE_IDATE"] == 1)
81
+ $fmt = "dd".$locale_info["LOCALE_SDATE"]."MM".$locale_info["LOCALE_SDATE"]."yyyy";
82
+ else if($locale_info["LOCALE_IDATE"] == 0)
83
+ $fmt = "MM".$locale_info["LOCALE_SDATE"]."dd".$locale_info["LOCALE_SDATE"]."yyyy";
84
+ else
85
+ $fmt = "yyyy".$locale_info["LOCALE_SDATE"]."MM".$locale_info["LOCALE_SDATE"]."dd";
86
+
87
+ if($showTime || $time[3] || $time[4] || $time[5]){
88
+ $timeAttrs = $this->pageObject->pSetEdit->getFormatTimeAttrs($this->field);
89
+ $fmt.= " " . $locale_info["LOCALE_STIMEFORMAT"];
90
+ }
91
+
92
+ if($time[0])
93
+ $ovalue = format_datetime_custom($time, $fmt);
94
+
95
+ $ovalue1 = $time[2]."-".$time[1]."-".$time[0];
96
+ if($showTime || $time[3] || $time[4] || $time[5])
97
+ $ovalue1.= " ".$time[3].":".$time[4].":".$time[5];
98
+
99
+ $ret= '<input '.$this->getPlaceholderAttr().' id="'.$this->cfield.'" '.$this->inputStyle.' class="'.$classString.'" type="Text" name="'.$this->cfield.'" value="'.$ovalue.'">';
100
+ $ret.= '<input id="ts'.$this->cfield.'" type="Hidden" name="ts'.$this->cfield.'" value="'.$ovalue1.'">';
101
+
102
+ $ret .= '<span class="input-group-addon" id="imgCal_'.$this->cfield.'"><span class="glyphicon glyphicon-calendar"></span></span>';
103
+
104
+ if ( isRTL() )
105
+ $ret .= "<span></span>"; // for bootstrap calend icon anomaly
106
+
107
+ $ret = '<div class="input-group date">' . $ret . '</div>';
108
+
109
+ echo $ret;
110
+ break;
111
+
112
+ case EDIT_DATE_DD_INLINE:
113
+ case EDIT_DATE_DD_DP:
114
+ $dp=1;
115
+ case EDIT_DATE_DD:
116
+ $controlWidth = $pSet->getControlWidth($this->field);
117
+ if($controlWidth > 0)
118
+ {
119
+ $controlWidth -= 10;
120
+ $yearWidth = floor($controlWidth * 0.3);
121
+ $yearStyle = 'style="min-width: '.$yearWidth.'px;margin-right:5px;" ';
122
+ $dayWidth = floor($controlWidth * 0.2);
123
+ $dayStyle = 'style="min-width: '.$dayWidth.'px; margin-right:5px;" ';
124
+ $mothWidth = $controlWidth - $yearWidth - $dayWidth;
125
+ $monthStyle = 'style="min-width: '.$mothWidth.'px; margin-right:5px;" ';
126
+ }
127
+ else
128
+ {
129
+ $dayStyle = '';
130
+ $monthStyle = '';
131
+ $yearStyle = '';
132
+ }
133
+ $alt = 'alt="'.$this->strLabel.'" ';
134
+
135
+ // for init normal select width/ After load js, this options will clear
136
+ $initMonthOpt = "<option>&nbsp;</option>";
137
+ if ( $time[1] )
138
+ {
139
+ $months = getMountNames();
140
+ $initMonthOpt = "<option>" . $months[$time[1]] . "</option>";
141
+ }
142
+ $initMonthOpt .= "<option>" . $this->maxLengthMonth() . "</option>";
143
+ $initDayOpt = "<option>" . ($time[2] ? $time[2] : "&nbsp;") ." </option><option>22</option>";
144
+ $initYearOpt = "<option>" . ($time[0] ? $time[0] : "&nbsp;") . "</option><option>2000</option>";
145
+ $retday='<select class="'. $classString.'" id="day'.$this->cfield.'" '.$dayStyle.$alt.'name="day'.$this->cfield.'" >'.$initDayOpt.'</select>';
146
+ $retmonth='<select class="'. $classString.'" id="month'.$this->cfield.'" '.$monthStyle.$alt.'name="month'.$this->cfield.'" >'.$initMonthOpt.'</option></select>';
147
+ $retyear='<select class="'. $classString.'" id="year'.$this->cfield.'" '.$yearStyle.$alt.'name="year'.$this->cfield.'" >'.$initYearOpt.'</select>';
148
+
149
+ $space = ($controlWidth > 0 ? '' : "&nbsp;");
150
+
151
+ if($locale_info["LOCALE_ILONGDATE"] == 1)
152
+ $ret = $retday.$space.$retmonth.$space.$retyear;
153
+ else if($locale_info["LOCALE_ILONGDATE"] == 0)
154
+ $ret = $retmonth.$space.$retday.$space.$retyear;
155
+ else
156
+ $ret = $retyear.$space.$retmonth.$space.$retday;
157
+
158
+ $setHiddenElem = 'class="'. $classString.' hiddenPickerElement"';
159
+
160
+ if($time[0] && $time[1] && $time[2])
161
+ $ret.="<input id=\"".$this->cfield."\" ".$setHiddenElem." name=\"".$this->cfield."\" value=\"".$time[0]."-".$time[1]."-".$time[2]."\">";
162
+ else
163
+ $ret.="<input id=\"".$this->cfield."\" ".$setHiddenElem." name=\"".$this->cfield."\" value=\"\">";
164
+
165
+ // calendar handling for three DD
166
+ if( $dp ) {
167
+ $ret .= '<button class="btn btn-default" id="imgCal_'.$this->cfield.'" aria-hidden=true><span class="glyphicon glyphicon-calendar" ></span></button>';
168
+ }
169
+
170
+ $ret = '<span class="bs-date-control form-inline">' . $ret . '</span>';
171
+ echo $ret;
172
+ break;
173
+
174
+ default: // case EDIT_DATE_SIMPLE:
175
+ $ovalue = $value;
176
+ if($time[0])
177
+ {
178
+ if($showTime || $time[3] || $time[4] || $time[5])
179
+ $ovalue = str_format_datetime($time);
180
+ else
181
+ $ovalue = format_shortdate($time);
182
+ }
183
+ echo '<input '.$this->getPlaceholderAttr().' id="'.$this->cfield.'" type=text class="'.$classString.'" name="'.$this->cfield.'" '.$this->inputStyle.' value="'.runner_htmlspecialchars($ovalue).'">';
184
+ }
185
+ $this->buildControlEnd($validate, $mode);
186
+ }
187
+
188
+ function getFirstElementId()
189
+ {
190
+ global $locale_info;
191
+ $dateEditType = $this->getDateEditType();
192
+
193
+ if ( !$dateEditType )
194
+ {
195
+ return $this->cfield;
196
+ }
197
+
198
+ switch( $dateEditType )
199
+ {
200
+ case EDIT_DATE_DD:
201
+ case EDIT_DATE_DD_INLINE:
202
+ case EDIT_DATE_DD_DP:
203
+ if($locale_info["LOCALE_ILONGDATE"] == 1)
204
+ return "day".$this->cfield;
205
+ else if($locale_info["LOCALE_ILONGDATE"] == 0)
206
+ return "month".$this->cfield;
207
+ else
208
+ return "year".$this->cfield;
209
+ break;
210
+
211
+ default:
212
+ return $this->cfield;
213
+ break;
214
+ }
215
+ }
216
+
217
+ function maxLengthMonth()
218
+ {
219
+ $maxLengthMonth = "";
220
+ $mounts = getMountNames();
221
+ $maxLenght = 0;
222
+ for ( $i =0; $i < count($mounts); $i++ )
223
+ {
224
+ $curMontn = $mounts[$i];
225
+ $curMonthLen = runner_strlen($curMontn);
226
+ if ( $maxLenght < $curMonthLen )
227
+ {
228
+ $maxLenght = $curMonthLen;
229
+ $maxLengthMonth = $curMontn;
230
+ }
231
+ }
232
+
233
+ return $maxLengthMonth;
234
+ }
235
+
236
+ /**
237
+ * Returns basic condition
238
+ */
239
+ public function getBasicFieldCondition( $svalue, $strSearchOption, $svalue2 = "", $etype = "" ) {
240
+ $searchFor = $this->processControlValue( $svalue, $etype );
241
+ $searchFor2 = $this->processControlValue( $svalue2, $etype );
242
+ $etype = "";
243
+ $pSet = $this->getProjectSettings();
244
+ if( !$pSet->dateEditShowTime($this->field) && IsDateTimeFieldType( $pSet->getFieldType($this->field) ) ) {
245
+ // search for date only in a datetime field
246
+
247
+ if( $strSearchOption == EQUALS ) {
248
+ // ( NOT field < date ) AND field < ( date + 1 day )
249
+ $tm = db2time( $searchFor );
250
+ if( !$tm[0] ) {
251
+ return DataCondition::_False();
252
+ }
253
+ $nextDay = adddays( $tm, 1 );
254
+ return DataCondition::_And( array(
255
+ DataCondition::_Not(
256
+ DataCondition::FieldIs( $this->field, dsopLESS, date2db( $tm ) )
257
+ ),
258
+ DataCondition::FieldIs( $this->field, dsopLESS, date2db( $nextDay ) )
259
+ ));
260
+ } else if( $strSearchOption == MORE_THAN ) {
261
+ // NOT ( field < ( date + 1 day ) )
262
+ $tm = db2time( $searchFor );
263
+ if( !$tm[0] ) {
264
+ return DataCondition::_False();
265
+ }
266
+ $nextDay = adddays( $tm, 1 );
267
+ return DataCondition::_Not(
268
+ DataCondition::FieldIs( $this->field, dsopLESS, date2db( $nextDay ) )
269
+ );
270
+
271
+ } else if( $strSearchOption == BETWEEN && $searchFor != "" && $searchFor2 != "" ) {
272
+ // true between only
273
+ // NOT ( field < date ) AND field < (date2+1)
274
+ $tm = db2time( $searchFor );
275
+ $tm2 = db2time( $searchFor2 );
276
+ if( !$tm[0] || !$tm2[0] ) {
277
+ return DataCondition::_False();
278
+ }
279
+ $tm2 = adddays( $tm2, 1 );
280
+ return DataCondition::_And( array(
281
+ DataCondition::_Not(
282
+ DataCondition::FieldIs( $this->field, dsopLESS, date2db( $tm ) )
283
+ ),
284
+ DataCondition::FieldIs( $this->field, dsopLESS, date2db( $tm2 ) )
285
+ ));
286
+
287
+ }
288
+
289
+ }
290
+ return parent::getBasicFieldCondition( $searchFor, $strSearchOption, $searchFor2, $etype );
291
+ }
292
+ }
293
+ ?>
classes/controls/DateTimeControl.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class DateTimeControl extends EditControl
3
+ {
4
+ /**
5
+ * Form the control specified search options array and built the control's search options markup
6
+ * @param String selOpt The search option value
7
+ * @param Boolean not It indicates if the search option negation is set
8
+ * @param Boolean both It indicates if the control needs 'NOT'-options
9
+ * @return String A string containing options markup
10
+ */
11
+ function getSearchOptions($selOpt, $not, $both)
12
+ {
13
+ $optionsArray = array(EQUALS, MORE_THAN, LESS_THAN, BETWEEN, EMPTY_SEARCH);
14
+ if($both)
15
+ {
16
+ $optionsArray[] = NOT_EQUALS;
17
+ $optionsArray[] = NOT_MORE_THAN;
18
+ $optionsArray[] = NOT_LESS_THAN;
19
+ $optionsArray[] = NOT_BETWEEN;
20
+ $optionsArray[] = NOT_EMPTY;
21
+ }
22
+ return $this->buildSearchOptions($optionsArray, $selOpt, $not, $both);
23
+ }
24
+ }
25
+ ?>
classes/controls/EditControlsContainer.php ADDED
@@ -0,0 +1,330 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EditControlsContainer
3
+ {
4
+ public $controls = array();
5
+ public $jsSettings = array();
6
+ public $pSetEdit = null;
7
+ public $pageType = "";
8
+ public $cipherer = null;
9
+
10
+ public $tName = "";
11
+
12
+ public $pageObject = null;
13
+
14
+ public $pageLikeInline = false;
15
+
16
+ public $tableBasedSearchPanelAdded = false;
17
+
18
+ public $searchPanelActivated = false;
19
+
20
+ /**
21
+ * Associative array used like a container to exchange some data between controls on one page
22
+ * @var {array}
23
+ */
24
+ public $globalVals = array();
25
+
26
+ /**
27
+ * @type Connection
28
+ */
29
+ protected $connection;
30
+
31
+ public $classNamesForEdit = array();
32
+
33
+ public $classNamesForSearch = array();
34
+
35
+ public function __construct($pageObject, $pSetEdit, $pageType, $cipherer = "")
36
+ {
37
+ if($pageObject != null)
38
+ {
39
+ $this->pageObject = $pageObject;
40
+ $this->tName = $pageObject->tName;
41
+
42
+ $this->pageLikeInline = $pageObject->pageType == PAGE_ADD && $pageObject->mode == ADD_INLINE ||
43
+ $pageObject->pageType == PAGE_EDIT && $pageObject->mode == EDIT_INLINE;
44
+ }
45
+ else
46
+ {
47
+ $this->tName = $pSetEdit->_table;
48
+ $this->cipherer = $cipherer;
49
+ }
50
+
51
+ $this->fillControlClassNames();
52
+
53
+ $this->setEditControlsConnection();
54
+
55
+ $this->pSetEdit = $pSetEdit;
56
+ $this->pageType = $pageType;
57
+ $this->searchPanelActivated = true;
58
+ }
59
+
60
+ /**
61
+ * Set the connection property
62
+ */
63
+ protected function setEditControlsConnection()
64
+ {
65
+ global $cman;
66
+
67
+ if( $this->pageObject != null )
68
+ $this->connection = $this->pageObject->connection;
69
+ else
70
+ $this->connection = $cman->byTable( $this->tName );
71
+ }
72
+
73
+ /**
74
+ * @return Boolean
75
+ */
76
+ public function isSearchPanelActivated()
77
+ {
78
+ if( $this->pageObject != null )
79
+ return $this->pageObject->isSearchPanelActivated();
80
+
81
+ return $this->pageType == PAGE_SEARCH;
82
+ }
83
+
84
+ function addControlsJSAndCSS()
85
+ {
86
+ $allowedPageTypes = array( PAGE_ADD, PAGE_EDIT, PAGE_VIEW, PAGE_LIST,
87
+ PAGE_SEARCH, PAGE_REGISTER, PAGE_LOGIN, PAGE_USERINFO );
88
+
89
+ // showing if there is Search panel on the page
90
+ $searchPanelActivated = $this->isSearchPanelActivated();
91
+
92
+ if( !in_array( $this->pageType, $allowedPageTypes ) && !$searchPanelActivated )
93
+ return;
94
+
95
+ switch( $this->pageType )
96
+ {
97
+ case PAGE_ADD:
98
+ $pageTypeStr = "Add";
99
+ break;
100
+ case PAGE_EDIT:
101
+ $pageTypeStr = "Edit";
102
+ break;
103
+ case PAGE_VIEW:
104
+ case PAGE_LIST:
105
+ $pageTypeStr = "List";
106
+ break;
107
+ default:
108
+ $pageTypeStr = "";
109
+ }
110
+
111
+ if( $pageTypeStr != "" )
112
+ {
113
+ $getEditFieldsFunc = "get".($this->pageLikeInline ? "Inline" : "").$pageTypeStr."Fields";
114
+ if( $this->pageLikeInline )
115
+ $appearOnPageFunc = "appearOnInline".$pageTypeStr;
116
+ else
117
+ $appearOnPageFunc = "appearOn".$pageTypeStr."Page";
118
+ }
119
+
120
+ switch( $this->pageType )
121
+ {
122
+ case PAGE_LOGIN:
123
+ case PAGE_REGISTER:
124
+ case PAGE_USERINFO:
125
+ $fields = $this->pSetEdit->getPageFields();
126
+ break;
127
+ case PAGE_SEARCH:
128
+ $fields = $this->pSetEdit->getAdvSearchFields();
129
+ break;
130
+ default:
131
+ $fields = array();
132
+ if( $getEditFieldsFunc )
133
+ $fields = $this->pSetEdit->$getEditFieldsFunc();
134
+ }
135
+
136
+ // Addign fields that aren't appear at list page, but appear on search panel
137
+ $searchFields = array();
138
+ if( $searchPanelActivated )
139
+ {
140
+ $searchFields = $this->pSetEdit->getPanelSearchFields();
141
+ $searchFields = array_merge($searchFields, $this->pSetEdit->getAllSearchFields());
142
+ $fields = array_merge($searchFields, $fields);
143
+ $fields = array_unique($fields);
144
+ }
145
+
146
+ foreach( $fields as $i => $f )
147
+ {
148
+ $appear = false;
149
+
150
+ if( $this->pageType == PAGE_REGISTER || $this->pageType == PAGE_SEARCH
151
+ || $this->pageType == PAGE_LOGIN || $this->pageType == PAGE_USERINFO
152
+ || in_array($f, $searchFields) )
153
+ {
154
+ $appear = true;
155
+ }
156
+ else if( $appearOnPageFunc )
157
+ $appear = $this->pSetEdit->$appearOnPageFunc($f);
158
+
159
+ if( $appear )
160
+ {
161
+ $editControl = $this->getControl($f);
162
+ $editControl->addJSFiles();
163
+ $editControl->addCSSFiles();
164
+ }
165
+ }
166
+ }
167
+
168
+ /**
169
+ * @param String field
170
+ * @param String id (optional)
171
+ * @param Array extraParmas (optional)
172
+ * @return Control
173
+ */
174
+ function getControl($field, $id = "", $extraParmas = array())
175
+ {
176
+ /*
177
+ if( count($extraParmas) && $extraParmas["makeReadonly"] ) {
178
+ include_once(getabspath("classes/controls/Control.php"));
179
+ $className = $this->classNamesForEdit[ EDIT_FORMAT_READONLY ];
180
+
181
+ $ctrl = createControlClass($className, $field, $this->pageObject != null ? $this->pageObject : $this, $id, $this->connection);
182
+ $ctrl->container = $this;
183
+
184
+ return $ctrl;
185
+ }
186
+ */
187
+
188
+ if( count($extraParmas) && $extraParmas["getConrirmFieldCtrl"] )
189
+ {
190
+ include_once(getabspath("classes/controls/Control.php"));
191
+ $className = $this->classNamesForEdit[ EDIT_FORMAT_PASSWORD ];
192
+
193
+ $ctrl = createControlClass($className, $field, $this->pageObject != null ? $this->pageObject : $this, $id, $this->connection);
194
+ if($extraParmas['isConfirm'])
195
+ $ctrl->field = Security::passwordField();
196
+ $ctrl->container = $this;
197
+
198
+ return $ctrl;
199
+ }
200
+
201
+ // if conrol does not created previously
202
+ if(!array_key_exists($field, $this->controls))
203
+ {
204
+ include_once(getabspath("classes/controls/Control.php"));
205
+
206
+ $userControl = false;
207
+ $editFormat = $this->getEditFormat($field);
208
+
209
+ if( ($this->pageType == PAGE_SEARCH || $this->pageType == PAGE_LIST ) && !$extraParmas["spreadsheet"] )
210
+ {
211
+ // Text field may be Lookup field on some page
212
+ $pageTypebyLookupFormat = $this->pSetEdit->getPageTypeByFieldEditFormat($field, EDIT_FORMAT_LOOKUP_WIZARD);
213
+
214
+ if( $editFormat == EDIT_FORMAT_TEXT_FIELD && $pageTypebyLookupFormat != "" )
215
+ {
216
+ $localPSet = new ProjectSettings($this->pSetEdit->_table, $pageTypebyLookupFormat);
217
+
218
+ if( $localPSet->getLinkField($field) != $localPSet->getDisplayField($field) )
219
+ $className = "LookupTextField";
220
+ else
221
+ $className = $this->classNamesForSearch[ $editFormat ];
222
+ }
223
+ else
224
+ $className = $this->classNamesForSearch[ $editFormat ];
225
+ }
226
+ else
227
+ $className = $this->classNamesForEdit[ $editFormat ];
228
+
229
+ if( $className == $this->classNamesForEdit[ EDIT_FORMAT_FILE ] && $this->pSetEdit->isBasicUploadUsed($field) )
230
+ $className = "FileFieldSingle";
231
+
232
+ if( !$className )
233
+ {
234
+ if($editFormat != "")
235
+ {
236
+ $className = "Edit".$editFormat;
237
+ $userControl = true;
238
+ include_once(getabspath("classes/controls/UserControl.php"));
239
+ if( !is_null($this->pageObject) )
240
+ $this->pageObject->AddJSFile("include/runnerJS/controls/".$className.".js", "include/runnerJS/editControls/Control.js");
241
+ }
242
+ else
243
+ $className = $this->classNamesForEdit[ EDIT_FORMAT_TEXT_FIELD ];
244
+ }
245
+
246
+ $this->controls[ $field ] = createControlClass($className, $field, $this->pageObject != null ? $this->pageObject : $this, $id, $this->connection);
247
+ $this->controls[ $field ]->container = $this;
248
+ $this->controls[ $field ]->forSpreadsheetGrid = $extraParmas["spreadsheet"];
249
+
250
+ if($userControl)
251
+ {
252
+ $this->controls[ $field ]->format = $className;
253
+ $this->controls[ $field ]->initUserControl();
254
+ }
255
+ }
256
+
257
+ if( $id !== "" )
258
+ $this->controls[ $field ]->setID($id);
259
+
260
+ return $this->controls[ $field ];
261
+ }
262
+
263
+ /**
264
+ * @deprecated
265
+ */
266
+ function isSystemControl($className)
267
+ {
268
+ include_once(getabspath("classes/controls/Control.php"));
269
+ if($this->pageType == PAGE_SEARCH || $this->pageType == PAGE_LIST)
270
+ return isset($this->classNamesForSearch[$className]);
271
+ else
272
+ return isset($this->classNamesForEdit[$className]);
273
+ }
274
+
275
+ /**
276
+ * Check if the host page is table based
277
+ * @return Boolean
278
+ */
279
+ function isPageTableBased()
280
+ {
281
+ if($this->pageType == PAGE_MENU || $this->pageType == PAGE_LOGIN || $this->pageType == PAGE_REMIND || $this->pageType == PAGE_CHANGEPASS)
282
+ {
283
+ return false;
284
+ }
285
+ return true;
286
+ }
287
+
288
+ function mobileTemplateMode()
289
+ {
290
+ return false;
291
+ }
292
+
293
+ protected function fillControlClassNames()
294
+ {
295
+ $this->classNamesForEdit[EDIT_FORMAT_TEXT_FIELD] = "TextField";
296
+ $this->classNamesForEdit[EDIT_FORMAT_TIME] = "TimeField";
297
+ $this->classNamesForEdit[EDIT_FORMAT_TEXT_AREA] = "TextAreaField";
298
+ $this->classNamesForEdit[EDIT_FORMAT_PASSWORD] = "PasswordField";
299
+ $this->classNamesForEdit[EDIT_FORMAT_DATE] = "DateField";
300
+ $this->classNamesForEdit[EDIT_FORMAT_CHECKBOX] = "CheckboxField";
301
+ $this->classNamesForEdit[EDIT_FORMAT_DATABASE_IMAGE] = "DatabaseFileField";
302
+ $this->classNamesForEdit[EDIT_FORMAT_DATABASE_FILE] = "DatabaseFileField";
303
+ $this->classNamesForEdit[EDIT_FORMAT_HIDDEN] = "HiddenField";
304
+ $this->classNamesForEdit[EDIT_FORMAT_READONLY] = "ReadOnlyField";
305
+ $this->classNamesForEdit[EDIT_FORMAT_FILE] = "FileField";
306
+ $this->classNamesForEdit[EDIT_FORMAT_LOOKUP_WIZARD] = "LookupField";
307
+
308
+ $this->classNamesForSearch[EDIT_FORMAT_TEXT_FIELD] = "TextField";
309
+ $this->classNamesForSearch[EDIT_FORMAT_TIME] = "TimeField";
310
+ $this->classNamesForSearch[EDIT_FORMAT_TEXT_AREA] = "TextField";
311
+ $this->classNamesForSearch[EDIT_FORMAT_PASSWORD] = "TextField";
312
+ $this->classNamesForSearch[EDIT_FORMAT_DATE] = "DateField";
313
+ $this->classNamesForSearch[EDIT_FORMAT_CHECKBOX] = "CheckboxField";
314
+ $this->classNamesForSearch[EDIT_FORMAT_DATABASE_IMAGE] = "TextField";
315
+ $this->classNamesForSearch[EDIT_FORMAT_DATABASE_FILE] = "TextField";
316
+ $this->classNamesForSearch[EDIT_FORMAT_HIDDEN] = "TextField";
317
+ $this->classNamesForSearch[EDIT_FORMAT_READONLY] = "TextField";
318
+ $this->classNamesForSearch[EDIT_FORMAT_FILE] = "FileField";
319
+ $this->classNamesForSearch[EDIT_FORMAT_LOOKUP_WIZARD] = "LookupField";
320
+
321
+ }
322
+
323
+ protected function getEditFormat( $field ) {
324
+ if( $this->pageObject ) {
325
+ return $this->pageObject->getEditFormat( $field );
326
+ }
327
+ return $this->pSetEdit->getEditFormat( $field );
328
+ }
329
+ }
330
+ ?>
classes/controls/FileField.php ADDED
@@ -0,0 +1,455 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once getabspath('classes/filehandler.php');
3
+
4
+ class FileField extends EditControl
5
+ {
6
+ /**
7
+ * Field random identifier for sessions values
8
+ * @var {string}
9
+ */
10
+ var $formStamp = "";
11
+
12
+ function __construct($field, $pageObject, $id, $connection)
13
+ {
14
+ parent::__construct($field, $pageObject, $id, $connection);
15
+ $this->format = EDIT_FORMAT_FILE;
16
+ }
17
+
18
+ function addJSFiles() {
19
+ if ( $this->format = EDIT_FORMAT_FILE ) {
20
+ $this->pageObject->AddJSFile("include/mupload.js");
21
+ }
22
+ }
23
+
24
+ function buildControl($value, $mode, $fieldNum, $validate, $additionalCtrlParams, $data)
25
+ {
26
+ parent::buildControl($value, $mode, $fieldNum, $validate, $additionalCtrlParams, $data);
27
+
28
+ if( $mode == MODE_SEARCH ) {
29
+ $this->format = "";
30
+
31
+ $classString = "";
32
+ if( $this->pageObject->isBootstrap() )
33
+ $classString = " class=\"form-control\"";
34
+
35
+ echo '<input id="'.$this->cfield.'" '.$classString.$this->inputStyle.' type="text" '
36
+ .('autocomplete="off" ')
37
+ .( $this->is508==true ? 'alt="'.$this->strLabel.'" ' : '')
38
+ .'name="'.$this->cfield.'" '.$this->pageObject->pSetEdit->getEditParams($this->field).' value="'
39
+ .runner_htmlspecialchars($value).'">';
40
+
41
+ $this->buildControlEnd($validate, $mode);
42
+ return;
43
+ }
44
+
45
+ $this->formStamp = generatePassword(15);
46
+
47
+ $filesArray = $this->getFileData( $value );
48
+
49
+ $keylink = "";
50
+ if($this->pageObject->pageType == PAGE_EDIT) {
51
+ if( $this->pageObject->keys )
52
+ {
53
+ $i = 1;
54
+ foreach($this->pageObject->keys as $keyName => $keyValue)
55
+ {
56
+ $keylink .= "&key".$i."=".rawurlencode( $keyValue );
57
+ $i++;
58
+ }
59
+ }
60
+ }
61
+ $fh = new RunnerFileHandler( $this->field, $this->pageObject->pSet, $this->formStamp );
62
+ $userFilesArray = $fh->loadFiles( $filesArray );
63
+
64
+ $jsonValue = my_json_encode($userFilesArray);
65
+ $multiple = "";
66
+ if( $this->pageObject->pSetEdit->getMaxNumberOfFiles($this->field) != 1 )
67
+ $multiple = "multiple ";
68
+ echo '
69
+ <!-- The file upload form used as target for the file upload widget -->
70
+ <form id="fileupload_'.$this->cfieldname.'" action="'.GetTableLink("mfhandler").'" method="POST" enctype="multipart/form-data">
71
+
72
+ <input type="hidden" name="formStamp_'.$this->cfieldname.'" id="formStamp_'.$this->cfieldname.'" value="'.$this->formStamp.'" />
73
+ <input type="hidden" name="_action" value="POST" />
74
+ <input type="hidden" id="value_'.$this->cfieldname.'" name="value_'.$this->cfieldname.'" value="'.runner_htmlspecialchars($jsonValue).'" />
75
+
76
+ <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
77
+ <div class="fileupload-buttonbar">
78
+ <div class="span7">
79
+ <!-- The fileinput-button span is used to style the file input field as button -->
80
+ <SPAN class="btn btn-primary btn-sm fileinput-button filesUpload">
81
+ <!--<A class="rnr-button filesUpload button" href="#" >-->
82
+ <input class="fileinput-button-input" type="file" accept="'.$this->pageObject->pSetEdit->getAcceptFileTypesHtml($this->field).'" name="files[]" value="'
83
+ ."Add files"
84
+ .'" '. $multiple .' />'
85
+ ."Add files"
86
+ .'<!--</A>-->
87
+ </SPAN>'
88
+ .'
89
+
90
+ </div>
91
+ <!-- The global progress information -->
92
+ <div class="fileupload-progress fade">
93
+ <!-- The global progress bar -->
94
+ <div class="progress" role="progressbar" aria-valuemin="0" aria-valuenow="0" aria-valuemax="100">
95
+ <div style="width:0;" class="bar progress-bar progress-bar-info progress-bar-striped active" ></div>
96
+ </div>
97
+ <!-- The extended global progress information -->
98
+ <div class="progress-extended">&nbsp;</div>
99
+ </div>
100
+ </div>
101
+ <!-- The loading indicator is shown during file processing -->
102
+ <div class="fileupload-loading"></div>
103
+ <!-- The table listing the files available for upload/download -->
104
+ <table class="mupload-files"><tbody class="files"></tbody></table>
105
+ </form>
106
+ ';
107
+ if(!isset($this->container->globalVals["muploadTemplateIncluded"]))
108
+ {
109
+ echo '<script type="text/x-tmpl" id="template-download">{% for (var i=0, file; file=o.files[i]; i++) { %}
110
+ <tr class="template-download fade">
111
+ {% if (file.error) { %}
112
+ <td></td>
113
+ <td class="name"><span class="text-muted">{%=file.name%}</span></td>
114
+ <td class="size"><span class="text-muted" dir="LTR">{%=o.formatFileSize(file.size)%}</span></td>
115
+ <td colspan=2 class="error"><span class="text-danger rnr-error">'
116
+ .""
117
+ .' {%=locale.fileupload.errors[file.error] || file.error%}</span></td>
118
+ {% } else { %}
119
+ <td class="preview">{% if (file.thumbnail_url) { %}
120
+ <a href="{%=file.url%}" title="{%=file.name%}" rel="gallery" download="{%=file.name%}"
121
+ {% if (!file.isIco) { %} {% } %}
122
+ ><img class="mupload-preview-img" src="{%=file.thumbnail_url%}&src=1"></a>
123
+ {% } else { %}
124
+ {% if (file.isImg) { %}
125
+ <a href="{%=file.url%}&nodisp=1" title="{%=file.name%}" rel="gallery" download="{%=file.name%}" ><img class="mupload-preview-img" src="{%=file.url%}&src=1"></a>
126
+ {% } %}
127
+ {% } %}</td>
128
+ <td class="name">
129
+ <a href="{%=file.url%}" title="{%=file.name%}" rel="{%=file.thumbnail_url&&\'gallery\'%}" download="{%=file.name%}">{%=file.name%}</a>
130
+ </td>
131
+ <td class="size"><span dir="LTR">{%=o.formatFileSize(file.size)%}</span></td>
132
+ <td></td>
133
+ <td class="delete">
134
+ {% if (!file.error) { %}
135
+ <SPAN class="btn btn-xs btn-default delete" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}" data-name="{%=file.name%}">
136
+ <!--<A href="#" >-->'
137
+ ."Delete"
138
+ .'<!--</A>-->
139
+ </SPAN>
140
+ {% } %}
141
+ </td>
142
+ {% } %}
143
+ </tr>
144
+ {% } %}
145
+ </script>
146
+ <script type="text/x-tmpl" id="template-upload">{% for (var i=0, file; file=o.files[i]; i++) { %}
147
+ <tr class="template-upload fade">
148
+ <td class="preview"><span class="fade"></span></td>
149
+ {% if (file.error) { %}
150
+ <td class="name"><span class="text-muted">{%=file.name%}</span></td>
151
+ <td class="size"><span class="text-muted">{%=o.formatFileSize(file.size)%}</span></td>
152
+ <td class="error" colspan="2"><span class="text-danger rnr-error">'
153
+ .""
154
+ .' {%=locale.fileupload.errors[file.error] || file.error%}</span></td>
155
+ {% } else if (o.files.valid && !i) { %}
156
+ <td class="name"><span>{%=file.name%}</span></td>
157
+ <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
158
+ <td>
159
+ <div class="progress progress-success progress-striped active" role="progressbar" aria-valuemin="0"
160
+ aria-valuemax="100" aria-valuenow="0"><div class="progress-bar bar" style="width:0;"></div></div>
161
+ </td>
162
+ {% } else { %}
163
+ <td></td>
164
+ {% } %}
165
+ <td class="cancel">{% if (!i) { %}
166
+ {% if (!file.error) { %}
167
+ <SPAN class="btn btn-default btn-xs">
168
+ <!--<A href="#" >-->'
169
+ ."Cancel"
170
+ .'<!--</A>-->
171
+ </SPAN>
172
+ {% } %}
173
+ {% } %}</td>
174
+ </tr>
175
+ {% } %}</script>';
176
+ $this->container->globalVals["muploadTemplateIncluded"] = true;
177
+ }
178
+ $this->buildControlEnd($validate, $mode);
179
+ }
180
+
181
+ /**
182
+ * Create CSS code for specifying control's width
183
+ */
184
+ function makeWidthStyle($widthPx)
185
+ {
186
+ if(0 == $widthPx)
187
+ return "";
188
+ return "min-width: ".$widthPx."px";
189
+ }
190
+
191
+ public function readWebValue(&$avalues, &$blobfields, $legacy1, $legacy2, &$filename_values)
192
+ {
193
+ $this->getPostValueAndType();
194
+ $this->formStamp = postvalue("formStamp_".$this->goodFieldName."_".$this->id);
195
+ if (FieldSubmitted($this->goodFieldName."_".$this->id) && $this->formStamp != "")
196
+ {
197
+ $filesArray = my_json_decode($this->webValue);
198
+ if(!is_array($filesArray) || count($filesArray) == 0)
199
+ $this->webValue = "";
200
+ else
201
+ {
202
+ if(count($_SESSION["mupload_".$this->formStamp]) > 0)
203
+ {
204
+ foreach($_SESSION["mupload_".$this->formStamp] as $fileArray)
205
+ $fileArray["deleted"] = true;
206
+ }
207
+ $result = array();
208
+ $uploadDir = $this->pageObject->pSetEdit->getLinkPrefix($this->field);
209
+ $searchStr = "";
210
+ foreach ($filesArray as $file)
211
+ {
212
+ if(isset($_SESSION["mupload_".$this->formStamp][$file["name"]]))
213
+ {
214
+ $sessionFile = $_SESSION["mupload_".$this->formStamp][$file["name"]]["file"];
215
+ $searchStr .= $file["name"].",!";
216
+ $result[] = array("name" => $sessionFile["name"],
217
+ "usrName" => $file["name"], "size" => $sessionFile["size"], "type" => $sessionFile["type"]
218
+ );
219
+ if($this->pageObject->pSetEdit->getCreateThumbnail($this->field)
220
+ && $sessionFile["thumbnail"] != "")
221
+ {
222
+ $lastIndex = count($result) - 1;
223
+ $result[$lastIndex]["thumbnail"] = $sessionFile["thumbnail"];
224
+ $result[$lastIndex]["thumbnail_type"] = $sessionFile["thumbnail_type"];
225
+ $result[$lastIndex]["thumbnail_size"] = $sessionFile["thumbnail_size"];
226
+ }
227
+ $_SESSION["mupload_".$this->formStamp][$file["name"]]["deleted"] = false;
228
+ }
229
+ }
230
+ if(count($result) > 0)
231
+ {
232
+ $result[0]["searchStr"] = $searchStr.":sStrEnd";
233
+ $this->webValue = my_json_encode_unescaped_unicode($result);
234
+ }
235
+ else
236
+ $this->webValue = "";
237
+ }
238
+ }
239
+ else
240
+ $this->webValue = false;
241
+
242
+ if(!($this->webValue===false))
243
+ {
244
+ if( $this->connection->dbType == nDATABASE_Informix )
245
+ {
246
+ if(IsTextType($this->pageObject->pSetEdit->getFieldType($this->field)))
247
+ $blobfields[] = $this->field;
248
+ }
249
+ $avalues[$this->field] = $this->webValue;
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Form the control specified search options array and built the control's search options markup
255
+ * @param String selOpt The search option value
256
+ * @param Boolean not It indicates if the search option negation is set
257
+ * @param Boolean both It indicates if the control needs 'NOT'-options
258
+ * @return String A string containing options markup
259
+ */
260
+ public function getSearchOptions($selOpt, $not, $both)
261
+ {
262
+ $optionsArray = array();
263
+ $isPHPEncripted = $this->pageObject->cipherer->isFieldPHPEncrypted($this->field);
264
+ if(!$isPHPEncripted){
265
+ $optionsArray[] = CONTAINS;
266
+ $optionsArray[] = EQUALS;
267
+ }
268
+ $optionsArray[] = EMPTY_SEARCH;
269
+ if($both)
270
+ {
271
+ if(!$isPHPEncripted){
272
+ $optionsArray[] = NOT_CONTAINS;
273
+ $optionsArray[] = NOT_EQUALS;
274
+ }
275
+ $optionsArray[] = NOT_EMPTY;
276
+ }
277
+ return $this->buildSearchOptions($optionsArray, $selOpt, $not, $both);
278
+ }
279
+
280
+ /**
281
+ * Fill the response array with the suggest values
282
+ *
283
+ * @param String value
284
+ * Note: the real value is preceeded with "_" so It's necessary to remove
285
+ * the first character before json decoding . Also It's important to add "_"
286
+ * to the beggining of the response suggest value because Searchsuggest
287
+ * expects that it starts with this character.
288
+ * @param String searchFor
289
+ * @param &Array response
290
+ * @param &Array row
291
+ */
292
+ public function suggestValue($value, $searchFor, &$response, &$row)
293
+ {
294
+ if(!$value)
295
+ return;
296
+
297
+ //value is preceeded with "_"
298
+ $value = substr($value, 1);
299
+
300
+ $filesArray = my_json_decode($value);
301
+
302
+ if(!is_array($filesArray) || count($filesArray) == 0)
303
+ $response[ "_".$value ] = "_".$value;
304
+ else
305
+ {
306
+ for($i = 0; $i < count($filesArray) && count($response) < 10; $i++)
307
+ {
308
+ if($this->pageObject->pSetEdit->getNCSearch())
309
+ $pos = stripos($filesArray[$i]["usrName"], $searchFor);
310
+ else
311
+ $pos = strpos($filesArray[$i]["usrName"], $searchFor);
312
+
313
+ if($pos !== false)
314
+ $response[ "_".$filesArray[$i]["usrName"] ] = "_".$filesArray[$i]["usrName"];
315
+ }
316
+ }
317
+ }
318
+
319
+ public function afterSuccessfulSave()
320
+ {
321
+ if( !$_SESSION["mupload_".$this->formStamp] ) {
322
+ return;
323
+ }
324
+ $fs = getStorageProvider( $this->pageObject->pSet, $this->field );
325
+ foreach( $_SESSION["mupload_".$this->formStamp] as $fileArray ) {
326
+ if( !$fileArray["deleted"] ) {
327
+ continue;
328
+ }
329
+ $fs->delete( $fileArray["file"]["name"] );
330
+ if( $fileArray["file"]["thumbnail"] ) {
331
+ $fs->delete( $fileArray["file"]["thumbnail"] );
332
+ }
333
+ }
334
+ unset($_SESSION["mupload_".$this->formStamp]);
335
+ }
336
+
337
+ /**
338
+ * @param String fieldValue
339
+ * @return String
340
+ */
341
+ public function getFieldValueCopy( $fieldValue )
342
+ {
343
+ $fs = getStorageProvider( $this->pageObject->pSet, $this->field );
344
+ if( !$fs->fast() ) {
345
+ return "[]";
346
+ }
347
+ $uploadFolder = $this->pageObject->pSetEdit->getUploadFolder( $this->field );
348
+
349
+ $filesData = $this->getFileData( $fieldValue );
350
+ foreach( array_keys( $filesData ) as $idx ) {
351
+ $file =& $filesData[ $idx ];
352
+ $newName = $fs->copyFile( $file["name"], $file["usrName"] );
353
+ if( !$newName ) {
354
+ continue;
355
+ }
356
+ $file["name"] = $newName;
357
+
358
+ if( $this->pageObject->pSetEdit->getCreateThumbnail( $this->field ) && $file["thumbnail"] ) {
359
+ $thumbnailPrefix = $this->pageObject->pSetEdit->getStrThumbnail( $this->field );
360
+ $newThumbnail = $fs->copyFile( $file["thumbnail"], $thumbnailPrefix.$file["usrName"] );
361
+ if( $newThumbnail ) {
362
+ $file["thumbnail"] = $newThumbnail;
363
+ } else {
364
+ unset( $file["thumbnail"] );
365
+ }
366
+ }
367
+ }
368
+
369
+ return my_json_encode( $filesData );
370
+ }
371
+
372
+ /**
373
+ * Returns basic condition
374
+ */
375
+ public function getBasicFieldCondition( $searchFor, $strSearchOption, $searchFor2 = "", $etype = "" ) {
376
+ if( $strSearchOption == EQUALS ) {
377
+ return $this->getFilenameCondition( dsopEQUAL, $searchFor );
378
+ } else if( $strSearchOption == STARTS_WITH ) {
379
+ return $this->getFilenameCondition( dsopSTART, $searchFor );
380
+ } else if( $strSearchOption == CONTAINS ) {
381
+ return $this->getFilenameCondition( dsopCONTAIN, $searchFor );
382
+ } else if( $strSearchOption == EMPTY_SEARCH ) {
383
+ return DataCondition::FieldIs( $this->field, dsopEMPTY, $searchFor );
384
+ }
385
+ return null;
386
+ }
387
+
388
+ /**
389
+ * Get file field search condition
390
+ * @param operation dsopEQUAL | dsopSTART | dsopCONTAIN
391
+ * @param String searchFor
392
+ * @return DsCondition
393
+ */
394
+ protected function getFilenameCondition( $operation, $searchFor ) {
395
+ $caseInsensitive = $this->pageObject->pSetEdit->getNCSearch() ? dsCASE_INSENSITIVE : dsCASE_DEFAULT;
396
+
397
+ $startCondition = DataCondition::FieldIs( $this->field, dsopSTART, "[{", $caseInsensitive );
398
+
399
+ // To extend like condition pattern
400
+ $likeWrapper = null;
401
+ $before = 'searchStr":"';
402
+ $after = ':sStrEnd"';
403
+
404
+ // set up suitable value and like wrapper parts
405
+ // to get proper like pattern for Condition with dsopCONTAIN op
406
+ // b $before, a $after, v $searchFor
407
+ if( $operation == dsopEQUAL ) {
408
+ // %bva% eg '%searchStr":"test.gif,!:sStrEnd"%'
409
+ // ',!' is added to the downloaded file name (ex. "test.gif,!")
410
+ $fileSearchFor = $before. $searchFor.',!' .$after;
411
+ } else if( $operation == dsopSTART ) {
412
+ // %bv%a% eg '%searchStr":"test.gif%:sStrEnd"%'
413
+ $fileSearchFor = $before.$searchFor;
414
+ $likeWrapper = array( 'after' => $after );
415
+ } else /* dsopCONTAIN */ {
416
+ // %b%v%a% eg '%searchStr":"%test.gif%:sStrEnd"%'
417
+ $fileSearchFor = $searchFor;
418
+ $likeWrapper = array( 'before' => $before, 'after' => $after );
419
+ }
420
+
421
+ return new DsCondition(
422
+ array(
423
+ new DsOperand( dsotCONDITION, DataCondition::_And( array(
424
+ $startCondition,
425
+ DataCondition::FieldIs( $this->field, dsopCONTAIN, $fileSearchFor, $caseInsensitive, 0, $likeWrapper )
426
+ ))),
427
+ new DsOperand( dsotCONDITION, DataCondition::_And( array(
428
+ DataCondition::_Not( $startCondition ),
429
+ DataCondition::FieldIs( $this->field, $operation, $searchFor, $caseInsensitive )
430
+ )))
431
+ ),
432
+ dsopOR,
433
+ $caseInsensitive
434
+ );
435
+ }
436
+ /**
437
+ * return parsed file info in unified format
438
+ * @return Array of arrays [
439
+ * "usrName" => user-provided filename
440
+ * "name" => file path if saved in filesystem
441
+ * "type" => (optional) file type in HTTP-ready format.
442
+ * "size" => (optional)size in bytes
443
+ * "thumbnail" => (optional)thumbnail file path
444
+ * "thumbnail_size" => (optional)thumbnail size
445
+ * "thumbnail_type" => (optional)thumbnail file type in HTTP-ready format
446
+ * ]
447
+ */
448
+ protected function getFileData( $value ) {
449
+ return RunnerFileHandler::getFileArray( $value, $this->field, $this->pageObject->pSet );
450
+ }
451
+
452
+
453
+
454
+ }
455
+ ?>
classes/controls/FileFieldSingle.php ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once getabspath('classes/filehandler.php');
3
+
4
+ class FileFieldSingle extends EditControl
5
+ {
6
+ function __construct($field, $pageObject, $id, $connection)
7
+ {
8
+ parent::__construct($field, $pageObject, $id, $connection);
9
+ $this->format = EDIT_FORMAT_FILE;
10
+
11
+ }
12
+
13
+
14
+ /**
15
+ * addJSFiles
16
+ * Add control JS files to page object
17
+ */
18
+ function addJSFiles()
19
+ {
20
+ }
21
+
22
+ /**
23
+ * addCSSFiles
24
+ * Add control CSS files to page object
25
+ */
26
+ function addCSSFiles()
27
+ {
28
+ }
29
+
30
+ function buildControl($value, $mode, $fieldNum, $validate, $additionalCtrlParams, $data)
31
+ {
32
+ parent::buildControl($value, $mode, $fieldNum, $validate, $additionalCtrlParams, $data);
33
+
34
+ if( $mode == MODE_SEARCH )
35
+ {
36
+ $this->format = "";
37
+
38
+ $classString = "";
39
+ if( $this->pageObject->isBootstrap() )
40
+ $classString = " class=\"form-control\"";
41
+
42
+ echo '<input id="'.$this->cfield.'" '.$classString.$this->inputStyle.' type="text" '
43
+ .('autocomplete="off" ')
44
+ .( $this->is508 == true ? 'alt="'.$this->strLabel.'" ' : '' )
45
+ .'name="'.$this->cfield.'" '.$this->pageObject->pSetEdit->getEditParams($this->field).' value="'
46
+ .runner_htmlspecialchars($value).'">';
47
+
48
+ $this->buildControlEnd($validate, $mode);
49
+ return;
50
+ }
51
+
52
+ $keyParams = array();
53
+ foreach( $this->pageObject->pSetEdit->getTableKeys() as $i => $kf ) {
54
+ $keyParams[] = "key".($i + 1). "=".runner_htmlspecialchars(rawurlencode( @$data[ $kf ] ));
55
+ }
56
+ $keyLink = "&" . implode("&", $keyParams);
57
+
58
+
59
+ $disp = "";
60
+ $strfilename = "";
61
+
62
+ $filename_size = $this->pageObject->pSetEdit->isUseTimestamp( $this->field )
63
+ ? 50
64
+ : 30;
65
+
66
+ if( $mode == MODE_EDIT || $mode == MODE_INLINE_EDIT )
67
+ {
68
+ // show current file
69
+ $filesArray = $this->getFileData( $value );
70
+ $fileName = "";
71
+ if( $filesArray ) {
72
+ $fileData = $filesArray[0];
73
+ $fileName = $fileData["usrName"];
74
+
75
+ $viewFormat = $this->pageObject->pSetEdit->getViewFormat( $this->field );
76
+ if( $viewFormat == FORMAT_FILE || $viewFormat == FORMAT_FILE_IMAGE )
77
+ $disp = $this->getFileOrImageMarkup( $fileData, $keyLink ) . "<br />";
78
+ }
79
+
80
+
81
+ // filename edit
82
+ $strfilename = '<input type=hidden name="filenameHidden_'.$this->cfieldname.'" value="'.runner_htmlspecialchars( $fileName ).'"><br>'
83
+ ."Filename"
84
+ .'&nbsp;&nbsp;<input type="text" style="background-color:gainsboro" disabled id="filename_'.$this->cfieldname
85
+ .'" name="filename_'.$this->cfieldname.'" size="'.$filename_size.'" maxlength="100" value="'.runner_htmlspecialchars( $fileName ).'">';
86
+
87
+ $strtype = '<br><input id="'.$this->ctype.'_keep" type="Radio" name="'.$this->ctype
88
+ .'" value="upload0" checked class="rnr-uploadtype">'."Keep";
89
+
90
+ if( (strlen($value) || $mode == MODE_INLINE_EDIT) && !$this->pageObject->pSetEdit->isRequired($this->field) )
91
+ {
92
+ $strtype .= '<input id="'.$this->ctype.'_delete" type="Radio" name="'.$this->ctype
93
+ .'" value="upload1" class="rnr-uploadtype">'."Delete";
94
+ }
95
+ $strtype .= '<input id="'.$this->ctype.'_update" type="Radio" name="'.$this->ctype
96
+ .'" value="upload2" class="rnr-uploadtype">'."Update";
97
+ }
98
+ else
99
+ {
100
+ // if Adding record
101
+ $strtype = '<input id="'.$this->ctype.'" type="hidden" name="'.$this->ctype.'" value="upload2">';
102
+
103
+ $strfilename = '<br>'."Filename"
104
+ .'&nbsp;&nbsp;<input type="text" id="filename_'.$this->cfieldname.'" name="filename_'.$this->cfieldname.'" size="'
105
+ .$filename_size.'" maxlength="100">';
106
+ }
107
+
108
+ echo $disp.$strtype;
109
+
110
+ if( $mode == MODE_EDIT || $mode == MODE_INLINE_EDIT )
111
+ echo '<br>';
112
+
113
+ echo '<input type="File" id="'.$this->cfield.'" '
114
+ .'accept="'.$this->pageObject->pSetEdit->getAcceptFileTypesHtml($this->field).'" '
115
+ .( ($mode == MODE_INLINE_EDIT || $mode == MODE_INLINE_ADD) && $this->is508 == true ? 'alt="'.$this->strLabel.'" ' : '')
116
+ .' name="'.$this->cfield.'" >'.$strfilename;
117
+
118
+ echo '<input type="Hidden" id="notempty_'.$this->cfieldname.'" value="'.(strlen($value)? 1 : 0).'">';
119
+
120
+ $this->buildControlEnd($validate, $mode);
121
+ }
122
+
123
+ /**
124
+ * Get the image or file link markup
125
+ * @param String value
126
+ * @param String fileName
127
+ * @param Boolean newUploaderWasUsed
128
+ * @param Array fileData
129
+ * @return String
130
+ */
131
+ function getFileOrImageMarkup( $fileData, $keylink )
132
+ {
133
+ $fileName = $fileData["usrName"];
134
+ $urls = $this->getFileUrls( $fileData, $keylink );
135
+ if( !$urls["url"] ) {
136
+ return "";
137
+ }
138
+
139
+
140
+ if( !CheckImageExtension( $fileName ) )
141
+ {
142
+ return "<a target=\"_blank\" href=\"". runner_htmlspecialchars( $urls["url"] )."\">"
143
+ .runner_htmlspecialchars( $fileName )."</a>";
144
+ }
145
+
146
+ if( !$urls["thumbnail"] ) {
147
+ $urls["thumbnail"] = $urls["url"];
148
+ }
149
+
150
+ $altAttr = " alt=\"".runner_htmlspecialchars( $fileName )."\"" ;
151
+ return "<a target=\"_blank\" href=\"". runner_htmlspecialchars( $urls["url"] ) . "\" >"
152
+ ."<img class=\"r-editfile-img\" ". $altAttr ." border=0 src=\"". runner_htmlspecialchars( $urls["thumbnail"] ) . "\"></a>";
153
+
154
+ }
155
+
156
+ /**
157
+ *
158
+ */
159
+ function readWebValue(&$avalues, &$blobfields, $legacy1, $legacy2, &$filename_values)
160
+ {
161
+ $this->getPostValueAndType();
162
+
163
+ if( FieldSubmitted( $this->goodFieldName."_".$this->id ) )
164
+ {
165
+ $fileNameForPrepareFunc = securityCheckFileName( postvalue("filename_".$this->goodFieldName."_".$this->id) );
166
+ if( $this->pageObject->pageType != PAGE_EDIT )
167
+ {
168
+ $this->webValue = prepare_upload($this->field, "upload2", $fileNameForPrepareFunc, $fileNameForPrepareFunc, ""
169
+ , $this->id, $this->pageObject);
170
+ }
171
+ else
172
+ {
173
+ if(substr($this->webType, 0, 4) == "file")
174
+ {
175
+ $prepearedFile = prepare_file($this->webValue, $this->field, $this->webType, $fileNameForPrepareFunc, $this->id);
176
+ if($prepearedFile !== false)
177
+ {
178
+ $this->webValue = $prepearedFile["value"];
179
+ $filename = $prepearedFile["filename"];
180
+ }
181
+ else
182
+ $this->webValue = false;
183
+ }
184
+ else if(substr($this->webType, 0, 6) == "upload")
185
+ {
186
+ if($fileNameForPrepareFunc)
187
+ $this->webValue = $fileNameForPrepareFunc;
188
+ if($this->webType == "upload1")
189
+ {
190
+ // file deletion, read filename from the database
191
+ $oldValues = $this->pageObject->getOldRecordData();
192
+ $fileNameForPrepareFunc = $oldValues[$this->field];
193
+ }
194
+ $this->webValue = prepare_upload($this->field, $this->webType, $fileNameForPrepareFunc, $this->webValue, "", $this->id, $this->pageObject);
195
+ }
196
+ }
197
+ }
198
+ else
199
+ $this->webValue = false;
200
+
201
+ if(!($this->webValue === false))
202
+ {
203
+ if( $this->webValue && $this->pageObject->pSetEdit->getCreateThumbnail($this->field) )
204
+ {
205
+ $contents = GetUploadedFileContents("value_".$this->goodFieldName."_".$this->id);
206
+ $ext = CheckImageExtension( GetUploadedFileName("value_".$this->goodFieldName."_".$this->id) );
207
+ if( $ext ) {
208
+ $thumb = CreateThumbnail($contents, $this->pageObject->pSetEdit->getThumbnailSize($this->field), $ext);
209
+ $this->pageObject->filesToSave[] = new SaveFile($thumb, $this->pageObject->pSetEdit->GetStrThumbnail($this->field)
210
+ .$this->webValue, $this->pageObject->pSetEdit->getUploadFolder($this->field), $this->pageObject->pSetEdit->isAbsolute($this->field));
211
+ }
212
+ }
213
+
214
+ $avalues[ $this->field ] = $this->webValue;
215
+ }
216
+ }
217
+
218
+ function makeWidthStyle($widthPx)
219
+ {
220
+ if(0 == $widthPx)
221
+ return "";
222
+ return "min-width: ".$widthPx."px";
223
+ }
224
+
225
+ protected function getFileData( $value ) {
226
+ return RunnerFileHandler::getFileArray( $value, $this->field, $this->pageObject->pSet );
227
+ }
228
+
229
+ /**
230
+ * @return Array
231
+ * "url" => string
232
+ * "thumbnail" => string
233
+ * Each element can be empty if no corresponding file exists
234
+ *
235
+ */
236
+ protected function getFileUrls( $fileData, $keylink ) {
237
+ $pSet = $this->pageObject->pSet;
238
+ $fs = getStorageProvider( $pSet, $this->field );
239
+ $fsInfo = $fs->getFileInfo( $fileData["name"] );
240
+ if( !$fsInfo ) {
241
+ return array();
242
+ }
243
+ $lastModified = time();
244
+ if( $fsInfo["lastModified"]) {
245
+ $lastModified = $fsInfo["lastModified"];
246
+ }
247
+
248
+ $params = array();
249
+ $params["file"] = $fileData["usrName"];
250
+ $params["table"] = $pSet->table();
251
+ $params["field"] = $this->field;
252
+ $params["hash"] = fileAttrHash( $keylink, $file["size"], $lastModified );
253
+
254
+ foreach( $additionalParams as $k => $val ) {
255
+ $params[ $k ] = $val;
256
+ }
257
+ $ret = array();
258
+ $ret["url"] = GetTableLink("file", "", prepareUrlQuery( $params ).$keylink );
259
+
260
+
261
+ if( $fileData["thumbnail"] && $fs->getFileInfo( $fileData["thumbnail"] ) ) {
262
+ $params["thumbnail"] = 1;
263
+ $ret["thumbnail"] = GetTableLink("file", "", prepareUrlQuery( $params ).$keylink );
264
+ }
265
+
266
+ if( !$ret["thumbnail"] && $fsInfo["size"] > 512000 ) {
267
+ $ret["thumbnail"] = "images/icons/jpg.png";
268
+ }
269
+
270
+
271
+ return $ret;
272
+
273
+
274
+ }
275
+
276
+ }
277
+ ?>