/** * Flushes the buffer content to the DB and clears the buffer. * * @return bool True when some data was flushed to the database. * False otherwise. */ public function flush() { if (!empty($this->buffer)) { $this->db->sql_multi_insert($this->table_name, $this->buffer); $this->buffer = array(); return true; } return false; }
/** * Permission Set * * Allows you to set permissions for a certain group/role * * @param string $name The name of the role/group * @param string|array $auth_option The auth_option or array of * auth_options you would like to set * @param string $type The type (role|group) * @param bool $has_permission True if you want to give them permission, * false if you want to deny them permission * @return null * @throws \src\db\migration\exception */ public function permission_set($name, $auth_option, $type = 'role', $has_permission = true) { if (!is_array($auth_option)) { $auth_option = array($auth_option); } $new_auth = array(); $sql = 'SELECT auth_option_id FROM ' . ACL_OPTIONS_TABLE . ' WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { $new_auth[] = (int) $row['auth_option_id']; } $this->db->sql_freeresult($result); if (empty($new_auth)) { return; } $current_auth = array(); $type = (string) $type; // Prevent PHP bug. switch ($type) { case 'role': $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . "\n\t\t\t\t\tWHERE role_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); $role_id = (int) $this->db->sql_fetchfield('role_id'); if (!$role_id) { throw new \src\db\migration\exception('ROLE_NOT_EXIST', $name); } $sql = 'SELECT auth_option_id, auth_setting FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE role_id = ' . $role_id; $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { $current_auth[$row['auth_option_id']] = $row['auth_setting']; } $this->db->sql_freeresult($result); break; case 'group': $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . "\n\t\t\t\t\tWHERE group_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); $group_id = (int) $this->db->sql_fetchfield('group_id'); if (!$group_id) { throw new \src\db\migration\exception('GROUP_NOT_EXIST', $name); } // If the group has a role set for them we will add the requested permissions to that role. $sql = 'SELECT auth_role_id FROM ' . ACL_GROUPS_TABLE . ' WHERE group_id = ' . $group_id . ' AND auth_role_id <> 0 AND forum_id = 0'; $this->db->sql_query($sql); $role_id = (int) $this->db->sql_fetchfield('auth_role_id'); if ($role_id) { $sql = 'SELECT role_name, role_type FROM ' . ACL_ROLES_TABLE . ' WHERE role_id = ' . $role_id; $this->db->sql_query($sql); $role_data = $this->db->sql_fetchrow(); $role_name = $role_data['role_name']; $role_type = $role_data['role_type']; // Filter new auth options to match the role type: a_ | f_ | m_ | u_ // Set new auth options to the role only if options matching the role type were found $auth_option = array_filter($auth_option, function ($option) use($role_type) { return strpos($option, $role_type) === 0; }); if (sizeof($auth_option)) { return $this->permission_set($role_name, $auth_option, 'role', $has_permission); } } $sql = 'SELECT auth_option_id, auth_setting FROM ' . ACL_GROUPS_TABLE . ' WHERE group_id = ' . $group_id; $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { $current_auth[$row['auth_option_id']] = $row['auth_setting']; } $this->db->sql_freeresult($result); break; } $sql_ary = array(); switch ($type) { case 'role': foreach ($new_auth as $auth_option_id) { if (!isset($current_auth[$auth_option_id])) { $sql_ary[] = array('role_id' => $role_id, 'auth_option_id' => $auth_option_id, 'auth_setting' => $has_permission); } } $this->db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary); break; case 'group': foreach ($new_auth as $auth_option_id) { if (!isset($current_auth[$auth_option_id])) { $sql_ary[] = array('group_id' => $group_id, 'auth_option_id' => $auth_option_id, 'auth_setting' => $has_permission); } } $this->db->sql_multi_insert(ACL_GROUPS_TABLE, $sql_ary); break; } $this->auth->acl_clear_prefetch(); }
/** * Updates wordlist and wordmatch tables when a message is posted or changed * * @param string $mode Contains the post mode: edit, post, reply, quote * @param int $post_id The id of the post which is modified/created * @param string &$message New or updated post content * @param string &$subject New or updated post subject * @param int $poster_id Post author's user id * @param int $forum_id The id of the forum in which the post is located */ public function index($mode, $post_id, &$message, &$subject, $poster_id, $forum_id) { if (!$this->config['fulltext_native_load_upd']) { /** * The search indexer is disabled, return */ return; } // Split old and new post/subject to obtain array of 'words' $split_text = $this->split_message($message); $split_title = $this->split_message($subject); $cur_words = array('post' => array(), 'title' => array()); $words = array(); if ($mode == 'edit') { $words['add']['post'] = array(); $words['add']['title'] = array(); $words['del']['post'] = array(); $words['del']['title'] = array(); $sql = 'SELECT w.word_id, w.word_text, m.title_match FROM ' . SEARCH_WORDLIST_TABLE . ' w, ' . SEARCH_WORDMATCH_TABLE . " m\n\t\t\t\tWHERE m.post_id = {$post_id}\n\t\t\t\t\tAND w.word_id = m.word_id"; $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { $which = $row['title_match'] ? 'title' : 'post'; $cur_words[$which][$row['word_text']] = $row['word_id']; } $this->db->sql_freeresult($result); $words['add']['post'] = array_diff($split_text, array_keys($cur_words['post'])); $words['add']['title'] = array_diff($split_title, array_keys($cur_words['title'])); $words['del']['post'] = array_diff(array_keys($cur_words['post']), $split_text); $words['del']['title'] = array_diff(array_keys($cur_words['title']), $split_title); } else { $words['add']['post'] = $split_text; $words['add']['title'] = $split_title; $words['del']['post'] = array(); $words['del']['title'] = array(); } unset($split_text); unset($split_title); // Get unique words from the above arrays $unique_add_words = array_unique(array_merge($words['add']['post'], $words['add']['title'])); // We now have unique arrays of all words to be added and removed and // individual arrays of added and removed words for text and title. What // we need to do now is add the new words (if they don't already exist) // and then add (or remove) matches between the words and this post if (sizeof($unique_add_words)) { $sql = 'SELECT word_id, word_text FROM ' . SEARCH_WORDLIST_TABLE . ' WHERE ' . $this->db->sql_in_set('word_text', $unique_add_words); $result = $this->db->sql_query($sql); $word_ids = array(); while ($row = $this->db->sql_fetchrow($result)) { $word_ids[$row['word_text']] = $row['word_id']; } $this->db->sql_freeresult($result); $new_words = array_diff($unique_add_words, array_keys($word_ids)); $this->db->sql_transaction('begin'); if (sizeof($new_words)) { $sql_ary = array(); foreach ($new_words as $word) { $sql_ary[] = array('word_text' => (string) $word, 'word_count' => 0); } $this->db->sql_return_on_error(true); $this->db->sql_multi_insert(SEARCH_WORDLIST_TABLE, $sql_ary); $this->db->sql_return_on_error(false); } unset($new_words, $sql_ary); } else { $this->db->sql_transaction('begin'); } // now update the search match table, remove links to removed words and add links to new words foreach ($words['del'] as $word_in => $word_ary) { $title_match = $word_in == 'title' ? 1 : 0; if (sizeof($word_ary)) { $sql_in = array(); foreach ($word_ary as $word) { $sql_in[] = $cur_words[$word_in][$word]; } $sql = 'DELETE FROM ' . SEARCH_WORDMATCH_TABLE . ' WHERE ' . $this->db->sql_in_set('word_id', $sql_in) . ' AND post_id = ' . intval($post_id) . "\n\t\t\t\t\t\tAND title_match = {$title_match}"; $this->db->sql_query($sql); $sql = 'UPDATE ' . SEARCH_WORDLIST_TABLE . ' SET word_count = word_count - 1 WHERE ' . $this->db->sql_in_set('word_id', $sql_in) . ' AND word_count > 0'; $this->db->sql_query($sql); unset($sql_in); } } $this->db->sql_return_on_error(true); foreach ($words['add'] as $word_in => $word_ary) { $title_match = $word_in == 'title' ? 1 : 0; if (sizeof($word_ary)) { $sql = 'INSERT INTO ' . SEARCH_WORDMATCH_TABLE . ' (post_id, word_id, title_match) SELECT ' . (int) $post_id . ', word_id, ' . (int) $title_match . ' FROM ' . SEARCH_WORDLIST_TABLE . ' WHERE ' . $this->db->sql_in_set('word_text', $word_ary); $this->db->sql_query($sql); $sql = 'UPDATE ' . SEARCH_WORDLIST_TABLE . ' SET word_count = word_count + 1 WHERE ' . $this->db->sql_in_set('word_text', $word_ary); $this->db->sql_query($sql); } } $this->db->sql_return_on_error(false); $this->db->sql_transaction('commit'); // destroy cached search results containing any of the words removed or added $this->destroy_cache(array_unique(array_merge($words['add']['post'], $words['add']['title'], $words['del']['post'], $words['del']['title'])), array($poster_id)); unset($unique_add_words); unset($words); unset($cur_words); }