Exemple #1
0
function selectQuery($D)
{
    global $timer;
    extract($D);
    if ($s3ql['from'] == 'deployment') {
        $data[0] = array('mothership' => $GLOBALS['s3db_info']['deployment']['mothership'], 'deployment_id' => $GLOBALS['s3db_info']['deployment']['Did'], 'self' => '1', 'description' => $GLOBALS['s3db_info']['server']['site_intro'], 'url' => S3DB_URI_BASE, 'message' => 'Successfully connected to deployment ' . $GLOBALS['s3db_info']['deployment']['Did'] . '. Please provice a key to query the data (for example: ' . ($_SERVER['https'] == 'on' ? 'https://' : 'http://') . $def . S3DB_URI_BASE . '/URI.php?key=xxxxxxxx. For syntax specification and instructions refer to http://s3db.org/');
        #return $data;
    }
    #echo '<pre>';print_r($s3ql);
    if (in_array($s3ql['from'], array_keys($GLOBALS['plurals']))) {
        $s3ql['from'] = $GLOBALS['plurals'][$s3ql['from']];
    }
    #echo '<pre>';print_r($s3ql);exit;
    if ($s3ql['from'] == 'classes') {
        $s3ql['from'] = 'collections';
    }
    if ($s3ql['from'] == 'instances') {
        $s3ql['from'] = 'items';
    }
    if ($s3ql['from'] == 'keys' && $_SESSION['db'] == '') {
        return formatReturn($GLOBALS['error_codes']['not_a_query'], 'Access keys cannot be queried in the API.', $s3ql['format'], '');
        exit;
    }
    if (eregi('^t', $s3ql['shared'])) {
        $shared = true;
        #shared being set to true will tell s3ql that he should not only retrieved uid native to the upstream resource being queried, but those that propagate toward it
        $s3ql = array_delete($s3ql, 'shared');
    }
    if ($s3ql['from'] == 'permission' && $user_id != 1) {
        return formatReturn($GLOBALS['error_codes']['no_permission_message'], 'User cannot query permissions.', $s3ql['format'], '');
        exit;
    }
    if (eregi('^t', $s3ql['shared'])) {
        $shared = true;
        #shared being set to true will tell s3ql that he should not only retrieved uid native to the upstream resource being queried, but those that propagate toward it
        $s3ql = array_delete($s3ql, 'shared');
    }
    if (eregi('complete', $s3ql['display'])) {
        $complete = true;
        #complete will tell s3ql that dictionary terms should be added to the output
        $s3ql = array_delete($s3ql, 'display');
    }
    $target = $s3ql['from'];
    $letter = strtoupper(substr($s3ql['from'], 0, 1));
    $table = strval($target);
    $element = $target;
    $cols = $GLOBALS['dbstruct'][$target];
    $element_id = $s3ql['where'][$GLOBALS['s3ids'][$element]];
    if ($table != '' && !in_array($table, array_keys($GLOBALS['dbstruct']))) {
        return formatReturn($GLOBALS['error_codes']['not_a_query'], 'Not a valid query.', '', $s3ql['format']);
    }
    #manage data in select
    #echo '<pre>';print_r($s3ql);
    #array_keys contains the things to replace and array_values the replacements
    if ($s3ql['select'] != '' && $s3ql['select'] != '*') {
        $s3ql_out = ereg_replace(' ', '', $s3ql['select']);
        #take out all the spaces
        $returnFields = explode(',', $s3ql_out);
        if (!ereg($GLOBALS['s3ids'][$element], $s3ql['select'])) {
            if (ereg('count|max|min', $s3ql['select'])) {
                $SQLfun = ereg_replace("\\(.*\\)", "", $select);
                $SQLfun = ereg_replace("count as count", "count", $SQLfun);
                $s3ql['select'] = '*';
            } else {
                $s3ql['select'] .= ',' . $GLOBALS['s3ids'][$element];
            }
        }
        ##Because of the new code, will also have to add the parent ids to the query
        #$parents = $GLOBALS['inherit'][$GLOBALS['s3ids'][$element]];
        $parents = $GLOBALS['inherit'][$GLOBALS['COREids'][$GLOBALS['singulars'][$element]]];
        ##duuuhhh
        if (is_array($parents)) {
            foreach ($parents as $p) {
                if (!in_array($p, $returnFields)) {
                    $s3ql['select'] .= ',' . str_replace($toreplace, $replacements, $p);
                }
            }
        }
    } else {
        $s3ql['select'] = '*';
    }
    #echo $s3ql['select'];exit;
    #echo '<pre>';print_r($s3ql);exit;
    $toreplace = array_keys($GLOBALS['s3map'][$target]);
    $replacements = array_values($GLOBALS['s3map'][$target]);
    #to replace query str with replacements, remove the spaces and explode by commas
    $select = explode(',', str_replace(' ', '', $s3ql['select']));
    foreach ($select as $s_key => $str_select) {
        if (in_array($str_select, $toreplace)) {
            $select[$s_key] = $replacements[array_search($str_select, $toreplace)];
        }
    }
    #echo '<pre>';print_r($select);exit;
    $s3ql['select'] = implode(',', array_unique($select));
    #$s3ql['select'] = str_replace($toreplace, $replacements, $s3ql['select']);
    #echo '<pre>';print_r($s3ql['select']);
    $select = urldecode($s3ql['select']);
    $select = eregi_replace('uid', $GLOBALS['s3ids'][$element] . ' as uid', $select);
    $select = eregi_replace('uri', $GLOBALS['s3ids'][$element] . ' as uri', $select);
    $select = eregi_replace('(,).*permissionOnResource', '', $select);
    #echo $P['out'].$P['SQLfun'];
    if ($select == $SQLfun) {
        $SQLfun = '';
    }
    #$s3ql_where_keys = str_replace(array('item_id', 'collection_id'), array('instance_id', 'class_id'), array_keys($s3ql['where']));
    #$s3ql['where'] = array_combine($s3ql_where_keys, $s3ql['where']);
    #transofrmt s3ql and get the return Fields
    $tranformed = S3QLselectTransform(compact('s3ql', 'db', 'user_id'));
    extract($tranformed);
    #anything that is queried must also go come out in the select
    if ($s3ql['where'] && $select != '*') {
        foreach ($s3ql['where'] as $more_outputs => $more_value) {
            if (!substr($select, $more_outputs)) {
                $select .= "," . str_replace($toreplace, $replacements, $more_outputs);
            }
        }
    }
    ##for statements, select must find file_name a well so that it is transofmred into a link
    if ($letter == 'S' && !ereg('file_name', $select)) {
        $select .= ',file_name';
    }
    $s3ql['select'] = $select;
    if ($timer) {
        $timer->setMarker('queryInterpreted');
    }
    #If there is any sort of S3 UID in the query, check its score when compared to the from
    $score = array('D' => '7', 'G' => '6', 'U' => '5', 'P' => '4', 'C' => '3', 'R' => '3', 'I' => '2', 'S' => '1');
    $fromScore = $score[strtoupper(substr($target, 0, 1))];
    $s3Ids = array_merge($GLOBALS['COREids'], array('rulelog' => 'rule_id', 'statementlog' => 'statement_id'));
    #echo '<pre>';print_r($s3ql);
    $shared_with_query = array();
    foreach ($s3Ids as $COREelement => $COREelement_id) {
        if ($s3ql['where'][$COREelement_id] != '' && !ereg('^~|regexp', $s3ql['where'][$COREelement_id])) {
            $id_name = $COREelement_id;
            $id_letter = strtoupper(substr($id_name, 0, 1));
            $whereScore[strtoupper(substr($id_name, 0, 1)) . $s3ql['where'][$COREelement_id]] = $score[strtoupper(substr($id_name, 0, 1))];
            #when idNameScore is < $fromScore, then we know: we are trying to query all resources that can view another particular resource (for example,all users that can view project x
            #echo $id_name;exit;
            $uid = strtoupper(substr($COREelement, 0, 1)) . $s3ql['where'][$COREelement_id];
            $uid_info = uid($uid);
            #Use URIinfo to find all data about this resource
            $element_info = URIinfo($uid, $user_id, $key, $db, $timer);
            $WhereInfo[$uid_info['uid']] = $element_info;
            if (!is_array($element_info)) {
                return formatReturn($GLOBALS['error_codes']['something_does_not_exist'], $uid . ' does not exist', $s3ql['format'], '');
                exit;
            } elseif ($id_letter != strtoupper(substr($element, 0, 1))) {
                ##Shared_with is any UID that can eb shared with any of the elements being requested (for example, Collection_id is shared_with Project, but Project_id is not shared  with Project
                array_push($shared_with_query, $uid);
                #do permissions on this uid propagate?
                #echo '<pre>';print_r($whereScore);exit;
            } else {
                $self_id = $s3ql['where'][$COREelement_id];
                if (!$element_info['view']) {
                    return formatReturn($GLOBALS['error_codes']['no_permission_message'], 'User does not have permission on ' . $uid, $s3ql['format'], '');
                    exit;
                }
            }
        }
    }
    #echo '<pre>';print_r($WhereInfo);exit;
    if ($self_id != '') {
        $data[0] = $element_info;
        if (ereg('^(U|G)$', $letter) && count($WhereInfo) == 2) {
            $whereId = array_diff(array_keys($WhereInfo), array($letter . $self_id));
            $D = array('shared_with' => $letter . $self_id, 'uid' => $whereId[0], 'strictsharedwith' => 1, 'strictuid' => 1, 'db' => $db, 'user_id' => $user_id, 'stream' => 'upstream', 'timer' => $timer);
            ##Look for shared_with in uid instead of uid in shared_with
            #echo 'ola';exit;
            #$data[0]['permissionOnResource']=permission4Resource($D);
            $p = array('shared_with' => $letter . $self_id, 'uid' => $whereId[0]);
            $hasP = has_permission($p, $db);
            $effective_permission_resource = permission4resource(array('user_id' => $self_id, 'shared_with' => $letter . $self_id, 'db' => $db, 'uid' => $whereId[0], 'strictsharedwith' => 1, 'strictuid' => 1, 'timer' => $timer, 'toFindInfo' => $WhereInfo[$whereId[0]]));
            if ($hasP || $effective_permission_resource != '') {
                $data[0]['permissionOnResource'] = $effective_permission_resource;
                $data[0]['assigned_permissionOnEntity'] = $hasP != "" ? $hasP : '---';
                $data[0]['effective_permissionOnEntity'] = $effective_permission_resource;
            } else {
                return array();
            }
        }
    } else {
        #echo 'ola';exit;
        #start building the query:
        $user_query = "select " . $select . " from s3db_" . $GLOBALS['s3tables'][$table];
        if (!user_is_admin($user_id, $db)) {
            $cols = array_diff($cols, array('account_pwd', 'account_phone', 'account_email', 'project_folder'));
        }
        #remove a few cols from query
        if ($timer) {
            $timer->setMarker('user is admin check');
        }
        #echo $user_id;exit;
        ##	echo $user_query;exit;
        #now add some constrains necessary due to the type of resource
        if (!(user_is_admin($user_id, $db) && $s3ql['where']['status'] == 'I')) {
            if (ereg('projects|classes|instances|rules|statements', $target)) {
                $status = "status!='I' and ";
            }
        }
        $user_query_const .= " where " . $status . $GLOBALS['s3ids'][$target] . "!='0'";
        ###
        #Filter query according to the element being requested
        $user_query_const .= filterByElement($s3ql, $user_id, $db);
        if ($user_query_const) {
            $user_query .= $user_query_const;
        } else {
            exit;
        }
        if ($timer) {
            $timer->setMarker('query filter');
        }
        if ($shared && !empty($shared_with_query) && strtoupper(substr($target, 0, 1)) != 'U') {
            #the "shared with" are the upstream resources being queried. These may or not be in  the permissions table (if the are remote). This basically finds not only elements that were created within a certain uid (for example Ix of Cx), but those that were later shared with that uid (for example Iy created within Cy but later shared with Iy)
            $uidQuery = simpleQueryUID($shared_with_query, $element, $db);
            if ($uidQuery) {
                extract($uidQuery);
                if (!ereg('G', $letter)) {
                    #query groups has a special syntax, it is already included in the query
                    $user_query .= $finalUID;
                }
                ##IS IT INCREASING THE QUERY TIME ABSURDELLY?
            }
            #else { #Go on with the regular query
            #		return formatReturn($GLOBALS['error_codes']['no_results'], 'Your query on '.$target.' did not return any results', $format,'');
            #	}
            if ($timer) {
                $timer->setMarker('Query to find shared UID');
            }
        }
        #now constrainthe query to resources that user cann access. Check for inherited permissions and direct permissions. Project is connected to deployment, rule and class to project, and so on. (see S3DB third report for the schema)
        #Fetch the cols of what is to be returned. Check for SqL functions. This will only affect the output
        if ($s3ql['select'] != '') {
            $out = urldecode($s3ql['select']);
            $SQLfun = ereg_replace("\\(.*\\)", "", $out);
            $SQLfun = ereg_replace("count as count", "count", $SQLfun);
            $P['out'] . $P['SQLfun'];
            if ($out == $SQLfun) {
                $SQLfun = '';
            } else {
                $extracol = $out;
            }
        }
        #echo $SQLfun;
        #Extract from the s3ql the value that are part of the syntax and assume the rest are the SQL extras (limit, creted_by, etc)
        $syntax = array('key', 'select', 'from', 'where', 'format');
        foreach ($s3ql as $i => $value) {
            if (!in_array($i, $syntax) && $value != '') {
                $SQLextra[$i] = ' ' . ereg_replace('_', ' ', $i) . ' ' . $value;
            }
        }
        #echo '<pre>';print_r($SQLextra);exit;
        #if there is orderby, move to the beginnign of the array
        if ($SQLextra['order_by'] != '') {
            $SQLextra = array_merge(array('order_by' => $SQLextra['order_by']), $SQLextra);
        }
        if (is_array($SQLextra)) {
            foreach ($SQLextra as $key => $value) {
                $query_extra .= $value;
            }
        }
        #Put in $P the values of what is queried, add to cols, if not already there, whatever is queried. Check if there are regular expressions anywhere. equalit will be replace by the regular expression
        $cols = $GLOBALS['dbstruct'][$table];
        foreach ($cols as $col) {
            if ($s3ql['where'][$col] != '') {
                if (!in_array($col, $GLOBALS['COREids']) && $col != $GLOBALS['COREids'][$element]) {
                    $user_query_fields .= ' and ' . $col . '  ' . parse_regexp($s3ql['where'][$col]);
                }
                $P[$col] = parse_regexp($s3ql['where'][$col]);
            }
        }
        #when the default query is performed, that is, not shared ids are requested, the query is faster is core_id are added
        if (!$shared) {
            if (is_array($s3ql['where']) && !empty($s3ql['where'])) {
                foreach ($s3ql['where'] as $q_field => $q_value) {
                    if (in_array($q_field, $GLOBALS['COREids']) || $q_field == $GLOBALS['COREids'][$element]) {
                        $sql_col = str_replace($toreplace, $replacements, $q_field);
                        if (!ereg('U|G', $letter)) {
                            ## Users and groups do not have the reousrce in the users table
                            $user_query_fields .= ' and ' . $sql_col . ' ' . parse_regexp($q_value);
                        } else {
                            #Because users queries do not include the parent_id in the talbe itself, they will involve a query in perm table
                            #$u_uid=letter($q_field).$q_value;
                        }
                    }
                }
            }
        }
        #glue them together.
        $user_query .= $user_query_fields . $query_extra;
        if ($timer) {
            $timer->setMarker('done building query');
        }
        ###Finally perform the query on whatever table is specified
        #$user_query = "select * from s3db_resource where resource_class_id = '389';";
        #if($_REQUEST['su3d']){
        #echo $user_query;
        #$timer->display();
        #exit;
        #}
        ##run it
        #complete query on LOCAL resources
        $db->query($user_query, __LINE__, __FILE__);
        $dbdata = get_object_vars($db);
        if ($timer) {
            $timer->setMarker('done with query');
        }
        if ($dbdata['Errno'] != '0') {
            return formatReturn($GLOBALS['error_codes']['something_went_wrong'], $dbdata['Error'], $format, '');
        }
        #put it in a nice structured variable
        $cols = $GLOBALS['dbstruct'][$target];
        if (is_array($returnFields) && $extracol == '') {
            $cols = array_unique(array_merge($cols, $returnFields));
        }
        #echo '<pre>';print_r($cols);
        while ($db->next_record()) {
            #echo '<pre>';print_r($db);
            $resultStr .= "\$data[] = Array(";
            if ($extracol != '') {
                $resultStr .= "'" . $extracol . "'=>'" . $db->f($SQLfun) . "',";
            }
            foreach ($cols as $col) {
                $resultStr .= "'" . $col . "'=>'" . addslashes($db->f($col)) . "'";
                if ($col != end($cols)) {
                    $resultStr .= ",";
                }
                if ($col == $GLOBALS['s3ids'][$target]) {
                    $retrieved['ids_str'] .= $retrieved['ids_str'] == '' ? $db->f($col) : '|' . $db->f($col);
                }
            }
            $resultStr .= ");";
        }
        #echo $resultStr;
        #evaluate the long string
        eval($resultStr);
        if (is_array($data)) {
            $data = array_filter($data);
        }
        if ($timer) {
            $timer->setMarker('query results captured');
        }
        #more often than not, a query is made that retrieves all rules/collection data; this data can be reused for permission migration
        if ($user_query_fields == "" && $SQLextra == "") {
            $all_data[letter($target)] = $data;
        }
        #BEFORE outputting data, are there any remote resources where the user is allowed?
        $ucode = strtoupper(substr($element, 0, 1));
        $ucode_and_id = $ucode . $element_id;
        ##Added ability to search locally on april 15 2008 to optimize queries
        ###Added ability to seeek permissions from file on jan 12 2009 to speed permissiosn query
        if (!ereg('users|groups|projects|keys|rulelog|statementlog|permission', $s3ql['from']) && !ereg('true|1', $s3ql['where']['local'])) {
            #REMOTE USERS< GROUPS< PROJECTS ARE INSERTED INTO DEPLOYMENT,M NO NEED TO FIND THEM AGAIN
            ##Added ability to search locally on april 15 to optimize queries
            ###Added ability to seeek permissions from file on jan 12 2009 to speed permissiosn query
            list($remoteIDS, $local_not_native) = remotePermissions(compact('s3ql', 'self_id', 'uidQuery', 'permissionsQuery', 'user_id', 'db', 'timer', 'shared_with_query', 'user_self_query', 'letter'));
            if ($timer) {
                $timer->setMarker('remote permisions queried');
            }
            ##NOTE: Local_not_native data need to be retrieve as well
            if (is_array($remoteIDS) && !empty($remoteIDS)) {
                foreach ($remoteIDS as $rem_id) {
                    #$rem_uid = substr($rem_id['uid'],1,strlen($rem_id['uid']));
                    $rem_uid = $rem_id['uid'];
                    $rem_resource_data = URIinfo($rem_uid, $user_id, $s3ql['key'], $db);
                    #echo '<pre>';print_r($rem_resource_data);exit;
                    if (is_array($rem_resource_data)) {
                        $rem_resource_data['shared_with'] = $rem_id['shared_with'];
                        $rem_resource_data['uid'] = $rem_id['uid'];
                        $rem_resource_data['permission_level'] = $rem_id['permission_level'];
                    }
                    #echo '<pre>';print_r($rem_resource_data);exit;
                    #concatenate them in the results; THIS SHOWS ONLY REMOTE RESOURCES THAT ARE AVAILABLE AT THE MOMENT!
                    if (is_array($s3ql['where'])) {
                        foreach ($s3ql['where'] as $query_field => $query_value) {
                            if ($query_value != $rem_resource_data[$query_field]) {
                                if (!in_array($query_field, $GLOBALS['COREids'])) {
                                    $rem_resource_data = array();
                                }
                            }
                        }
                    }
                    if (is_array($data) && is_array($rem_resource_data)) {
                        array_push($data, $rem_resource_data);
                    } elseif (is_array($rem_resource_data) && !empty($rem_resource_data)) {
                        $data[] = $rem_resource_data;
                    }
                }
                if ($timer) {
                    $timer->setMarker('Remote data retrieved');
                }
            }
        }
        if (is_array($data)) {
            $data = array_filter($data);
        }
        #now we're ready to display the data
        $pack = compact('data', 'whereScore', 'WhereInfo', 'fromScore', 's3ql', 'key', 'target', 'db', 'user_id', 'cols', 'returnFields', 's3ql_out', 'target', 'uidQuery', 'timer', 'shared_with_query', 'all_data', 'letter', 'model');
        if (!ereg('keys|accesslog|rulelog|statementlog|permission', $s3ql['from'])) {
            $data = includeAllData($pack);
        }
    }
    ##if complete was requested, let's retrieve every link and distribute accordingly rather that querying by uid, would would take much longer
    if ($complete) {
        $alluid = array();
        foreach ($data as $kuid => $data_info) {
            array_push($alluid, $letter . $data_info[$GLOBALS['s3ids'][$element]]);
        }
        include_once S3DB_SERVER_ROOT . '/s3dbcore/dictionary.php';
        $s3qlL = compact('user_id', 'db');
        $s3qlL['from'] = 'links';
        $formatL = 'array';
        $links = query_user_dictionaries($s3qlL, $db, $user_id, $formatL);
        if (is_array($links) && !empty($links)) {
            foreach ($links as $moreData) {
                if ($moreData['uid'] != '') {
                    $foundIt = array_search($moreData['uid'], $alluid);
                    if ($foundIt) {
                        $data[$foundIt]['links'][$moreData['relation']] = $moreData['value'];
                    }
                    #$data[$moreData['uid']]['links'][$moreData['relation']]=$moreData['value'];
                }
            }
        }
        if ($timer) {
            $timer->setMarker('Dictionary data included!');
        }
    }
    if (is_array($data) && !empty($data)) {
        $data = array_combine(range(0, count($data) - 1), $data);
        return $data;
    } else {
        #$emptycols = array(array_combine($cols, array_fill(1,count($cols), '')));
        #echo '<pre>';print_r($emptycols);exit;
        return array();
        #return formatReturn($GLOBALS['error_codes']['no_results'], 'Your query returned no results', $format,'');
    }
}
Exemple #2
0
function selectQuery($D)
{
    extract($D);
    if ($s3ql['from'] == 'deployment') {
        $data[0] = array('mothership' => $GLOBALS['s3db_info']['deployment']['mothership'], 'deployment_id' => $GLOBALS['s3db_info']['deployment']['Did'], 'description' => $GLOBALS['s3db_info']['server']['site_intro'], 'url' => S3DB_URI_BASE, 'message' => 'Successfully connected to deployment ' . $GLOBALS['s3db_info']['deployment']['Did'] . '. Please provice a key to query the data (for example: ' . ($_SERVER['https'] == 'on' ? 'https://' : 'http://') . $def . S3DB_URI_BASE . '/URI.php?key=xxxxxxxx. For syntax specification and instructions refer to http://s3db.org/');
        return $data;
    }
    #echo '<pre>';print_r($s3ql);
    if (in_array($s3ql['from'], array_keys($GLOBALS['plurals']))) {
        $s3ql['from'] = $GLOBALS['plurals'][$s3ql['from']];
    }
    #echo '<pre>';print_r($s3ql);exit;
    if ($s3ql['from'] == 'classes') {
        $s3ql['from'] = 'collections';
    }
    if ($s3ql['from'] == 'instances') {
        $s3ql['from'] = 'items';
    }
    if ($s3ql['from'] == 'keys' && $_SESSION['db'] == '') {
        return formatReturn($GLOBALS['error_codes']['not_a_query'], 'Access keys cannot be queried in the API.', $s3ql['format'], '');
        exit;
    }
    $target = $s3ql['from'];
    $letter = strtoupper(substr($s3ql['from'], 0, 1));
    $table = strval($target);
    $element = $target;
    $cols = $GLOBALS['dbstruct'][$target];
    $element_id = $s3ql['where'][$GLOBALS['s3ids'][$element]];
    if ($table != '' && !in_array($table, array_keys($GLOBALS['dbstruct']))) {
        return formatReturn($GLOBALS['error_codes']['not_a_query'], 'Not a valid query.', '', $s3ql['format']);
    }
    #manage data in select
    #echo '<pre>';print_r($s3ql);
    #array_keys contains the things to replace and array_values the replacements
    if ($s3ql['select'] != '' && $s3ql['select'] != '*') {
        $s3ql_out = ereg_replace(' ', '', $s3ql['select']);
        #take out all the spaces
        $returnFields = explode(',', $s3ql_out);
        if (!ereg($GLOBALS['s3ids'][$element], $s3ql['select'])) {
            if (ereg('count|max|min', $s3ql['select'])) {
                $SQLfun = ereg_replace("\\(.*\\)", "", $select);
                $SQLfun = ereg_replace("count as count", "count", $SQLfun);
                $s3ql['select'] = '*';
            } else {
                $s3ql['select'] .= ',' . $GLOBALS['s3ids'][$element];
            }
        }
    } else {
        $s3ql['select'] = '*';
    }
    #echo '<pre>';print_r($s3ql);exit;
    $toreplace = array_keys($GLOBALS['s3map'][$target]);
    $replacements = array_values($GLOBALS['s3map'][$target]);
    $s3ql['select'] = str_replace($toreplace, $replacements, $s3ql['select']);
    $select = urldecode($s3ql['select']);
    $select = eregi_replace('uid', $GLOBALS['s3ids'][$element] . ' as uid', $select);
    $select = eregi_replace('uri', $GLOBALS['s3ids'][$element] . ' as uri', $select);
    #echo $P['out'].$P['SQLfun'];
    if ($select == $SQLfun) {
        $SQLfun = '';
    }
    #$s3ql_where_keys = str_replace(array('item_id', 'collection_id'), array('instance_id', 'class_id'), array_keys($s3ql['where']));
    #$s3ql['where'] = array_combine($s3ql_where_keys, $s3ql['where']);
    #transofrmt s3ql and get the return Fields
    $tranformed = S3QLselectTransform(compact('s3ql', 'db', 'user_id'));
    extract($tranformed);
    #If there is any sort of S3 UID in the query, check its score when compared to the from
    $score = array('D' => '7', 'G' => '6', 'U' => '5', 'P' => '4', 'C' => '3', 'R' => '3', 'I' => '2', 'S' => '1');
    $fromScore = $score[strtoupper(substr($target, 0, 1))];
    $s3Ids = array_merge($GLOBALS['COREids'], array('rulelog' => 'rule_id', 'statementlog' => 'statement_id'));
    #echo '<pre>';print_r($s3ql);exit;
    $shared_with_query = array();
    foreach ($s3Ids as $COREelement => $COREelement_id) {
        if ($s3ql['where'][$COREelement_id] != '' && !ereg('^~|regexp', $s3ql['where'][$COREelement_id])) {
            $id_name = $COREelement_id;
            $id_letter = strtoupper(substr($id_name, 0, 1));
            $whereScore[strtoupper(substr($id_name, 0, 1)) . $s3ql['where'][$COREelement_id]] = $score[strtoupper(substr($id_name, 0, 1))];
            #when idNameScore is < $fromScore, then we know: we are trying to query all resources that can view another particular resource (for example,all users that can view project x
            #echo $id_name;exit;
            $uid = strtoupper(substr($COREelement, 0, 1)) . $s3ql['where'][$COREelement_id];
            $uid_info = uid($uid);
            $element_info = URIinfo($uid, $user_id, $key, $db);
            $WhereInfo[$uid_info['uid']] = $element_info;
            #echo '<pre>';print_r($user_info);
            #echo '<pre>';print_r($element_info);exit;
            if (!is_array($element_info)) {
                return formatReturn($GLOBALS['error_codes']['something_does_not_exist'], $uid . ' does not exist', $s3ql['format'], '');
                exit;
            } elseif ($id_letter != strtoupper(substr($element, 0, 1))) {
                ##Shared_with is any UID that can eb shared with any of the elements being requested (for example, Collection_id is shared_with Project, but Project_id is not shared  with Project
                array_push($shared_with_query, $uid);
                #do permissions on this uid propagate?
                #echo '<pre>';print_r($whereScore);exit;
            } else {
                $self_id = $s3ql['where'][$COREelement_id];
                if (!$element_info['view']) {
                    return formatReturn($GLOBALS['error_codes']['no_permission_message'], 'User does not have permission on ' . $uid, $s3ql['format'], '');
                    exit;
                }
            }
        }
    }
    #echo '<pre>';print_r($WhereInfo);exit;
    if ($self_id != '') {
        $data[0] = $element_info;
    } else {
        #start building the query:
        $user_query = "select " . $select . " from s3db_" . $GLOBALS['s3tables'][$table];
        if (!user_is_admin($user_id, $db)) {
            $cols = array_diff($cols, array('account_pwd', 'account_phone', 'account_email', 'project_folder'));
        }
        #remove a few cols from query
        #echo $user_query;exit;
        #now add some constrains necessary due to the type of resource
        if (!(user_is_admin($user_id, $db) && $s3ql['where']['status'] == 'I')) {
            if (ereg('projects|classes|instances|rules|statements', $target)) {
                $status = "status!='I' and ";
            }
        }
        $user_query_const .= " where " . $status . $GLOBALS['s3ids'][$target] . "!='0'";
        ###
        #Filter query according to the element being requested
        $user_query_const .= filterByElement($s3ql, $user_id, $db);
        if ($user_query_const) {
            $user_query .= $user_query_const;
        } else {
            exit;
        }
        if (!empty($shared_with_query) && strtoupper(substr($target, 0, 1)) != 'U') {
            ##Added 15Apr08 for faster queries (taking too long on MySQL using table joins)
            $uidQuery = simpleQueryUID($shared_with_query, $element, $db);
            if ($uidQuery) {
                extract($uidQuery);
                $user_query .= $finalUID;
            } elseif ($user_id != '1') {
                return formatReturn($GLOBALS['error_codes']['no_results'], 'Your query on ' . $target . ' did not return any results', $format, '');
            }
        }
        #echo 'ola'.$uidQuery;exit;
        #now constrainthe query to resources that user cann access. Check for inherited permissions and direct permissions. Project is connected to deployment, rule and class to project, and so on. (see S3DB third report for the schema)
        #Fetch the cols of what is to be returned. Check for SqL functions. This will only affect the output
        if ($s3ql['select'] != '') {
            $out = urldecode($s3ql['select']);
            $SQLfun = ereg_replace("\\(.*\\)", "", $out);
            $SQLfun = ereg_replace("count as count", "count", $SQLfun);
            $P['out'] . $P['SQLfun'];
            if ($out == $SQLfun) {
                $SQLfun = '';
            } else {
                $extracol = $out;
            }
        }
        #echo $SQLfun;
        #Extract from the s3ql the value that are part of the syntax and assume the rest are the SQL extras (limit, creted_by, etc)
        $syntax = array('key', 'select', 'from', 'where', 'format');
        foreach ($s3ql as $i => $value) {
            if (!in_array($i, $syntax) && $value != '') {
                $SQLextra[$i] = ' ' . ereg_replace('_', ' ', $i) . ' ' . $value;
            }
        }
        #echo '<pre>';print_r($SQLextra);exit;
        #if there is orderby, move to the beginnign of the array
        if ($SQLextra['order_by'] != '') {
            $SQLextra = array_merge(array('order_by' => $SQLextra['order_by']), $SQLextra);
        }
        if (is_array($SQLextra)) {
            foreach ($SQLextra as $key => $value) {
                $query_extra .= $value;
            }
        }
        #Put in $P the values of what is queried, add to cols, if not already there, whatever is queried. Check if there are regular expressions anywhere. equalit will be replace by the regular expression
        $cols = $GLOBALS['dbstruct'][$table];
        foreach ($cols as $col) {
            if ($s3ql['where'][$col] != '') {
                if (!in_array($col, $GLOBALS['COREids']) && $col != $GLOBALS['COREids'][$element]) {
                    $user_query_fields .= ' and ' . $col . '  ' . parse_regexp($s3ql['where'][$col]);
                }
                $P[$col] = parse_regexp($s3ql['where'][$col]);
            }
        }
        #glue them together.
        $user_query .= $user_query_fields . $query_extra;
        ###Finally perform the query on whatever table is specified
        #$user_query = "select * from s3db_resource where resource_class_id = '389';";
        //echo $user_query;
        //exit;
        #run it
        #complete query on LOCAL resources
        $db->query($user_query, __LINE__, __FILE__);
        $dbdata = get_object_vars($db);
        #echo '<pre>';print_r($dbdata);
        #exit;
        if ($dbdata['Errno'] != '0') {
            return formatReturn($GLOBALS['error_codes']['something_went_wrong'], $dbdata['Error'], $format, '');
        }
        #put it in a nice structured variable
        $cols = $GLOBALS['dbstruct'][$target];
        if (is_array($returnFields) && $extracol == '') {
            $cols = array_unique(array_merge($cols, $returnFields));
        }
        #echo '<pre>';print_r($cols);
        while ($db->next_record()) {
            #echo '<pre>';print_r($db);
            $resultStr .= "\$data[] = Array(";
            if ($extracol != '') {
                $resultStr .= "'" . $extracol . "'=>'" . $db->f($SQLfun) . "',";
            }
            foreach ($cols as $col) {
                $resultStr .= "'" . $col . "'=>'" . addslashes($db->f($col)) . "'";
                if ($col != end($cols)) {
                    $resultStr .= ",";
                }
                if ($col == $GLOBALS['s3ids'][$target]) {
                    $retrieved['ids_str'] .= $retrieved['ids_str'] == '' ? $db->f($col) : '|' . $db->f($col);
                }
            }
            $resultStr .= ");";
        }
        #echo $resultStr;
        #evaluate the long string
        eval($resultStr);
        if (is_array($data)) {
            $data = array_filter($data);
        }
        #echo '<pre>';print_r($data);
        #BEFORE outputting data, are there any remote resources where the user is allowed?
        $ucode = strtoupper(substr($element, 0, 1));
        $ucode_and_id = $ucode . $element_id;
        ##Added ability to search locally on april 15 to optimize queries
        if (!ereg('users|group|projects|keys|rulelog|statementlog', $s3ql['from']) && !ereg('true|1', $s3ql['where']['local'])) {
            #REMOTE USERS< GROUPS< PROJECTS ARE INSERTED INTO DEPLOYMENT,M NO NEED TO FIND THEM AGAIN
            #Remote permissions query: changed 23Mar08 for specifying query in uid
            $remote_permissions_query .= "select * from s3db_permission where uid " . $regexp . " '^" . $GLOBALS['s3codesInv'][$GLOBALS['singulars'][$s3ql['from']]] . "' and permission_level " . $regexp . " '(1|2)\$'";
            #the idea is to select anything that does not exist locally
            $remote_permissions_query .= " and id not in (select " . $GLOBALS['s3ids'][$GLOBALS['s3codes'][$letter]] . " from s3db_" . $GLOBALS['s3tables'][$GLOBALS['s3codes'][$letter]] . ")";
            if ($user_self_query != '') {
                $remote_permissions_query .= " and id = '" . $self_id . "'";
            }
            if ($uidQuery != '') {
                $remote_permissions_query .= " and id " . $regexp . " '^(" . $uidQuery['str_ids'] . ")\$'";
            }
            if ($permissionsQuery != '') {
                $remote_permissions_query .= " and id " . $regexp . " '^(" . $permissionsQuery['str_ids'] . ")\$'";
            }
            #echo $remote_permissions_query;exit;
            $db->query($remote_permissions_query, __LINE__, __FILE__);
            #this will return ALL the elements shared by USER
            while ($db->next_record()) {
                $remote_id[] = array('uid' => $db->f('uid'), 'shared_with' => $db->f('shared_with'), 'permission_level' => $db->f('permission_level'));
            }
            if (is_array($remote_id)) {
                foreach ($remote_id as $rem_id) {
                    #$rem_uid = substr($rem_id['uid'],1,strlen($rem_id['uid']));
                    $rem_uid = $rem_id['uid'];
                    $rem_resource_data = URIinfo($rem_uid, $user_id, $s3ql['key'], $db);
                    #echo '<pre>';print_r($rem_resource_data);exit;
                    if (is_array($rem_resource_data)) {
                        $rem_resource_data['shared_with'] = $rem_id['shared_with'];
                        $rem_resource_data['uid'] = $rem_id['uid'];
                        $rem_resource_data['permission_level'] = $rem_id['permission_level'];
                    }
                    #echo '<pre>';print_r($rem_resource_data);exit;
                    #concatenate them in the results; THIS SHOWS ONLY REMOTE RESOURCES THAT ARE AVAILABLE AT THE MOMENT!
                    if (is_array($s3ql['where'])) {
                        foreach ($s3ql['where'] as $query_field => $query_value) {
                            if ($query_value != $rem_resource_data[$query_field]) {
                                if (!in_array($query_field, $GLOBALS['COREids'])) {
                                    $rem_resource_data = array();
                                }
                            }
                        }
                    }
                    if (is_array($data) && is_array($rem_resource_data)) {
                        array_push($data, $rem_resource_data);
                    } elseif (is_array($rem_resource_data) && !empty($rem_resource_data)) {
                        $data[] = $rem_resource_data;
                    }
                }
            }
        }
        if (is_array($array)) {
            $data = array_filter($data);
        }
        #echo '<pre>';print_r($data);exit;
        #now we're ready to display the data
        $pack = compact('data', 'whereScore', 'WhereInfo', 'fromScore', 's3ql', 'key', 'target', 'db', 'user_id', 'cols', 'returnFields', 'target', 'uidQuery');
        if (!ereg('keys|accesslog', $s3ql['from'])) {
            $data = includeAllData($pack);
        }
    }
    #echo '<pre>';print_r($data);exit;
    #$data = filterDataForQuery($data, $cols,$returnFields, $whereScore, $fromScore, $s3ql, $key, $target, $db, $user_id);
    if (is_array($data) && !empty($data)) {
        $data = array_combine(range(0, count($data) - 1), $data);
        return $data;
    } else {
        return formatReturn($GLOBALS['error_codes']['no_results'], 'Your query returned no results', $format, '');
    }
}
Exemple #3
0
function listS3db($x)
{
    if ($GLOBALS['s3db_info']['server']['db']['db_type'] == 'mysql') {
        $regexp = 'regexp';
    } else {
        $regexp = '~';
    }
    if (is_array($x)) {
        extract($x);
    }
    #Just a fix for those scripts taht don't have db var implements
    if (!is_object($db)) {
        $db = $_SESSION['db'];
    }
    #this contains the primeary key (or whatever in the table that cannot be empty) The goal is to reduce this extended query cases to only a few
    $s3idNames = array('projects' => 'project_id', 'project' => 'project_id', 'classes' => 'resource_id', 'instances' => 'resource_id', 'resource' => 'resource_id', 'rules' => 'rule_id', 'rule' => 'rule_id', 'statements' => 'statement_id', 'statement' => 'statement_id', 'access_keys' => 'key_id', 'file_transfer' => 'file_id', 'access_rules' => 'rule_id', 'access_log' => 'login_id', 'rule_change_log' => 'rule_id');
    if (ereg('^(project|projects|class|instance|rule|statement|classes|instances|rules|statements)$', $table) && $user_id != '1') {
        $query_end .= " and status = 'A'";
        $query_end .= " and (" . $s3idNames[$table] . " in (select id from s3db_permission where uid ~ '^" . strtoupper(substr($table, 0, 1)) . "' and shared_with = 'U" . $user_id . "' and permission_level ~ '[^(0)]') or (";
        $final = ")";
    }
    if (ereg('(project|statement_log|rule_change_log)', $table)) {
        if ($project_list != '' && $user_id != '1') {
            $query_end .= " project_id " . $project_list . ") or (project_owner = '" . $user_id . "')" . $final;
        }
    }
    if (ereg('^(rule|class|rules|classes)$', $table)) {
        #if(ereg('^(rule|rules)$', $table)){
        if ($project_list != '' && $permission_list != '') {
            $query_end .= "project_id " . $project_list . " or permission " . $permission_list . ")" . $final;
        }
        if ($project_id != '') {
            #the and can go in hre because for rules and classes, user projects are always in the query
            $query_end .= " and (project_id " . $project_id . " or permission " . $permission . ")";
            $cols = array_diff($cols, array('project_id', 'permission'));
        }
        if (ereg('(class|classes)', $table)) {
            $table = 'resource';
            $x['iid'] = '0';
        }
    }
    if (ereg('(intances|instances)', $table)) {
        $table = 'resource';
        $x['iid'] = '1';
        $select = str_replace('project_id', 'r.project_id', $select);
        if ($user_id != '1') {
            $query_end .= " resource_class_id " . $class_list . ")" . $final;
        }
    }
    if (ereg('^(statement|statements)$', $table)) {
        if ($rule_list != '') {
            $query_end .= " rule_id " . $rule_list . ")" . $final;
        }
        $table = 'statement';
    }
    if (ereg('access_rules', $table)) {
        if ($rule_list != '' && $project_list != '') {
            $query_end .= " and (rule_id " . $rule_list . " or project_id " . $project_list . ")";
        }
    }
    if (ereg('(user|users|group|groups)', $table)) {
        $table = 'account';
    }
    #echo '<pre>';print_r($x);
    #get the values for the columns, default will be "and"
    foreach ($cols as $col) {
        if ($x[$col] != '') {
            $query_end .= " and " . $col . " " . parse_regexp($x[$col]);
        }
    }
    #echo $query_end;exit;
    #get the extra input SQL vars
    if (is_array($SQLextra)) {
        foreach ($SQLextra as $extra => $value) {
            $extras .= $value;
        }
    }
    #Retrieve only specific cols. Increase speed query and accept count and group by requests
    if ($x['out'] == '' || $x['out'] == '*') {
        #this menas no specific function is being called, only general results of the query are to be in the output
        $select = '*';
    } else {
        $select = $x['out'];
        #detect if the user is calling an SQL function on select
        if ($SQLfun != '') {
            $extracol = $x['out'];
        }
        #if ($SQLfun == 'distinct')
        #echo $extracol = str_replace(array($SQLfun, "(", ")"), "", $x['out']);
    }
    #"Sensitive queries": project_id dependent or user dependent
    #if($table=='project')
    #{
    #$sql = "select distinct ".$select." from s3db_project where (project_owner='".$user_id."' or project_id in (select acl_project_id from s3db_project_acl where acl_account = '".$user_id."' and acl_rights ".$regexp." '^(1|2|3)'))".$query_end.$extras;
    #echo $sql = "select distinct ".$select." from s3db_project where project_id!='0'".$query_end.$extras;
    #echo  $sql = "select distinct ".$select." from s3db_project where project_id!='0'".$query_end.$extras;
    #}
    if ($table == 'resource' && $x['iid'] == '0') {
        #$to_replace = array(' permission', 'status');
        #$replacements = array(' s3db_rule.permission ', 's3db_rule.status');
        $shared_with_list = $x['project_id'] != '' ? str_replace(array('~ \'', '^', '$\''), array('', '', '$'), $x['project_id']) : str_replace(array('~ \'', '^', '$\''), array('', '', '$'), $project_list);
        $project_list = $x['project_id'] != '' ? $x['project_id'] : $project_list;
        $extras = str_replace('order by ', 'order by s3db_resource.', $extras);
        $query_end = str_replace('project_id', 's3db_rule.project_id', $query_end);
        $query_end = str_replace(' permission ', ' s3db_rule.permission ', $query_end);
        $query_end = str_replace('status', 's3db_rule.status', $query_end);
        #$sql = "select ".$select." from s3db_resource, s3db_rule where subject=entity and s3db_rule.project_id=s3db_resource.project_id and object='UID' ".$query_end.$extras;
        $sql = "select " . $select . " from s3db_resource, s3db_rule where subject=entity and iid='0' and object='UID' and s3db_rule.project_id=s3db_resource.project_id and (rule_id in (select id from s3db_permission where shared_with ~ '^P(" . $shared_with_list . ")' and uid ~ '^R') or (s3db_rule.project_id " . $project_list . "))" . $query_end;
        #echo $sql;
    } elseif ($table == 'account') {
        if ($user_id != '1') {
            $query_end = $query_end . " and account_id!='1'";
        }
        #only admin can see grop admin/himself
        if ($account_type == 'g' && $x['imp_user_id'] != '') {
            $sql = "select " . $select . " from s3db_account where account_status = 'A' and ((account_id in (select group_id from s3db_account_group where account_id='" . $x['imp_user_id'] . "') or created_by='" . $x['imp_user_id'] . "'))" . $query_end . $extras;
        } elseif ($x['project_id'] != '') {
            $extras = str_replace('order by ', 'order by a.', $extras);
            $sql = "select " . $select . " from s3db_account as a, s3db_project_acl as b where (a.account_id = '" . $user_id . "' and a.account_id = b.acl_account and a.account_status = 'A') or (a.account_id = b.acl_account and b.acl_project_id ='" . $x['project_id'] . "')" . $query_end . $extras;
        } elseif ($x['account_type'] != 'g' && $x['group_id'] != '') {
            $sql = "select " . $select . " from s3db_account where account_status = 'A' and account_id in (select account_id from s3db_account_group where group_id = '" . $x['group_id'] . "')" . $query_end . $extras;
        } elseif ($x['account_type'] != 'g') {
            $sql = "select " . $select . " from s3db_account, s3db_addr where (addr_id = account_addr_id or (account_addr_id = '-10' and addr_id = '1'))" . $query_end . $extras;
        } elseif ($account_type == 'g') {
            $sql = "select " . $select . " from s3db_" . $table . " where " . $table . "_id!='0' " . $query_end . $extras;
        }
        #echo 'ola'.$sql;
    } elseif (ereg('(access_keys|access_log|rule_change_log|file_transfer|statement_log)', $table)) {
        if ($table == 'statement_log') {
            $query_end = str_replace(' project_id', ' old_project_id', $query_end);
        }
        if ($table != 'rule_change_log' && $table != 'access_rules') {
            $sql = "select " . $select . " from s3db_" . $table . " where " . $s3idNames[$table] . "!='0'" . $query_end . $extras;
        } else {
            $sql = "select " . $select . " from s3db_" . $table . " where " . $s3idNames[$table] . "!='0'" . $query_end . $extras;
        }
    } elseif ($table == 'access_rules') {
        if ($x['project_id'] != '' && $x['rule_id'] != '') {
            $sql = "select " . $select . " from s3db_" . $table . " where " . $s3idNames[$table] . "!='0'  and (project_id " . $x['project_id'] . " or rule_id " . $x['rule_id'] . ')' . $query_end . $extras;
        } elseif ($x['rule_id'] != '') {
            $sql = "select " . $select . " from s3db_" . $table . " where " . $s3idNames[$table] . "!='0' and rule_id " . $x['rule_id'] . '' . $query_end . $extras;
        } elseif ($x['project_id'] != '') {
            $sql = "select " . $select . " from s3db_" . $table . " where " . $s3idNames[$table] . "!='0' and project_id " . $x['project_id'] . '' . $query_end . $extras;
        } else {
            $sql = "select " . $select . " from s3db_" . $table . " where " . $s3idNames[$table] . "!='0'" . $query_end . $extras;
        }
    } elseif ($table == 'project_acl') {
        $extras = str_replace('order by ', 'order by a.', $extras);
        #$sql = "select ".$select." from s3db_".$table." where acl_project_id!='0' ".$query_end.$extras;
        $sql = "select " . $select . " from s3db_account as a, s3db_project_acl as b where a.account_id in (select b.acl_account from s3db_project_acl where b.acl_project_id!='0' and b.acl_project_id = '" . $project_id . "' and a.account_id = b.acl_account)" . $query_end . $extras;
    } else {
        $sql = "select " . $select . " from s3db_" . $table . " where " . $table . "_id!='0' " . $query_end . $extras;
    }
    $db->query($sql, __LINE__, __FILE__);
    $dbdata = get_object_vars($db);
    if ($dbdata['Errno'] != '0' && $table == 'rules') {
        $sql = "select " . $select . " from s3db_rule where project_id = '" . $project_id . "'" . $query_end . $extras;
        $db->query($sql, __LINE__, __FILE__);
    }
    #echo $sql;
    #exit;
    $_SESSION['sqlquery'] = $sql;
    if (ereg('[(projects)|(classes)|(rules)|(instances)|(statements)]', $table)) {
        $cols = array_merge($cols, array('project_id', 'permission'));
        #put the cols back for data retrieve
    }
    $cols = array_unique($cols);
    while ($db->next_record()) {
        $resultStr .= "\$data[] = Array(";
        if ($extracol != '') {
            $resultStr .= "'" . $extracol . "'=>'" . $db->f($SQLfun) . "',";
        }
        foreach ($cols as $col) {
            $resultStr .= "'" . $col . "'=>'" . addslashes($db->f($col)) . "'";
            if ($col != end($cols)) {
                $resultStr .= ",";
            }
        }
        $resultStr .= ");";
        #echo $resultStr;
        #evaluate the long string
        #eval($resultStr);
    }
    #echo end($cols);
    #echo $resultStr;
    #evaluate the long string
    eval($resultStr);
    #echo $sql.'<pre>data';print_r($data);
    return $data;
}