]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/DetailView/DetailView.php
Release 6.4.0
[Github/sugarcrm.git] / include / DetailView / DetailView.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM Community Edition is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38
39 /**
40  * DetailView - display single record
41  * @api
42  */
43 class DetailView extends ListView {
44
45         var $list_row_count = null;
46         var $return_to_list_only=false;
47         var $offset_key_mismatch=false;
48         var $no_record_found=false;
49
50         function DetailView(){
51                 parent::ListView();
52
53                 global $theme, $app_strings, $currentModule;
54                 $this->local_theme = $theme;
55                 $this->local_app_strings =$app_strings;
56         }
57
58         function processSugarBean($html_varName, $seed, &$offset, $isfirstview=0) {
59                 global $row_count, $sugar_config;
60
61                 global $next_offset;
62                 global $previous_offset;
63                 global $list_view_row_count;
64                 global $current_offset;
65                 if (!empty($sugar_config['disable_vcr']) )  {
66                             $seed->retrieve($_REQUEST['record']);
67                                 return $seed;
68                 }
69                 $isfirstview = 0;
70
71                 $nav_history_set=false;
72                 $nav_history_array=array();
73                 $nav_offset='';
74                 $nav_ids_visited=array();
75                 $nav_stamp='';
76
77                 //get the session variable DETAIL_NAV_HISTORY,
78                 //the format of the variable stamp,offset, array of IDs visited.
79         $nav_history=$this->getLocalSessionVariable($html_varName, "DETAIL_NAV_HISTORY");
80                 if (!empty($nav_history)) {
81                         $nav_history_set=true;
82                         $nav_history_array=explode(":",$nav_history);
83                         $nav_stamp=$nav_history_array[0];
84                         $nav_offset=$nav_history_array[1];
85                         eval("\$nav_ids_visited= ".$nav_history_array[2].";");
86                 }
87
88                 //from list                                                                     offset is there but $bNavHistorySet is false.
89                 //from next,previous,start and end buttons      offset and $bNavHistorySet is true.
90                 //from tracker                                                          offset is not there but $bNavHistorySet may or may not exist.
91                 if (isset($_REQUEST['offset']) && !empty($_REQUEST['offset'])) {
92                         //get offset values.
93                         $offset = $_REQUEST['offset'];
94                         if($offset < 0){
95                                 $offset = 0;
96                         }
97                         //if the stamp has changed, ignore the offset and navigate to the record.
98                         //use case, search, navigate to detail, copy URL, search again, paste URL.
99                         if (!$this->isRequestFromListView($html_varName))  {
100                             $result = $seed->retrieve($_REQUEST['record']);
101                                 return $result;
102                         }
103
104                         if ($nav_history_set) {
105                                 if (isset($nav_ids_visited[$offset])) {
106                                         unset($nav_ids_visited[$offset]);
107                                 }
108                         }
109
110                 } else {
111                         if ($nav_history_set) {
112                                 //try to locate the ID in the nav_history array.
113
114                                 $key = array_search($_REQUEST['record'], $nav_ids_visited);
115                                 if ($key === false) {
116                                         //do not show the VCR buttons.
117
118                                 $result = $seed->retrieve($_REQUEST['record']);
119                                         return $result;
120                                 }
121                                 $offset=$key;
122                                 $_REQUEST['offset'] = $offset;
123                                 $_GET['offset'] = $offset;
124                                 $_POST['offset'] = $offset;
125
126                                 $_REQUEST['stamp'] = $nav_stamp;
127                                 $_GET['stamp'] = $nav_stamp;
128                                 $_POST['stamp'] = $nav_stamp;
129                                 if (isset($nav_ids_visited[$offset])) {
130                                         unset($nav_ids_visited[$offset]);
131                                 }
132
133                         } else {
134                                 if(!empty($seed->id))return $seed;
135
136                         $result = $seed->retrieve($_REQUEST['record']);
137                                 return $result;
138                         }
139                 }
140
141         //Check if this is the first time we have viewed this record
142         $var = $this->getLocalSessionVariable($html_varName, "IS_FIRST_VIEW");
143         if(!isset($var) || !$var){
144             $isFirstView = true;
145         }
146         else{
147             $isFirstView = false;
148         }
149         //indicate that this is not the first time anymore
150         $this->setLocalSessionVariable($html_varName, "IS_FIRST_VIEW",  false);
151
152         // All 3 databases require this because the limit query does a > db_offset comparision.
153                 $db_offset=$offset-1;
154
155                 $this->populateQueryWhere($isFirstView, $html_varName);
156                 if(ACLController::requireOwner($seed->module_dir, 'view')) {
157                         global $current_user;
158                         $seed->getOwnerWhere($current_user->id);
159                 if(!empty($this->query_where)) {
160                         $this->query_where .= ' AND ';
161                 }
162                 $this->query_where .= $seed->getOwnerWhere($current_user->id);
163                 }
164
165         $order = $this->getLocalSessionVariable($seed->module_dir.'2_'.$html_varName, "ORDER_BY");
166         $orderBy = '';
167         if(!empty($order['orderBy']))
168                 $orderBy = $order['orderBy'];
169          if(!empty($orderBy) && !empty($order['direction']))
170                 $orderBy .= ' ' . $order['direction'];
171
172         $this->query_orderby =  $seed->process_order_by($orderBy,null);
173                 $current_offset = $_REQUEST['offset'] -1;
174                 $response = $seed->process_detail_query(SugarVCR::retrieve($seed->module_dir), 0, -1, -1, '', $current_offset);
175                 //$response = $seed->get_detail(, $this->query_where, $db_offset);
176                 $object = $response['bean'];
177                 $row_count = $response['row_count'];
178                 $next_offset = $response['next_offset'];
179                 $previous_offset = $response['previous_offset'];
180                 $list_view_row_count = $row_count;
181                 $this->setListViewRowCount($row_count);
182
183                 //if the retrieved id is not same as the request ID then hide the VCR buttons.
184                 if (empty($object->id)) {
185                         $this->no_record_found=true;
186                 }
187                 if (empty($_REQUEST['InDetailNav']) and strcmp($_REQUEST['record'],$object->id)!=0)  {
188                          $this->offset_key_mismatch=true;
189                 }
190                 if ($this->no_record_found or $this->offset_key_mismatch ) {
191                         if ($nav_history_set) {
192                                 $this->return_to_list_only=true;
193                         }
194                 $result = $seed->retrieve($_REQUEST['record']);
195                         return $result;
196                 }
197
198                 //update the request with correct value for the record attribute.
199                 //need only when using the VCR buttuoms. This is a workaround need to fix the values
200                 //set in the VCR links.
201                 $_REQUEST['record'] = $object->id;
202                 $_GET['record'] = $object->id;
203                 $_POST['record'] = $object->id;
204
205                 //set nav_history.
206                 if (empty($nav_stamp)) {
207                         $nav_stamp=$_GET['stamp'];
208                 }
209                 if (empty($nav_offset)) {
210                         $nav_offset=$offset;
211                 }
212                 //store a maximum of 20 entries in the nav_ids_visited array.
213                 //remove the oldest entry when this limit is reached.
214                 if (count($nav_ids_visited) >= 20) {
215                         reset($nav_ids_visited);
216                         unset($nav_ids_visited[key($nav_ids_visited)]);
217                 }
218                 $nav_ids_visited[$offset]=$object->id;
219                 $nav_history=sprintf("%s:%s:%s",$nav_stamp,$nav_offset,var_export($nav_ids_visited,true));
220         $this->setLocalSessionVariable($html_varName, "DETAIL_NAV_HISTORY",$nav_history);
221
222                 return $object;
223         }
224
225         function populateQueryWhere($isfirstview, $html_varName){
226                 if($isfirstview){
227             $this->query_where = $this->getVariableFromSession($_REQUEST['module'], 'QUERY_WHERE');
228
229             //this is a fail safe, in case the old ListView is still in use
230             if(empty($this->query_where)){
231                 $this->query_where = $this->getLocalSessionVariable($html_varName, "QUERY_WHERE");
232             }
233                         //SETTING QUERY FOR LATER USE
234                         $this->setSessionVariable("QUERY_DETAIL", "where", $this->query_where);
235                 }
236                 else{
237                         $this->query_where = $this->getSessionVariable("QUERY_DETAIL", "where");
238                 }
239         }
240
241         function processListNavigation( &$xtpl, $html_varName, $current_offset, $display_audit_link = false){
242                 global $export_module, $sugar_config, $current_user;
243         //intialize audit_link
244         $audit_link = '';
245
246                 $row_count = $this->getListViewRowCount();
247
248         if($display_audit_link && (!isset($sugar_config['disc_client']) || $sugar_config['disc_client'] == false))
249         {
250             //Audit link
251             $popup_request_data = array(
252                         'call_back_function' => 'set_return',
253                         'form_name' => 'EditView',
254                         'field_to_name_array' => array(),
255                     );
256             $json = getJSONobj();
257             $encoded_popup_request_data = $json->encode($popup_request_data);
258             $audit_link = "<a href='javascript:void(0)' onclick='open_popup(\"Audit\", \"600\", \"400\", \"&record=".$_REQUEST['record']."&module_name=".$_REQUEST['module']."\", true, false, $encoded_popup_request_data);'>".$this->local_app_strings['LNK_VIEW_CHANGE_LOG']."</a>";
259         }
260
261         $html_text = "";
262         $pre_html_text = "";
263                 $pre_html_text .= "<tr class='pagination'>\n";
264                 $pre_html_text .= "<td COLSPAN=\"20\">\n";
265         $pre_html_text .= "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\"><tr><td style=\"text-align: left\" >&nbsp;".$audit_link."</td>\n";
266
267
268
269         if ($this->return_to_list_only == true) {
270                 if($current_offset != 0 && $this->isRequestFromListView($html_varName))
271                 {
272                         if($current_offset < 0){
273                                 $current_offset = 1;
274                         }
275                         else if($current_offset > $row_count){
276                                 $current_offset = $row_count;
277                         }
278
279                                 $this->set_base_URL($html_varName);
280                         $list_URL = $this->base_URL.'&action=index&module='.$_REQUEST['module'];
281                         $current_page = floor($current_offset / $this->records_per_page) * $this->records_per_page;
282
283                         $list_URL .= '&'.$this->getSessionVariableName($html_varName,"offset").'='.$current_page;
284                         //$list_link = "<a href=\"$list_URL\" >".$this->local_app_strings['LNK_LIST_RETURN']."&nbsp;</a>";
285                                 $list_link = "<button type='button' class='button' title='{$GLOBALS['app_strings']['LNK_LIST_RETURN']}' onClick='location.href=\"$list_URL\";'>".$this->local_app_strings['LNK_LIST_RETURN']."</button>";
286
287                                 $html_text .= "<td nowrap align='right' scope='row'>".$list_link;
288
289                                 if ($row_count != 0) {
290                                 $resume_URL  = $this->base_URL.$current_offset."&InDetailNav=1";
291                                 //$resume_link = "<a href=\"$resume_URL\" >".$this->local_app_strings['LNK_RESUME']."&nbsp;</a>";
292                                         $resume_link = "<button type='button' class='button' title='$this->local_app_strings['LNK_RESUME']' onClick='location.href=\"$resume_URL\";'>".$this->local_app_strings['LNK_RESUME']."</button>";
293
294                                 $html_text .= "&nbsp;&nbsp;".$resume_link;
295                                 }
296                                 $html_text .= "</td>";
297                 }
298         }
299                 else {
300                 if($current_offset != 0 && $this->isRequestFromListView($html_varName))
301                 {
302                         if($current_offset < 0){
303                                 $current_offset = 1;
304                         }
305                         else if($current_offset > $row_count){
306                                 $current_offset = $row_count;
307                         }
308
309                         $next_offset = $current_offset + 1;
310                         $previous_offset = $current_offset - 1;
311
312                                 $this->set_base_URL($html_varName);
313
314                         $start_URL = $this->base_URL."1"."&InDetailNav=1";
315                         $current_URL = $this->base_URL.$current_offset."&InDetailNav=1";
316                         $previous_URL  = $this->base_URL.$previous_offset."&InDetailNav=1";
317                         $next_URL  = $this->base_URL.$next_offset."&InDetailNav=1";
318                         $end_URL  = $this->base_URL.$row_count."&InDetailNav=1";
319
320                         $current_page = floor($current_offset / $this->records_per_page) * $this->records_per_page;
321
322                         if(1 == $current_offset){
323                                 //$start_link = SugarThemeRegistry::current()->getImage("start_off","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_START'])."&nbsp;".$this->local_app_strings['LNK_LIST_START'];
324                                         //$previous_link = SugarThemeRegistry::current()->getImage("previous_off","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_PREVIOUS'])."&nbsp;".$this->local_app_strings['LNK_LIST_PREVIOUS']."";
325                                         $start_link = "<button type='button' title='{$this->local_app_strings['LNK_LIST_START']}' class='button' disabled>".SugarThemeRegistry::current()->getImage("start_off","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_START'])."</button>";
326                                         $previous_link = "<button type='button' title='{$this->local_app_strings['LNK_LIST_PREVIOUS']}' class='button' disabled>".SugarThemeRegistry::current()->getImage("previous_off","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_PREVIOUS'])."</button>";
327
328                                 }else{
329                                         //$start_link = "<a href=\"$start_URL\">".SugarThemeRegistry::current()->getImage("start","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_START'])."</a>&nbsp;<a href=\"$start_URL\">".$this->local_app_strings['LNK_LIST_START']."</a>";
330                                         $start_link = "<button type='button' class='button' title='{$this->local_app_strings['LNK_LIST_START']}' onClick='location.href=\"$start_URL\";'>".SugarThemeRegistry::current()->getImage("start","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_START'])."</button>";
331
332                                         if(0 != $current_offset){
333                                                 //$previous_link = "<a href=\"$previous_URL\">".SugarThemeRegistry::current()->getImage("previous","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_PREVIOUS'])."</a>&nbsp;<a href=\"$previous_URL\" >".$this->local_app_strings['LNK_LIST_PREVIOUS']."</a>";
334                                                 $previous_link = "<button type='button' class='button' title='{$this->local_app_strings['LNK_LIST_PREVIOUS']}' onClick='location.href=\"$previous_URL\";'>".SugarThemeRegistry::current()->getImage("previous","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_PREVIOUS'])."</button>";
335                                 }
336                                 else {
337                                         //$previous_link = SugarThemeRegistry::current()->getImage("previous_off","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_PREVIOUS'])."&nbsp;".$this->local_app_strings['LNK_LIST_PREVIOUS'];
338                                                 $previous_link = "<button type='button' title='{$this->local_app_strings['LNK_LIST_PREVIOUS']}' class='button' disabled>".SugarThemeRegistry::current()->getImage("previous_off","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_PREVIOUS'])."</button>";
339
340                                 }
341                         }
342
343
344                         if($row_count <= $current_offset){
345                                 //$end_link = $this->local_app_strings['LNK_LIST_END']."&nbsp;".SugarThemeRegistry::current()->getImage("end_off","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_END']);
346                                 //$next_link = $this->local_app_strings['LNK_LIST_NEXT']."&nbsp;".SugarThemeRegistry::current()->getImage("next_off","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_NEXT']);
347                                         $end_link = "<button type='button' title='{$this->local_app_strings['LNK_LIST_END']}' class='button' disabled>".SugarThemeRegistry::current()->getImage("end_off","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_END'])."</button>";
348                                         $next_link = "<button type='button' title='{$this->local_app_strings['LNK_LIST_NEXT']}' class='button' disabled>".SugarThemeRegistry::current()->getImage("next_off","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_NEXT'])."</button>";
349                         }
350                         else{
351                                 //$end_link = "<a href=\"$end_URL\">".$this->local_app_strings['LNK_LIST_END']."</a>&nbsp;<a href=\"$end_URL\">".SugarThemeRegistry::current()->getImage("end","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_END'])."</a>";
352                                 //$next_link = "<a href=\"$next_URL\">".$this->local_app_strings['LNK_LIST_NEXT']."</a>&nbsp;<a href=\"$next_URL\">".SugarThemeRegistry::current()->getImage("next","border='0' align='absmiddle'",,null,null,'.gif',$this->local_app_strings['LNK_LIST_NEXT'])."</a>";
353                                         $end_link = "<button type='button' class='button' title='{$this->local_app_strings['LNK_LIST_END']}' onClick='location.href=\"$end_URL\";'>".SugarThemeRegistry::current()->getImage("end","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_END'])."</button>";
354                                         $next_link = "<button type='button' class='button' title='{$this->local_app_strings['LNK_LIST_NEXT']}' onClick='location.href=\"$next_URL\";'>".SugarThemeRegistry::current()->getImage("next","border='0' align='absmiddle'",null,null,'.gif',$this->local_app_strings['LNK_LIST_NEXT'])."</button>";
355
356                         }
357
358                         $html_text .= "<td nowrap align='right' >".$start_link."&nbsp;&nbsp;".$previous_link."&nbsp;&nbsp;(".$current_offset." ".$this->local_app_strings['LBL_LIST_OF']." ".$row_count.")&nbsp;&nbsp;".$next_link."&nbsp;&nbsp;".$end_link."</td>";
359
360                 }
361                 }
362         $post_html_text = "</tr></table>\n";
363         $post_html_text .= "</td>\n";
364                 $post_html_text .= "</tr>\n";
365                 $showVCRControl = true;
366                 if(isset($sugar_config['disable_vcr'])) {
367                     $showVCRControl = !$sugar_config['disable_vcr'];
368                 }
369                 if ( $showVCRControl && $html_text != "" )
370                     $xtpl->assign("PAGINATION",$pre_html_text.$html_text.$post_html_text);
371         }
372
373
374         function set_base_URL($html_varName) {
375
376                 if(!isset($this->base_URL)){
377
378                         $this->base_URL = $_SERVER['PHP_SELF'];
379                 if(empty($this->base_URL)){
380                         $this->base_URL = 'index.php';
381                 }
382
383                 /*fixes an issue with
384                 deletes when doing a search*/
385                 foreach($_GET as $name=>$value){
386                         if(!empty($value)){
387                                 if($name != $this->getSessionVariableName($html_varName,"ORDER_BY") && $name != "offset" && substr_count($name, "ORDER_BY")==0 && $name!="isfirstview"){
388                                         if (is_array($value)) {
389                                                 foreach($value as $valuename=>$valuevalue){
390                                                                 $this->base_URL .= "&{$name}[]=".$valuevalue;
391                                                 }
392                                         } else {
393                                                 if(substr_count( $this->base_URL, '?') > 0){
394                                                         $this->base_URL .= "&$name=$value";
395                                                 }else{
396                                                                 $this->base_URL .= "?$name=$value";
397                                                 }
398                                         }
399                                 }
400                         }
401                 }
402
403                 if($_SERVER['REQUEST_METHOD'] == 'POST'){
404                         $this->base_URL .= '?';
405                         if(isset($_REQUEST['action'])) $this->base_URL .= '&action='.$_REQUEST['action'];
406                         if(isset($_REQUEST['record'])) $this->base_URL .= '&record='.$_REQUEST['record'];
407                         if(isset($_REQUEST['module'])) $this->base_URL .= '&module='.$_REQUEST['module'];
408                 }
409                 $this->base_URL .= "&offset=";
410                 }
411         }
412         function setListViewRowCount($count)
413         {
414                 $this->list_row_count = $count;
415         }
416
417         function getListViewRowCount()
418         {
419                 return $this->list_row_count;
420         }
421
422         /* This method will return in all of these cases: When selecting any of the VCR buttons (start,prev,next or last)
423          * and navigating from list to detail for the first time.
424          * if false in this case: the user changes the list query (which generates a new stamp) and pastes a URL
425          * from a previously navigated item.
426          */
427     function isRequestFromListView($html_varName)
428     {
429         $varList = $this->getLocalSessionVariable($html_varName, "FROM_LIST_VIEW");
430         if(isset($_GET['stamp']) && isset($varList) && $varList == $_GET['stamp']){
431             return true;
432         }
433         else{
434             return false;
435         }
436     }
437
438     /**
439      * Return a variable from the session. uses the new ListView session data. Hence the '2'
440      *
441      * @param unknown_type $name - the name of the variable to set in the session
442      * @param unknown_type $value - the value of the variable to set
443      */
444     function getVariableFromSession($name, $value){
445           if(isset($_SESSION[$name."2_".$value])){
446             return $_SESSION[$name."2_".$value];
447         }
448         else{
449             return "";
450     }
451     }
452
453         }
454 ?>