From 809699cf8e36263a6470246ed5faec2f13ee7b87 Mon Sep 17 00:00:00 2001 From: Moritz Strohm <strohm@data-quest.de> Date: Fri, 28 Sep 2018 13:07:18 +0200 Subject: [PATCH] started work on ticket 7, re #7 --- classes/TandemMatching.class.php | 125 ++++++++++++++++--------------- 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/classes/TandemMatching.class.php b/classes/TandemMatching.class.php index a828b94..f4f3b6c 100644 --- a/classes/TandemMatching.class.php +++ b/classes/TandemMatching.class.php @@ -21,12 +21,12 @@ require_once(__DIR__ . '/../models/TandemUserMotherLanguage.class.php'); */ class TandemMatching { - + /** * Helper method for building the SQL query for findMatches and countMatches. * Since both methods use the same query and differ only in the result * the query can be built in this helper method. - * + * * @return Array Associative array with two attributes: * - 'query': The SQL query * - 'params': Parameters for the SQL query @@ -35,9 +35,9 @@ class TandemMatching { //if the gender attribute is set we must convert its value to //the Stud.IP system values: 1 = male, 2 = female, 0 = unspecified: - + $request_gender = null; - + if($tandem_request->gender and TandemPlugin::isGenderSearchEnabled()) { //If gender search is enabled and a gender preference is set //we must filter for those settings. @@ -47,92 +47,93 @@ class TandemMatching $request_gender = 2; } } - - + + $sql = 'INNER JOIN tandem_user_mother_languages as tuml ON tuml.user_id = tandem_profiles.user_id '; - + if($request_gender) { //If the gender attribute from the request was converted correctly //we must also search for the gender information using the user_info table. $sql .= 'INNER JOIN user_info ON tuml.user_id = user_info.user_id '; } - + $sql .= 'WHERE tuml.language_id = :target_language_id - AND tuml.user_id <> :user_id + AND tuml.user_id <> :user_id AND tandem_profiles.target_language_id IN ( :request_user_mother_language_ids ) '; - - + + //We must check, if there are tandem pairs. Profiles in tandem pairs //with pair status 1 (accepted) and 0 (requested) are filtered out. //Also all profiles where a tandem request was made to are filtered out. - + $pairs_exist = (TandemPair::countBySql('TRUE') > 0); - + if($pairs_exist) { //QUERY EXPLAINATION: // tandem_profiles.id NOT IN: // We must filter all profiles that are bound to a pair matching // the following criteria. - // - // SELECT request_profile_id FROM tandem_pairs WHERE status > '-1' + // + // SELECT request_profile_id FROM tandem_pairs WHERE status > '-1' // AND request_profile_id = :profile_id: // The profile-ID of the profile we're searching matches for - // must match either the request_profile_id or the - // offer_profile_id. The latter filters out all requests + // must match either the request_profile_id or the + // offer_profile_id. The latter filters out all requests // and established pairs that have been made with that profile. - // + // // SELECT offer_profile_id FROM tandem_pairs WHERE status > '-1': // The same as with request_profile_id but here we're selecting // the offer_profile_ids and use them in a UNION. - // + // // SELECT request_profile_id FROM tandem_pairs WHERE status = '1' // and // SELECT offer_profile_id FROM tandem_pairs WHERE status = '1': // We select the request_profile_ids and offer_profile_ids // of all established pairs. // ) - + $sql .= "AND tandem_profiles.id NOT IN ( - SELECT request_profile_id FROM tandem_pairs WHERE request_profile_id = :profile_id OR offer_profile_id = :profile_id + SELECT request_profile_id AS id FROM tandem_pairs WHERE request_profile_id = :profile_id OR offer_profile_id = :profile_id UNION - SELECT offer_profile_id FROM tandem_pairs WHERE offer_profile_id = :profile_id OR request_profile_id = :profile_id + SELECT offer_profile_id AS id FROM tandem_pairs WHERE offer_profile_id = :profile_id OR request_profile_id = :profile_id UNION - SELECT request_profile_id FROM tandem_pairs WHERE status = '1' + SELECT request_profile_id AS id FROM tandem_pairs WHERE status = '1' UNION - SELECT offer_profile_id FROM tandem_pairs WHERE status = '1' + SELECT offer_profile_id AS id FROM tandem_pairs WHERE status = '1' + GROUP BY id ) "; } - - + + $request_user_mother_language_ids = []; $rumls = TandemUserMotherLanguage::findBySql( 'user_id = :user_id', ['user_id' => $tandem_request->user_id] ); - + foreach($rumls as $ruml) { $request_user_mother_language_ids[] = $ruml->language_id; } - - + + $sql_params = [ 'target_language_id' => $tandem_request->target_language_id, 'user_id' => $tandem_request->user_id, 'request_user_mother_language_ids' => $request_user_mother_language_ids ]; - + if($request_gender) { //The offere must have the gender the requester wishes. $sql .= 'AND user_info.geschlecht = :request_gender '; $sql_params['request_gender'] = $request_gender; } - + if(TandemPlugin::isGenderSearchEnabled()) { //The requester must have the gender the offerer wishes. $requester_gender = $tandem_request->user->geschlecht; - + //convert Stud.IP gender to TandemPlugin gender: if($requester_gender == '1') { $requester_gender = 'm'; @@ -141,7 +142,7 @@ class TandemMatching } else { $requester_gender = ''; } - + if($requester_gender != '') { //In cases where the gender is relevant //we must extend the SQL query and check if the offerer @@ -154,42 +155,42 @@ class TandemMatching $sql .= "AND tandem_profiles.gender = '' "; } } - - + + if($offer_user_id != null) { $sql .= 'AND tandem_profiles.user_id = :offer_user_id '; $sql_params['offer_user_id'] = $offer_user_id; } - - + + if($pairs_exist) { $sql_params['profile_id'] = $tandem_request->id; } - + $sql .= ' GROUP BY tandem_profiles.id, tandem_profiles.user_id '; - - + + if($limit > 0) { $sql .= 'LIMIT :limit'; $sql_params['limit'] = $limit; } - - + + return [ 'query' => $sql, 'params' => $sql_params ]; } - - + + /** * Finds matches for a given tandem request. - * + * * @param TandemProfile $tandem_request A tandem profile * that shall be checked for matches. * @param int $limit Limits the number of matches. * @param string $offer_user_id Limits the search for profiles for one offerer. - * + * * @return TandemProfile[] List of tandem profiles that match the criteria * specified in $tandem_request. */ @@ -204,21 +205,21 @@ class TandemMatching 'profile_id' => $tandem_request->id ] ); - + if($pair_count > 0) { //We don't look for matches if there is already a pair! return []; } - + $query = self::buildMatchSqlQuery($tandem_request, $limit, $offer_user_id); - + return TandemProfile::findBySql($query['query'], $query['params']); } - - + + /** * Counts matches for a given tandem profile. - * + * * @param TandemProfile $tandem_request A tandem profile * that shall be checked for matches. * @param string $offer_user_id Limits the search for profiles for one offerer. @@ -236,36 +237,36 @@ class TandemMatching 'profile_id' => $tandem_request->id ] ); - + if($pair_count > 0) { //We don't count matches if there is already a pair! return 0; } - + $query = self::buildMatchSqlQuery($tandem_request, 0, $offer_user_id); - + return TandemProfile::countBySql($query['query'], $query['params']); } - - - + + + static public function matchesExist(Array $profiles = []) { if(!$profiles) { //Empty array means we can't look for matches! return false; } - - + + foreach($profiles as $profile) { $count_result = self::countMatches($profile); - + if($count_result > 0) { //We have found one match: That's enough to see if a match exists: return true; } } - + //No matches found: return false; } -- GitLab