/** * @return bool */ public function valid() { $this->data = $this->db->fetchAssoc($this->res); if (is_array($this->data) && (strpos($this->data['login'], ',') !== false || strpos($this->data['login'], ';') !== false)) { $parts = array_filter(array_map('trim', preg_split("/[ ]*[;,][ ]*/", trim($this->data['login'])))); foreach ($parts as $part) { if (ilStr::strPos(ilStr::strToLower($part), ilStr::strToLower($this->term)) !== false) { $this->users_stack[] = $part; } } if ($this->users_stack) { $this->data = null; } } return is_array($this->data) || count($this->users_stack) > 0; }
/** * Returns the index of the found answer, if the given answer is in the * set of correct answers and matchess * the matching options, otherwise FALSE is returned * * @param array $answers An array containing the correct answers * @param string $answer The text of the given answer * @return mixed The index of the correct answer, FALSE otherwise * @access public */ function isAnswerCorrect($answers, $answer) { include_once "./Services/Utilities/classes/class.ilStr.php"; $result = 0; $textrating = $this->getTextRating(); foreach ($answers as $key => $value) { switch ($textrating) { case TEXTGAP_RATING_CASEINSENSITIVE: if (strcmp(ilStr::strToLower($value), ilStr::strToLower($answer)) == 0 && $this->answers[$key]->getPoints() > 0) { return $key; } break; case TEXTGAP_RATING_CASESENSITIVE: if (strcmp($value, $answer) == 0 && $this->answers[$key]->getPoints() > 0) { return $key; } break; case TEXTGAP_RATING_LEVENSHTEIN1: if (levenshtein($value, $answer) <= 1 && $this->answers[$key]->getPoints() > 0) { return $key; } break; case TEXTGAP_RATING_LEVENSHTEIN2: if (levenshtein($value, $answer) <= 2 && $this->answers[$key]->getPoints() > 0) { return $key; } break; case TEXTGAP_RATING_LEVENSHTEIN3: if (levenshtein($value, $answer) <= 3 && $this->answers[$key]->getPoints() > 0) { return $key; } break; case TEXTGAP_RATING_LEVENSHTEIN4: if (levenshtein($value, $answer) <= 4 && $this->answers[$key]->getPoints() > 0) { return $key; } break; case TEXTGAP_RATING_LEVENSHTEIN5: if (levenshtein($value, $answer) <= 5 && $this->answers[$key]->getPoints() > 0) { return $key; } break; } } return FALSE; }
/** * Converts a path consisting of object titles into a path consisting of tree * nodes. The comparison is non-case sensitive. * * Note: this function returns the same result as getNodePath, * but takes a title path as parameter. * * @access public * @param Array Path array with object titles. * e.g. array('ILIAS','English','Course A') * @param ref_id Startnode of the relative path. * Specify null, if the title path is an absolute path. * Specify a ref id, if the title path is a relative * path starting at this ref id. * @return array ordered path info (depth,parent,child,obj_id,type,title) * or null, if the title path can not be converted into a node path. */ function getNodePathForTitlePath($titlePath, $a_startnode_id = null) { global $ilDB, $log; //$log->write('getNodePathForTitlePath('.implode('/',$titlePath)); // handle empty title path if ($titlePath == null || count($titlePath) == 0) { if ($a_startnode_id == 0) { return null; } else { return $this->getNodePath($a_startnode_id); } } // fetch the node path up to the startnode if ($a_startnode_id != null && $a_startnode_id != 0) { // Start using the node path to the root of the relative path $nodePath = $this->getNodePath($a_startnode_id); $parent = $a_startnode_id; } else { // Start using the root of the tree $nodePath = array(); $parent = 0; } // Convert title path into Unicode Normal Form C // This is needed to ensure that we can compare title path strings with // strings from the database. require_once 'include/Unicode/UtfNormal.php'; include_once './Services/Utilities/classes/class.ilStr.php'; $inClause = 'd.title IN ('; for ($i = 0; $i < count($titlePath); $i++) { $titlePath[$i] = ilStr::strToLower(UtfNormal::toNFC($titlePath[$i])); if ($i > 0) { $inClause .= ','; } $inClause .= $ilDB->quote($titlePath[$i], 'text'); } $inClause .= ')'; // Fetch all rows that are potential path elements if ($this->table_obj_reference) { $joinClause = 'JOIN ' . $this->table_obj_reference . ' r ON t.child = r.' . $this->ref_pk . ' ' . 'JOIN ' . $this->table_obj_data . ' d ON r.' . $this->obj_pk . ' = d.' . $this->obj_pk; } else { $joinClause = 'JOIN ' . $this->table_obj_data . ' d ON t.child = d.' . $this->obj_pk; } // The ORDER BY clause in the following SQL statement ensures that, // in case of a multiple objects with the same title, always the Object // with the oldest ref_id is chosen. // This ensure, that, if a new object with the same title is added, // WebDAV clients can still work with the older object. $q = 'SELECT t.depth, t.parent, t.child, d.' . $this->obj_pk . ' obj_id, d.type, d.title ' . 'FROM ' . $this->table_tree . ' t ' . $joinClause . ' ' . 'WHERE ' . $inClause . ' ' . 'AND t.depth <= ' . (count($titlePath) + count($nodePath)) . ' ' . 'AND t.tree = 1 ' . 'ORDER BY t.depth, t.child ASC'; $r = $ilDB->query($q); $rows = array(); while ($row = $r->fetchRow(DB_FETCHMODE_ASSOC)) { $row['title'] = UtfNormal::toNFC($row['title']); $row['ref_id'] = $row['child']; $rows[] = $row; } // Extract the path elements from the fetched rows for ($i = 0; $i < count($titlePath); $i++) { $pathElementFound = false; foreach ($rows as $row) { if ($row['parent'] == $parent && ilStr::strToLower($row['title']) == $titlePath[$i]) { // FIXME - We should test here, if the user has // 'visible' permission for the object. $nodePath[] = $row; $parent = $row['child']; $pathElementFound = true; break; } } // Abort if we haven't found a path element for the current depth if (!$pathElementFound) { //$log->write('ilTree.getNodePathForTitlePath('.var_export($titlePath,true).','.$a_startnode_id.'):null'); return null; } } // Return the node path //$log->write('ilTree.getNodePathForTitlePath('.var_export($titlePath,true).','.$a_startnode_id.'):'.var_export($nodePath,true)); return $nodePath; }
/** * Returns the points for a text gap and compares the given solution with * the entered solution using the text gap rating options. * * @param string $a_original The original (correct) text * @param string $a_entered The text entered by the user * @param integer $max_points The maximum number of points for the solution * @access public */ function getTextgapPoints($a_original, $a_entered, $max_points) { include_once "./Services/Utilities/classes/class.ilStr.php"; $result = 0; $gaprating = $this->getTextgapRating(); switch ($gaprating) { case TEXTGAP_RATING_CASEINSENSITIVE: if (strcmp(ilStr::strToLower($a_original), ilStr::strToLower($a_entered)) == 0) { $result = $max_points; } break; case TEXTGAP_RATING_CASESENSITIVE: if (strcmp($a_original, $a_entered) == 0) { $result = $max_points; } break; case TEXTGAP_RATING_LEVENSHTEIN1: if (levenshtein($a_original, $a_entered) <= 1) { $result = $max_points; } break; case TEXTGAP_RATING_LEVENSHTEIN2: if (levenshtein($a_original, $a_entered) <= 2) { $result = $max_points; } break; case TEXTGAP_RATING_LEVENSHTEIN3: if (levenshtein($a_original, $a_entered) <= 3) { $result = $max_points; } break; case TEXTGAP_RATING_LEVENSHTEIN4: if (levenshtein($a_original, $a_entered) <= 4) { $result = $max_points; } break; case TEXTGAP_RATING_LEVENSHTEIN5: if (levenshtein($a_original, $a_entered) <= 5) { $result = $max_points; } break; } return $result; }
/** * Checks if one of the keywords matches the answertext * * @param string $answertext The answertext of the user * @param string $a_keyword The keyword which should be checked * @return boolean TRUE if the keyword matches, FALSE otherwise * @access private */ function isKeywordMatching($answertext, $a_keyword) { $result = FALSE; $textrating = $this->getTextRating(); include_once "./Services/Utilities/classes/class.ilStr.php"; switch ($textrating) { case TEXTGAP_RATING_CASEINSENSITIVE: if (ilStr::strPos(ilStr::strToLower($answertext), ilStr::strToLower($a_keyword)) !== false) { return TRUE; } break; case TEXTGAP_RATING_CASESENSITIVE: if (ilStr::strPos($answertext, $a_keyword) !== false) { return TRUE; } break; } $answerwords = array(); if (preg_match_all("/([^\\s.]+)/", $answertext, $matches)) { foreach ($matches[1] as $answerword) { array_push($answerwords, trim($answerword)); } } foreach ($answerwords as $a_original) { switch ($textrating) { case TEXTGAP_RATING_LEVENSHTEIN1: if (levenshtein($a_original, $a_keyword) <= 1) { return TRUE; } break; case TEXTGAP_RATING_LEVENSHTEIN2: if (levenshtein($a_original, $a_keyword) <= 2) { return TRUE; } break; case TEXTGAP_RATING_LEVENSHTEIN3: if (levenshtein($a_original, $a_keyword) <= 3) { return TRUE; } break; case TEXTGAP_RATING_LEVENSHTEIN4: if (levenshtein($a_original, $a_keyword) <= 4) { return TRUE; } break; case TEXTGAP_RATING_LEVENSHTEIN5: if (levenshtein($a_original, $a_keyword) <= 5) { return TRUE; } break; } } return $result; }
/** * * Called by class ilMailFormGUI * * @param string search string surrounded with wildcards * @param string native search string * @return stdClass search result as an object of type stdClass * @access public * */ public function getRecipientAsync($a_search, $a_native_search) { global $ilDB; $query = "SELECT DISTINCT\n\t\t\t\tabook.login login,\n\t\t\t\tabook.firstname firstname,\n\t\t\t\tabook.lastname lastname,\n\t\t\t\t'addressbook' type\n\t\t\tFROM addressbook abook\n\t\t\tWHERE abook.user_id = " . $ilDB->quote($this->user_id, 'integer') . "\n\t\t\tAND abook.login IS NOT NULL\n\t\t\tAND (" . $ilDB->like('abook.login', 'text', $a_search) . "\n\t\t\t\t\tOR " . $ilDB->like('abook.firstname', 'text', $a_search) . "\n\t\t\t\t\tOR " . $ilDB->like('abook.lastname', 'text', $a_search) . "\n\t\t\t)"; $union_query_1 = "SELECT DISTINCT\n\t\t\t\tabook.email login,\n\t\t\t\tabook.firstname firstname,\n\t\t\t\tabook.lastname lastname,\n\t\t\t\t'addressbook' type\n\t\t\tFROM addressbook abook\n\t\t\tWHERE abook.user_id = " . $ilDB->quote($this->user_id, 'integer') . "\n\t\t\tAND abook.login IS NULL\n\t\t\tAND (" . $ilDB->like('abook.email', 'text', $a_search) . "\n\t\t\t\t\tOR " . $ilDB->like('abook.firstname', 'text', $a_search) . "\n\t\t\t\t\tOR " . $ilDB->like('abook.lastname', 'text', $a_search) . "\n\t\t\t)"; $union_query_2 = "SELECT DISTINCT\n\t\t\t\tmail.rcp_to login,\n\t\t\t\t'' firstname,\n\t\t\t\t'' lastname,\n\t\t\t\t'mail' type\n\t\t\tFROM mail\n\t\t\tWHERE " . $ilDB->like('mail.rcp_to', 'text', $a_search) . "\n\t\t\tAND sender_id = " . $ilDB->quote($this->user_id, 'integer') . "\n\t\t\tAND mail.sender_id = mail.user_id"; $queries = array('addressbook_1' => $query, 'mail' => $union_query_2); if ($this->allow_smtp == 1) { $queries['addressbook_2'] = $union_query_1; } include_once 'Services/Utilities/classes/class.ilStr.php'; try { // MySql: Join the array values for mysql to one select statement if ($ilDB->getDbType() != 'oracle') { $queries['all'] = implode(' UNION ', $queries); } foreach ($queries as $type => $query) { // Oracle: Distincts do no work with clobs if ('mail' == $type && $ilDB->getDbType() == 'oracle') { $query = str_replace('DISTINCT', '', $query); } $ilDB->setLimit(0, 20); $query_res = $ilDB->query($query); while ($row = $ilDB->fetchObject($query_res)) { if ($row->type == 'mail') { if (strpos($row->login, ',') || strpos($row->login, ';')) { $parts = preg_split("/[ ]*[;,][ ]*/", trim($row->login)); foreach ($parts as $part) { if (ilStr::strPos(ilStr::strToLower($part), ilStr::strToLower($a_native_search)) !== false) { $this->addResult($part, '', '', 'mail'); } } } else { $this->addResult($row->login, '', '', 'mail'); } } else { $this->addResult($row->login, $row->firstname, $row->lastname, 'addressbook'); } } } } catch (ilException $e) { } return $this->result; }