function action_get_reports()
 {
     global $app_list_strings, $db, $current_user;
     $queryArray = preg_split('/::/', $_REQUEST['node']);
     switch ($queryArray[0]) {
         case 'src':
             $returnArray[] = array('id' => 'favorites', 'text' => 'Favorites', 'expanded' => true);
             $returnArray[] = array('id' => 'modules', 'text' => 'by Module', 'expanded' => true);
             break;
         case 'modules':
             if (isset($_SESSION['KReports']['lastviewed'])) {
                 $lastViewedArray = preg_split('/::/', $_SESSION['KReports']['lastviewed']);
             }
             $modulesQuery = 'SELECT distinct report_module FROM kreports ';
             // check if we have KINAMu orManagement Installed for Authorization Check
             if (file_exists('modules/KOrgObjects/KOrgObject.php')) {
                 require_once 'modules/KOrgObjects/KOrgObject.php';
                 $thisKOrgObject = new KOrgObject();
                 $modulesQuery .= $thisKOrgObject->getOrgunitJoin('kreports', 'KReport', 'kreports', '1') . ' ';
             }
             $modulesQuery .= 'WHERE deleted =  \'0\' ORDER BY report_module ASC';
             $reportResults = $db->query($modulesQuery);
             while ($moduleEntry = $db->fetchByAssoc($reportResults)) {
                 $returnArray[] = array('id' => 'module::' . $moduleEntry['report_module'], 'text' => $app_list_strings['moduleList'][$moduleEntry['report_module']], 'expanded' => isset($lastViewedArray[0]) && $lastViewedArray[0] == $moduleEntry['report_module'] ? true : false);
             }
             break;
         case 'module':
             $moduleQuery = 'SELECT * FROM kreports ';
             if (file_exists('modules/KOrgObjects/KOrgObject.php')) {
                 require_once 'modules/KOrgObjects/KOrgObject.php';
                 $thisKOrgObject = new KOrgObject();
                 $moduleQuery .= $thisKOrgObject->getOrgunitJoin('kreports', 'KReport', 'kreports', '1') . ' ';
             }
             $moduleQuery .= 'WHERE report_module = \'' . $queryArray[1] . '\' AND deleted =  \'0\' ORDER BY report_module ASC';
             $reportResults = $db->query($moduleQuery);
             while ($moduleEntry = $db->fetchByAssoc($reportResults)) {
                 $returnArray[] = array('id' => $moduleEntry['id'], 'leaf' => true, 'text' => $moduleEntry['name'], 'href' => 'index.php?module=KReports&action=DetailView&record=' . $moduleEntry['id']);
             }
             break;
         case 'favorites':
             $returnArray[] = array('id' => 'last10', 'leaf' => false, 'text' => 'last 10');
             $returnArray[] = array('id' => 'top10', 'leaf' => false, 'text' => 'top 10');
             $reportResults = $db->query('SELECT * FROM kreportsfavorites WHERE user_id = \'' . $current_user->id . '\'  ORDER BY description ASC');
             while ($moduleEntry = $db->fetchByAssoc($reportResults)) {
                 $returnArray[] = array('id' => $moduleEntry['report_id'], 'leaf' => true, 'text' => $moduleEntry['description'], 'href' => 'index.php?module=KReports&action=DetailView&record=' . $moduleEntry['report_id'] . '&favid=' . $moduleEntry['report_id']);
             }
             break;
         case 'last10':
             $reportResults = $db->query('SELECT report_id, name FROM kreportstats INNER JOIN kreports ON kreports.id = kreportstats.report_id  WHERE user_id = \'' . $current_user->id . '\' GROUP  BY report_id ORDER BY max(date) DESC');
             while ($moduleEntry = $db->fetchByAssoc($reportResults)) {
                 $returnArray[] = array('id' => $moduleEntry['report_id'], 'leaf' => true, 'text' => $moduleEntry['name'], 'href' => 'index.php?module=KReports&action=DetailView&record=' . $moduleEntry['report_id']);
             }
             break;
         case 'top10':
             $reportResults = $db->query('SELECT report_id, name FROM kreportstats INNER JOIN kreports ON kreports.id = kreportstats.report_id  WHERE user_id = \'' . $current_user->id . '\' GROUP  BY report_id ORDER BY count(kreportstats.id) DESC');
             while ($moduleEntry = $db->fetchByAssoc($reportResults)) {
                 $returnArray[] = array('id' => $moduleEntry['report_id'], 'leaf' => true, 'text' => $moduleEntry['name'], 'href' => 'index.php?module=KReports&action=DetailView&record=' . $moduleEntry['report_id']);
             }
             break;
     }
     print json_encode_kinamu($returnArray);
 }
 function build_from_string()
 {
     global $db, $app_list_strings, $beanList, $beanFiles, $current_user;
     // Create a root GUID
     $this->rootGuid = randomstring();
     $this->joinSegments = array();
     $this->maxDepth = 0;
     $kOrgUnits = false;
     //check if we do the Org Check
     if (file_exists('modules/KOrgObjects/KOrgObject.php') && $GLOBALS['sugarconfig']['orgmanaged']) {
         require_once 'modules/KOrgObjects/KOrgObject.php';
         $thisKOrgObject = new KOrgObject();
         $kOrgUnits = true;
     }
     /*
      * Build the array for the joins based on the various Path we have
      */
     foreach ($this->tablePath as $thisPath => $thisPathJoinType) {
         // Process backcutting until we have found the node going upwards
         // in the segments array or we are on the root segment
         // (when no '::' can be found)
         if (substr_count($thisPath, '::') > $this->maxDepth) {
             $this->maxDepth = substr_count($thisPath, '::');
         }
         while (strpos($thisPath, '::') && !isset($this->joinSegments[$thisPath])) {
             // add the segment to the segments table
             $this->joinSegments[$thisPath] = array('alias' => randomstring(), 'linkalias' => randomstring(), 'level' => substr_count($thisPath, '::'), 'jointype' => $thisPathJoinType);
             // find last occurence of '::' in the string and cut off there
             $thisPath = substr($thisPath, strrpos($thisPath, "::"));
         }
     }
     // Get the main Table we select from
     $this->fromString = 'FROM ' . $this->get_table_for_module($this->root_module) . ' ' . $this->rootGuid;
     // check if this is an array so we need to add joins ...
     // add an entry for the root Object ...
     // needed as reference for the GUID
     $this->joinSegments['root:' . $this->root_module] = array('alias' => $this->rootGuid, 'level' => 0);
     // get ther root Object
     require_once $beanFiles[$beanList[$this->root_module]];
     $this->joinSegments['root:' . $this->root_module]['object'] = new $beanList[$this->root_module]();
     // check for Custom Fields
     if ($this->joinSegments['root:' . $this->root_module]['object']->hasCustomFields()) {
         $this->joinSegments['root:' . $this->root_module]['customjoin'] = randomstring();
         $this->fromString .= ' LEFT JOIN ' . $this->get_table_for_module($this->root_module) . '_cstm as ' . $this->joinSegments['root:' . $this->root_module]['customjoin'] . '  ON ' . $this->rootGuid . '.id = ' . $this->joinSegments['root:' . $this->root_module]['customjoin'] . '.id_c';
     }
     // changed so we spport teams in Pro
     if ($this->authChecklevel != 'none') {
         switch ($GLOBALS['sugar_config']['KReports']['authCheck']) {
             case 'KOrgObjects':
                 $this->fromString .= $thisKOrgObject->getOrgunitJoin($this->joinSegments['root:' . $this->root_module]['object']->table_name, $this->joinSegments['root:' . $this->root_module]['object']->object_name, $this->rootGuid, '1');
                 break;
             case 'KAuthObjects':
                 $selectArray = array('where' => '', 'from' => '', 'select' => '');
                 $GLOBALS['KAuthAccessController']->addAuthAccessToListArray($selectArray, $this->joinSegments['root:' . $this->root_module]['object'], $this->joinSegments['root:' . $this->root_module]['alias'], true);
                 if (!empty($selectArray['where'])) {
                     if (empty($this->whereString)) {
                         $this->whereString = " " . $selectArray['where'] . " ";
                     } else {
                         $this->whereString .= " AND " . $selectArray['where'] . " ";
                     }
                 }
                 if (!empty($selectArray['join'])) {
                     $this->fromString .= ' ' . $selectArray['join'] . ' ';
                 }
                 break;
             case 'PRO':
                 $this->fromString .= ' ';
                 $this->joinSegments['root:' . $this->root_module]['object']->add_team_security_where_clause($this->fromString, $this->rootGuid);
                 break;
                 //2013-03-26 Bug#460 Typo changed
             //2013-03-26 Bug#460 Typo changed
             case 'SecurityGroups':
                 if ($this->joinSegments['root:' . $this->root_module]['object']->bean_implements('ACL') && ACLController::requireSecurityGroup($this->joinSegments['root:' . $this->root_module]['object']->module_dir, 'list')) {
                     require_once 'modules/SecurityGroups/SecurityGroup.php';
                     global $current_user;
                     $owner_where = str_replace($this->joinSegments['root:' . $this->root_module]['object']->table_name, $this->rootGuid, $this->joinSegments['root:' . $this->root_module]['object']->getOwnerWhere($current_user->id));
                     $group_where = SecurityGroup::getGroupWhere($this->rootGuid, $this->joinSegments['root:' . $this->root_module]['object']->module_dir, $current_user->id);
                     if (!empty($owner_where)) {
                         if (empty($this->whereString)) {
                             $this->whereString = " (" . $owner_where . " or " . $group_where . ") ";
                         } else {
                             $this->whereString .= " AND (" . $owner_where . " or " . $group_where . ") ";
                         }
                     } else {
                         $this->whereString .= ' AND ' . $group_where;
                     }
                 }
                 break;
         }
     }
     // Index to iterate through the join table building the joins
     // from the root object outward going
     $levelCounter = 1;
     if (is_array($this->joinSegments)) {
         while ($levelCounter <= $this->maxDepth) {
             // set the array back to the first element in the array
             reset($this->joinSegments);
             foreach ($this->joinSegments as $thisPath => $thisPathDetails) {
                 // process only entries for the respective levels
                 if ($thisPathDetails['level'] == $levelCounter) {
                     // get the last enrty and the one before and the relevant arrays
                     $rightPath = substr($thisPath, strrpos($thisPath, "::") + 2, strlen($thisPath));
                     $leftPath = substr($thisPath, 0, strrpos($thisPath, "::"));
                     // explode into the relevant arrays
                     $rightArray = explode(':', $rightPath);
                     $leftArray = explode(':', $leftPath);
                     // 2011-07-21 add check for audit records
                     if ($rightArray[2] == 'audit') {
                         //handle audit link
                         $this->fromString .= $thisPathJoinType . $this->joinSegments[$leftPath]['object']->table_name . '_audit ' . $this->joinSegments[$thisPath]['alias'] . ' ON ' . $this->joinSegments[$thisPath]['alias'] . '.parent_id = ' . $this->joinSegments[$leftPath]['alias'] . '.id';
                     } elseif ($rightArray[0] == 'relationship') {
                         // set alias for the path to the linkalias of the connected bean
                         $this->joinSegments[$thisPath]['alias'] = $this->joinSegments[$leftPath]['linkalias'];
                     } elseif ($rightArray[0] == 'relate') {
                         //left Path Object must be set since we process from the top
                         if (!$this->joinSegments[$leftPath]['object'] instanceof $beanList[$rightArray[1]]) {
                             die('fatal Error in Join');
                         }
                         // load the module on the right hand side
                         require_once $beanFiles[$beanList[$this->joinSegments[$leftPath]['object']->field_defs[$rightArray[2]]['module']]];
                         $this->joinSegments[$thisPath]['object'] = new $beanList[$this->joinSegments[$leftPath]['object']->field_defs[$rightArray[2]]['module']]();
                         // join on the id = relate id .. on _cstm if custom field .. on main if regular
                         $this->fromString .= ' ' . $thisPathDetails['jointype'] . ' ' . $this->joinSegments[$thisPath]['object']->table_name . ' AS ' . $this->joinSegments[$thisPath]['alias'] . ' ON ' . $this->joinSegments[$thisPath]['alias'] . '.id=' . ($this->joinSegments[$leftPath]['object']->field_defs[$this->joinSegments[$leftPath]['object']->field_defs[$rightArray[2]]['id_name']]['source'] == 'custom_fields' ? $this->joinSegments[$leftPath]['customjoin'] : $this->joinSegments[$leftPath]['alias']) . '.' . $this->joinSegments[$leftPath]['object']->field_defs[$rightArray[2]]['id_name'] . ' ';
                         // check for Custom Fields
                         if ($this->joinSegments[$thisPath]['object']->hasCustomFields()) {
                             $this->joinSegments[$thisPath]['customjoin'] = randomstring();
                             $this->fromString .= ' LEFT JOIN ' . $this->joinSegments[$thisPath]['object']->table_name . '_cstm as ' . $this->joinSegments[$thisPath]['customjoin'] . ' ON ' . $this->joinSegments[$thisPath]['alias'] . '.id = ' . $this->joinSegments[$thisPath]['customjoin'] . '.id_c';
                         }
                     } else {
                         //left Path Object must be set since we process from the top
                         if (!$this->joinSegments[$leftPath]['object'] instanceof $beanList[$rightArray[1]]) {
                             $GLOBALS['log']->error('KReporter: fatal error in join with left path ' . $thisPath);
                             die('fatal Error in Join ' . $thisPath);
                         }
                         // load the relationship .. resp link
                         $this->joinSegments[$leftPath]['object']->load_relationship($rightArray[2]);
                         // set aliases for left and right .. will be processed properly anyway in the build of the link
                         // ... funny enough so
                         //2011-12-29 check if we have a jointpye
                         if ($thisPathDetails['jointype'] != '') {
                             //2011-12-29 see if the relationship vuilds on a custom field
                             if (isset($this->joinSegments[$leftPath]['object']->field_name_map[$this->joinSegments[$leftPath]['object']->{$rightArray}[2]->_relationship->rhs_key]['source']) && ($this->joinSegments[$leftPath]['object']->field_name_map[$this->joinSegments[$leftPath]['object']->{$rightArray}[2]->_relationship->rhs_key]['source'] == 'custom_fields' || $this->joinSegments[$leftPath]['object']->field_name_map[$this->joinSegments[$leftPath]['object']->{$rightArray}[2]->_relationship->lhs_key]['source'] == 'custom_fields')) {
                                 $join_params = array('join_type' => $thisPathDetails['jointype'], 'right_join_table_alias' => $this->joinSegments[$leftPath]['customjoin'], 'left_join_table_alias' => $this->joinSegments[$leftPath]['customjoin'], 'join_table_link_alias' => $this->joinSegments[$thisPath]['linkalias'], 'join_table_alias' => $this->joinSegments[$thisPath]['alias']);
                             } else {
                                 $join_params = array('join_type' => $thisPathDetails['jointype'], 'right_join_table_alias' => $this->joinSegments[$leftPath]['alias'], 'left_join_table_alias' => $this->joinSegments[$leftPath]['alias'], 'join_table_link_alias' => $this->joinSegments[$thisPath]['linkalias'], 'join_table_alias' => $this->joinSegments[$thisPath]['alias']);
                             }
                             //2010-09-09 Bug to handle left side join relationship
                             if (isset($this->joinSegments[$leftPath]['object']->field_defs[$rightArray[2]]['side']) && $this->joinSegments[$leftPath]['object']->field_defs[$rightArray[2]]['side'] == 'left' && !$this->joinSegments[$leftPath]['object']->{$rightArray}[2]->_swap_sides) {
                                 $this->joinSegments[$leftPath]['object']->{$rightArray}[2]->_swap_sides = true;
                             }
                             $linkJoin = $this->joinSegments[$leftPath]['object']->{$rightArray}[2]->getJoin($join_params);
                             $this->fromString .= ' ' . $linkJoin;
                         }
                         // load the module on the right hand side
                         require_once $beanFiles[$beanList[$this->joinSegments[$leftPath]['object']->{$rightArray}[2]->getRelatedModuleName()]];
                         $this->joinSegments[$thisPath]['object'] = new $beanList[$this->joinSegments[$leftPath]['object']->{$rightArray}[2]->getRelatedModuleName()]();
                         //bugfix 2010-08-19, respect ACL role access for owner reuqired in select
                         if ($this->joinSegments[$leftPath]['object']->bean_implements('ACL') && ACLController::requireOwner($this->joinSegments[$leftPath]['object']->module_dir, 'list')) {
                             //2013-02-22 missing check if we have a wherestring at all
                             if ($this->whereString != '') {
                                 $this->whereString .= ' AND ';
                             }
                             $this->whereString .= $this->joinSegments[$leftPath]['alias'] . '.assigned_user_id=\'' . $current_user->id . '\'';
                         }
                         // check for Custom Fields
                         if ($this->joinSegments[$thisPath]['object']->hasCustomFields()) {
                             $this->joinSegments[$thisPath]['customjoin'] = randomstring();
                             $this->fromString .= ' LEFT JOIN ' . $this->joinSegments[$thisPath]['object']->table_name . '_cstm as ' . $this->joinSegments[$thisPath]['customjoin'] . ' ON ' . $this->joinSegments[$thisPath]['alias'] . '.id = ' . $this->joinSegments[$thisPath]['customjoin'] . '.id_c';
                         }
                         // append join for Orgobjects if Object is OrgManaged
                         if ($this->authChecklevel != 'none' && $this->authChecklevel != 'top') {
                             switch ($GLOBALS['sugar_config']['KReports']['authCheck']) {
                                 case 'KOrgObjects':
                                     $this->fromString .= $thisKOrgObject->getOrgunitJoin($this->joinSegments[$thisPath]['object']->table_name, $this->joinSegments[$thisPath]['object']->object_name, $this->joinSegments[$thisPath]['alias'], '1');
                                     break;
                                 case 'KAuthObjects':
                                     $selectArray = array('where' => '', 'from' => '', 'select' => '');
                                     $GLOBALS['KAuthAccessController']->addAuthAccessToListArray($selectArray, $this->joinSegments[$thisPath]['object'], $this->joinSegments[$thisPath]['alias'], true);
                                     if (!empty($selectArray['where'])) {
                                         if (empty($this->whereString)) {
                                             $this->whereString = " " . $selectArray['where'] . " ";
                                         } else {
                                             $this->whereString .= " AND " . $selectArray['where'] . " ";
                                         }
                                     }
                                     if (!empty($selectArray['join'])) {
                                         $this->fromString .= ' ' . $selectArray['join'] . ' ';
                                     }
                                     break;
                                 case 'PRO':
                                     $this->fromString .= ' ';
                                     $this->joinSegments[$thisPath]['object']->add_team_security_where_clause($this->fromString, $this->joinSegments[$thisPath]['alias']);
                                     break;
                                     //2013-03-26 Bug#460 Typo changed
                                 //2013-03-26 Bug#460 Typo changed
                                 case 'SecurityGroups':
                                     if ($this->joinSegments[$thisPath]['object']->bean_implements('ACL') && ACLController::requireSecurityGroup($this->joinSegments[$thisPath]['object']->module_dir, 'list')) {
                                         require_once 'modules/SecurityGroups/SecurityGroup.php';
                                         global $current_user;
                                         $owner_where = str_replace($this->joinSegments[$thisPath]['object']->table_name, $this->joinSegments[$thisPath]['alias'], $this->joinSegments[$thisPath]['object']->getOwnerWhere($current_user->id));
                                         $group_where = SecurityGroup::getGroupWhere($this->joinSegments[$thisPath]['alias'], $this->joinSegments[$thisPath]['object']->module_dir, $current_user->id);
                                         if (!empty($owner_where)) {
                                             if (empty($this->whereString)) {
                                                 $this->whereString = " (" . $owner_where . " or " . $group_where . ") ";
                                             } else {
                                                 $this->whereString .= " AND (" . $owner_where . " or " . $group_where . ") ";
                                             }
                                         } else {
                                             $this->whereString .= ' AND ' . $group_where;
                                         }
                                     }
                                     break;
                             }
                         }
                     }
                 }
             }
             // increase Counter to tackle next level
             $levelCounter++;
         }
     }
 }