PluginProbe
wpForo Forum / 1.4.13
wpForo Forum v1.4.13
3.1.5 3.1.4 3.1.2 3.1.1 3.1.0 3.0.9 3.0.8 3.0.7 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 1.4.13 1.4.2 All 137 releases
wpforo / wpf-includes / class-template.php

class-template.php in wpForo Forum 1.4.13, at wpf-includes/class-template.php

2,147 lines 109.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // Exit if accessed directly
3 if( !defined( 'ABSPATH' ) ) exit;
4
5 define('WPFORO_THEME_DIR', WPFORO_DIR . '/wpf-themes' );
6 define('WPFORO_THEME_URL', WPFORO_URL . '/wpf-themes' );
7
8 class wpForoTemplate{
9 public $default;
10 public $options;
11 public $style;
12 public $theme;
13
14 function __construct(){
15 $this->init_defaults();
16 $this->init_options();
17 }
18
19 public function init(){
20 $this->init_hooks();
21 $this->init_member_templates();
22 $this->init_nav_menu();
23 }
24
25 private function init_hooks(){
26 if( is_wpforo_page() ){
27 add_filter("mce_external_plugins", array($this, 'add_tinymce_buttons'), 15);
28 add_filter("tiny_mce_plugins", array($this, 'filter_tinymce_plugins'), 15);
29 add_filter("wp_mce_translation", array($this, 'add_tinymce_translations'));
30
31 add_action('wp_footer', array($this, 'add_footer_html'), 999999, 0);
32
33 //ajax actions hooks
34 add_action('wp_ajax_wpforo_active_tab_content_ajax', array($this, 'ajx_active_tab_content'));
35 }
36 }
37
38 private function init_defaults(){
39 $this->default = new stdClass;
40
41 $this->default->style = array(
42 'font_size_forum' => 17,
43 'font_size_topic' => 16,
44 'font_size_post_content' => 14,
45 'custom_css' => "#wpforo-wrap {\r\n font-size: 13px; width: 100%; padding:10px 20px; margin:0px;\r\n}\r\n"
46 );
47
48 $theme = $this->find_theme( 'classic' );
49 if( $current_theme = get_option('wpforo_theme_options') ) $theme = wpforo_deep_merge($theme, $current_theme);
50 $this->default->options = $theme;
51 }
52
53 private function init_options(){
54 $this->style = get_wpf_option('wpforo_style_options', $this->default->style);
55
56 $this->options = get_wpf_option('wpforo_theme_options', $this->default->options);
57 $this->theme = $this->options['folder'];
58
59 $this->init_defines();
60 }
61
62 private function init_defines(){
63 define('WPFORO_THEME', $this->theme );
64 define('WPFORO_TEMPLATE_DIR', WPFORO_THEME_DIR . '/' . $this->theme );
65 define('WPFORO_TEMPLATE_URL', WPFORO_THEME_URL . '/' . $this->theme );
66 }
67
68 function add_tinymce_buttons($plugin_array) {
69 $plugin_array = array();
70 $plugin_array['wpforo_pre_button'] = WPFORO_URL . '/wpf-assets/js/tinymce-pre.js';
71 $plugin_array['wpforo_link_button'] = WPFORO_URL . '/wpf-assets/js/tinymce-link.js';
72 $plugin_array['wpforo_source_code_button'] = WPFORO_URL . '/wpf-assets/js/tinymce-code.js';
73 $plugin_array['emoticons'] = WPFORO_URL . '/wpf-assets/js/tinymce-emoji.js';
74 return $plugin_array;
75 }
76
77 function filter_tinymce_plugins($plugins){
78 return array('hr','lists','textcolor','paste');
79 }
80
81 function add_tinymce_translations($mce_translation){
82 $mce_translation['Insert link'] = __( 'Insert link' );
83 $mce_translation['Link Text'] = __( 'Link Text' );
84 $mce_translation['Open link in a new tab'] = __( 'Open link in a new tab' );
85 return $mce_translation;
86 }
87
88 function topic_form($forumid){
89 if(!isset(WPF()->post->options['max_upload_size']) || !WPF()->post->options['max_upload_size']){ $server_mus = wpforo_human_size_to_bytes(ini_get('upload_max_filesize')); if( !$server_mus || $server_mus > 10485760 ) $server_mus = 10485760; WPF()->post->options['max_upload_size'] = $server_mus;}
90 ?>
91 <div id="wpf-topic-create" class="wpf-topic-create">
92 <form name="topic" action="" enctype="multipart/form-data" method="POST">
93 <?php wp_nonce_field( 'wpforo_verify_form', 'wpforo_form' ); ?>
94 <input type="hidden" name="topic[action]" value="add"/>
95 <input type="hidden" id="wpf_parent" name="topic[forumid]" value="<?php echo intval($forumid) ?>" />
96
97 <?php if(!is_user_logged_in()): ?>
98 <?php $guest = WPF()->member->get_guest_cookies(); ?>
99 <div class="wpf-topic-guest-fields">
100 <div class="wpf-topic-guest-name">
101 <label style="padding-left:8px;"> <?php wpforo_phrase('Author Name') ?> * </label>
102 <input id="wpf_user_name" type="text" placeholder="<?php esc_attr( wpforo_phrase('Your name') ) ?>" name="topic[name]" value="<?php echo esc_attr($guest['name']) ?>" />
103 </div>
104 <div class="wpf-topic-guest-email">
105 <label style="padding-left:8px;"> <?php wpforo_phrase('Author Email') ?> * </label>
106 <input id="wpf_user_email" type="text" placeholder="<?php esc_attr( wpforo_phrase('Your email') ) ?>" name="topic[email]" value="<?php echo esc_attr($guest['email']) ?>" />
107 </div>
108 <div class="wpf-clear"></div>
109 </div>
110 <?php endif; ?>
111
112 <label style="padding-left:8px;"> <?php wpforo_phrase('Topic Title') ?> * </label>
113 <input id="wpf_title" class="wpf-subject" type="text" name="topic[title]" autocomplete="off" required autofocus placeholder="<?php esc_attr( wpforo_phrase('Enter title here') ) ?>">
114 <?php
115 $content = '';
116 $editor_id = 'postbody';
117 $settings = array(
118 'wpautop' => true,// use wpautop?
119 'media_buttons'=> FALSE,// show insert / upload button(s)
120 'textarea_name'=> $editor_id,// set the textarea name to something different, square brackets [] can be used here
121 'textarea_rows'=> get_option('default_post_edit_rows', 20),// rows = "..."
122 'tabindex'=> '',
123 'editor_height' => '180',
124 'editor_css' => '', // intended for extra styles for both visual and HTML editors buttons, needs to include the < style > tags, can use "scoped".
125 'editor_class'=> '', // add extra class(es) to the editor textarea
126 'teeny'=> FALSE, // output the minimal editor config used in Press This
127 'dfw'=> false, // replace the default fullscreen with DFW (supported on the front - end in WordPress 3.4)
128 'tinymce'=> array(
129 'toolbar1' => 'fontsizeselect,bold,italic,underline,strikethrough,forecolor,bullist,numlist,hr,alignleft,aligncenter,alignright,alignjustify,link,unlink,blockquote,pre,undo,redo,pastetext,source_code,emoticons',
130 'toolbar2' => '',
131 'toolbar3' => '',
132 'toolbar4' => '',
133 'content_style' => 'blockquote{border: #cccccc 1px dotted; background: #F7F7F7; padding:10px;font-size:12px; font-style:italic; margin: 20px 10px;}',
134 'object_resizing' => false
135 ), // load TinyMCE, can be used to pass settings directly to TinyMCE using an array()
136 'quicktags'=> true, // load Quicktags, can be used to pass settings directly to Quicktags using an array()
137 'default_editor' => 'tinymce'
138 );
139 wp_editor( $content, $editor_id, $settings );
140 ?>
141 <div class="wpf-extra-fields">
142 <?php do_action('wpforo_topic_form_extra_fields_before') ?>
143 <div class="wpf-main-fields">
144 <?php if(WPF()->perm->forum_can('s', $forumid)) : ?>
145 <input id="wpf_t_sticky" name="topic[type]" type="checkbox" value="1">&nbsp;&nbsp;
146 <i class="fas fa-exclamation wpfsx"></i>&nbsp;&nbsp;<label for="wpf_t_sticky" style="padding-bottom:2px; cursor: pointer;"><?php wpforo_phrase('Set Topic Sticky'); ?>&nbsp;</label>
147 <span class="wpfbs">&nbsp;&nbsp;|&nbsp;&nbsp;</span>
148 <?php endif; ?>
149 <?php if(WPF()->perm->forum_can('p', $forumid) || WPF()->perm->forum_can('op', $forumid)) : ?>
150 <input id="wpf_t_private" name="topic[private]" type="checkbox" value="1">&nbsp;&nbsp;
151 <i class="fas fa-eye-slash wpfsx"></i>&nbsp;&nbsp;<label for="wpf_t_private" style="padding-bottom:2px; cursor: pointer;" title="<?php wpforo_phrase('Only Admins and Moderators can see your private topics.'); ?>"><?php wpforo_phrase('Private Topic'); ?>&nbsp;</label>
152
153 <?php endif; ?>
154 <?php do_action('wpforo_topic_form_buttons_hook'); ?>&nbsp;&nbsp;
155 </div>
156 <?php if( WPF()->perm->can_attach() ): ?>
157 <?php if(!defined('WPFOROATTACH_BASENAME') && WPF()->perm->forum_can('a', $forumid)): ?>
158 <div class="wpf-default-attachment" style="padding-top:5px;">
159 <label for="wpf_file"><?php wpforo_phrase('Attach file:') ?> </label> <input id="wpf_file" type="file" name="attachfile" />
160 <p><?php wpforo_phrase('Maximum allowed file size is'); echo ' ' . wpforo_print_size(WPF()->post->options['max_upload_size']); ?></p>
161 </div>
162 <?php endif; ?>
163 <?php endif; ?>
164 <?php do_action('wpforo_topic_form_extra_fields_after') ?>
165 </div>
166 <?php if( wpforo_feature('subscribe_checkbox_on_post_editor') ) : ?>
167 <div class="wpf-topic-sbs"><input id="wpf-topic-sbs" type="checkbox" name="wpforo_topic_subs" value="1" <?php echo ( wpforo_feature('subscribe_checkbox_default_status') ) ? 'checked="true" ' : ''; ?>/>&nbsp;<label for="wpf-topic-sbs"><?php wpforo_phrase('Subscribe to this topic') ?></label></div>
168 <?php endif; ?>
169 <?php do_action('wpforo_editor_topic_submit_before', $forumid) ?>
170 <input id="wpf_formbutton" type="submit" name="topic[save]" class="button button-primary forum_submit" value="<?php wpforo_phrase('Add Topic') ?>">
171 <?php do_action('wpforo_editor_topic_submit_after', $forumid) ?>
172 <div class="wpf-clear"></div>
173 </form>
174 </div>
175
176 <?php
177 }
178
179 /**
180 *
181 * @param array $args
182 *
183 * Please note that all array elements are required!
184 * example of args
185 * $default = array(
186 * "topic_closed" => $topic['closed'], // is topic closed or opened (values 1 or 0)
187 * "topicid" => $topic['topicid'], // the id of topic
188 * "forumid" => $forum_data['forumid'],
189 * "layout" => $cat_layout,
190 * "topic_title" => $topic['title'] // the title of topic
191 * );
192 *
193 * @return html form
194 */
195
196 function reply_form($args){
197 extract($args, EXTR_OVERWRITE); ?>
198 <!-- Report Dialog -->
199
200 <div id="wpf_reportdialog" title="<?php esc_attr( wpforo_phrase('Report to Administration') ) ?>" style="display: none">
201 <form id="wpf_reportform">
202 <input type="hidden" id="wpf_reportpostid" value=""/>
203 <textarea required style="width:100%; height:105px;" id="wpf_reportmessagecontent" placeholder="<?php esc_attr( wpforo_phrase('Write message') ) ?>"></textarea>
204 </form>
205 <input style="float: right;" id="wpf_sendreport" type="submit" value="<?php wpforo_phrase('Send Report') ?>"/>
206 </div>
207
208 <!-- Report Dialog end -->
209 <?php
210 if( $topic_closed ) return;
211
212 $head_html = '<p id="wpf-reply-form-title">'.wpforo_phrase('Leave a reply', false).'</p>';
213 $head_html = apply_filters( 'wpforo_reply_form_head', $head_html, $args );
214 if(!isset(WPF()->post->options['max_upload_size']) || !WPF()->post->options['max_upload_size']){$server_mus = wpforo_human_size_to_bytes(ini_get('upload_max_filesize')); if( !$server_mus || $server_mus > 10485760 ) $server_mus = 10485760; WPF()->post->options['max_upload_size'] = $server_mus;}
215 ?>
216 <div id="wpf-form-wrapper">
217 <?php echo $head_html; //this is a HTML content ?>
218 <div id="wpf-post-create" class="wpf-post-create">
219 <form name="post" action="" enctype="multipart/form-data" method="POST" class="editor">
220 <?php wp_nonce_field( 'wpforo_verify_form', 'wpforo_form' ); ?>
221 <input type="hidden" id="wpf_formaction" name="post[action]" value="add"/>
222 <input type="hidden" id="wpf_formtopicid" name="post[topicid]" value="<?php echo intval($topicid) ?>"/>
223 <input type="hidden" id="wpf_postparentid" name="post[parentid]" value="0"/>
224 <input type="hidden" id="wpf_formpostid" name="post[postid]" value=""/>
225 <input type="hidden" id="wpf_parent" name="post[forumid]" value="<?php echo intval($forumid) ?>" />
226 <?php if(!is_user_logged_in()): ?>
227 <?php $guest = WPF()->member->get_guest_cookies(); ?>
228 <div class="wpf-post-guest-fields">
229 <div class="wpf-post-guest-name">
230 <label style="padding-left:8px;"> <?php wpforo_phrase('Author Name') ?> * </label>
231 <input id="wpf_user_name" type="text" placeholder="<?php esc_attr( wpforo_phrase('Your name') ) ?>" name="post[name]" value="<?php echo esc_attr($guest['name']) ?>" />
232 </div>
233 <div class="wpf-post-guest-email">
234 <label style="padding-left:8px;"> <?php wpforo_phrase('Author Email') ?> * </label>
235 <input id="wpf_user_email" type="text" placeholder="<?php esc_attr( wpforo_phrase('Your email') ) ?>" name="post[email]" value="<?php echo esc_attr($guest['email']) ?>" />
236 </div>
237 <div class="wpf-clear"></div>
238 </div>
239 <label style="padding-left:8px;"> <?php wpforo_phrase('Post Title') ?> * </label>
240 <?php endif; ?>
241 <?php
242 $reply_title = wpforo_phrase('RE', false) . ': '. $topic_title;
243 $reply_title = apply_filters( 'wpforo_reply_form_field_title', $reply_title, $args );
244 $reply_title = esc_attr($reply_title);
245 ?>
246 <input id="wpf_title" required="true" type="text" name="post[title]" class="wpf-subject" value="<?php if($reply_title) echo esc_attr($reply_title); ?>" autocomplete="off" placeholder="<?php if($reply_title) echo esc_attr($reply_title); ?>"><br/>
247 <?php
248 $content = '';
249 $editor_id = 'postbody';
250 $settings = array(
251 'wpautop' => true,// use wpautop?
252 'media_buttons'=> FALSE,// show insert / upload button(s)
253 'textarea_name'=> $editor_id,// set the textarea name to something different, square brackets [] can be used here
254 'textarea_rows'=> get_option('default_post_edit_rows', 5),// rows = "..."
255 'editor_class'=> 'wpeditor', // add extra class(es) to the editor textarea
256 'teeny'=> false, // output the minimal editor config used in Press This
257 'dfw'=> false, // replace the default fullscreen with DFW (supported on the front - end in WordPress 3.4)
258 'editor_height' => '180',
259 'tinymce'=> array(
260 'toolbar1' => 'fontsizeselect,bold,italic,underline,strikethrough,forecolor,bullist,numlist,hr,alignleft,aligncenter,alignright,alignjustify,link,unlink,blockquote,pre,undo,redo,pastetext,source_code,emoticons',
261 'toolbar2' => '',
262 'toolbar3' => '',
263 'toolbar4' => '',
264 'content_style' => 'blockquote{border: #cccccc 1px dotted; background: #F7F7F7; padding:10px;font-size:12px; font-style:italic; margin: 20px 10px;}',
265 'object_resizing' => false
266 ), // load TinyMCE, can be used to pass settings directly to TinyMCE using an array()
267 'quicktags'=> true, // load Quicktags, can be used to pass settings directly to Quicktags using an array()
268 'default_editor' => 'tinymce', // load Quicktags, can be used to pass settings directly to Quicktags using an array()
269 );
270 wp_editor( $content, $editor_id, $settings );
271 ?>
272 <div class="wpf-extra-fields">
273 <?php do_action('wpforo_reply_form_extra_fields_before') ?>
274 <?php do_action('wpforo_reply_form_buttons_hook'); ?>&nbsp;&nbsp;
275 <?php if( WPF()->perm->can_attach() ): ?>
276 <?php if(!defined('WPFOROATTACH_BASENAME') && WPF()->perm->forum_can('a', $forumid)): ?>
277 <div class="wpf-default-attachment">
278 <label for="wpf_file"><?php wpforo_phrase('Attach file:') ?> </label> <input id="wpf_file" type="file" name="attachfile" />
279 <p><?php wpforo_phrase('Maximum allowed file size is'); echo ' ' . wpforo_print_size(WPF()->post->options['max_upload_size']); ?></p>
280 </div>
281 <?php endif; ?>
282 <?php endif; ?>
283 <?php do_action('wpforo_reply_form_extra_fields_after') ?>
284 </div>
285 <?php if( wpforo_feature('subscribe_checkbox_on_post_editor') ) :
286 $args = array( "userid" => WPF()->current_userid , "itemid" => intval($topicid), "type" => "topic" );
287 $subscribe = WPF()->sbscrb->get_subscribe( $args );
288 if( !isset($subscribe['subid']) ) : ?>
289 <div class="wpf-topic-sbs"><input id="wpf-topic-sbs" type="checkbox" name="wpforo_topic_subs" value="1" <?php echo ( wpforo_feature('subscribe_checkbox_default_status') ) ? 'checked="true" ' : ''; ?> />&nbsp;<label for="wpf-topic-sbs"><?php wpforo_phrase('Subscribe to this topic') ?></label></div>
290 <?php endif;
291 endif; ?>
292 <?php do_action('wpforo_editor_post_submit_before', $args) ?>
293 <input id="wpf_formbutton" type="submit" name="post[save]" class="button button-primary forum_submit" value="<?php wpforo_phrase('Add Reply') ?>">
294 <?php do_action('wpforo_editor_post_submit_after', $args) ?>
295 <div class="wpf-clear"></div>
296 </form>
297 </div>
298 </div>
299 <?php
300 }
301
302 public function topic_moderation_tabs($tabs = array()){
303 $tabs = apply_filters('wpforo_topic_moderation_tabs', $tabs);
304 if(!$tabs) return;
305 $default_tab = array('title' => '', 'id' => '', 'class' => '', 'icon' => '', 'active' => false);
306 ?>
307 <div class="wpf-tool-tabs">
308 <?php foreach ($tabs as $tab) : $tab = wpforo_parse_args($tab, $default_tab); ?>
309 <div id="<?php echo esc_attr($tab['id']) ?>" class="wpf-tool-tab <?php echo $tab['class']; echo ($tab['active'] ? ' wpf-tt-active' : ''); ?>">
310 <i class="<?php echo $tab['icon'] ?>"></i>&nbsp;
311 <?php echo $tab['title'] ?>
312 </div>
313 <?php endforeach; ?>
314 </div>
315 <div id="wpf_tool_tab_content_wrap">
316 <i class="fas fa-spinner fa-spin wpf-icon-spinner"></i>
317 </div>
318 <?php
319 }
320
321 private function topic_merge_form(){
322 ?>
323 <div class="wpf-tool wpf-tool-merge">
324 <h3><i class="fas fa-code-branch"></i></h3>
325 <div class="wpf-cl"></div>
326 <form method="post" enctype="multipart/form-data" action="">
327 <?php wp_nonce_field( 'wpforo_verify_form', 'wpforo_form' ); ?>
328 <ul>
329 <li class="wpf-target-topic">
330 <label for="target-topic" class="wpf-input-label"><?php wpforo_phrase('Target Topic URL') ?> <sup>*</sup></label>
331 <div class="wpf-tool-desc">
332 <?php wpforo_phrase('Please copy the target topic URL from browser address bar and paste in the field below.') ?><br/>
333 </div>
334 <input id="target-topic" type="text" required name="wpforo[target_topic_url]" value="" placeholder="http://example.com/community/main-forum/target-topic/" />
335 <div class="wpf-tool-desc" style="margin: 15px 1px 0px 1px;">
336 <?php wpforo_phrase('All posts will be merged and displayed (ordered) in target topic according to posts dates. If you want to append merged posts to the end of the target topic you should allow to update posts dates to current date by check the option below.') ?>
337 </div>
338 </li>
339 <li class="wpf-update-date-and-append"><input id="update-date-and-append" type="checkbox" name="wpforo[update_date_and_append]" value="1" /> <label for="update-date-and-append"><?php wpforo_phrase('Update post dates (current date) to allow append posts to the end of the target topic.') ?></label></li>
340 <li class="wpf-update-to-target-title"><input id="update-to-target-title" type="checkbox" name="wpforo[to_target_title]" value="1" checked /> <label for="update-to-target-title"><?php wpforo_phrase('Update post titles with target topic title.') ?></label></li>
341 <li><i class="fas fa-info-circle wpfcl-5" style="font-size: 16px;"></i> &nbsp;<?php wpforo_phrase('Topics once merged cannot be unmerged. This topic URL will no longer be available.') ?></li>
342 <li class="wpf-submit"><input type="submit" name="wpforo[topic_merge]" value="<?php wpforo_phrase('Merge') ?>"></li>
343 </ul>
344 </form>
345 </div>
346 <?php
347 }
348
349 private function reply_move_form(){
350 if( !$posts = WPF()->post->get_posts( array('topicid' => WPF()->current_object['topicid']) ) ) return;
351 if( count($posts) < 2 ) return;
352 ?>
353 <div class="wpf-tool wpf-tool-split">
354 <h3><i class="far fa-share-square"></i></h3>
355 <div class="wpf-cl"></div>
356 <form id="wpforo_split_form" method="post" enctype="multipart/form-data" action="">
357 <?php wp_nonce_field( 'wpforo_verify_form', 'wpforo_form' ); ?>
358 <ul>
359 <li id="wpf_split_target_url" class="wpf-target-topic">
360 <label for="spl-target-url" class="wpf-input-label"><?php wpforo_phrase('Target Topic URL') ?> <sup>*</sup></label>
361 <div class="wpf-tool-desc">
362 <?php wpforo_phrase('Please copy the target topic URL from browser address bar and paste in the field below.') ?><br/>
363 </div>
364 <input id="spl-target-url" type="text" name="wpforo[target_topic_url]" required placeholder="http://example.com/community/main-forum/target-topic/" />
365 <div class="wpf-tool-desc" style="margin: 15px 1px 0px 1px;">
366 <?php wpforo_phrase('All posts will be merged and displayed (ordered) in target topic according to posts dates. If you want to append merged posts to the end of the target topic you should allow to update posts dates to current date by check the option below.') ?>
367 </div>
368 </li>
369 <li id="wpf_split_append">
370 <input id="spl-update-date-and-append" type="checkbox" name="wpforo[update_date_and_append]" value="1" />
371 <label for="spl-update-date-and-append"><?php wpforo_phrase('Update post dates (current date) to allow append posts to the end of the target topic.') ?></label>
372 </li>
373 <li>
374 <input id="split-update-to-target-title" type="checkbox" name="wpforo[to_target_title]" value="1" checked />
375 <label for="split-update-to-target-title"><?php wpforo_phrase('Update post titles with target topic title.') ?></label>
376 </li>
377 <li>
378 <label class="wpf-input-label"><?php wpforo_phrase('Select Posts to Split') ?> <sup>*</sup></label>
379 <div class="wpf-split-posts">
380 <ul>
381 <?php foreach ($posts as $post) : ?>
382 <li>
383 <label title="<?php wpforo_text($post['body'], 200); ?>"><input type="checkbox" name="wpforo[posts][]" value="<?php echo $post['postid'] ?>" /><?php wpforo_text($post['body'], 100); ?></label>
384 </li>
385 <?php endforeach; ?>
386 </ul>
387 </div>
388 </li>
389 <li style="padding-top: 10px;"><i class="fas fa-info-circle wpfcl-5" style="font-size: 16px;"></i> &nbsp;<?php wpforo_phrase('Topic once split cannot be unsplit. The first post of new topic becomes the earliest reply.') ?></li>
390 <li class="wpf-submit"><input type="submit" name="wpforo[topic_split]" value="<?php wpforo_phrase('Move') ?>"></li>
391 </ul>
392 </form>
393 </div>
394 <?php
395 }
396
397
398 private function topic_split_form(){
399 if( !$posts = WPF()->post->get_posts( array('topicid' => WPF()->current_object['topicid']) ) ) return;
400 if( count($posts) < 2 ) return;
401 ?>
402 <div class="wpf-tool wpf-tool-split">
403 <h3><i class="fas fa-cut"></i></h3>
404 <div class="wpf-cl"></div>
405 <form id="wpforo_split_form" method="post" enctype="multipart/form-data" action="">
406 <?php wp_nonce_field( 'wpforo_verify_form', 'wpforo_form' ); ?>
407 <ul>
408 <li>
409 <input id="wpf_split_create_new" type="checkbox" name="wpforo[create_new]" value="1" checked>
410 <label for="wpf_split_create_new" class="wpf-input-label" style="display: inline-block;"><?php wpforo_phrase('Create New Topic') ?></label>
411 <div class="wpf-tool-desc">
412 <?php wpforo_phrase('Create new topic with split posts. The first post of new topic becomes the earliest reply.') ?><br/>
413 </div>
414 </li>
415 <li id="wpf_split_target_url" class="wpf-target-topic" style="display: none;">
416 <label for="spl-target-url" class="wpf-input-label"><?php wpforo_phrase('Target Topic URL') ?> <sup>*</sup></label>
417 <div class="wpf-tool-desc">
418 <?php wpforo_phrase('Please copy the target topic URL from browser address bar and paste in the field below.') ?><br/>
419 </div>
420 <input id="spl-target-url" type="text" name="wpforo[target_topic_url]" required disabled placeholder="http://example.com/community/main-forum/target-topic/" />
421 <div class="wpf-tool-desc" style="margin: 15px 1px 0px 1px;">
422 <?php wpforo_phrase('All posts will be merged and displayed (ordered) in target topic according to posts dates. If you want to append merged posts to the end of the target topic you should allow to update posts dates to current date by check the option below.') ?>
423 </div>
424 </li>
425 <li id="wpf_split_append" style="display: none;">
426 <input id="spl-update-date-and-append" type="checkbox" name="wpforo[update_date_and_append]" value="1" />
427 <label for="spl-update-date-and-append"><?php wpforo_phrase('Update post dates (current date) to allow append posts to the end of the target topic.') ?></label>
428 </li>
429 <li id="wpf_split_new_title">
430 <label for="spl-topic-title" class="wpf-input-label"><?php wpforo_phrase('New Topic Title') ?> <sup>*</sup></label>
431 <input id="spl-topic-title" type="text" name="wpforo[new_topic_title]" required placeholder="<?php wpforo_phrase('Topic Title') ?>" />
432 </li>
433 <li id="wpf_split_forumid"><label for="spl-topic-forum" class="wpf-input-label"><?php wpforo_phrase('New Topic Forum') ?> <sup>*</sup></label>
434 <select id="spl-topic-forum" name="wpforo[new_topic_forumid]"><?php WPF()->forum->tree('select_box', false, WPF()->current_object['forumid'] ) ?></select></li>
435 <li>
436 <input id="split-update-to-target-title" type="checkbox" name="wpforo[to_target_title]" value="1" checked />
437 <label for="split-update-to-target-title"><?php wpforo_phrase('Update post titles with target topic title.') ?></label>
438 </li>
439 <li>
440 <label class="wpf-input-label"><?php wpforo_phrase('Select Posts to Split') ?> <sup>*</sup></label>
441 <div class="wpf-split-posts">
442 <ul>
443 <?php foreach ($posts as $post) : ?>
444 <li>
445 <label title="<?php wpforo_text($post['body'], 200); ?>"><input type="checkbox" name="wpforo[posts][]" value="<?php echo $post['postid'] ?>" /><?php wpforo_text($post['body'], 100); ?></label>
446 </li>
447 <?php endforeach; ?>
448 </ul>
449 </div>
450 </li>
451 <li style="padding-top: 10px;"><i class="fas fa-info-circle wpfcl-5" style="font-size: 16px;"></i> &nbsp;<?php wpforo_phrase('Topic once split cannot be unsplit. The first post of new topic becomes the earliest reply.') ?></li>
452 <li class="wpf-submit"><input type="submit" name="wpforo[topic_split]" value="<?php wpforo_phrase('Split') ?>"></li>
453 </ul>
454 </form>
455 </div>
456 <?php
457 }
458
459 private function topic_move_form($topicid = NULL){
460 if(!$topicid && empty(WPF()->current_object['topicid'])) return;
461 if(!$topicid) $topicid = WPF()->current_object['topicid'];
462 ?>
463 <div class="wpf-tool wpf-tool-split">
464 <h3><i class="far fa-share-square"></i></h3>
465 <div class="wpf-cl"></div>
466 <form id="wpf_topicmoveform" method="POST" enctype="multipart/form-data" action="">
467 <ul>
468 <li>
469 <div id="wpf_movedialog" title="<?php esc_attr(wpforo_phrase('Move topic')) ?>">
470 <div class="form-field">
471 <label for="parent"></label>
472 <label for="spl-target-url" class="wpf-input-label"
473 style="padding-bottom: 7px;"><?php wpforo_phrase('Choose Target Forum') ?>
474 <sup>*</sup></label>
475
476 <?php wp_nonce_field('wpforo_verify_form', 'wpforo_form'); ?>
477 <input type="hidden" name="movetopicid" value="<?php echo intval($topicid) ?>"/>
478 <input type="hidden" name="post[save]" value="move"/>
479 <select id="wpf_parent" name="topic[forumid]" class="postform">
480 <?php WPF()->forum->tree('select_box', FALSE); ?>
481 </select>
482
483 </div>
484 </div>
485 </li>
486 <li style="padding-top: 20px;"><i class="fas fa-info-circle wpfcl-5" style="font-size: 16px;"></i>
487 &nbsp;<?php wpforo_phrase('This action changes topic URL. Once the topic is moved to other forum the old URL of this topic will no longer be available.') ?>
488 </li>
489 <li class="wpf-submit"><input type="submit" value="<?php wpforo_phrase('Move') ?>"/></li>
490 </ul>
491 </form>
492 </div>
493 <?php
494 }
495
496 function pagenavi($paged, $items_count, $permalink = TRUE, $class = ''){
497 $items_per_page = ( WPF()->current_object['template'] == 'topic' ? WPF()->post->options['topics_per_page'] : WPF()->post->options['posts_per_page'] );
498 if($items_count <= $items_per_page) return;
499
500 $pages_count = ceil($items_count/$items_per_page);
501
502 $current_url = ( WPF()->current_url ? WPF()->current_url : wpforo_get_request_uri() );
503 if($permalink){
504 $url = trim( preg_replace('#\/paged\/[\d]+\/*.*$#is', '', $current_url), '/' ) . '/paged/';
505 }else{
506 $url = trim( preg_replace('#[\&\?]wpfpaged=[\d]*.*$#is', '', $current_url), '/' );
507 $url .= (strpos($url, '?') === FALSE ? '?' : '&') . 'wpfpaged=';
508 }
509 ?>
510
511 <div class="wpf-navi <?php echo esc_attr($class) ?>">
512 <div class="wpf-navi-wrap">
513 <span class="wpf-page-info"><?php wpforo_phrase('Page') ?> <?php echo intval($paged) ?> / <?php echo intval($pages_count) ?></span>
514 <?php if( $paged - 1 > 0 ): ?><a href="<?php echo esc_url($url) . ($paged - 1) ?>" class="wpf-prev-button"><i class="fas fa-chevron-left fa-sx"></i> <?php wpforo_phrase('prev') ?></a><?php endif ?>
515 <select class="wpf-navi-dropdown" onchange="if (this.value) window.location.href=this.value" title="<?php esc_attr( wpforo_phrase('Select Page') ) ?>">
516 <?php for($i = 1; $i <= $pages_count; $i++) : ?>
517 <option value="<?php echo esc_url($url) . $i ?>" <?php echo $paged == $i ? ' selected="selected"' : '' ?>><?php echo intval($i); ?></option>
518 <?php endfor; ?>
519 </select>
520 <?php if( $paged + 1 <= $pages_count ): ?><a href="<?php echo esc_url($url) . ($paged + 1) ?>" class="wpf-prev-button"><?php wpforo_phrase('next') ?> <i class="fas fa-chevron-right fa-sx"></i></a><?php endif ?>
521 </div>
522 </div>
523
524 <?php
525 }
526
527 function likers($postid){
528 if(!$postid) return '';
529
530 $l_count = wpforo_post($postid, 'likes_count');
531 $l_usernames = wpforo_post($postid, 'likers_usernames');
532 $return = '';
533
534 if( $l_count ){
535 if($l_usernames[0]['ID'] == WPF()->current_userid) $l_usernames[0]['display_name'] = wpforo_phrase('You', FALSE);
536 if($l_count == 1){
537 $return = sprintf( wpforo_phrase('%s liked', FALSE), '<a href="' . esc_url(WPF()->member->get_profile_url($l_usernames[0]['ID'])) . '">'.esc_html($l_usernames[0]['display_name']).'</a>' );
538 }elseif($l_count == 2){
539 $return = sprintf( wpforo_phrase('%s and %s liked', FALSE), '<a href="' . esc_url(WPF()->member->get_profile_url($l_usernames[0]['ID'])) . '">'.esc_html($l_usernames[0]['display_name']).'</a>', '<a href="'.esc_url(WPF()->member->get_profile_url($l_usernames[1]['ID'])).'">'.esc_html($l_usernames[1]['display_name']).'</a>' );
540 }elseif($l_count == 3){
541 $return = sprintf( wpforo_phrase('%s, %s and %s liked', FALSE), '<a href="' . esc_url(WPF()->member->get_profile_url($l_usernames[0]['ID'])) .'">'.esc_html($l_usernames[0]['display_name']).'</a>', '<a href="'.esc_url(WPF()->member->get_profile_url($l_usernames[1]['ID'])).'">'.esc_html($l_usernames[1]['display_name']).'</a>', '<a href="'.esc_url(WPF()->member->get_profile_url($l_usernames[2]['ID'])).'">'.esc_html($l_usernames[2]['display_name']).'</a>' );
542 }elseif($l_count >= 4){
543 $l_count = $l_count - 3;
544 $return = sprintf( wpforo_phrase('%s, %s, %s and %d people liked', FALSE), '<a href="' . esc_url(WPF()->member->get_profile_url($l_usernames[0]['ID'])) .'">'.esc_html($l_usernames[0]['display_name']).'</a>', '<a href="'.esc_url(WPF()->member->get_profile_url($l_usernames[1]['ID'])).'">'.esc_html($l_usernames[1]['display_name']).'</a>', '<a href="'.esc_url(WPF()->member->get_profile_url($l_usernames[2]['ID'])).'">'.esc_html($l_usernames[2]['display_name']).'</a>', $l_count );
545 }
546 }
547 return $return;
548 }
549
550
551 /**
552 * Get actions buttons
553 *
554 * @since 1.0.0
555 *
556 * @param array $buttons names function will return buttons by this array
557 *
558 * @param array $forum required
559 *
560 * @param array $topic required
561 *
562 * @param array $post required
563 *
564 * @param int $is_topic required this is a first post in the loop
565 *
566 * $buttons = array( 'reply', 'answer', 'comment', 'quote', 'like', 'report', 'sticky', 'close', 'edit', 'delete', 'link' );
567 *
568 * @return void
569 */
570
571 function buttons( $buttons, $forum = array(), $topic = array(), $post = array(), $is_topic = FALSE ){
572 $buttons = (array) $buttons;
573
574 $button_html = array();
575 $login = is_user_logged_in();
576
577 $forumid = (isset($forum['forumid'])) ? $forum['forumid'] : 0;
578 $topicid = (isset($topic['topicid'])) ? $topic['topicid'] : 0;
579 $postid = (isset($post['postid'])) ? $post['postid'] : 0;
580
581 $is_sticky = (isset($topic['type'])) ? $topic['type'] : 0;
582 $is_closed = (isset($topic['closed'])) ? $topic['closed'] : 0;
583 $is_private = (isset($topic['private'])) ? $topic['private'] : 0;
584 $is_solved = (isset($post['is_answer'])) ? $post['is_answer'] : 0;
585 $is_approve = (isset($post['status'])) ? $post['status'] : 0;
586
587 foreach($buttons as $button){
588
589 switch($button){
590
591 case 'reply':
592 if($is_closed) break;
593 if( WPF()->perm->forum_can('cr', $forumid) ){
594 $button_html[] = '<span id="parentpostid'.intval($postid).'" class="wpforo-reply wpf-action"><i class="fas fa-reply fa-rotate-180"></i>' . wpforo_phrase('Reply', false).'</span>';
595 }else{
596 $button_html[] = '<span class="wpf-action not_reg_user"><i class="fas fa-reply fa-rotate-180"></i> ' . wpforo_phrase('Reply', false).'</span>';
597 }
598 break;
599 case 'answer':
600 if( WPF()->perm->forum_can('cr', $forumid) ){
601 $button_html[] = '<span class="wpforo-answer wpf-button"><i class="fas fa-pencil-alt"></i> ' . wpforo_phrase('Answer', false).'</span>';
602 }else{
603 $button_html[] = '<span class="wpf-button not_reg_user"><i class="fas fa-pencil-alt"></i> ' . wpforo_phrase('Answer', false).'</span>';
604 }
605 break;
606 case 'comment':
607 if($is_closed) break;
608 $title = wpforo_phrase('Use comments to ask for more information or suggest improvements. Avoid answering questions in comments.', false);
609 if( WPF()->perm->forum_can('cr', $forumid) ) {
610 $button_html[] = '<span id="parentpostid'.intval($postid).'" class="wpforo-childreply wpf-button" title="'.esc_attr($title).'"><i class="fas fa-comment"></i> ' . wpforo_phrase('Add a comment', false).'</span>';
611 }else{
612 $button_html[] = '<span class="not_reg_user wpf-button" title="'.esc_attr($title).'"><i class="fas fa-comment"></i> ' . wpforo_phrase('Add a comment', false).'</span>';
613 }
614 break;
615 case 'quote':
616 if($is_closed) break;
617 if( WPF()->perm->forum_can('cr', $forumid) ) {
618 $button_html[] = '<span class="wpf-action wpforo-quote" data-postid="'.wpforo_bigintval($postid).'"><i class="fas fa-quote-left wpfsx"></i>' . wpforo_phrase('Quote', false).'</span>';
619 }else{
620 $button_html[] = '<span class="wpf-action not_reg_user"><i class="fas fa-quote-left wpfsx"></i>' . wpforo_phrase('Quote', false).'</span>';
621 }
622 break;
623 case 'like':
624 if( WPF()->perm->forum_can('l', $forumid) && $login && WPF()->current_userid != $post['userid'] ) {
625 $like_status = ( WPF()->post->is_liked( $postid, WPF()->current_userid ) === FALSE ? 'wpforo-like' : 'wpforo-unlike' );
626 $like_icon = ( $like_status == 'wpforo-like') ? 'up' : 'down';
627 $button_html[] = '<span class="wpf-action '. $like_status .'" data-postid="'. wpforo_bigintval($postid) .'"><i class="fas fa-thumbs-'. esc_attr($like_icon) .' wpfsx wpforo-like-ico"></i><span class="wpforo-like-txt">' . wpforo_phrase( str_replace('wpforo-', '', $like_status), false) . '</span></span>';
628 }
629 break;
630 case 'report':
631 if( WPF()->perm->forum_can('r', $forumid) && $login ) {
632 $button_html[] = '<span class="wpf-action wpforo-report" data-postid="'. wpforo_bigintval($postid) .'"><i class="fas fa-exclamation-triangle"></i>' . wpforo_phrase('Report', false).'</span>';
633 }
634 break;
635 case 'sticky':
636 $sticky_status = ( $is_sticky ? 'wpforo-unsticky' : 'wpforo-sticky');
637 if( WPF()->perm->forum_can('s', $forumid) ) {
638 $button_html[] = '<span class="wpf-action '. $sticky_status .'" data-topicid="'. wpforo_bigintval($topicid) .'"><i class="fas fa-exclamation wpfsx"></i><span class="wpforo-sticky-txt">' . wpforo_phrase( str_replace('wpforo-', '', $sticky_status), false).'</span></span>';
639 }
640 break;
641 case 'private':
642 if( $login ){
643 if( WPF()->perm->forum_can('p', $forumid) || (WPF()->current_userid == $post['userid'] && WPF()->perm->forum_can('op', $forumid)) ) {
644 $private_status = ( $is_private ? 'wpforo-public' : 'wpforo-private');
645 $private_icon = ( $private_status == 'wpforo-public') ? 'eye' : 'eye-slash';
646 $button_html[] = '<span id="wpfprivate'. intval($topicid) .'" class="wpf-action '. $private_status .'"><i id="privateicon'. intval($topicid) .'" class="fas fa-'. esc_attr($private_icon) .' wpfsx"></i><span id="privatetext'. intval($topicid) .'">' . wpforo_phrase( str_replace('wpforo-', '', $private_status), false).'</span></span>';
647 }
648 }
649 break;
650 case 'solved':
651 $solved_status = ( $is_solved ? 'wpforo-unsolved' : 'wpforo-solved');
652 if( WPF()->perm->forum_can('sv', $forumid) || (WPF()->current_userid == $post['userid'] && WPF()->perm->forum_can('osv', $forumid)) ) {
653 $button_html[] = '<span id="wpfsolved'. intval($postid) .'" class="wpf-action '. $solved_status .'"><i class="fas fa-check-circle wpfsx"></i><span id="solvedtext'. intval($postid) .'">' . wpforo_phrase( str_replace('wpforo-', '', $solved_status), false).'</span></span>';
654 }
655 break;
656 case 'approved':
657 if( WPF()->perm->forum_can('au', $forumid) && $login ) {
658 $approve_status = ( !$is_approve ? 'wpforo-unapprove' : 'wpforo-approve');
659 $approve_icon = ( $approve_status == 'wpforo-unapprove') ? 'fa-exclamation-circle' : 'fa-check';
660 $button_html[] = '<span id="wpfapprove'. intval($postid) .'" class="wpf-action '. $approve_status .'"><i id="approveicon'. intval($postid) .'" class="fas '. esc_attr($approve_icon) .' wpfsx"></i><span id="approvetext'. intval($postid) .'">' . wpforo_phrase( str_replace('wpforo-', '', $approve_status), false).'</span></span>';
661 }
662 break;
663 case 'close':
664 if( WPF()->perm->forum_can('cot', $forumid) && $login ) {
665 $open_status = ( $is_closed ? 'wpforo-open' : 'wpforo-close' );
666 $open_icon = ($open_status == 'wpforo-open') ? 'unlock' : 'lock';
667 $button_html[] = '<span id="wpfclose'. intval($topicid) .'" class="wpf-action '. $open_status .'"><i id="closeicon'. intval($topicid) .'" class="fas fa-'. esc_attr($open_icon) .' wpfsx"></i><span id="closetext'. intval($topicid) .'">' . wpforo_phrase( str_replace('wpforo-', '', $open_status), false).'</span></span>';
668 }
669 break;
670 case 'tools':
671 if( WPF()->perm->forum_can('mt', $forumid) && $login ) {
672 $button_html[] = '<span class="wpf-action wpforo-tools"><i class="fas fa-cog"></i>' . wpforo_phrase('Tools', false).' <sep>&nbsp;|</sep> </span>';
673 }
674 break;
675 case 'edit':
676 if($is_closed) break;
677 $diff = current_time( 'timestamp', 1 ) - strtotime($post['created']);
678 if( WPF()->member->current_user_is_new() && $post['status'] ){
679 //New registered user's unapproved topic/post | No Edit button.
680 }
681 elseif( !$login && isset($post['email'])
682 && wpforo_is_owner($post['userid'], $post['email'])
683 && WPF()->perm->forum_can( ($is_topic ? 'eot' : 'eor' ), $forumid )
684 && $diff < WPF()->post->options[($is_topic ? 'eot' : 'eor' ).'_durr']
685 ) {
686 $a = ( $is_topic ) ? 'wpfedittopicpid' : '';
687 $b = ( $is_topic ) ? $postid : $postid;
688 $button_html[] = '<span id="'. esc_attr( $a . $b ) .'" class="wpforo-edit wpf-action"><i class="fas fa-edit wpfsx"></i>' . wpforo_phrase('Edit', false).'</span>';
689
690 }
691 elseif( $login ) {
692 if( WPF()->perm->forum_can( ($is_topic ? 'et' : 'er'), $forumid ) ||
693 ( WPF()->current_userid == $post['userid']
694 && WPF()->perm->forum_can( ($is_topic ? 'eot' : 'eor' ), $forumid )
695 && ( WPF()->post->options[($is_topic ? 'eot' : 'eor' ).'_durr'] == 0 ||
696 $diff < WPF()->post->options[($is_topic ? 'eot' : 'eor' ).'_durr'])
697 )
698 ) {
699 $a = ( $is_topic ) ? 'wpfedittopicpid' : '';
700 $b = ( $is_topic ) ? $postid : $postid;
701 $button_html[] = '<span id="'. esc_attr( $a . $b ) .'" class="wpforo-edit wpf-action"><i class="fas fa-edit wpfsx"></i>' . wpforo_phrase('Edit', false).'</span>';
702 }
703 }
704 break;
705 case 'delete':
706 if( $login ){
707 if( WPF()->member->current_user_is_new() && $post['status'] ){
708 //New registered user's unapproved topic/post | No Delete button.
709 }
710 else{
711 $diff = current_time( 'timestamp', 1 ) - strtotime($post['created']);
712 if( WPF()->perm->forum_can( ($is_topic ? 'dt' : 'dr' ), $forumid ) ||
713 (WPF()->current_userid == $post['userid'] &&
714 WPF()->perm->forum_can( ($is_topic ? 'dot' : 'dor' ), $forumid ) &&
715 ( WPF()->post->options[($is_topic ? 'dot' : 'dor' ).'_durr'] == 0 ||
716 $diff < WPF()->post->options[($is_topic ? 'dot' : 'dor' ).'_durr'])
717 )
718 ){
719 $a = ( $is_topic ) ? 'wpftopicdelete' : 'wpfreplydelete';
720 $b = ( $is_topic ) ? $topicid : $postid;
721 $button_html[] = '<span id="'. esc_attr( $a . $b ) .'" class="wpf-action wpforo-delete"><i class="fas fa-times wpfsx"></i>' . wpforo_phrase('Delete', false).'</span>';
722 }
723 }
724 }
725 break;
726 case 'link':
727 $url = ( $is_topic ) ? WPF()->topic->get_topic_url( $topic ) : wpforo_post( $postid, 'url' );
728 $button_html[] = '<a href="'. esc_url($url) .'"><i class="fas fa-link wpfsx"></i></a>';
729 break;
730 case 'positivevote':
731 if( WPF()->perm->forum_can('v', $forumid) && $login ) {
732 $button_html[] = '<i class="wpforo-voteup fas fa-play fa-rotate-270 wpfcl-0" data-type="' . ( $is_topic ? 'topic' : 'reply' ) . '" data-postid="'. wpforo_bigintval($postid) .'"></i>';
733 }else{
734 $button_html[] = '<i class="not_reg_user fas fa-play fa-rotate-270 wpfcl-0"></i>';
735 }
736 break;
737 case 'negativevote':
738 if( WPF()->perm->forum_can('v', $forumid) && $login ) {
739 $button_html[] = '<i class="wpforo-votedown fas fa-play fa-rotate-90 wpfcl-0" data-type="' . ( $is_topic ? 'topic' : 'reply' ) . '" data-postid="'. wpforo_bigintval($postid) .'"></i>';
740 }else{
741 $button_html[] = '<i class="not_reg_user fas fa-play fa-rotate-90 wpfcl-0"></i>';
742 }
743 break;
744 case 'isanswer':
745 $is_answer = WPF()->post->is_answered( $postid );
746 $is_answer = ( $is_answer == 0 ) ? '-not' : '';
747 if( $login ){
748 $button_html[] = '<div class="wpf-toggle'. esc_attr($is_answer) .'-answer" data-postid="'. wpforo_bigintval($postid) .'"><i class="fas fa-check"></i></div>';
749 }else{
750 $button_html[] = '<div class="wpf-toggle'. esc_attr($is_answer) .'-answer not_reg_user"><i class="fas fa-check"></i></div>';
751 }
752 break;
753 } //switch
754 } //foreach
755
756 $before = '<span class="wpforo-action-buttons-wrap">';
757 $after = '</span>';
758 echo $before . implode('', $button_html) . $after;
759
760 }
761
762 /**
763 * display QA Layout Votes count for loop current post
764 * @param array $post loop current post array
765 * @return void
766 */
767 public function vote_count($post){
768 $votes = ( !empty($post['votes']) ? $post['votes'] : 0 );
769 printf('<span class="wpfvote-num wpfcl-0">%d</span>', $votes);
770 }
771
772 function breadcrumb($url_data){
773 extract($url_data, EXTR_OVERWRITE);
774
775 switch($template) :
776 case 'search': ?>
777
778 <div class="wpf-breadcrumb">
779 <a href="<?php echo wpforo_home_url() ?>" class="wpf-root" title="<?php esc_attr( wpforo_phrase('Forums') ) ?>"><i class="fas fa-home"></i></a>
780
781 <a href="#" class="active"><?php wpforo_phrase('Search') ?></a>
782
783 <a href="#" class="wpf-end">&nbsp;</a>
784 </div>
785
786 <?php break;
787 case 'signup': ?>
788
789 <div class="wpf-breadcrumb">
790 <a href="<?php echo wpforo_home_url() ?>" class="wpf-root" title="<?php esc_attr( wpforo_phrase('Forums') ) ?>"><i class="fas fa-home"></i></a>
791
792 <a href="#" class="active"><?php wpforo_phrase('Register') ?></a>
793
794 <a href="#" class="wpf-end">&nbsp;</a>
795 </div>
796
797 <?php break;
798 case 'signin': ?>
799
800 <div class="wpf-breadcrumb">
801 <a href="<?php echo wpforo_home_url() ?>" class="wpf-root" title="<?php esc_attr( wpforo_phrase('Forums') ) ?>"><i class="fas fa-home"></i></a>
802
803 <a href="#" class="active"><?php wpforo_phrase('Login') ?></a>
804
805 <a href="#" class="wpf-end">&nbsp;</a>
806 </div>
807
808 <?php break;
809 case 'members': ?>
810
811 <div class="wpf-breadcrumb">
812 <a href="<?php echo wpforo_home_url() ?>" class="wpf-root" title="<?php esc_attr( wpforo_phrase('Forums') ) ?>"><i class="fas fa-home"></i></a>
813
814 <?php if(isset($_GET['wpfms'])) : ?>
815
816 <a href="<?php echo wpforo_home_url('members') ?>"><?php wpforo_phrase('Members') ?></a>
817 <a href="#" class="active"><?php wpforo_phrase('Search') ?></a>
818
819 <?php else : ?>
820
821 <a href="#" class="active"><?php wpforo_phrase('Members') ?></a>
822
823 <?php endif ?>
824
825 <a href="#" class="wpf-end">&nbsp;</a>
826 </div>
827
828 <?php break;
829 case 'recent': ?>
830
831 <div class="wpf-breadcrumb">
832 <a href="<?php echo wpforo_home_url() ?>" class="wpf-root" title="<?php esc_attr( wpforo_phrase('Forums') ) ?>"><i class="fas fa-home"></i></a>
833
834 <a href="#" class="active"><?php wpforo_phrase('Recently Added') ?></a>
835
836 <a href="#" class="wpf-end">&nbsp;</a>
837 </div>
838
839 <?php break;
840 case 'profile': ?>
841
842 <div class="wpf-breadcrumb">
843 <a href="<?php echo wpforo_home_url() ?>" class="wpf-root" title="<?php esc_attr( wpforo_phrase('Forums') ) ?>"><i class="fas fa-home"></i></a>
844
845 <a href="<?php echo wpforo_home_url('members') ?>"><?php wpforo_phrase('Members') ?></a>
846 <a href="#" class="active"><?php @wpforo_text( wpforo_make_dname($user['display_name'], $user['user_nicename']), 19 ) ?></a>
847
848 <a href="#" class="wpf-end">&nbsp;</a>
849 </div>
850
851 <?php break;
852 case 'account': ?>
853
854 <div class="wpf-breadcrumb">
855 <a href="<?php echo wpforo_home_url() ?>" class="wpf-root" title="<?php esc_attr( wpforo_phrase('Forums') ) ?>"><i class="fas fa-home"></i>
856
857 <a href="<?php echo wpforo_home_url('members') ?>"><?php wpforo_phrase('Members') ?></a>
858 <a href="<?php echo esc_url($user['profile_url']) ?>"><?php wpforo_text( wpforo_make_dname($user['display_name'], $user['user_nicename']), 19 ) ?></a>
859 <a href="#" class="active"><?php wpforo_phrase('Account') ?></a>
860
861 <a href="#" class="wpf-end">&nbsp;</a>
862 </div>
863
864 <?php break;
865 case 'activity': ?>
866
867 <div class="wpf-breadcrumb">
868 <a href="<?php echo wpforo_home_url() ?>" class="wpf-root" title="<?php esc_attr( wpforo_phrase('Forums') ) ?>"><i class="fas fa-home"></i>
869
870 <a href="<?php echo wpforo_home_url('members') ?>"><?php wpforo_phrase('Members') ?></a>
871 <a href="<?php echo esc_url($user['profile_url']) ?>"><?php wpforo_text( wpforo_make_dname($user['display_name'], $user['user_nicename']), 19 ) ?></a>
872 <a href="#" class="active"><?php wpforo_phrase('Activity') ?></a>
873
874 <a href="#" class="wpf-end">&nbsp;</a>
875 </div>
876
877 <?php break;
878 case 'subscriptions': ?>
879
880 <div class="wpf-breadcrumb">
881 <a href="<?php echo wpforo_home_url() ?>" class="wpf-root" title="<?php esc_attr( wpforo_phrase('Forums') ) ?>"><i class="fas fa-home"></i>
882
883 <a href="<?php echo wpforo_home_url('members') ?>"><?php wpforo_phrase('Members') ?></a>
884 <a href="<?php echo esc_url($user['profile_url']) ?>"><?php wpforo_text( wpforo_make_dname($user['display_name'], $user['user_nicename']), 19 ) ?></a>
885 <a href="#" class="active"><?php wpforo_phrase('Subscriptions') ?></a>
886
887 <a href="#" class="wpf-end">&nbsp;</a>
888 </div>
889
890 <?php break;
891 // TODO: move code to pm plugin
892 case 'messages': ?>
893
894 <div class="wpf-breadcrumb">
895 <a href="<?php echo wpforo_home_url() ?>" class="wpf-root" title="<?php esc_attr( wpforo_phrase('Forums') ) ?>"><i class="fas fa-home"></i>
896
897 <a href="<?php echo wpforo_home_url('members') ?>"><?php wpforo_phrase('Members') ?></a>
898
899 <?php if(!empty($user)) : ?>
900
901 <a href="<?php echo esc_url($user['profile_url']) ?>"><?php wpforo_text( wpforo_make_dname($user['display_name'], $user['user_nicename']), 19 ) ?></a>
902
903 <?php endif ?>
904
905 <a href="#" class="active"><?php wpforo_phrase('Messages') ?></a>
906
907 <a href="#" class="wpf-end">&nbsp;</a>
908 </div>
909
910 <?php break;
911 case 'topic': ?>
912
913 <div class="wpf-breadcrumb">
914 <a href="<?php echo ( !isset($forumid) ? '#' : wpforo_home_url() ) ?>" class="wpf-root<?php echo ( !isset($forumid) ? ' active' : '' ) ?>" title="<?php esc_attr( wpforo_phrase('Forums') ) ?>"><i class="fas fa-home"></i></a>
915
916 <?php if(isset($forumid)) : ?>
917 <?php $relative_ids = array();
918 WPF()->forum->get_all_relative_ids($forumid, $relative_ids);
919 foreach( $relative_ids as $key => $rel_forumid ) : ?>
920 <?php $forum = wpforo_forum($rel_forumid) ?>
921 <?php if(!empty($forum)): ?>
922 <?php if( $key != ( count($relative_ids) - 1 ) ) : ?>
923 <a href="<?php echo esc_url( $forum['url'] ) ?>" title="<?php echo esc_attr($forum['title']) ?>"><?php wpforo_text($forum['title'], 19) ?></a>
924 <?php else : ?>
925 <a href="#" class="active" title="<?php echo esc_attr($forum['title']) ?>"><?php wpforo_text($forum['title'], 19) ?></a>
926 <?php endif ?>
927 <?php endif ?>
928 <?php endforeach ?>
929 <?php endif ?>
930
931 <a href="#" class="wpf-end">&nbsp;</a>
932 </div>
933
934 <?php break;
935 case 'post': ?>
936
937 <div class="wpf-breadcrumb">
938 <a href="<?php echo ( !isset($forumid) ? '#' : wpforo_home_url() ) ?>" class="wpf-root<?php echo ( !isset($forumid) ? ' active' : '' ) ?>" title="<?php esc_attr( wpforo_phrase('Forums') ) ?>"><i class="fas fa-home"></i></a>
939
940 <?php if(isset($forumid)) : ?>
941 <?php $relative_ids = array();
942 WPF()->forum->get_all_relative_ids($forumid, $relative_ids);
943 foreach( $relative_ids as $key => $rel_forumid ) : ?>
944 <?php $forum = wpforo_forum($rel_forumid) ?>
945 <?php if(!empty($forum)): ?>
946 <a href="<?php echo esc_url( $forum['url'] ) ?>" title="<?php echo esc_attr($forum['title']) ?>"><?php wpforo_text($forum['title'], 19) ?></a>
947 <?php endif ?>
948 <?php endforeach ?>
949 <?php endif ?>
950 <?php if(!empty($topic)) : ?>
951
952 <a href="#" class="active" title="<?php echo esc_attr($topic['title']) ?>"><?php wpforo_text($topic['title'], 19) ?></a>
953
954 <?php endif ?>
955 <a href="#" class="wpf-end">&nbsp;</a>
956 </div>
957
958 <?php break;
959 default: ?>
960
961 <div class="wpf-breadcrumb">
962 <a href="#" class="wpf-root active"><?php wpforo_phrase('Forums') ?></a>
963 <a href="#" class="wpf-end">&nbsp;</a>
964 </div>
965
966 <?php
967 endswitch;
968
969 }
970
971 function icon($type, $item = array(), $echo = true, $data = 'icon' ){
972
973 $icon = array();
974 $status = false;
975
976 if( isset($item['status']) && $item['status'] ){
977 $icon['class'] = 'fas fa-exclamation-circle';
978 $icon['color'] = 'wpfcl-5';
979 $icon['title'] = wpforo_phrase('Unapproved', false);
980 if($echo) {
981 $status = true; echo ($data == 'icon') ? implode(' ', $icon) : $icon['title'];
982 }
983 else{
984 return ($data == 'icon') ? implode(' ', $icon) : $icon['title'];
985 }
986 }
987
988 if(isset($item['type'])){
989
990 if( $type == 'topic' ){
991 if(WPF()->topic->is_private($item['topicid'])){
992 $icon['class'] = 'fas fa-eye-slash';
993 $icon['color'] = 'wpfcl-1';
994 $icon['title'] = wpforo_phrase('Private', false);
995 if($echo) {
996 $status = true; echo ($data == 'icon') ? implode(' ', $icon) : $icon['title'];
997 }
998 else{
999 return ($data == 'icon') ? implode(' ', $icon) : $icon['title'];
1000 }
1001 }
1002 if( wpforo_topic($item['topicid'], 'is_answer') ){
1003 $icon['class'] = 'fas fa-check-circle';
1004 $icon['color'] = 'wpfcl-8';
1005 $icon['title'] = wpforo_phrase('Solved', false);
1006 if($echo) {
1007 $status = true; echo ($data == 'icon') ? implode(' ', $icon) : $icon['title'];
1008 }
1009 else{
1010 return ($data == 'icon') ? implode(' ', $icon) : $icon['title'];
1011 }
1012 }
1013 }
1014
1015 if( $item['closed'] && $item['type'] == 1 ){
1016 $icon['class'] = 'fas fa-lock';
1017 $icon['color'] = 'wpfcl-1';
1018 $icon['title'] = wpforo_phrase('Closed', false);
1019 if($echo) { $status = true; echo ($data == 'icon') ? implode(' ', $icon) : $icon['title']; } else{ return ($data == 'icon') ? implode(' ', $icon) : $icon['title']; }
1020 }
1021 elseif( $item['closed'] && $item['type'] != 1 ){
1022 $icon['class'] = 'fas fa-lock';
1023 $icon['color'] = 'wpfcl-1';
1024 $icon['title'] = wpforo_phrase('Closed', false);
1025 if($echo) { $status = true; echo ($data == 'icon') ? implode(' ', $icon) : $icon['title']; } else{ return ($data == 'icon') ? implode(' ', $icon) : $icon['title']; }
1026 }
1027 elseif( !$item['closed'] && $item['type'] == 1 ){
1028 $icon['class'] = 'fas fa-thumbtack';
1029 $icon['color'] = 'wpfcl-5';
1030 $icon['title'] = wpforo_phrase('Sticky', false);
1031 if($echo) { $status = true; echo ($data == 'icon') ? implode(' ', $icon) : $icon['title']; } else{ return ($data == 'icon') ? implode(' ', $icon) : $icon['title']; }
1032 }
1033
1034 if( $status ){
1035 //do nothing
1036 }
1037 else{
1038 if( $type == 'forum' ){
1039 $icon['class'] = 'fas fa-comments';
1040 $icon['color'] = 'wpfcl-2';
1041 }
1042 elseif( $type == 'topic' ){
1043 if( $item['posts'] == 1 ){
1044 $icon['class'] = 'far fa-file';
1045 $icon['color'] = 'wpfcl-2';
1046 $icon['title'] = '';
1047 }
1048 elseif( $item['posts'] > 1 && $item['posts'] <= 5 ){
1049 $icon['class'] = 'far fa-file-alt';
1050 $icon['color'] = 'wpfcl-2';
1051 $icon['title'] = '';
1052 }
1053 elseif( $item['posts'] > 5 && $item['posts'] <= 20 ){
1054 $icon['class'] = 'fas fa-file-alt';
1055 $icon['color'] = 'wpfcl-2';
1056 $icon['title'] = '';
1057 }
1058 elseif( $item['posts'] > 20 ){
1059 $icon['class'] = 'fas fa-file-alt';
1060 $icon['color'] = 'wpfcl-5';
1061 $icon['title'] = '';
1062 }
1063 else{
1064 $icon['class'] = 'far fa-file';
1065 $icon['color'] = 'wpfcl-2';
1066 $icon['title'] = '';
1067 }
1068 }
1069 if($echo) { echo ($data == 'icon') ? implode(' ', $icon) : $icon['title']; } else{ return ($data == 'icon') ? implode(' ', $icon) : $icon['title']; }
1070 }
1071
1072 }
1073 else{
1074 return false;
1075 }
1076
1077 }
1078
1079 public function member_buttons( $member ){
1080 if(empty($member)) return;
1081 $profile_access = ( WPF()->perm->usergroup_can('vprf') ? true : false );
1082
1083 if( $profile_access ){
1084 ?>
1085 <a class="wpf-member-profile-button" title="<?php wpforo_phrase('Profile') ?>" href="<?php echo esc_url(WPF()->member->profile_url($member)) ?>">
1086 <i class="fas fa-user"></i>
1087 </a>
1088 <a class="wpf-member-profile-button" title="<?php wpforo_phrase('Activity') ?>" href="<?php echo esc_url(WPF()->member->profile_url($member, 'activity')) ?>">
1089 <i class="far fa-comments"></i>
1090 </a>
1091 <a class="wpf-member-profile-button" title="<?php wpforo_phrase('Subscriptions') ?>" href="<?php echo esc_url(WPF()->member->profile_url($member, 'subscriptions')) ?>">
1092 <i class="fas fa-rss"></i>
1093 </a>
1094 <?php do_action( 'wpforo_member_info_buttons', $member ); ?>
1095 <?php
1096 }
1097 }
1098
1099 public function member_social_buttons( $member ){
1100
1101 $socnets = array();
1102 if(empty($member)) return false;
1103 $social_access = ( WPF()->perm->usergroup_can('vmsn') ? true : false );
1104
1105 if( $social_access ){
1106
1107 if( isset($member['facebook']) && $member['facebook'] ){
1108 $socnets['facebook']['set'] = $member['facebook'];
1109 $member['facebook'] = ( strpos($member['facebook'], 'facebook.com') === FALSE ) ? 'https://www.facebook.com/' . trim($member['facebook'], '/') : $member['facebook'] ;
1110 $socnets['facebook']['value'] = $member['facebook'];
1111 $socnets['facebook']['protocol'] = 'https://';
1112 $socnets['facebook']['title'] = wpforo_phrase('Facebook', false);
1113 }
1114
1115 if( isset($member['twitter']) && $member['twitter'] ){
1116 $socnets['twitter']['set'] = $member['twitter'];
1117 $member['twitter'] = ( strpos($member['twitter'], 'twitter.com') === FALSE ) ? 'http://twitter.com/' . trim($member['twitter'], '/') : $member['twitter'] ;
1118 $socnets['twitter']['value'] = $member['twitter'];
1119 $socnets['twitter']['protocol'] = 'https://';
1120 $socnets['twitter']['title'] = wpforo_phrase('Twitter', false);
1121 }
1122
1123 if( isset($member['gtalk']) && $member['gtalk'] ){
1124 $socnets['gtalk']['set'] = $member['gtalk'];
1125 $socnets['gtalk']['value'] = $member['gtalk'];
1126 $socnets['gtalk']['protocol'] = 'https://';
1127 $socnets['gtalk']['title'] = wpforo_phrase('Google+', false);
1128 }
1129
1130 if( isset($member['yahoo']) && $member['yahoo'] ){
1131 $socnets['yahoo']['set'] = $member['yahoo'];
1132 $socnets['yahoo']['value'] = $member['yahoo'];
1133 $socnets['yahoo']['protocol'] = 'mailto:';
1134 $socnets['yahoo']['title'] = wpforo_phrase('Yahoo', false);
1135 }
1136
1137 if( isset($member['aim']) && $member['aim'] ){
1138 $socnets['aim']['set'] = $member['aim'];
1139 $socnets['aim']['value'] = $member['aim'];
1140 $socnets['aim']['protocol'] = 'mailto:';
1141 $socnets['aim']['title'] = wpforo_phrase('AOL IM', false);
1142 }
1143
1144 if( isset($member['icq']) && $member['icq'] ){
1145 $socnets['icq']['set'] = $member['icq'];
1146 $socnets['icq']['value'] = 'www.icq.com/whitepages/cmd.php?uin=' . $member['icq'] . '&action=message';
1147 $socnets['icq']['protocol'] = 'https://';
1148 $socnets['icq']['title'] = wpforo_phrase('ICQ', false);
1149 }
1150
1151 if( isset($member['msn']) && $member['msn'] ){
1152 $socnets['msn']['set'] = $member['msn'];
1153 $socnets['msn']['value'] = $member['msn'];
1154 $socnets['msn']['protocol'] = 'mailto:';
1155 $socnets['msn']['title'] = wpforo_phrase('MSN', false);
1156 }
1157
1158 if( isset($member['skype']) && $member['skype'] ){
1159 $socnets['skype']['set'] = $member['skype'];
1160 $socnets['skype']['value'] = $member['skype'];
1161 $socnets['skype']['protocol'] = 'skype:';
1162 $socnets['skype']['title'] = wpforo_phrase('Skype', false);
1163 }
1164
1165 ?>
1166 <div class="wpf-member-socnet-wrap">
1167 <?php if(!empty($socnets)): ?>
1168 <?php foreach( $socnets as $key => $socnet ): ?>
1169 <?php if( !$socnet['set'] ) continue; ?>
1170 <?php $title = $member['display_name'] . ' - ' . $socnet['title']; ?>
1171 <?php $url = ($key == 'skype') ? 'skype:' . esc_attr($socnet['value']) : esc_url($socnet['protocol'] . str_replace( array('https://', 'http://', 'skype:', 'mailto:'), '', $socnet['value'])); ?>
1172 <a href="<?php echo $url ?>" class="wpf-member-socnet-button" title="<?php echo esc_attr($title) ?>">
1173 <img src="<?php echo esc_url(WPFORO_URL) ?>/wpf-assets/images/sn/<?php echo $key ?>.png" alt="<?php echo esc_attr($title) ?>" title="<?php echo esc_attr($title) ?>" />
1174 </a>
1175 <?php endforeach; ?>
1176 <?php endif; ?>
1177 <?php do_action( 'wpforo_member_socnet_buttons', $member ); ?>
1178 </div>
1179 <?php
1180 }
1181 }
1182
1183 public function init_member_templates(){
1184 WPF()->member_tpls = array(
1185 'account' => wpftpl('profile-account.php'),
1186 'activity' => wpftpl('profile-activity.php'),
1187 'subscriptions' => wpftpl('profile-subscriptions.php')
1188 );
1189 WPF()->member_tpls = apply_filters('wpforo_member_templates_filter', WPF()->member_tpls);
1190 WPF()->member_tpls['profile'] = wpftpl('profile-home.php');
1191 }
1192
1193 function has_menu(){
1194 return has_nav_menu( 'wpforo-menu' );
1195 }
1196
1197 function nav_menu(){
1198 if ( has_nav_menu( 'wpforo-menu' ) ){
1199 $defaults = array(
1200 'theme_location' => 'wpforo-menu',
1201 'menu' => '',
1202 'container' => '',
1203 'container_class' => '',
1204 'container_id' => '',
1205 'menu_class' => 'wpf-menu',
1206 'menu_id' => 'wpf-menu',
1207 'echo' => true,
1208 'fallback_cb' => 'wp_page_menu',
1209 'before' => '',
1210 'after' => '',
1211 'link_before' => '',
1212 'link_after' => '',
1213 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
1214 'depth' => 0,
1215 'walker' => ''
1216 );
1217 wp_nav_menu( $defaults );
1218 }
1219 }
1220
1221 function init_nav_menu(){
1222
1223 if(isset(WPF()->current_object) && !empty(WPF()->current_object)){
1224
1225 extract(WPF()->current_object, EXTR_OVERWRITE);
1226
1227 WPF()->menu['wpforo-home'] = array(
1228 'href' => wpforo_home_url(),
1229 'label' => wpforo_phrase('forums', FALSE),
1230 'attr' => ( $template == 'forum' || $template == 'topic' || $template == 'post' ? ' class="wpforo-active"' : '' ),
1231 'submenues' => array()
1232 );
1233
1234 if(WPF()->perm->usergroup_can('vmem')){
1235 WPF()->menu['wpforo-members'] = array(
1236 'href' => wpforo_home_url('members'),
1237 'label' => wpforo_phrase('members', FALSE),
1238 'attr' => ( $template == 'members' ? ' class="wpforo-active"' : '' ),
1239 'submenues' => array()
1240 );
1241 }
1242
1243 WPF()->menu['wpforo-recent'] = array(
1244 'href' => wpforo_home_url('recent'),
1245 'label' => wpforo_phrase('Recent Posts', FALSE),
1246 'attr' => ( $template == 'recent' ? ' class="wpforo-active"' : '' ),
1247 'submenues' => array()
1248 );
1249
1250 if( is_user_logged_in() ){
1251
1252 $member_id = WPF()->current_userid;
1253 $url_profile = WPF()->member->get_profile_url($member_id, 'profile');
1254 $url_account = WPF()->member->get_profile_url($member_id, 'account');
1255 $url_activity = WPF()->member->get_profile_url($member_id, 'activity');
1256 $url_subscriptions = WPF()->member->get_profile_url($member_id, 'subscriptions');
1257
1258 WPF()->menu['wpforo-profile-home'] = array(
1259 'href' => $url_profile,
1260 'label' => wpforo_phrase('my profile', FALSE),
1261 'attr' => ( isset(WPF()->member_tpls[$template]) && WPF()->member_tpls[$template] && WPF()->current_object['user_is_same_current_user'] ? ' class="wpforo-active"' : '' ),
1262 'submenues' => array()
1263 );
1264 WPF()->menu['wpforo-profile-account'] = array(
1265 'href' => $url_account,
1266 'label' => wpforo_phrase('account', FALSE),
1267 'attr' => ( $template == 'account' && WPF()->current_object['user_is_same_current_user'] ? ' class="wpforo-active"' : '' ),
1268 'submenues' => array()
1269 );
1270 WPF()->menu['wpforo-profile-activity'] = array(
1271 'href' => $url_activity,
1272 'label' => wpforo_phrase('activity', FALSE),
1273 'attr' => ( $template == 'activity' && WPF()->current_object['user_is_same_current_user'] ? ' class="wpforo-active"' : '' ),
1274 'submenues' => array()
1275 );
1276 WPF()->menu['wpforo-profile-subscriptions'] = array(
1277 'href' => $url_subscriptions,
1278 'label' => wpforo_phrase('subscriptions', FALSE),
1279 'attr' => ( $template == 'subscriptions' && WPF()->current_object['user_is_same_current_user'] ? ' class="wpforo-active"' : '' ),
1280 'submenues' => array()
1281 );
1282 WPF()->menu['wpforo-logout'] = array(
1283 'href' => wpforo_home_url('?wpforo=logout'),
1284 'label' => wpforo_phrase('logout', FALSE),
1285 'attr' => '',
1286 'submenues' => array()
1287 );
1288
1289 }else{
1290
1291 if( wpforo_feature('user-register') ){
1292 WPF()->menu['wpforo-register'] = array(
1293 'href' => wpforo_register_url(),
1294 'label' => wpforo_phrase('register', FALSE),
1295 'attr' => ( isset($_GET['wpforo']) && $_GET['wpforo'] == 'signup' ? ' class="wpforo-active"' : '' ),
1296 'submenues' => array()
1297 );
1298 }
1299 WPF()->menu['wpforo-login'] = array(
1300 'href' => wpforo_login_url(),
1301 'label' => wpforo_phrase('login', FALSE),
1302 'attr' => ( isset($_GET['wpforo']) && $_GET['wpforo'] == 'signin' ? ' class="wpforo-active"' : '' ),
1303 'submenues' => array()
1304 );
1305 }
1306
1307 WPF()->menu = apply_filters('wpforo_menu_array_filter', WPF()->menu);
1308 }
1309 }
1310
1311 /**
1312 *
1313 * Checks in current active theme options if certain layout exists.
1314 *
1315 * @since 1.0.0
1316 *
1317 * @param mixed $identifier Layout id (folder name) OR @layout variable in header ( 1 or Extended )
1318 * @param string $identifier_type The type of first parameter 'id' OR 'name' (@layout)
1319 *
1320 * @return boolean true/false
1321 *
1322 **/
1323 function layout_exists( $identifier, $identifier_type = 'id' ){
1324
1325 $layouts = $this->options['layouts'];
1326
1327 if( $identifier_type == 'id' ){
1328 if( isset($layouts[$identifier]) && !empty($layouts[$identifier])){
1329 return true;
1330 }
1331 else{
1332 return false;
1333 }
1334 }
1335 elseif( $identifier_type = 'name' ){
1336 foreach( $layouts as $id => $layout ){
1337 if( !isset($layout['name']) && $layout['name'] == $identifier ){
1338 return true;
1339 }
1340 }
1341 return false;
1342 }
1343 }
1344
1345 /**
1346 *
1347 * Finds and returns all layouts information in array from theme's /layouts/ folder
1348 *
1349 * @since 1.0.0
1350 *
1351 * @param string $theme Theme id ( folder name ) e.g. 'classic'
1352 *
1353 * @return array
1354 *
1355 **/
1356 function find_layouts( $theme ){
1357 $layout_data = array();
1358 $layouts = $this->find_themes('/'.$theme.'/layouts', 'php', 'layout');
1359 if(!empty($layouts)){
1360 foreach( $layouts as $layout ){
1361 $lid = trim(basename(dirname( $layout['file']['value'] )), '/');
1362 $layout_data[$lid]['id'] = $lid;
1363 $layout_data[$lid]['name'] = $layout['name']['value'];
1364 $layout_data[$lid]['version'] = $layout['version']['value'];
1365 $layout_data[$lid]['description'] = $layout['description']['value'];
1366 $layout_data[$lid]['author'] = $layout['author']['value'];
1367 $layout_data[$lid]['url'] = $layout['layout_url']['value'];
1368 $layout_data[$lid]['file'] = $layout['file']['value'];
1369 }
1370 }
1371 return $layout_data;
1372 }
1373
1374 function show_layout_selectbox($layoutid = 0){
1375 $layouts = $this->find_layouts( WPFORO_THEME );
1376 if( !empty($layouts) ){
1377 foreach( $layouts as $layout ) : ?>
1378 <option value="<?php echo esc_attr(trim($layout['id'])) ?>" <?php echo ( $layoutid == $layout['id'] ? 'selected' : '' ); ?> ><?php echo esc_html($layout['name']) ?></option>
1379 <?php
1380 endforeach;
1381 }
1382 }
1383
1384 /**
1385 *
1386 * Finds and returns styles array from theme's /styles/colors.php file
1387 *
1388 * @since 1.0.0
1389 *
1390 * @param string $theme Theme id ( folder name ) e.g. 'classic'
1391 *
1392 * @return array
1393 *
1394 **/
1395 function find_styles( $theme ){
1396 $colors = array();
1397 $color_file = WPFORO_THEME_DIR . '/' . $theme . '/styles/colors.php';
1398 if( file_exists($color_file) ){
1399 include( $color_file );
1400 }
1401 return $colors;
1402 }
1403
1404 /**
1405 *
1406 * Scans certain theme directory and returns all information in array ( theme header, layouts, styles ).
1407 *
1408 * @since 1.0.0
1409 *
1410 * @param string $theme_file Theme folder name or main css file base path ( 'classic' OR classic/style.css' )
1411 *
1412 * @return array
1413 *
1414 **/
1415 function find_theme( $theme_file ){
1416 $theme = array();
1417 $theme_file = trim(trim($theme_file, '/'));
1418
1419 if( preg_match('|\.[\w\d]{2,4}$|is', $theme_file) ){
1420 $theme_folder = trim(basename(dirname($theme_file)), '/');
1421 }
1422 else{
1423 $theme_folder = $theme_file;
1424 $theme_file = $theme_file . '/style.css';
1425 }
1426
1427 if( !is_readable( WPFORO_THEME_DIR . '/' . $theme_file ) ){
1428 $theme['error'] = __('Theme file not readable', 'wpforo') .' ('.$theme_file.')';
1429 }
1430 else{
1431 $theme_data = $this->find_theme_headers( WPFORO_THEME_DIR . '/' . $theme_file );
1432 $theme['id'] = $theme_folder;
1433 $theme['name'] = $theme_data['name']['value'];
1434 $theme['version'] = $theme_data['version']['value'];
1435 $theme['description'] = $theme_data['description']['value'];
1436 $theme['author'] = $theme_data['author']['value'];
1437 $theme['url'] = $theme_data['theme_url']['value'];
1438 $theme['file'] = $theme_file;
1439 $theme['folder'] = $theme_folder;
1440 $theme['layouts'] = $this->find_layouts( $theme_folder );
1441 $styles = $this->find_styles( $theme_folder );
1442 if(!empty($styles)){
1443 reset($styles);
1444 $theme['style'] = key($styles);
1445 $theme['styles'] = $styles;
1446 }
1447 }
1448
1449 return $theme;
1450 }
1451
1452 /**
1453 *
1454 * Scans wpForo themes (wpf-themes) folder, reads main files' headers and returns information about all themes in array.
1455 * This function can also be used to scan and get information about layouts in each theme /layouts/ folder.
1456 *
1457 * @since 1.0.0
1458 *
1459 * @param string $base_dir Absolute path to scan directory (e.g. /home/public_html/wp-content/plugins/wpforo/wpf-themes/)
1460 * @param string $ext File extension which may contain header information
1461 * @param string $mode 'theme' or 'layout'
1462 *
1463 * @return array
1464 *
1465 **/
1466 function find_themes( $base_dir = '', $ext = 'css', $mode = 'theme' ){
1467 $themes = array ();
1468 $themes_dir = @opendir( WPFORO_THEME_DIR . $base_dir );
1469 $theme_files = array();
1470 if( $themes_dir ){
1471 while( ($file = readdir( $themes_dir )) !== false ){
1472 if( substr($file, 0, 1) == '.' ) continue;
1473 if( is_dir( WPFORO_THEME_DIR . $base_dir .'/'.$file ) ){
1474 $themes_subdir = @opendir( WPFORO_THEME_DIR . $base_dir .'/'.$file );
1475 if( $themes_subdir ){
1476 while(($subfile = readdir( $themes_subdir ) ) !== false ){
1477 if( substr($subfile, 0, 1) == '.' ) continue;
1478 if( substr($subfile, -4) == '.' . $ext ) $theme_files[] = "$file/$subfile";
1479 }
1480 closedir( $themes_subdir );
1481 }
1482 }
1483 else{
1484 if( substr($file, -4) == '.' . $ext ) $theme_files[] = $file;
1485 }
1486 }
1487 closedir( $themes_dir );
1488 }
1489 if( empty($theme_files) ) return $themes;
1490 foreach( $theme_files as $theme_file ){
1491 if( !is_readable( WPFORO_THEME_DIR . $base_dir . '/' . $theme_file ) ) continue;
1492 if( $mode == 'theme' ){
1493 $theme_data = $this->find_theme_headers( WPFORO_THEME_DIR . $base_dir . '/' . $theme_file );
1494 }
1495 elseif( $mode == 'layout' ){
1496 $theme_data = $this->find_layout_headers( WPFORO_THEME_DIR . $base_dir . '/' . $theme_file );
1497 }
1498 if( empty($theme_data['name']['value']) ) continue;
1499 $themes[wpforo_clear_basename($theme_file)] = $theme_data;
1500 }
1501 return $themes;
1502 }
1503
1504 /**
1505 *
1506 * Reads theme main file's header variables and returns information in array.
1507 *
1508 * @since 1.0.0
1509 *
1510 * @param string $file Absolute path to file (e.g. /home/public_html/wp-content/plugins/wpforo/wpf-themes/style.css)
1511 *
1512 * @return array
1513 *
1514 **/
1515 function find_theme_headers( $file ){
1516 $theme_headers = array();
1517 $headers = array(
1518 'name' => 'Theme Name',
1519 'version' => 'Version',
1520 'description' => 'Description',
1521 'author' => 'Author',
1522 'theme_url' => 'Theme URI',
1523 );
1524 $fp = fopen( $file, 'r' );
1525 $data = fread( $fp, 8192 );
1526 fclose( $fp );
1527 $data = str_replace( "\r", "\n", $data );
1528 foreach ( $headers as $header_key => $header_name ){
1529 if ( preg_match( '|^[\s\t\/*#@]*' . preg_quote( $header_name, '|' ) . ':(.*)$|mi', $data, $match ) && $match[1] ){
1530 $theme_headers[$header_key]['name'] = $header_name;
1531 $theme_headers[$header_key]['value'] = trim(preg_replace("/\s*(?:\*\/|\?>).*/", '', $match[1]));
1532 }
1533 else{
1534 $theme_headers[$header_key]['name'] = $header_name;
1535 $theme_headers[$header_key]['value'] = '';
1536 }
1537 }
1538 $theme_headers['file']['name'] = 'file';
1539 $theme_headers['file']['value'] = $file;
1540 return $theme_headers;
1541 }
1542
1543 /**
1544 *
1545 * Reads layout main file's header variables and returns information in array.
1546 *
1547 * @since 1.0.0
1548 *
1549 * @param string $file Absolute path to file (e.g. /home/public_html/wp-content/plugins/wpforo/wpf-themes/layouts/1/forum.php)
1550 *
1551 * @return array
1552 *
1553 **/
1554 function find_layout_headers( $file ){
1555 $theme_headers = array();
1556 $headers = array(
1557 'name' => 'layout',
1558 'version' => 'version',
1559 'description' => 'description',
1560 'author' => 'author',
1561 'layout_url' => 'url',
1562 );
1563 $fp = fopen( $file, 'r' );
1564 $data = fread( $fp, 8192 );
1565 fclose( $fp );
1566 $data = str_replace( "\r", "\n", $data );
1567 foreach ( $headers as $header_key => $header_name ){
1568 if ( preg_match( '|^[\s\t\/*#@]*' . preg_quote( $header_name, '|' ) . ':(.*)$|mi', $data, $match ) && $match[1] ){
1569 $theme_headers[$header_key]['name'] = $header_name;
1570 $theme_headers[$header_key]['value'] = trim(preg_replace("/\s*(?:\*\/|\?>).*/", '', $match[1]));
1571 }
1572 else{
1573 $theme_headers[$header_key]['name'] = $header_name;
1574 $theme_headers[$header_key]['value'] = '';
1575 }
1576 }
1577 $theme_headers['file']['name'] = 'file';
1578 $theme_headers['file']['value'] = trim(str_replace( WPFORO_THEME_DIR, '', $file), '/');
1579 return $theme_headers;
1580 }
1581
1582 public function copyright(){
1583 if( wpforo_feature('copyright') ): ?>
1584 <div id="wpforo-poweredby">
1585 <p class="wpf-by">
1586 <span onclick='javascript:document.getElementById("bywpforo").style.display = "inline";document.getElementById("awpforo").style.display = "none";' id="awpforo"> <img align="absmiddle" title="<?php esc_attr( wpforo_phrase('Powered by') ) ?> wpForo version <?php echo esc_html(WPFORO_VERSION) ?>" alt="Powered by wpForo" class="wpdimg" src="<?php echo WPFORO_URL ?>/wpf-assets/images/wpforo-info.png" alt="wpForo"> </span><a id="bywpforo" target="_blank" href="http://wpforo.com/">&nbsp;<?php wpforo_phrase('Powered by') ?> wpForo version <?php echo esc_html(WPFORO_VERSION) ?></a>
1587 </p>
1588 </div>
1589 <?php
1590 endif;
1591 }
1592
1593 public function member_menu( $userid, $menu = array() ){
1594 if( empty($menu) ) $menu = array('profile' => 'fas fa-user', 'account' => 'fas fa-cog', 'activity' => 'fas fa-comments', 'subscriptions' => 'fas fa-rss');
1595 $menu = apply_filters('wpforo_member_menu_filter', $menu, $userid);
1596 if( !($userid == WPF()->current_userid || WPF()->perm->usergroup_can('em')) ) unset($menu['account']);
1597 if( !($userid == WPF()->current_userid || WPF()->perm->usergroup_can('vpra')) ) unset($menu['activity']);
1598 if( !($userid == WPF()->current_userid || WPF()->perm->usergroup_can('vprs')) ) unset($menu['subscriptions']);
1599 foreach( $menu as $key => $value ) :
1600 ?>
1601 <a class="wpf-profile-menu <?php echo ( WPF()->current_object['template'] == $key ? ' wpforo-active' : '' ) ?>" href="<?php echo esc_url( WPF()->member->get_profile_url($userid, $key) ) ?>">
1602 <i class="<?php echo $value ?>"></i> <?php wpforo_phrase($key) ?>
1603 </a>
1604 <?php
1605 endforeach;
1606 }
1607
1608 public function member_template(){
1609 $permission = true;
1610 extract(WPF()->current_object, EXTR_OVERWRITE);
1611 extract($user, EXTR_OVERWRITE);
1612 if( $template == 'account' && !($userid == WPF()->current_userid || WPF()->perm->usergroup_can('em')) ) $permission = false;
1613 if( $template == 'activity' && !($userid == WPF()->current_userid || WPF()->perm->usergroup_can('vpra')) ) $permission = false;
1614 if( $template == 'subscriptions' && !($userid == WPF()->current_userid || WPF()->perm->usergroup_can('vprs')) ) $permission = false;
1615 if( $permission ){
1616 include( (isset(WPF()->member_tpls[$template]) && WPF()->member_tpls[$template] ? WPF()->member_tpls[$template] : WPF()->member_tpls['profile']) );
1617 }
1618 else{
1619 ?>
1620 <div class="wpfbg-7 wpf-page-message-wrap">
1621 <div class="wpf-page-message-text">
1622 <?php wpforo_phrase('You do not have permission to view this page') ?>
1623 </div>
1624 </div>
1625 <?php
1626 }
1627 }
1628
1629 public function member_error(){
1630 echo apply_filters('wpforo_member_error_filter', wpforo_phrase('Members not found', FALSE));
1631 }
1632
1633 public function field( $args, $wrap = true ){
1634
1635 $default = array(
1636 'label' => '',
1637 'title' => '',
1638 'name' => '',
1639 'value' => '', //url
1640 'values' => '',
1641 'type' => 'text',
1642 'placeholder' => '',
1643 'description' => '',
1644 'id' => '',
1645 'class' => '',
1646 'attributes' => '',
1647 'isWrapItem' => '',
1648 'isLabelFirst' => '',
1649 'isDisabled' => false,
1650 'isEditable' => 1,
1651 'isRequired' => 1,
1652 'isMultiChoice' => 0,
1653 'isConfirmPassword' => 1,
1654 'minLength' => 0,
1655 'maxLength' => 0,
1656 'faIcon' => '',
1657 'html' => '',
1658 'varname' => (( isset(WPF()->form['varname']) ) ? WPF()->form['varname'] : 'wpfdata'),
1659 'template' => (( isset(WPF()->form['template']) ) ? WPF()->form['template'] : WPF()->current_object['template']),
1660 'canBeInactive' => 1,
1661 'canEdit' => array('1'),
1662 'canView' => array('1', '2', '3', '5'),
1663 'can' => ''
1664 );
1665
1666
1667 $args = wpforo_parse_args( $args, $default );
1668 $args['faIcon'] = trim($args['faIcon']);
1669 if( strpos($args['faIcon'], ' ') === false ) $args['faIcon'] = 'fas ' . $args['faIcon'];
1670 extract( $args );
1671 $field_html = '';
1672 $minLength_attr = '';
1673 $maxLength_attr = '';
1674 $isRequired = ( $isRequired ) ? ' required="required" ' : '';
1675 $isDisabled = ( $isDisabled ) ? ' disabled="disabled" ' : '';
1676 if( !$isDefault ){ $varname = 'data'; }
1677 $fieldName = ( !empty($varname) ? $varname . '[' . $name . ']' : $name );
1678 $fieldId = ( !empty($varname) ? $varname . '_' : '' ) . ( ($id) ? $id : $name );
1679 $minLength = ($minLength) ? intval($minLength): '';
1680 $maxLength = ($maxLength) ? intval($maxLength): '';
1681 if( $minLength ) { $minLength_attr = ($type == 'date' || $type == 'number' || $type == 'range') ? ' min="' . $minLength . '" ' : ' minlength="' . $minLength . '" '; }
1682 if( $maxLength ) { $maxLength_attr = ($type == 'date' || $type == 'number' || $type == 'range') ? ' max="' . $maxLength . '" ' : ' maxlength="' . $maxLength . '" '; }
1683 $minmax = $minLength_attr . ' ' . $maxLength_attr;
1684 $attributes .= ' autocomplete="off"';
1685 $args['value'] = ( isset(WPF()->form['value'][$name]) ) ? WPF()->form['value'][$name] : $args['value'];
1686 if( !$isDefault && $varname ) $args['value'] = ( isset(WPF()->form['value'][$varname][$name]) ) ? WPF()->form['value'][$varname][$name] : $args['value'];
1687 $value = $args['value'];
1688
1689 if( $type == 'textarea' ){
1690 $field_html = '<textarea '. $isRequired .' name="' . esc_attr($fieldName) . '" id="' . esc_attr($fieldId) . '" class="' . esc_attr($class) . '" ' . $isDisabled . ' '.$attributes.' ' . trim($minmax) . ' placeholder="' . esc_attr($placeholder) . '">' . esc_textarea($value) . '</textarea>';
1691 }
1692 elseif( $type == 'password' ){
1693 $password_html = '';
1694 if( $template == 'account' ){
1695 $isRequired = 0;
1696 $args['label'] = wpforo_phrase('Old password', false); $args['description'] = '';
1697 $password_html = '<input type="password" name="' . esc_attr($varname) . '[old_pass]" value="" id="' . esc_attr($fieldId) . '-old" class="' . esc_attr($class) . '" ' . $isDisabled . ' '.$attributes.' placeholder="' . esc_attr( wpforo_phrase('Old password', false) ) . '"/><i class="fas fa-eye-slash wpf-show-password"></i>';
1698 $field_html .= ( $wrap ) ? $this->field_wrap( $args, $password_html ) : $password_html;
1699 }
1700 if( $template == 'register' && wpforo_feature('user-register-email-confirm') ){
1701 //If the option "User Registration with Email Confirmation" is enabled password fields should be removed on registration page.
1702 }
1703 else{
1704 if( $isConfirmPassword ) { $p1 = '1'; $p2 = '2'; } else{ $p1 = ''; $p2 = ''; } $fieldName = ( !empty($varname) ? $varname . '[' . $name . $p1 . ']' : $name . $p1 );
1705 if( $template == 'account' ) { $label = wpforo_phrase('New', false) . ' ' . $label; } $args['label'] = $label; $args['description'] = $description;
1706 $password_html = '<input type="password" name="' . esc_attr($fieldName) . '" value="" id="' . esc_attr($fieldId) . '-new1" class="' . esc_attr($class) . '" ' . $isDisabled . ' '.$attributes.' ' . trim($minmax) . ' placeholder="' . esc_attr($placeholder) . '"/><i class="fas fa-eye-slash wpf-show-password"></i>';
1707 $field_html .= ( $wrap ) ? $this->field_wrap( $args, $password_html ) : $password_html;
1708 if( $isConfirmPassword ){
1709 $args['label'] = wpforo_phrase('Confirm Password', false); $args['description'] = '';
1710 $fieldName = ( !empty($varname) ? $varname . '[' . $name . $p2 . ']' : $name . $p2 );
1711 $password_html = '<input type="password" name="' . esc_attr($fieldName) . '" value="" id="' . esc_attr($fieldId) . '-new2" class="' . esc_attr($class) . '" ' . $isDisabled . ' ' . $attributes . ' ' . trim($minmax) . ' placeholder="' . esc_attr($placeholder) . '"/><i class="fas fa-eye-slash wpf-show-password"></i>';
1712 $field_html .= ( $wrap ) ? $this->field_wrap( $args, $password_html ) : $password_html;
1713 }
1714 }
1715 }
1716 elseif( $type == 'file' ){
1717 $extensions = '';
1718 if( $fileExtensions ) {
1719 $fileExtensions = wpforo_parse_args($fileExtensions);
1720 foreach($fileExtensions as $key => $ext ){ if( strpos($ext, '.') === FALSE ) $fileExtensions[ $key ] = '.' . $ext; }
1721 $fileExtensions = implode(', ', $fileExtensions);
1722 if( $fileExtensions ) $extensions = 'accept="' .$fileExtensions . '"';
1723 }
1724 $field_html = '<input '. $isRequired .' type="file" name="' . esc_attr($fieldName) . '" value="" id="' . esc_attr($fieldId) . '" class="' . esc_attr($class) . '" ' . $isDisabled . ' ' . $attributes . ' ' . $extensions . ' />';
1725 }
1726 elseif( $type == 'checkbox' ){
1727 $step = 0;
1728 $field_html = '';
1729 $value = (is_serialized($value)) ? unserialize($value) : (array)$value;
1730 if( !is_array($values) ) $values = wpforo_string2array($values);
1731 if( !empty($values) ){
1732 foreach( $values as $v ){
1733 $v = trim($v);
1734 $data = explode('=>', $v);
1735 $item_value = isset($data[0]) ? $data[0] : 'no_value';
1736 $item_label = isset($data[1]) ? $data[1] : $item_value;
1737 $item_fieldid = $fieldId . '_' . ($step + 1);
1738 $item_fieldname = $fieldName . '[]';
1739 $checked = ( in_array($item_value, $value) ) ? 'checked="checked"' : '';
1740 $field_html .= '<div class="wpf-field-item">';
1741 $input_html = '<input type="checkbox" name="' . esc_attr($item_fieldname) . '" id="' . esc_attr($item_fieldid) . '" class="wpf-input-checkbox ' . esc_attr($class) . '" value="' . esc_attr($item_value) . '" ' . $checked . ' ' . $isDisabled . ' '.$attributes.' />';
1742 if ($isWrapItem) {
1743 $field_html .= '<label>';
1744 if ($isLabelFirst) { $field_html .= '<span class="wpf-checkbox-label">'. stripslashes($item_label) .'</span> ' . $input_html; } else { $field_html .= $input_html . ' <span class="wpf-checkbox-label">' . stripslashes($item_label) . '</span>'; }
1745 $field_html .= '</label>';
1746 }
1747 else {
1748 if ($isLabelFirst) { $field_html .= '<span class="wpf-checkbox-label">' . stripslashes($item_label) . '</span> ' . $input_html; } else { $field_html .= $input_html . ' <span class="wpf-checkbox-label">' . stripslashes($item_label) . '</span>'; }
1749 }
1750 $field_html .= '</div>';
1751 $step++;
1752 }
1753 }
1754 }
1755 elseif( $type == 'radio' ){
1756 $step = 0;
1757 $field_html = '';
1758 if (!is_array($values)) $values = wpforo_string2array($values);
1759 if (!empty($values)) {
1760 $item_values = array();
1761 foreach ($values as $v) {
1762 $v = trim($v);
1763 $data = explode('=>', $v);
1764 $item_value = $data[0];
1765 $item_label = isset($data[1]) ? $data[1] : $item_value;
1766 $item_fieldid = $fieldId . '_' . ($step + 1);
1767 $attrs = ($isRequired) ? 'required="required"' : '';
1768 $attrs .= ($item_value == $value) ? ' checked="checked"' : '';
1769
1770 $field_html .= '<div class="wpf-field-item">';
1771 $input_html = '<input type="radio" name="' . esc_attr($fieldName) . '" id="' . esc_attr($item_fieldid) . '" class="wpf-input-radio ' . esc_attr($class) . '" value="' . esc_attr($item_value) . '" ' . $attrs . ' ' . $isDisabled . ' ' . $attributes . ' />';
1772 if ($isWrapItem) {
1773 $field_html .= '<label>';
1774 if ($isLabelFirst) {
1775 $field_html .= '<span class="wpf-radio-label">' . stripslashes($item_label) . '</span> ' . $input_html;
1776 } else {
1777 $field_html .= $input_html . ' <span class="wpf-radio-label">' . stripslashes($item_label) . '</span>';
1778 }
1779 $field_html .= '</label>';
1780 } else {
1781 if ($isLabelFirst) {
1782 $field_html .= '<span class="wpf-radio-label">' . stripslashes($item_label) . '</span> ' . $input_html;
1783 } else {
1784 $field_html .= $input_html . ' <span class="wpf-radio-label">' . stripslashes($item_label) . '</span>';
1785 }
1786 }
1787 $field_html .= '</div>';
1788 $step++;
1789 }
1790
1791 }
1792 }
1793 elseif( $type == 'select' ){
1794
1795 $isMultiChoice = $isMultiChoice ? 'multiple="multiple"' : '';
1796 $field_html = '<select '. $isRequired .' name="' . esc_attr($fieldName) . '" id="' . esc_attr($fieldId) . '" class="' . esc_attr($class) . '" ' . $isMultiChoice . ' ' . $isDisabled . ' '.$attributes.'>';
1797 $field_html .= '<option value="">' . wpforo_phrase('--- Choose ---', false) . '</option>';
1798 if( !empty($values) ){
1799 foreach ($values as $k => $v) {
1800 if( is_array($v) ){
1801 $field_html .= '<optgroup label="' . esc_attr($k) . '">';
1802 foreach ($v as $_k => $_v){
1803 $data = explode('=>', $_v);
1804 $item_value = isset($data[0]) ? $data[0] : 'no_value';
1805 $item_label = isset($data[1]) ? $data[1] : $item_value;
1806 $value = stripslashes(htmlspecialchars(trim($value)));
1807 $item_value = stripslashes(htmlspecialchars(trim($item_value)));
1808 $selected = ( $item_value == $value ) ? 'selected="selected"' : '';
1809 $field_html .= '<option value="' . esc_attr($item_value) . '" ' . $selected . '>' . stripslashes($item_label) . '</option>';
1810 }
1811 $field_html .= '</optgroup>';
1812 }else{
1813 $data = explode('=>', $v);
1814 $item_value = isset($data[0]) ? $data[0] : 'no_value';
1815 $item_label = isset($data[1]) ? $data[1] : $item_value;
1816 $value = stripslashes(htmlspecialchars(trim($value)));
1817 $item_value = stripslashes(htmlspecialchars(trim($item_value)));
1818 $selected = ( $item_value == $value ) ? 'selected="selected"' : '';
1819 $field_html .= '<option value="' . esc_attr($item_value) . '" ' . $selected . '>' . stripslashes($item_label) . '</option>';
1820 }
1821 }
1822 }
1823 $field_html .= '</select>';
1824 }
1825 elseif ($type == 'usergroup') {
1826 $groupids = array();
1827
1828 if ($allowedGroupIds) {
1829 if (!is_array($allowedGroupIds)) $allowedGroupIds = explode(',', trim($allowedGroupIds));
1830 $groupids = $allowedGroupIds;
1831 }
1832 if ( !WPF()->current_object['user_is_same_current_user'] && (WPF()->current_user_groupid == 1 || current_user_can('administrator') ) ) $groupids = WPF()->usergroup->get_usergroups('groupid');
1833
1834 if( WPF()->current_object['user_is_same_current_user'] && !in_array(WPF()->current_user_groupid, $allowedGroupIds) ) $groupids = array();
1835
1836 $groupids = array_filter($groupids);
1837 if( $groupids ){
1838 $field_html = '<select ' . $isRequired . ' name="' . esc_attr($fieldName) . '" id="' . esc_attr($fieldId) . '" class="' . esc_attr($class) . '" ' . $isDisabled . ' ' . $attributes . '>';
1839 $field_html .= '<option value="">' . wpforo_phrase('--- Choose ---', false) . '</option>';
1840 foreach ($groupids as $groupid) {
1841 if ( $group = WPF()->usergroup->get_usergroup($groupid) ) {
1842 $selected = ($groupid == $value) ? 'selected="selected"' : '';
1843 $field_html .= '<option value="' . esc_attr($groupid) . '" ' . $selected . '>' . $group['name'] . '</option>';
1844 }
1845 }
1846 $field_html .= '</select>';
1847 }
1848 }
1849 elseif( $type == 'avatar' ){
1850 $remote_url = ( $value && strpos($value, 'wpforo/avatars') === FALSE ) ? $value : '';
1851 $field_html = '<ul>
1852 <li><input ' . $isRequired . ' name="' . esc_attr($varname) . '[avatar_type]" id="wpfat_gravatar" value="gravatar" ' . ( $value == '' || $value == NULL ? 'checked="checked"' : '' ) . ' type="radio" />&nbsp; <label for="wpfat_gravatar">' . wpforo_phrase('Wordpress avatar system', false) . '</label></li>
1853 <li><input name="' . esc_attr($varname) . '[avatar_type]" id="wpfat_remote" value="remote" ' . ( $value && strpos($value, 'wpforo/avatars') === FALSE ? 'checked="checked"' : '' ) . ' type="radio" />&nbsp; <label for="wpfat_remote">' . wpforo_phrase('Specify avatar by URL:', false) . '</label> <input autocomplete="off" name="' . esc_attr($varname) . '[avatar_url]" value="' . esc_url($remote_url) . '" maxlength="300" data-wpfucf-minmaxlength="1,300" type="url" /></li>';
1854 if( WPF()->perm->usergroup_can('upa') ) {
1855 if( strpos($value, 'gravatar.com') === FALSE && strpos($value, 'facebook.com') === FALSE ){
1856 $url = $value . '?lm=' . time();
1857 }
1858 $field_html .= '<li><input name="' . esc_attr($varname) . '[avatar_type]" id="wpfat_custom" value="custom" type="radio" ' . ( (strpos($url, 'wpforo/avatars') !== FALSE) ? 'checked' : '' ) . ' />&nbsp;<label for="wpfat_custom"> ' . wpforo_phrase('Upload an avatar', false) . '</label>' . ( strpos($url, 'wpforo/avatars') !== FALSE ? '<br /><img src="' . esc_url($url) . '" class="wpf-custom-avatar-img"/>' : '' ) .'&nbsp; <input class="wpf-custom-avatar" name="avatar" type="file" />&nbsp;</li>';
1859 }
1860 $field_html .= '</ul>
1861 <script type="text/javascript">jQuery(document).ready(function($){$( "input[name=\'member\[avatar_url\]\']" ).click(function(){$( "#wpfat_remote" ).prop(\'checked\', true);}); $( "input[name=\'avatar\']" ).click(function(){$( "#wpfat_custom" ).prop(\'checked\', true);});});</script>';
1862 }
1863 elseif( $type == 'html' ){
1864 $field_html = stripslashes($html);
1865 }
1866 elseif( $type == 'url' || $name == 'user_nicename' ){
1867 $field_html = '<input ' . $isRequired . ' type="' . $type .'" value="' . esc_attr( urldecode($value) ) . '" name="' . esc_attr($fieldName) .'" id="' . esc_attr($fieldId) . '" class="' . esc_attr($class) . '" ' . $isDisabled . ' '.$attributes.' ' . trim($minmax) . ' placeholder="' . esc_attr($placeholder) . '"/>';
1868 }
1869 else{
1870 $field_html = '<input ' . $isRequired . ' type="' . $type .'" value="' . esc_attr($value) . '" name="' . esc_attr($fieldName) .'" id="' . esc_attr($fieldId) . '" class="' . esc_attr($class) . '" ' . $isDisabled . ' '.$attributes.' ' . trim($minmax) . ' placeholder="' . esc_attr($placeholder) . '"/>';
1871 }
1872
1873 if( $wrap && $type != 'password' && $field_html ) $field_html = $this->field_wrap( $args, $field_html );
1874
1875 return $field_html;
1876
1877 }
1878
1879
1880 public function field_wrap( $args, $field_html ){
1881 if( !is_array($args) || empty($args) ) return $field_html;
1882 extract( $args );
1883 $field_wrap_html = '';
1884 $is_owner = false;
1885 $rIcon = '';
1886 if( isset(WPF()->current_object['user']['ID']) ) {
1887 $is_owner = wpforo_is_owner( WPF()->current_object['user']['ID'] );
1888 }
1889 $field_name_class = sanitize_text_field($name);
1890 if( $isRequired ) $rIcon = ' <span class="wpf-field-required-icon" title="' . esc_attr(wpforo_phrase('Required field', false)) . '">*</span>';
1891 $field_required_class = ( $isRequired ) ? 'wpf-field-required' : '';
1892 if( $template == 'register' ){
1893 $field_wrap_html .= '<div class="wpf-field wpf-field-type-' . esc_attr($type) . ' wpf-field-name-' . esc_attr($field_name_class) . ' ' . esc_attr($field_required_class) . '" title="' . esc_attr($title) . '">';
1894 if( $type == 'html' ){
1895 $field_wrap_html .= $field_html;
1896 }
1897 else{
1898 if ( $label || $description ) {
1899 $field_wrap_html .= '<div class="wpf-label-wrap">';
1900 if ($label){ $field_wrap_html .= '<p class="wpf-label wpfcl-1">' . stripslashes($label) . $rIcon . '</p>'; }
1901 if ($description){ $field_wrap_html .= '<div class="wpf-desc wpfcl-2">' . $description . '</div>'; }
1902 $field_wrap_html .= '</div>';
1903 }
1904 $field_wrap_html .= '<div class="wpf-field-wrap">';
1905 if($faIcon){ $field_wrap_html .= '<i class="' . esc_attr($faIcon) . ' wpf-field-icon"></i>'; }
1906 $field_wrap_html .= $field_html;
1907 $field_wrap_html .= '</div>';
1908 }
1909 $field_wrap_html .= '<div class="wpf-field-cl"></div></div>';
1910 }
1911 elseif( $template == 'account' ){
1912
1913 $canEdit = ( !empty($canEdit) ) ? (array)$canEdit : array(1);
1914 $current_user_can_moderate = ( in_array( WPF()->current_user_groupid, $canEdit) ) ? true : false;
1915
1916 if( !$is_owner && !$current_user_can_moderate && WPF()->current_user_groupid !== 1) return;
1917 if( !$isEditable && !$current_user_can_moderate && WPF()->current_user_groupid !== 1 && !$value) return;
1918 if( $name == 'signature' && ( !WPF()->perm->usergroup_can('ups') || !wpforo_feature('signature'))) return;
1919 if( $name == 'avatar' && ( !wpforo_feature('custom-avatars') || !wpforo_feature('avatars') ) ) return;
1920 if( $name == 'groupid' && WPF()->current_user_groupid !== 1 ) return;
1921
1922 $field_wrap_html .= '<div class="wpf-field wpf-field-type-' . esc_attr($type) . ' wpf-field-name-' . esc_attr($field_name_class) . ' ' . esc_attr($field_required_class) . '" title="' . esc_attr($title) . '">';
1923
1924 if( $type == 'html' ){
1925 $field_wrap_html .= $field_html;
1926 }
1927 elseif($name == 'user_login'){
1928 $field_wrap_html .= '<div class="wpf-label-wrap">';
1929 $field_wrap_html .= '<p class="wpf-label wpfcl-1">' . stripslashes($label) . '</p>';
1930 $field_wrap_html .= '</div>';
1931 $field_wrap_html .= '<div class="wpf-field-wrap">';
1932 $field_wrap_html .= '<span class="wpf-username">' . $value . '</span>';
1933 $field_wrap_html .= '</div>';
1934 }
1935 elseif( !$isEditable && !$current_user_can_moderate && WPF()->current_user_groupid !== 1 ){
1936 $field_wrap_html .= '<div class="wpf-label-wrap">';
1937 $field_wrap_html .= '<p class="wpf-label wpfcl-1">' . stripslashes($label) . '</p>';
1938 $field_wrap_html .= '</div>';
1939 $field_wrap_html .= '<div class="wpf-field-wrap">';
1940 $field_wrap_html .= '<span class="wpf-filed-value"><i class="' . esc_attr($faIcon) . '"></i> ' . $value . '</span>';
1941 $field_wrap_html .= '</div>';
1942 }
1943 else{
1944 if ( $label || $description ) {
1945 $field_wrap_html .= '<div class="wpf-label-wrap">';
1946 if ($label){ $field_wrap_html .= '<p class="wpf-label wpfcl-1">' . stripslashes($label) . $rIcon . '</p>'; }
1947 if ($description){ $field_wrap_html .= '<div class="wpf-desc wpfcl-2">' . $description . '</div>'; }
1948 $field_wrap_html .= '</div>';
1949 }
1950 $field_wrap_html .= '<div class="wpf-field-wrap">';
1951 if($faIcon){ $field_wrap_html .= '<i class="' . esc_attr($faIcon) . ' wpf-field-icon"></i>'; }
1952 $field_wrap_html .= $field_html;
1953 switch ($type){
1954 case 'file':
1955 if( !empty($value) ) {
1956 $wp_upload_dir = wp_upload_dir();
1957 $value = $wp_upload_dir['baseurl'] . "/" . trim($value, '/');
1958 $field_wrap_html .= '<br/>' . sprintf('<a href="%s" target="_blank">%s</a>', $value, basename($value));
1959 }
1960 break;
1961 }
1962 $field_wrap_html .= '</div>';
1963 }
1964
1965 $field_wrap_html .= '<div class="wpf-field-cl"></div></div>';
1966 }
1967 elseif( $template == 'profile' ){
1968 if( !$is_owner && !in_array( WPF()->current_user_groupid, $canView ) ){ return ''; }
1969 if( $type != 'html' && (!isset($value) || (!is_numeric($value) && empty($value))) ){ return ''; }
1970 if(is_string($value)) $value = trim($value);
1971 if(is_array($value)) $value = array_map('trim', $value);
1972 if( $type == 'textarea' ) $value = wpautop(wpforo_kses(stripslashes($value)));
1973 $field_wrap_html .= '<div class="wpf-field wpf-field-type-' . esc_attr($type) . ' wpf-field-name-' . esc_attr($field_name_class) . ' ' . esc_attr($field_required_class) . '" title="' . esc_attr($title) . '">';
1974 if( $type == 'html' ){
1975 $field_wrap_html .= $field_html;
1976 }
1977 else{
1978 if( !$faIcon ) { $faIcon = 'fas fa-address-card'; }
1979 if( $label ) {
1980 $field_wrap_html .= '<div class="wpf-label-wrap">';
1981 if ($label){
1982 $field_wrap_html .= '<p class="wpf-label wpfcl-1"><i class="' . esc_attr($faIcon) . ' wpf-field-icon"></i> ' . stripslashes($label) . '</p>';
1983 }
1984 $field_wrap_html .= '</div>';
1985 }
1986 if( isset($value) && !empty($value) ){
1987 if( is_array($value) ){
1988 $field_wrap_html .= esc_html(implode( ', ', $value));
1989 }
1990 else{
1991 switch ($args['type']){
1992 case 'url':
1993 $value = sprintf('<a href="%s" target="_blank" rel="nofollow">%s</a>', $value, $value);
1994 break;
1995 case 'email':
1996 $value = sprintf('<a href="mailto:%s" rel="nofollow">%s</a>', $value, $value);
1997 break;
1998 case 'phone':
1999 $value = sprintf('<a href="tel:%s" rel="nofollow">%s</a>', $value, $value);
2000 break;
2001 case 'file':
2002 if( !empty($value) ){
2003 $wp_upload_dir = wp_upload_dir();
2004 $value = $wp_upload_dir['baseurl'] . "/" . trim($value, '/');
2005 $value = sprintf('<a href="%s" target="_blank">%s</a>', $value, basename($value));
2006 }
2007 break;
2008 }
2009
2010 switch ($args['name']){
2011 case 'skype':
2012 $value = sprintf('<a href="skype:%s?userinfo" rel="nofollow">%s</a>', $value, $value);
2013 break;
2014 case 'location':
2015 $value = sprintf('<a href="//maps.google.com/?q=%s" target="_blank" rel="nofollow">%s</a>', $value, $value);
2016 break;
2017 case 'signature':
2018 $value = wpforo_signature( $value, array('echo' => 0) );
2019 break;
2020 case 'about':
2021 $value = wpforo_nofollow_tag( $value );
2022 break;
2023 }
2024
2025
2026 $field_wrap_html .= '<div class="wpf-field-wrap">';
2027 $field_wrap_html .= $value;
2028 $field_wrap_html .= '</div>';
2029 }
2030 }
2031 }
2032 $field_wrap_html .= '<div class="wpf-field-cl"></div></div>';
2033 }
2034 elseif( $template == 'members' ){
2035 $field_wrap_html .= '<div class="wpf-field wpf-field-type-' . esc_attr($type) . ' wpf-field-name-' . esc_attr($field_name_class) . ' ' . esc_attr($field_required_class) . '" title="' . esc_attr($title) . '">';
2036 if( $type == 'html' ){
2037 $field_wrap_html .= $field_html;
2038 }
2039 else{
2040 if ( $label || $description ) {
2041 $field_wrap_html .= '<div class="wpf-label-wrap">';
2042 if ($label){ $field_wrap_html .= '<p class="wpf-label wpfcl-1">' . stripslashes($label) . $rIcon . '</p>'; }
2043 if ($description){ $field_wrap_html .= '<div class="wpf-desc wpfcl-2">' . $description . '</div>'; }
2044 $field_wrap_html .= '</div>';
2045 }
2046 $field_wrap_html .= '<div class="wpf-field-wrap">';
2047 if($faIcon){
2048 $field_wrap_html .= '<i class="' . esc_attr($faIcon) . ' wpf-field-icon"></i>';
2049 }
2050 $field_wrap_html .= $field_html;
2051 $field_wrap_html .= '</div>';
2052 }
2053 $field_wrap_html .= '<div class="wpf-field-cl"></div></div>';
2054 }
2055 else{
2056 $field_wrap_html .= '<div class="wpf-field wpf-field-type-' . esc_attr($type) . ' wpf-field-name-' . esc_attr($field_name_class) . ' ' . esc_attr($field_required_class) . '" title="' . esc_attr($title) . '">';
2057 $field_wrap_html .= '<div class="wpf-field-wrap">' . $field_html . '<div class="wpf-field-cl"></div></div>';
2058 $field_wrap_html .= '<div class="wpf-field-cl"></div></div>';
2059 }
2060 return $field_wrap_html;
2061 }
2062
2063
2064 public function form_fields( $fields ){
2065 if(empty($fields)) return '';
2066 $html = '';
2067 foreach ($fields as $row_key => $row){
2068 $rowClasses = "row-$row_key " . apply_filters('wpforo_row_classes', '', $row_key);
2069 $html .= '<div class="wpf-tr ' . esc_attr( $rowClasses ) . '">';
2070 foreach ( $row as $col_key => $col ){
2071 $colClasses = "row_$row_key-col_$col_key " . apply_filters('wpforo_col_classes', '', $row_key, $col_key);
2072 $html .= '<div class="wpf-td wpfw-' . count($row) . ' ' . esc_attr( $colClasses ) . '">';
2073 foreach ( $col as $field ){
2074 if( !empty($field) ) $html .= $this->field( $field );
2075 }
2076 $html .= '</div>';
2077 }
2078 $html .= '<div class="wpf-cl"></div></div>';
2079 }
2080
2081 return $html;
2082 }
2083
2084 public function forum_subscribe_link(){
2085 if ( WPF()->current_userid || WPF()->current_user_email ): ?>
2086 <?php
2087 $args = array( "userid" => WPF()->current_userid, "itemid" => WPF()->current_object['forumid'], "type" => "forum", 'user_email' => WPF()->current_user_email );
2088 $subscribe = WPF()->sbscrb->get_subscribe( $args );
2089 if( isset( $subscribe['subid'] ) ): ?>
2090 <span class="wpf-unsubscribe-forum wpf-action" id="wpfsubscribe-<?php echo WPF()->current_object['forumid'] ?>"><?php wpforo_phrase('Unsubscribe') ?></span>
2091 <?php else: ?>
2092 <span class="wpf-subscribe-forum wpf-action wpfcl-5" id="wpfsubscribe-<?php echo WPF()->current_object['forumid'] ?>"><i class="far fa-envelope wpfcl-5"></i> <?php wpforo_phrase('Subscribe for new topics') ?></span>
2093 <?php endif; ?>
2094 <?php endif;
2095 }
2096
2097 public function topic_subscribe_link(){
2098 if ( WPF()->current_userid || WPF()->current_user_email ){
2099 $args = array( "userid" => WPF()->current_userid , "itemid" => WPF()->current_object['topicid'], "type" => "topic", 'user_email' => WPF()->current_user_email );
2100 $subscribe = WPF()->sbscrb->get_subscribe( $args );
2101 if( isset( $subscribe['subid'] ) ): ?>
2102 <span class="wpf-unsubscribe-topic wpf-action" id="wpfsubscribe-<?php echo WPF()->current_object['topicid'] ?>" ><?php wpforo_phrase('Unsubscribe') ?></span>
2103 <?php else: ?>
2104 <span class="wpf-subscribe-topic wpf-action wpfcl-5" id="wpfsubscribe-<?php echo WPF()->current_object['topicid'] ?>" ><i class="far fa-envelope"></i> <?php wpforo_phrase('Subscribe for new replies') ?></span>
2105 <?php endif;
2106 }
2107 }
2108
2109 public function ajx_active_tab_content(){
2110 if( !empty($_POST['active_tab_id']) ){
2111 $active_tab_id = sanitize_textarea_field($_POST['active_tab_id']);
2112 switch ($active_tab_id){
2113 case 'topic_merge_form':
2114 $this->topic_merge_form();
2115 exit();
2116 break;
2117 case 'reply_move_form':
2118 $this->reply_move_form();
2119 exit();
2120 break;
2121 case 'topic_split_form':
2122 $this->topic_split_form();
2123 exit();
2124 break;
2125 case 'topic_move_form':
2126 $this->topic_move_form();
2127 exit();
2128 break;
2129 }
2130 }
2131 echo 0;
2132 exit();
2133 }
2134
2135 public function add_footer_html(){
2136 ?>
2137 <div id="wpforo-load" class="wpforo-load">
2138 <i class="fas fa-3x fa-spinner fa-spin"></i>&nbsp;&nbsp;<br/>
2139 <span class="loadtext"><?php wpforo_phrase('Working') ?></span>
2140 </div>
2141
2142 <div id="wpf-msg-box">
2143 <p><?php echo sprintf( wpforo_phrase('Please %s or %s', FALSE), '<a href="' . wpforo_login_url() . '">'.wpforo_phrase('Login', FALSE).'</a>', '<a href="' . wpforo_register_url() . '">'.wpforo_phrase('Register', FALSE).'</a>' ) ?></p>
2144 </div>
2145 <?php
2146 }
2147 }