Пример #1
0
 /**
  * This listener is run when the KernelEvents::EXCEPTION event is triggered
  *
  * @param GetResponseForExceptionEvent $event
  * @return null
  */
 public function on_kernel_exception(GetResponseForExceptionEvent $event)
 {
     $exception = $event->getException();
     $message = $exception->getMessage();
     if ($exception instanceof \src\exception\exception_interface) {
         $message = call_user_func_array(array($this->user, 'lang'), array_merge(array($message), $exception->get_parameters()));
     }
     if (!$event->getRequest()->isXmlHttpRequest()) {
         page_header($this->user->lang('INFORMATION'));
         $this->template->assign_vars(array('MESSAGE_TITLE' => $this->user->lang('INFORMATION'), 'MESSAGE_TEXT' => $message));
         $this->template->set_filenames(array('body' => 'message_body.html'));
         page_footer(true, false, false);
         $response = new Response($this->template->assign_display('body'), 500);
     } else {
         $data = array();
         if (!empty($message)) {
             $data['message'] = $message;
         }
         if (defined('DEBUG')) {
             $data['trace'] = $exception->getTrace();
         }
         $response = new JsonResponse($data, 500);
     }
     if ($exception instanceof HttpExceptionInterface) {
         $response->setStatusCode($exception->getStatusCode());
         $response->headers->add($exception->getHeaders());
     }
     $event->setResponse($response);
 }
Пример #2
0
 /**
  * Generate ISO 8601 date string (RFC 3339)
  */
 public function format_date($time)
 {
     static $zone_offset;
     static $offset_string;
     if (empty($offset_string)) {
         $zone_offset = $this->user->create_datetime()->getOffset();
         $offset_string = src_format_timezone_offset($zone_offset);
     }
     return gmdate("Y-m-d\\TH:i:s", $time + $zone_offset) . $offset_string;
 }
Пример #3
0
    /**
     * Get the notification type id from the name
     *
     * @param string $notification_type_name The name
     * @return int the notification_type_id
     * @throws \src\notification\exception
     */
    public function get_notification_type_id($notification_type_name)
    {
        $notification_type_ids = $this->cache->get('notification_type_ids');
        if ($notification_type_ids === false) {
            $notification_type_ids = array();
            $sql = 'SELECT notification_type_id, notification_type_name
				FROM ' . $this->notification_types_table;
            $result = $this->db->sql_query($sql);
            while ($row = $this->db->sql_fetchrow($result)) {
                $notification_type_ids[$row['notification_type_name']] = (int) $row['notification_type_id'];
            }
            $this->db->sql_freeresult($result);
            $this->cache->put('notification_type_ids', $notification_type_ids);
        }
        if (!isset($notification_type_ids[$notification_type_name])) {
            if (!isset($this->notification_types[$notification_type_name]) && !isset($this->notification_types['notification.type.' . $notification_type_name])) {
                throw new \src\notification\exception($this->user->lang('NOTIFICATION_TYPE_NOT_EXIST', $notification_type_name));
            }
            $sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array('notification_type_name' => $notification_type_name, 'notification_type_enabled' => 1));
            $this->db->sql_query($sql);
            $notification_type_ids[$notification_type_name] = (int) $this->db->sql_nextid();
            $this->cache->put('notification_type_ids', $notification_type_ids);
        }
        return $notification_type_ids[$notification_type_name];
    }
Пример #4
0
 /**
  * Dependencies should be specified in the service definition and can be
  * then accessed in __construct(). Arguments are sent through the URL path
  * and should match the parameters of the method you are using as your
  * controller.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request Symfony Request object
  * @param mixed $controller A callable (controller class, method)
  * @return array An array of arguments to pass to the controller
  * @throws \src\controller\exception
  */
 public function getArguments(Request $request, $controller)
 {
     // At this point, $controller contains the object and method name
     list($object, $method) = $controller;
     $mirror = new \ReflectionMethod($object, $method);
     $arguments = array();
     $parameters = $mirror->getParameters();
     $attributes = $request->attributes->all();
     foreach ($parameters as $param) {
         if (array_key_exists($param->name, $attributes)) {
             if (is_string($attributes[$param->name])) {
                 $value = $attributes[$param->name];
                 $this->type_cast_helper->set_var($value, $attributes[$param->name], 'string', true, false);
                 $arguments[] = $value;
             } else {
                 $arguments[] = $attributes[$param->name];
             }
         } else {
             if ($param->getClass() && $param->getClass()->isInstance($request)) {
                 $arguments[] = $request;
             } else {
                 if ($param->isDefaultValueAvailable()) {
                     $arguments[] = $param->getDefaultValue();
                 } else {
                     throw new \src\controller\exception($this->user->lang('CONTROLLER_ARGUMENT_VALUE_MISSING', $param->getPosition() + 1, get_class($object) . ':' . $method, $param->name));
                 }
             }
         }
     }
     return $arguments;
 }
Пример #5
0
 /**
  * {@inheritDoc}
  */
 public function validate_profile_field(&$field_value, $field_data)
 {
     $field_value = (bool) $field_value;
     if (!$field_value && $field_data['field_required']) {
         return $this->user->lang('FIELD_REQUIRED', $this->get_field_name($field_data['lang_name']));
     }
     return false;
 }
Пример #6
0
 /**
  * Prepare to output the notification to the template
  *
  * @return array Template variables
  */
 public function prepare_for_display()
 {
     $mark_hash = generate_link_hash('mark_notification_read');
     if ($this->get_url()) {
         $u_mark_read = append_sid($this->src_root_path . 'index.' . $this->php_ext, 'mark_notification=' . $this->notification_id . '&hash=' . $mark_hash);
     } else {
         $redirect = ($this->user->page['page_dir'] ? $this->user->page['page_dir'] . '/' : '') . $this->user->page['page_name'] . ($this->user->page['query_string'] ? '?' . $this->user->page['query_string'] : '');
         $u_mark_read = append_sid($this->src_root_path . 'index.' . $this->php_ext, 'mark_notification=' . $this->notification_id . '&hash=' . $mark_hash . '&redirect=' . urlencode($redirect));
     }
     return array('NOTIFICATION_ID' => $this->notification_id, 'STYLING' => $this->get_style_class(), 'AVATAR' => $this->get_avatar(), 'FORMATTED_TITLE' => $this->get_title(), 'REFERENCE' => $this->get_reference(), 'FORUM' => $this->get_forum(), 'REASON' => $this->get_reason(), 'URL' => $this->get_url(), 'TIME' => $this->user->format_date($this->notification_time), 'UNREAD' => !$this->notification_read, 'U_MARK_READ' => !$this->notification_read ? $u_mark_read : '');
 }
Пример #7
0
 /**
  * Output a message
  *
  * In case of an error, please throw an exception instead
  *
  * @param string $message The message to display (must be a language variable)
  * @param array $parameters The parameters to use with the language var
  * @param string $title Title for the message (must be a language variable)
  * @param int $code The HTTP status code (e.g. 404, 500, 503, etc.)
  * @return Response A Response instance
  */
 public function message($message, array $parameters = array(), $title = 'INFORMATION', $code = 200)
 {
     array_unshift($parameters, $message);
     $message_text = call_user_func_array(array($this->user, 'lang'), $parameters);
     $message_title = $this->user->lang($title);
     if ($this->request->is_ajax()) {
         global $refresh_data;
         return new JsonResponse(array('MESSAGE_TITLE' => $message_title, 'MESSAGE_TEXT' => $message_text, 'S_USER_WARNING' => false, 'S_USER_NOTICE' => false, 'REFRESH_DATA' => !empty($refresh_data) ? $refresh_data : null), $code);
     }
     $this->template->assign_vars(array('MESSAGE_TEXT' => $message_text, 'MESSAGE_TITLE' => $message_title));
     return $this->render('message_body.html', $message_title, $code);
 }
Пример #8
0
 /**
  * Validates the contents of the authors field
  *
  * @return boolean True when passes validation, throws exception if invalid
  * @throws \src\extension\exception
  */
 public function validate_authors()
 {
     if (empty($this->metadata['authors'])) {
         throw new \src\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'authors'));
     }
     foreach ($this->metadata['authors'] as $author) {
         if (!isset($author['name'])) {
             throw new \src\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'author name'));
         }
     }
     return true;
 }
Пример #9
0
 /**
  * Check accuracy of attachment statistics.
  *
  * @return bool|string	Returns false if stats are correct or error message
  *	otherwise.
  */
 public function check_stats_accuracy()
 {
     // Get fresh stats.
     $stats = $this->get_attachment_stats();
     // Get current files stats
     $num_files = (int) $this->config['num_files'];
     $total_size = (double) $this->config['upload_dir_size'];
     if ($num_files != $stats['num_files'] || $total_size != $stats['upload_dir_size']) {
         $u_resync = $this->u_action . '&action=stats';
         return $this->user->lang('FILES_STATS_WRONG', (int) $stats['num_files'], get_formatted_filesize($stats['upload_dir_size']), '<a href="' . $u_resync . '">', '</a>');
     }
     return false;
 }
Пример #10
0
 /**
  * Wrapper for \acp_modules::get_module_infos()
  *
  * @param string $class Module Class
  * @param string $basename Module Basename
  * @return array Module Information
  * @throws \src\db\migration\exception
  */
 protected function get_module_info($class, $basename)
 {
     if (!class_exists('acp_modules')) {
         include $this->src_root_path . 'includes/acp/acp_modules.' . $this->php_ext;
         $this->user->add_lang('acp/modules');
     }
     $acp_modules = new \acp_modules();
     $module = $acp_modules->get_module_infos($basename, $class, true);
     if (empty($module)) {
         throw new \src\db\migration\exception('MODULE_INFO_FILE_NOT_EXIST', $class, $basename);
     }
     return array_pop($module);
 }
Пример #11
0
 /**
  * {@inheritDoc}
  */
 public function validate_profile_field(&$field_value, $field_data)
 {
     $field_value = (int) $field_value;
     // retrieve option lang data if necessary
     if (!$this->lang_helper->is_set($field_data['field_id'], $field_data['lang_id'], 1)) {
         $this->lang_helper->load_option_lang($field_data['lang_id']);
     }
     if (!$this->lang_helper->is_set($field_data['field_id'], $field_data['lang_id'], $field_value)) {
         return $this->user->lang('FIELD_INVALID_VALUE', $this->get_field_name($field_data['lang_name']));
     }
     if ($field_value == $field_data['field_novalue'] && $field_data['field_required']) {
         return $this->user->lang('FIELD_REQUIRED', $this->get_field_name($field_data['lang_name']));
     }
     return false;
 }
Пример #12
0
 /**
  * {@inheritDoc}
  */
 public function validate_profile_field(&$field_value, $field_data)
 {
     if (trim($field_value) === '' && !$field_data['field_required']) {
         return false;
     }
     $field_value = (int) $field_value;
     if ($field_value < $field_data['field_minlen']) {
         return $this->user->lang('FIELD_TOO_SMALL', (int) $field_data['field_minlen'], $this->get_field_name($field_data['lang_name']));
     } else {
         if ($field_value > $field_data['field_maxlen']) {
             return $this->user->lang('FIELD_TOO_LARGE', (int) $field_data['field_maxlen'], $this->get_field_name($field_data['lang_name']));
         }
     }
     return false;
 }
Пример #13
0
 /**
  * {@inheritDoc}
  */
 public function get_profile_value($field_value, $field_data)
 {
     $date = explode('-', $field_value);
     $day = isset($date[0]) ? (int) $date[0] : 0;
     $month = isset($date[1]) ? (int) $date[1] : 0;
     $year = isset($date[2]) ? (int) $date[2] : 0;
     if (!$day && !$month && !$year && !$field_data['field_show_novalue']) {
         return null;
     } else {
         if ($day && $month && $year) {
             // Date should display as the same date for every user regardless of timezone
             return $this->user->create_datetime()->setDate($year, $month, $day)->setTime(0, 0, 0)->format($this->user->lang['DATE_FORMAT'], true);
         }
     }
     return $field_value;
 }
Пример #14
0
 /**
  * Install style(s)
  */
 protected function action_install()
 {
     // Get list of styles to install
     $dirs = $this->request_vars('dir', '', true);
     // Get list of styles that can be installed
     $styles = $this->find_available(false);
     // Install each style
     $messages = array();
     $installed_names = array();
     $installed_dirs = array();
     $last_installed = false;
     foreach ($dirs as $dir) {
         if (in_array($dir, $this->reserved_style_names)) {
             $messages[] = $this->user->lang('STYLE_NAME_RESERVED', htmlspecialchars($dir));
             continue;
         }
         $found = false;
         foreach ($styles as &$style) {
             // Check if:
             // 1. Directory matches directory we are looking for
             // 2. Style is not installed yet
             // 3. Style with same name or directory hasn't been installed already within this function
             if ($style['style_path'] == $dir && empty($style['_installed']) && !in_array($style['style_path'], $installed_dirs) && !in_array($style['style_name'], $installed_names)) {
                 // Install style
                 $style['style_active'] = 1;
                 $style['style_id'] = $this->install_style($style);
                 $style['_installed'] = true;
                 $found = true;
                 $last_installed = $style['style_id'];
                 $installed_names[] = $style['style_name'];
                 $installed_dirs[] = $style['style_path'];
                 $messages[] = sprintf($this->user->lang['STYLE_INSTALLED'], htmlspecialchars($style['style_name']));
             }
         }
         if (!$found) {
             $messages[] = sprintf($this->user->lang['STYLE_NOT_INSTALLED'], htmlspecialchars($dir));
         }
     }
     // Show message
     if (!count($messages)) {
         trigger_error($this->user->lang['NO_MATCHING_STYLES_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING);
     }
     $message = implode('<br />', $messages);
     $message .= '<br /><br /><a href="' . $this->u_base_action . '&amp;mode=style' . '">&laquo; ' . $this->user->lang('STYLE_INSTALLED_RETURN_INSTALLED_STYLES') . '</a>';
     $message .= '<br /><br /><a href="' . $this->u_base_action . '&amp;mode=install' . '">&raquo; ' . $this->user->lang('STYLE_INSTALLED_RETURN_UNINSTALLED_STYLES') . '</a>';
     trigger_error($message, E_USER_NOTICE);
 }
Пример #15
0
    /**
     * Build Array for user insertion into custom profile fields table
     */
    public function build_insert_sql_array($cp_data)
    {
        $sql_not_in = array();
        foreach ($cp_data as $key => $null) {
            $sql_not_in[] = strncmp($key, 'pf_', 3) === 0 ? substr($key, 3) : $key;
        }
        $sql = 'SELECT f.field_type, f.field_ident, f.field_default_value, l.lang_default_value
			FROM ' . $this->fields_language_table . ' l, ' . $this->fields_table . ' f
			WHERE l.lang_id = ' . $this->user->get_iso_lang_id() . '
				' . (sizeof($sql_not_in) ? ' AND ' . $this->db->sql_in_set('f.field_ident', $sql_not_in, true) : '') . '
				AND l.field_id = f.field_id';
        $result = $this->db->sql_query($sql);
        while ($row = $this->db->sql_fetchrow($result)) {
            $profile_field = $this->type_collection[$row['field_type']];
            $cp_data['pf_' . $row['field_ident']] = $profile_field->get_default_field_value($row);
        }
        $this->db->sql_freeresult($result);
        return $cp_data;
    }
Пример #16
0
 /**
  * Obtains the latest version information
  *
  * @param bool $force_update Ignores cached data. Defaults to false.
  * @param bool $force_cache Force the use of the cache. Override $force_update.
  * @return string Version info, includes stable and unstable data
  * @throws \RuntimeException
  */
 public function get_versions($force_update = false, $force_cache = false)
 {
     $cache_file = '_versioncheck_' . $this->host . $this->path . $this->file;
     $info = $this->cache->get($cache_file);
     if ($info === false && $force_cache) {
         throw new \RuntimeException($this->user->lang('VERSIONCHECK_FAIL'));
     } else {
         if ($info === false || $force_update) {
             try {
                 $info = $this->file_downloader->get($this->host, $this->path, $this->file);
             } catch (\src\exception\runtime_exception $exception) {
                 $prepare_parameters = array_merge(array($exception->getMessage()), $exception->get_parameters());
                 throw new \RuntimeException(call_user_func_array(array($this->user, 'lang'), $prepare_parameters));
             }
             $error_string = $this->file_downloader->get_error_string();
             if (!empty($error_string)) {
                 throw new \RuntimeException($error_string);
             }
             $info = json_decode($info, true);
             // Sanitize any data we retrieve from a server
             if (!empty($info)) {
                 $json_sanitizer = function (&$value, $key) {
                     $type_cast_helper = new \src\request\type_cast_helper();
                     $type_cast_helper->set_var($value, $value, gettype($value), true);
                 };
                 array_walk_recursive($info, $json_sanitizer);
             }
             if (empty($info['stable']) && empty($info['unstable'])) {
                 $this->user->add_lang('acp/common');
                 throw new \RuntimeException($this->user->lang('VERSIONCHECK_FAIL'));
             }
             $info['stable'] = empty($info['stable']) ? array() : $info['stable'];
             $info['unstable'] = empty($info['unstable']) ? $info['stable'] : $info['unstable'];
             $this->cache->put($cache_file, $info, 86400);
             // 24 hours
         }
     }
     return $info;
 }
Пример #17
0
 /**
  * Return current page
  *
  * @param int $num_items the total number of items, posts, topics, etc.
  * @param int $per_page the number of items, posts, etc. per page
  * @param int $start the item which should be considered currently active, used to determine the page we're on
  * @return string Descriptive pagination string (e.g. "page 1 of 10")
  */
 public function on_page($num_items, $per_page, $start)
 {
     $on_page = $this->get_on_page($per_page, $start);
     return $this->user->lang('PAGE_OF', $on_page, max(ceil($num_items / $per_page), 1));
 }
Пример #18
0
    /**
     * This function fills $this->search_query with the cleaned user search query
     *
     * If $terms is 'any' then the words will be extracted from the search query
     * and combined with | inside brackets. They will afterwards be treated like
     * an standard search query.
     *
     * Then it analyses the query and fills the internal arrays $must_not_contain_ids,
     * $must_contain_ids and $must_exclude_one_ids which are later used by keyword_search()
     *
     * @param	string	$keywords	contains the search query string as entered by the user
     * @param	string	$terms		is either 'all' (use search query as entered, default words to 'must be contained in post')
     * 	or 'any' (find all posts containing at least one of the given words)
     * @return	boolean				false if no valid keywords were found and otherwise true
     */
    public function split_keywords($keywords, $terms)
    {
        $tokens = '+-|()*';
        $keywords = trim($this->cleanup($keywords, $tokens));
        // allow word|word|word without brackets
        if (strpos($keywords, ' ') === false && strpos($keywords, '|') !== false && strpos($keywords, '(') === false) {
            $keywords = '(' . $keywords . ')';
        }
        $open_bracket = $space = false;
        for ($i = 0, $n = strlen($keywords); $i < $n; $i++) {
            if ($open_bracket !== false) {
                switch ($keywords[$i]) {
                    case ')':
                        if ($open_bracket + 1 == $i) {
                            $keywords[$i - 1] = '|';
                            $keywords[$i] = '|';
                        }
                        $open_bracket = false;
                        break;
                    case '(':
                        $keywords[$i] = '|';
                        break;
                    case '+':
                    case '-':
                    case ' ':
                        $keywords[$i] = '|';
                        break;
                    case '*':
                        if ($i === 0 || $keywords[$i - 1] !== '*' && strcspn($keywords[$i - 1], $tokens) === 0) {
                            if ($i === $n - 1 || $keywords[$i + 1] !== '*' && strcspn($keywords[$i + 1], $tokens) === 0) {
                                $keywords = substr($keywords, 0, $i) . substr($keywords, $i + 1);
                            }
                        }
                        break;
                }
            } else {
                switch ($keywords[$i]) {
                    case ')':
                        $keywords[$i] = ' ';
                        break;
                    case '(':
                        $open_bracket = $i;
                        $space = false;
                        break;
                    case '|':
                        $keywords[$i] = ' ';
                        break;
                    case '-':
                    case '+':
                        $space = $keywords[$i];
                        break;
                    case ' ':
                        if ($space !== false) {
                            $keywords[$i] = $space;
                        }
                        break;
                    default:
                        $space = false;
                }
            }
        }
        if ($open_bracket) {
            $keywords .= ')';
        }
        $match = array('#  +#', '#\\|\\|+#', '#(\\+|\\-)(?:\\+|\\-)+#', '#\\(\\|#', '#\\|\\)#');
        $replace = array(' ', '|', '$1', '(', ')');
        $keywords = preg_replace($match, $replace, $keywords);
        $num_keywords = sizeof(explode(' ', $keywords));
        // We limit the number of allowed keywords to minimize load on the database
        if ($this->config['max_num_search_keywords'] && $num_keywords > $this->config['max_num_search_keywords']) {
            trigger_error($this->user->lang('MAX_NUM_SEARCH_KEYWORDS_REFINE', (int) $this->config['max_num_search_keywords'], $num_keywords));
        }
        // $keywords input format: each word separated by a space, words in a bracket are not separated
        // the user wants to search for any word, convert the search query
        if ($terms == 'any') {
            $words = array();
            preg_match_all('#([^\\s+\\-|()]+)(?:$|[\\s+\\-|()])#u', $keywords, $words);
            if (sizeof($words[1])) {
                $keywords = '(' . implode('|', $words[1]) . ')';
            }
        }
        // set the search_query which is shown to the user
        $this->search_query = $keywords;
        $exact_words = array();
        preg_match_all('#([^\\s+\\-|()]+)(?:$|[\\s+\\-|()])#u', $keywords, $exact_words);
        $exact_words = $exact_words[1];
        $common_ids = $words = array();
        if (sizeof($exact_words)) {
            $sql = 'SELECT word_id, word_text, word_common
				FROM ' . SEARCH_WORDLIST_TABLE . '
				WHERE ' . $this->db->sql_in_set('word_text', $exact_words) . '
				ORDER BY word_count ASC';
            $result = $this->db->sql_query($sql);
            // store an array of words and ids, remove common words
            while ($row = $this->db->sql_fetchrow($result)) {
                if ($row['word_common']) {
                    $this->common_words[] = $row['word_text'];
                    $common_ids[$row['word_text']] = (int) $row['word_id'];
                    continue;
                }
                $words[$row['word_text']] = (int) $row['word_id'];
            }
            $this->db->sql_freeresult($result);
        }
        // Handle +, - without preceeding whitespace character
        $match = array('#(\\S)\\+#', '#(\\S)-#');
        $replace = array('$1 +', '$1 +');
        $keywords = preg_replace($match, $replace, $keywords);
        // now analyse the search query, first split it using the spaces
        $query = explode(' ', $keywords);
        $this->must_contain_ids = array();
        $this->must_not_contain_ids = array();
        $this->must_exclude_one_ids = array();
        $mode = '';
        $ignore_no_id = true;
        foreach ($query as $word) {
            if (empty($word)) {
                continue;
            }
            // words which should not be included
            if ($word[0] == '-') {
                $word = substr($word, 1);
                // a group of which at least one may not be in the resulting posts
                if ($word[0] == '(') {
                    $word = array_unique(explode('|', substr($word, 1, -1)));
                    $mode = 'must_exclude_one';
                } else {
                    $mode = 'must_not_contain';
                }
                $ignore_no_id = true;
            } else {
                // no prefix is the same as a +prefix
                if ($word[0] == '+') {
                    $word = substr($word, 1);
                }
                // a group of words of which at least one word should be in every resulting post
                if ($word[0] == '(') {
                    $word = array_unique(explode('|', substr($word, 1, -1)));
                }
                $ignore_no_id = false;
                $mode = 'must_contain';
            }
            if (empty($word)) {
                continue;
            }
            // if this is an array of words then retrieve an id for each
            if (is_array($word)) {
                $non_common_words = array();
                $id_words = array();
                foreach ($word as $i => $word_part) {
                    if (strpos($word_part, '*') !== false) {
                        $id_words[] = '\'' . $this->db->sql_escape(str_replace('*', '%', $word_part)) . '\'';
                        $non_common_words[] = $word_part;
                    } else {
                        if (isset($words[$word_part])) {
                            $id_words[] = $words[$word_part];
                            $non_common_words[] = $word_part;
                        } else {
                            $len = utf8_strlen($word_part);
                            if ($len < $this->word_length['min'] || $len > $this->word_length['max']) {
                                $this->common_words[] = $word_part;
                            }
                        }
                    }
                }
                if (sizeof($id_words)) {
                    sort($id_words);
                    if (sizeof($id_words) > 1) {
                        $this->{$mode . '_ids'}[] = $id_words;
                    } else {
                        $mode = $mode == 'must_exclude_one' ? 'must_not_contain' : $mode;
                        $this->{$mode . '_ids'}[] = $id_words[0];
                    }
                } else {
                    if (!$ignore_no_id && sizeof($non_common_words)) {
                        trigger_error(sprintf($this->user->lang['WORDS_IN_NO_POST'], implode($this->user->lang['COMMA_SEPARATOR'], $non_common_words)));
                    }
                }
                unset($non_common_words);
            } else {
                if (($wildcard = strpos($word, '*') !== false) || isset($words[$word])) {
                    if ($wildcard) {
                        $len = utf8_strlen(str_replace('*', '', $word));
                        if ($len >= $this->word_length['min'] && $len <= $this->word_length['max']) {
                            $this->{$mode . '_ids'}[] = '\'' . $this->db->sql_escape(str_replace('*', '%', $word)) . '\'';
                        } else {
                            $this->common_words[] = $word;
                        }
                    } else {
                        $this->{$mode . '_ids'}[] = $words[$word];
                    }
                } else {
                    if (!isset($common_ids[$word])) {
                        $len = utf8_strlen($word);
                        if ($len < $this->word_length['min'] || $len > $this->word_length['max']) {
                            $this->common_words[] = $word;
                        }
                    }
                }
            }
        }
        // Return true if all words are not common words
        if (sizeof($exact_words) - sizeof($this->common_words) > 0) {
            return true;
        }
        return false;
    }
Пример #19
0
 /**
  * Performs a search on keywords depending on display specific params. You have to run split_keywords() first
  *
  * @param	string		$type				contains either posts or topics depending on what should be searched for
  * @param	string		$fields				contains either titleonly (topic titles should be searched), msgonly (only message bodies should be searched), firstpost (only subject and body of the first post should be searched) or all (all post bodies and subjects should be searched)
  * @param	string		$terms				is either 'all' (use query as entered, words without prefix should default to "have to be in field") or 'any' (ignore search query parts and just return all posts that contain any of the specified words)
  * @param	array		$sort_by_sql		contains SQL code for the ORDER BY part of a query
  * @param	string		$sort_key			is the key of $sort_by_sql for the selected sorting
  * @param	string		$sort_dir			is either a or d representing ASC and DESC
  * @param	string		$sort_days			specifies the maximum amount of days a post may be old
  * @param	array		$ex_fid_ary			specifies an array of forum ids which should not be searched
  * @param	string		$post_visibility	specifies which types of posts the user can view in which forums
  * @param	int			$topic_id			is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched
  * @param	array		$author_ary			an array of author ids if the author should be ignored during the search the array is empty
  * @param	string		$author_name		specifies the author match, when ANONYMOUS is also a search-match
  * @param	array		&$id_ary			passed by reference, to be filled with ids for the page specified by $start and $per_page, should be ordered
  * @param	int			$start				indicates the first index of the page
  * @param	int			$per_page			number of ids each page is supposed to contain
  * @return	boolean|int						total number of results
  */
 public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page)
 {
     // No keywords? No posts.
     if (!strlen($this->search_query) && !sizeof($author_ary)) {
         return false;
     }
     $id_ary = array();
     $join_topic = $type != 'posts';
     // Sorting
     if ($type == 'topics') {
         switch ($sort_key) {
             case 'a':
                 $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'poster_id ' . ($sort_dir == 'a' ? 'ASC' : 'DESC'));
                 break;
             case 'f':
                 $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'forum_id ' . ($sort_dir == 'a' ? 'ASC' : 'DESC'));
                 break;
             case 'i':
             case 's':
                 $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'post_subject ' . ($sort_dir == 'a' ? 'ASC' : 'DESC'));
                 break;
             case 't':
             default:
                 $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'topic_last_post_time ' . ($sort_dir == 'a' ? 'ASC' : 'DESC'));
                 break;
         }
     } else {
         switch ($sort_key) {
             case 'a':
                 $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'poster_id');
                 break;
             case 'f':
                 $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'forum_id');
                 break;
             case 'i':
             case 's':
                 $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'post_subject');
                 break;
             case 't':
             default:
                 $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'post_time');
                 break;
         }
     }
     // Most narrow filters first
     if ($topic_id) {
         $this->sphinx->SetFilter('topic_id', array($topic_id));
     }
     $search_query_prefix = '';
     switch ($fields) {
         case 'titleonly':
             // Only search the title
             if ($terms == 'all') {
                 $search_query_prefix = '@title ';
             }
             // Weight for the title
             $this->sphinx->SetFieldWeights(array("title" => 5, "data" => 1));
             // 1 is first_post, 0 is not first post
             $this->sphinx->SetFilter('topic_first_post', array(1));
             break;
         case 'msgonly':
             // Only search the body
             if ($terms == 'all') {
                 $search_query_prefix = '@data ';
             }
             // Weight for the body
             $this->sphinx->SetFieldWeights(array("title" => 1, "data" => 5));
             break;
         case 'firstpost':
             // More relative weight for the title, also search the body
             $this->sphinx->SetFieldWeights(array("title" => 5, "data" => 1));
             // 1 is first_post, 0 is not first post
             $this->sphinx->SetFilter('topic_first_post', array(1));
             break;
         default:
             // More relative weight for the title, also search the body
             $this->sphinx->SetFieldWeights(array("title" => 5, "data" => 1));
             break;
     }
     if (sizeof($author_ary)) {
         $this->sphinx->SetFilter('poster_id', $author_ary);
     }
     // As this is not simply possible at the moment, we limit the result to approved posts.
     // This will make it impossible for moderators to search unapproved and softdeleted posts,
     // but at least it will also cause the same for normal users.
     $this->sphinx->SetFilter('post_visibility', array(ITEM_APPROVED));
     if (sizeof($ex_fid_ary)) {
         // All forums that a user is allowed to access
         $fid_ary = array_unique(array_intersect(array_keys($this->auth->acl_getf('f_read', true)), array_keys($this->auth->acl_getf('f_search', true))));
         // All forums that the user wants to and can search in
         $search_forums = array_diff($fid_ary, $ex_fid_ary);
         if (sizeof($search_forums)) {
             $this->sphinx->SetFilter('forum_id', $search_forums);
         }
     }
     $this->sphinx->SetFilter('deleted', array(0));
     $this->sphinx->SetLimits($start, (int) $per_page, SPHINX_MAX_MATCHES);
     $result = $this->sphinx->Query($search_query_prefix . str_replace('&quot;', '"', $this->search_query), $this->indexes);
     // Could be connection to localhost:9312 failed (errno=111,
     // msg=Connection refused) during rotate, retry if so
     $retries = SPHINX_CONNECT_RETRIES;
     while (!$result && strpos($this->sphinx->GetLastError(), "errno=111,") !== false && $retries--) {
         usleep(SPHINX_CONNECT_WAIT_TIME);
         $result = $this->sphinx->Query($search_query_prefix . str_replace('&quot;', '"', $this->search_query), $this->indexes);
     }
     if ($this->sphinx->GetLastError()) {
         add_log('critical', 'LOG_SPHINX_ERROR', $this->sphinx->GetLastError());
         if ($this->auth->acl_get('a_')) {
             trigger_error($this->user->lang('SPHINX_SEARCH_FAILED', $this->sphinx->GetLastError()));
         } else {
             trigger_error($this->user->lang('SPHINX_SEARCH_FAILED_LOG'));
         }
     }
     $result_count = $result['total_found'];
     if ($result_count && $start >= $result_count) {
         $start = floor(($result_count - 1) / $per_page) * $per_page;
         $this->sphinx->SetLimits((int) $start, (int) $per_page, SPHINX_MAX_MATCHES);
         $result = $this->sphinx->Query($search_query_prefix . str_replace('&quot;', '"', $this->search_query), $this->indexes);
         // Could be connection to localhost:9312 failed (errno=111,
         // msg=Connection refused) during rotate, retry if so
         $retries = SPHINX_CONNECT_RETRIES;
         while (!$result && strpos($this->sphinx->GetLastError(), "errno=111,") !== false && $retries--) {
             usleep(SPHINX_CONNECT_WAIT_TIME);
             $result = $this->sphinx->Query($search_query_prefix . str_replace('&quot;', '"', $this->search_query), $this->indexes);
         }
     }
     $id_ary = array();
     if (isset($result['matches'])) {
         if ($type == 'posts') {
             $id_ary = array_keys($result['matches']);
         } else {
             foreach ($result['matches'] as $key => $value) {
                 $id_ary[] = $value['attrs']['topic_id'];
             }
         }
     } else {
         return false;
     }
     $id_ary = array_slice($id_ary, 0, (int) $per_page);
     return $result_count;
 }
Пример #20
0
 /**
  * Splits keywords entered by a user into an array of words stored in $this->split_words
  * Stores the tidied search query in $this->search_query
  *
  * @param string &$keywords Contains the keyword as entered by the user
  * @param string $terms is either 'all' or 'any'
  * @return bool false if no valid keywords were found and otherwise true
  */
 public function split_keywords(&$keywords, $terms)
 {
     if ($terms == 'all') {
         $match = array('#\\sand\\s#iu', '#\\sor\\s#iu', '#\\snot\\s#iu', '#(^|\\s)\\+#', '#(^|\\s)-#', '#(^|\\s)\\|#');
         $replace = array(' +', ' |', ' -', ' +', ' -', ' |');
         $keywords = preg_replace($match, $replace, $keywords);
     }
     // Filter out as above
     $split_keywords = preg_replace("#[\n\r\t]+#", ' ', trim(htmlspecialchars_decode($keywords)));
     // Split words
     $split_keywords = preg_replace('#([^\\p{L}\\p{N}\'*"()])#u', '$1$1', str_replace('\'\'', '\' \'', trim($split_keywords)));
     $matches = array();
     preg_match_all('#(?:[^\\p{L}\\p{N}*"()]|^)([+\\-|]?(?:[\\p{L}\\p{N}*"()]+\'?)*[\\p{L}\\p{N}*"()])(?:[^\\p{L}\\p{N}*"()]|$)#u', $split_keywords, $matches);
     $this->split_words = $matches[1];
     // We limit the number of allowed keywords to minimize load on the database
     if ($this->config['max_num_search_keywords'] && sizeof($this->split_words) > $this->config['max_num_search_keywords']) {
         trigger_error($this->user->lang('MAX_NUM_SEARCH_KEYWORDS_REFINE', (int) $this->config['max_num_search_keywords'], sizeof($this->split_words)));
     }
     // to allow phrase search, we need to concatenate quoted words
     $tmp_split_words = array();
     $phrase = '';
     foreach ($this->split_words as $word) {
         if ($phrase) {
             $phrase .= ' ' . $word;
             if (strpos($word, '"') !== false && substr_count($word, '"') % 2 == 1) {
                 $tmp_split_words[] = $phrase;
                 $phrase = '';
             }
         } else {
             if (strpos($word, '"') !== false && substr_count($word, '"') % 2 == 1) {
                 $phrase = $word;
             } else {
                 $tmp_split_words[] = $word;
             }
         }
     }
     if ($phrase) {
         $tmp_split_words[] = $phrase;
     }
     $this->split_words = $tmp_split_words;
     unset($tmp_split_words);
     unset($phrase);
     foreach ($this->split_words as $i => $word) {
         $clean_word = preg_replace('#^[+\\-|"]#', '', $word);
         // check word length
         $clean_len = utf8_strlen(str_replace('*', '', $clean_word));
         if ($clean_len < $this->config['fulltext_mysql_min_word_len'] || $clean_len > $this->config['fulltext_mysql_max_word_len']) {
             $this->common_words[] = $word;
             unset($this->split_words[$i]);
         }
     }
     if ($terms == 'any') {
         $this->search_query = '';
         foreach ($this->split_words as $word) {
             if (strpos($word, '+') === 0 || strpos($word, '-') === 0 || strpos($word, '|') === 0) {
                 $word = substr($word, 1);
             }
             $this->search_query .= $word . ' ';
         }
     } else {
         $this->search_query = '';
         foreach ($this->split_words as $word) {
             if (strpos($word, '+') === 0 || strpos($word, '-') === 0) {
                 $this->search_query .= $word . ' ';
             } else {
                 if (strpos($word, '|') === 0) {
                     $this->search_query .= substr($word, 1) . ' ';
                 } else {
                     $this->search_query .= '+' . $word . ' ';
                 }
             }
         }
     }
     $this->search_query = utf8_htmlspecialchars($this->search_query);
     if ($this->search_query) {
         $this->split_words = array_values($this->split_words);
         sort($this->split_words);
         return true;
     }
     return false;
 }
Пример #21
0
 /**
  * Sends an error message back to the client via JSON response
  *
  * @param int $code		The error code
  * @param string $msg	The translation string of the message to be sent
  *
  * @return null
  */
 public function emit_error($code, $msg)
 {
     $json_response = new \src\json_response();
     $json_response->send(array('jsonrpc' => '2.0', 'id' => 'id', 'error' => array('code' => $code, 'message' => $this->user->lang($msg))));
 }
Пример #22
0
 /**
  * {@inheritDoc}
  */
 public function get_name()
 {
     return $this->user->lang('FIELD_' . strtoupper($this->get_name_short()));
 }
Пример #23
0
    /**
     * {@inheritDoc}
     */
    public function get_logs($mode, $count_logs = true, $limit = 0, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $log_time = 0, $sort_by = 'l.log_time DESC', $keywords = '')
    {
        $this->entry_count = 0;
        $this->last_page_offset = $offset;
        $topic_id_list = $reportee_id_list = array();
        $profile_url = $this->get_is_admin() && $this->src_admin_path ? append_sid("{$this->src_admin_path}index.{$this->php_ext}", 'i=users&amp;mode=overview') : append_sid("{$this->src_root_path}memberlist.{$this->php_ext}", 'mode=viewprofile');
        switch ($mode) {
            case 'admin':
                $log_type = LOG_ADMIN;
                $sql_additional = '';
                break;
            case 'mod':
                $log_type = LOG_MOD;
                $sql_additional = '';
                if ($topic_id) {
                    $sql_additional = 'AND l.topic_id = ' . (int) $topic_id;
                } else {
                    if (is_array($forum_id)) {
                        $sql_additional = 'AND ' . $this->db->sql_in_set('l.forum_id', array_map('intval', $forum_id));
                    } else {
                        if ($forum_id) {
                            $sql_additional = 'AND l.forum_id = ' . (int) $forum_id;
                        }
                    }
                }
                break;
            case 'user':
                $log_type = LOG_USERS;
                $sql_additional = 'AND l.reportee_id = ' . (int) $user_id;
                break;
            case 'users':
                $log_type = LOG_USERS;
                $sql_additional = '';
                break;
            case 'critical':
                $log_type = LOG_CRITICAL;
                $sql_additional = '';
                break;
            default:
                $log_type = false;
                $sql_additional = '';
        }
        /**
         * Overwrite log type and limitations before we count and get the logs
         *
         * NOTE: if log_type is false, no entries will be returned.
         *
         * @event core.get_logs_modify_type
         * @var	string	mode		Mode of the entries we display
         * @var	bool	count_logs	Do we count all matching entries?
         * @var	int		limit		Limit the number of entries
         * @var	int		offset		Offset when fetching the entries
         * @var	mixed	forum_id	Limit entries to the forum_id,
         *							can also be an array of forum_ids
         * @var	int		topic_id	Limit entries to the topic_id
         * @var	int		user_id		Limit entries to the user_id
         * @var	int		log_time	Limit maximum age of log entries
         * @var	string	sort_by		SQL order option
         * @var	string	keywords	Will only return entries that have the
         *							keywords in log_operation or log_data
         * @var	string	profile_url	URL to the users profile
         * @var	int		log_type	Limit logs to a certain type. If log_type
         *							is false, no entries will be returned.
         * @var	string	sql_additional	Additional conditions for the entries,
         *								e.g.: 'AND l.forum_id = 1'
         * @since 3.1.0-a1
         */
        $vars = array('mode', 'count_logs', 'limit', 'offset', 'forum_id', 'topic_id', 'user_id', 'log_time', 'sort_by', 'keywords', 'profile_url', 'log_type', 'sql_additional');
        extract($this->dispatcher->trigger_event('core.get_logs_modify_type', compact($vars)));
        if ($log_type === false) {
            $this->last_page_offset = 0;
            return array();
        }
        $sql_keywords = '';
        if (!empty($keywords)) {
            // Get the SQL condition for our keywords
            $sql_keywords = $this->generate_sql_keyword($keywords);
        }
        $get_logs_sql_ary = array('SELECT' => 'l.*, u.username, u.username_clean, u.user_colour', 'FROM' => array($this->log_table => 'l', USERS_TABLE => 'u'), 'WHERE' => 'l.log_type = ' . (int) $log_type . "\n\t\t\t\t\tAND l.user_id = u.user_id\n\t\t\t\t\t{$sql_keywords}\n\t\t\t\t\t{$sql_additional}", 'ORDER_BY' => $sort_by);
        if ($log_time) {
            $get_logs_sql_ary['WHERE'] = 'l.log_time >= ' . (int) $log_time . '
					AND ' . $get_logs_sql_ary['WHERE'];
        }
        /**
         * Modify the query to obtain the logs data
         *
         * @event core.get_logs_main_query_before
         * @var	array	get_logs_sql_ary	The array in the format of the query builder with the query
         *									to get the log count and the log list
         * @var	string	mode				Mode of the entries we display
         * @var	bool	count_logs			Do we count all matching entries?
         * @var	int		limit				Limit the number of entries
         * @var	int		offset				Offset when fetching the entries
         * @var	mixed	forum_id			Limit entries to the forum_id,
         *									can also be an array of forum_ids
         * @var	int		topic_id			Limit entries to the topic_id
         * @var	int		user_id				Limit entries to the user_id
         * @var	int		log_time			Limit maximum age of log entries
         * @var	string	sort_by				SQL order option
         * @var	string	keywords			Will only return entries that have the
         *									keywords in log_operation or log_data
         * @var	string	profile_url			URL to the users profile
         * @var	int		log_type			Limit logs to a certain type. If log_type
         *									is false, no entries will be returned.
         * @var	string	sql_additional		Additional conditions for the entries,
         *									e.g.: 'AND l.forum_id = 1'
         * @since 3.1.5-RC1
         */
        $vars = array('get_logs_sql_ary', 'mode', 'count_logs', 'limit', 'offset', 'forum_id', 'topic_id', 'user_id', 'log_time', 'sort_by', 'keywords', 'profile_url', 'log_type', 'sql_additional');
        extract($this->dispatcher->trigger_event('core.get_logs_main_query_before', compact($vars)));
        if ($count_logs) {
            $count_logs_sql_ary = $get_logs_sql_ary;
            $count_logs_sql_ary['SELECT'] = 'COUNT(l.log_id) AS total_entries';
            unset($count_logs_sql_ary['ORDER_BY']);
            $sql = $this->db->sql_build_query('SELECT', $count_logs_sql_ary);
            $result = $this->db->sql_query($sql);
            $this->entry_count = (int) $this->db->sql_fetchfield('total_entries');
            $this->db->sql_freeresult($result);
            if ($this->entry_count == 0) {
                // Save the queries, because there are no logs to display
                $this->last_page_offset = 0;
                return array();
            }
            // Return the user to the last page that is valid
            while ($this->last_page_offset >= $this->entry_count) {
                $this->last_page_offset = max(0, $this->last_page_offset - $limit);
            }
        }
        $sql = $this->db->sql_build_query('SELECT', $get_logs_sql_ary);
        $result = $this->db->sql_query_limit($sql, $limit, $this->last_page_offset);
        $i = 0;
        $log = array();
        while ($row = $this->db->sql_fetchrow($result)) {
            $row['forum_id'] = (int) $row['forum_id'];
            if ($row['topic_id']) {
                $topic_id_list[] = (int) $row['topic_id'];
            }
            if ($row['reportee_id']) {
                $reportee_id_list[] = (int) $row['reportee_id'];
            }
            $log_entry_data = array('id' => (int) $row['log_id'], 'reportee_id' => (int) $row['reportee_id'], 'reportee_username' => '', 'reportee_username_full' => '', 'user_id' => (int) $row['user_id'], 'username' => $row['username'], 'username_full' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, $profile_url), 'ip' => $row['log_ip'], 'time' => (int) $row['log_time'], 'forum_id' => (int) $row['forum_id'], 'topic_id' => (int) $row['topic_id'], 'viewforum' => $row['forum_id'] && $this->auth->acl_get('f_read', $row['forum_id']) ? append_sid("{$this->src_root_path}viewforum.{$this->php_ext}", 'f=' . $row['forum_id']) : false, 'action' => isset($this->user->lang[$row['log_operation']]) ? $row['log_operation'] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}');
            /**
             * Modify the entry's data before it is returned
             *
             * @event core.get_logs_modify_entry_data
             * @var	array	row			Entry data from the database
             * @var	array	log_entry_data	Entry's data which is returned
             * @since 3.1.0-a1
             */
            $vars = array('row', 'log_entry_data');
            extract($this->dispatcher->trigger_event('core.get_logs_modify_entry_data', compact($vars)));
            $log[$i] = $log_entry_data;
            if (!empty($row['log_data'])) {
                $log_data_ary = unserialize($row['log_data']);
                $log_data_ary = $log_data_ary !== false ? $log_data_ary : array();
                if (isset($this->user->lang[$row['log_operation']])) {
                    // Check if there are more occurrences of % than
                    // arguments, if there are we fill out the arguments
                    // array. It doesn't matter if we add more arguments than
                    // placeholders.
                    $num_args = 0;
                    if (!is_array($this->user->lang[$row['log_operation']])) {
                        $num_args = substr_count($this->user->lang[$row['log_operation']], '%');
                    } else {
                        foreach ($this->user->lang[$row['log_operation']] as $case => $plural_string) {
                            $num_args = max($num_args, substr_count($plural_string, '%'));
                        }
                    }
                    if ($num_args - sizeof($log_data_ary) > 0) {
                        $log_data_ary = array_merge($log_data_ary, array_fill(0, $num_args - sizeof($log_data_ary), ''));
                    }
                    $lang_arguments = array_merge(array($log[$i]['action']), $log_data_ary);
                    $log[$i]['action'] = call_user_func_array(array($this->user, 'lang'), $lang_arguments);
                    // If within the admin panel we do not censor text out
                    if ($this->get_is_admin()) {
                        $log[$i]['action'] = bbcode_nl2br($log[$i]['action']);
                    } else {
                        $log[$i]['action'] = bbcode_nl2br(censor_text($log[$i]['action']));
                    }
                } else {
                    if (!empty($log_data_ary)) {
                        $log[$i]['action'] .= '<br />' . implode('', $log_data_ary);
                    }
                }
                /* Apply make_clickable... has to be seen if it is for good. :/
                			// Seems to be not for the moment, reconsider later...
                			$log[$i]['action'] = make_clickable($log[$i]['action']);
                			*/
            } else {
                $log[$i]['action'] = $this->user->lang($log[$i]['action']);
            }
            $i++;
        }
        $this->db->sql_freeresult($result);
        /**
         * Get some additional data after we got all log entries
         *
         * @event core.get_logs_get_additional_data
         * @var	array	log			Array with all our log entries
         * @var	array	topic_id_list		Array of topic ids, for which we
         *									get the permission data
         * @var	array	reportee_id_list	Array of additional user IDs we
         *									get the username strings for
         * @since 3.1.0-a1
         */
        $vars = array('log', 'topic_id_list', 'reportee_id_list');
        extract($this->dispatcher->trigger_event('core.get_logs_get_additional_data', compact($vars)));
        if (sizeof($topic_id_list)) {
            $topic_auth = $this->get_topic_auth($topic_id_list);
            foreach ($log as $key => $row) {
                $log[$key]['viewtopic'] = isset($topic_auth['f_read'][$row['topic_id']]) ? append_sid("{$this->src_root_path}viewtopic.{$this->php_ext}", 'f=' . $topic_auth['f_read'][$row['topic_id']] . '&amp;t=' . $row['topic_id']) : false;
                $log[$key]['viewlogs'] = isset($topic_auth['m_'][$row['topic_id']]) ? append_sid("{$this->src_root_path}mcp.{$this->php_ext}", 'i=logs&amp;mode=topic_logs&amp;t=' . $row['topic_id'], true, $this->user->session_id) : false;
            }
        }
        if (sizeof($reportee_id_list)) {
            $reportee_data_list = $this->get_reportee_data($reportee_id_list);
            foreach ($log as $key => $row) {
                if (!isset($reportee_data_list[$row['reportee_id']])) {
                    continue;
                }
                $log[$key]['reportee_username'] = $reportee_data_list[$row['reportee_id']]['username'];
                $log[$key]['reportee_username_full'] = get_username_string('full', $row['reportee_id'], $reportee_data_list[$row['reportee_id']]['username'], $reportee_data_list[$row['reportee_id']]['user_colour'], false, $profile_url);
            }
        }
        /**
         * Allow modifying or execute extra final filter on log entries
         *
         * @event core.get_logs_after
         * @var	array	log			Array with all our log entries
         * @var	array	topic_id_list		Array of topic ids, for which we
         *									get the permission data
         * @var	array	reportee_id_list	Array of additional user IDs we
         *									get the username strings for
         * @var	string	mode		Mode of the entries we display
         * @var	bool	count_logs	Do we count all matching entries?
         * @var	int		limit		Limit the number of entries
         * @var	int		offset		Offset when fetching the entries
         * @var	mixed	forum_id	Limit entries to the forum_id,
         *							can also be an array of forum_ids
         * @var	int		topic_id	Limit entries to the topic_id
         * @var	int		user_id		Limit entries to the user_id
         * @var	int		log_time	Limit maximum age of log entries
         * @var	string	sort_by		SQL order option
         * @var	string	keywords	Will only return entries that have the
         *							keywords in log_operation or log_data
         * @var	string	profile_url	URL to the users profile
         * @var	int		log_type	The type of logs it was filtered
         * @since 3.1.3-RC1
         */
        $vars = array('log', 'topic_id_list', 'reportee_id_list', 'mode', 'count_logs', 'limit', 'offset', 'forum_id', 'topic_id', 'user_id', 'log_time', 'sort_by', 'keywords', 'profile_url', 'log_type');
        extract($this->dispatcher->trigger_event('core.get_logs_after', compact($vars)));
        return $log;
    }
Пример #24
0
 /**
  * Replace "error" strings with their real, localized form
  *
  * @param \src\user src User object
  * @param array	$error Array containing error strings
  *        Key values can either be a string with a language key or an array
  *        that will be passed to vsprintf() with the language key in the
  *        first array key.
  *
  * @return array Array containing the localized error strings
  */
 public function localize_errors(\src\user $user, $error)
 {
     foreach ($error as $key => $lang) {
         if (is_array($lang)) {
             $lang_key = array_shift($lang);
             $error[$key] = vsprintf($user->lang($lang_key), $lang);
         } else {
             $error[$key] = $user->lang("{$lang}");
         }
     }
     return $error;
 }
Пример #25
0
/**
* Options to pick a timezone and date/time
*
* @param	\src\template\template $template	src template object
* @param	\src\user	$user				Object of the current user
* @param	string		$default			A timezone to select
* @param	boolean		$truncate			Shall we truncate the options text
*
* @return		array		Returns an array containing the options for the time selector.
*/
function src_timezone_select($template, $user, $default = '', $truncate = false)
{
    static $timezones;
    $default_offset = '';
    if (!isset($timezones)) {
        $unsorted_timezones = src_get_timezone_identifiers($default);
        $timezones = array();
        foreach ($unsorted_timezones as $timezone) {
            $tz = new DateTimeZone($timezone);
            $dt = $user->create_datetime('now', $tz);
            $offset = $dt->getOffset();
            $current_time = $dt->format($user->lang['DATETIME_FORMAT'], true);
            $offset_string = src_format_timezone_offset($offset, true);
            $timezones['UTC' . $offset_string . ' - ' . $timezone] = array('tz' => $timezone, 'offset' => $offset_string, 'current' => $current_time);
            if ($timezone === $default) {
                $default_offset = 'UTC' . $offset_string;
            }
        }
        unset($unsorted_timezones);
        uksort($timezones, 'src_tz_select_compare');
    }
    $tz_select = $opt_group = '';
    foreach ($timezones as $key => $timezone) {
        if ($opt_group != $timezone['offset']) {
            // Generate tz_select for backwards compatibility
            $tz_select .= $opt_group ? '</optgroup>' : '';
            $tz_select .= '<optgroup label="' . $user->lang(array('timezones', 'UTC_OFFSET_CURRENT'), $timezone['offset'], $timezone['current']) . '">';
            $opt_group = $timezone['offset'];
            $template->assign_block_vars('timezone_select', array('LABEL' => $user->lang(array('timezones', 'UTC_OFFSET_CURRENT'), $timezone['offset'], $timezone['current']), 'VALUE' => $key . ' - ' . $timezone['current']));
            $selected = !empty($default_offset) && strpos($key, $default_offset) !== false ? ' selected="selected"' : '';
            $template->assign_block_vars('timezone_date', array('VALUE' => $key . ' - ' . $timezone['current'], 'SELECTED' => !empty($selected), 'TITLE' => $user->lang(array('timezones', 'UTC_OFFSET_CURRENT'), $timezone['offset'], $timezone['current'])));
        }
        $label = $timezone['tz'];
        if (isset($user->lang['timezones'][$label])) {
            $label = $user->lang['timezones'][$label];
        }
        $title = $user->lang(array('timezones', 'UTC_OFFSET_CURRENT'), $timezone['offset'], $label);
        if ($truncate) {
            $label = truncate_string($label, 50, 255, false, '...');
        }
        // Also generate timezone_select for backwards compatibility
        $selected = $timezone['tz'] === $default ? ' selected="selected"' : '';
        $tz_select .= '<option title="' . $title . '" value="' . $timezone['tz'] . '"' . $selected . '>' . $label . '</option>';
        $template->assign_block_vars('timezone_select.timezone_options', array('TITLE' => $title, 'VALUE' => $timezone['tz'], 'SELECTED' => !empty($selected), 'LABEL' => $label));
    }
    $tz_select .= '</optgroup>';
    return $tz_select;
}
Пример #26
0
 function get_passworded_forums()
 {
     return $this->user->get_passworded_forums();
 }
Пример #27
0
 /**
  * Returns the language string of a permission
  *
  * @param	string	$permission	Identifier of the permission
  * @return	string	Language string
  */
 public function get_permission_lang($permission)
 {
     return isset($this->permissions[$permission]['lang']) ? $this->user->lang($this->permissions[$permission]['lang']) : $this->user->lang('ACL_' . strtoupper($permission));
 }
Пример #28
0
 /**
  * Output all the notification methods to the template
  *
  * @param \src\notification\manager $src_notifications
  * @param \src\template\template $template
  * @param \src\user $user
  * @param string $block
  */
 public function output_notification_methods(\src\notification\manager $src_notifications, \src\template\template $template, \src\user $user, $block = 'notification_methods')
 {
     $notification_methods = $src_notifications->get_subscription_methods();
     foreach ($notification_methods as $method => $method_data) {
         $template->assign_block_vars($block, array('METHOD' => $method_data['id'], 'NAME' => $user->lang($method_data['lang'])));
     }
 }