$qbInfo['joins'][] = "INNER JOIN acl ON abet_assessment.fk_acl = acl.id"; $qbInfo['joins'][] = "INNER JOIN acl_entry ON acl_entry.fk_acl = acl.id AND acl_entry.fk_profile = '{$_SESSION['id']}'"; } // grab all assessments that the user can access, along with their keys $query = new Query(new QueryBuilder(SELECT_QUERY, $qbInfo)); // structure the navigation tree around the heirarchy of assessments to which the // user has access; we present the same navigation structure to all kinds of users $userTools = new stdClass(); $userTools->label = 'Content'; $userTools->children = array(); create_unique_id($userTools, 'top-level', 1); // mappings to remember content organizers as we go through results $mappings = array(); $criteria = array(); // build main navigation subtree ('userTools') for ($i = 1; $i <= $query->get_number_of_rows(); $i++) { /* grab a result row: each row represents a potential content item; some fields may be null (from the outer joins); we build the navigation top-down: program -> criterion -> characteristic -> assessment -> content Since we bracket content under shared organizers we keep a mapping for each assessment within characteristic within criterion within program. */ $row = $query->get_row_assoc($i); // get ids $a = $row['program.id']; $b = $row['abet_criterion.id']; $c = $row['abet_characteristic.id']; $d = $row['abet_assessment.id']; $idProgram = is_null($a) ? null : "{$a}";