Ejemplo n.º 1
0
 /**
  * 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;
 }
Ejemplo n.º 2
0
    /**
     * 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();
    }
Ejemplo n.º 3
0
    /**
     * 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);
    }