├── styles
└── prosilver
│ ├── template
│ ├── index.html
│ ├── event
│ │ ├── overall_footer_after.html
│ │ ├── overall_header_head_append.html
│ │ ├── viewtopic_body_postrow_custom_fields_before.html
│ │ ├── memberlist_view_user_statistics_after.html
│ │ ├── index_body_stat_blocks_before.html
│ │ ├── mcp_warn_post_add_warning_field_after.html
│ │ ├── mcp_warn_user_add_warning_field_after.html
│ │ └── viewtopic_body_post_buttons_before.html
│ ├── rateuser.html
│ ├── ratepost.html
│ ├── postdetails.html
│ ├── userdetails.html
│ ├── details.html
│ └── reputation.js
│ └── theme
│ ├── images
│ ├── neg.png
│ ├── pos.png
│ ├── icons_rating.png
│ └── reputation_delete.png
│ ├── reputation_viewtopic.css
│ └── reputation_common.css
├── config
├── tables.yml
├── listeners.yml
├── notifications.yml
├── routing.yml
└── services.yml
├── adm
└── style
│ ├── event
│ ├── acp_group_options_after.html
│ └── acp_forums_normal_settings_append.html
│ ├── reputation_settings.html
│ ├── reputation_rate.html
│ └── reputation_overview.html
├── composer.json
├── exception
├── out_of_bounds.php
├── invalid_argument.php
└── base.php
├── notification
└── type
│ ├── rate_post_negative.php
│ ├── rate_post_positive.php
│ └── rate_user.php
├── migrations
├── converter
│ ├── c3_remove_columns.php
│ ├── c6_remove_data.php
│ ├── c1_convert_table.php
│ ├── c5_remove_permissions.php
│ ├── c4_remove_modules.php
│ └── c2_convert_data.php
└── v10x
│ ├── m4_initial_modules.php
│ ├── m6_main_reputation_types.php
│ ├── m5_initial_columns.php
│ ├── m3_initial_permissions.php
│ ├── m1_initial_schema.php
│ └── m2_initial_data.php
├── controller
├── acp_interface.php
└── action_controller.php
├── acp
├── reputation_info.php
└── reputation_module.php
├── core
├── reputation_power_interface.php
├── reputation_helper.php
├── reputation_manager_interface.php
├── reputation_power.php
└── reputation_manager.php
├── language
└── en
│ ├── reputation_toplist.php
│ ├── reputation_warning.php
│ ├── exceptions.php
│ ├── reputation_common.php
│ ├── permissions_reputation.php
│ ├── info_acp_reputation.php
│ ├── reputation_rating.php
│ ├── reputation_system.php
│ └── reputation_acp.php
├── event
├── main_listener.php
├── memberlist_listener.php
├── index_listener.php
├── mcp_listener.php
├── acp_listener.php
└── viewtopic_listener.php
├── README.md
└── ext.php
/styles/prosilver/template/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/styles/prosilver/theme/images/neg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Pico/phpBB-Reputation-System/HEAD/styles/prosilver/theme/images/neg.png
--------------------------------------------------------------------------------
/styles/prosilver/theme/images/pos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Pico/phpBB-Reputation-System/HEAD/styles/prosilver/theme/images/pos.png
--------------------------------------------------------------------------------
/styles/prosilver/theme/images/icons_rating.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Pico/phpBB-Reputation-System/HEAD/styles/prosilver/theme/images/icons_rating.png
--------------------------------------------------------------------------------
/config/tables.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | tables.reputations: %core.table_prefix%reputations
3 | tables.reputation_types: %core.table_prefix%reputation_types
4 |
--------------------------------------------------------------------------------
/styles/prosilver/theme/images/reputation_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Pico/phpBB-Reputation-System/HEAD/styles/prosilver/theme/images/reputation_delete.png
--------------------------------------------------------------------------------
/styles/prosilver/template/event/overall_footer_after.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/styles/prosilver/template/event/overall_header_head_append.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/adm/style/event/acp_group_options_after.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
{USERNAME_FULL}
11 |
12 |
13 |
14 | - {AVATAR_IMG}
15 | - {RANK_TITLE}
16 | - {RANK_IMG}
17 |
18 |
19 |
20 |
21 |
22 | - {L_RANK}:
- {RANK_TITLE}
23 | - {L_RANK}:
- {RANK_IMG}
24 |
25 | - {L_REPUTATION}:
{REPUTATION}
26 |
27 |
- {L_RS_POWER}:
- {RS_POWER}
28 |
- {L_RS_VOTING_POWER}:
- {RS_POWER_LEFT}
29 |
30 |
- {L_RS_POST_COUNT}:
- {POST_COUNT}
31 |
- {L_RS_USER_COUNT}:
- {USER_COUNT}
32 |
- {L_RS_POSITIVE_COUNT}:
- {POSITIVE_COUNT} ({L_RS_POINTS}: {POSITIVE_SUM})
33 |
- {L_RS_NEGATIVE_COUNT}:
- {NEGATIVE_COUNT} ({L_RS_POINTS}: {NEGATIVE_SUM})
34 |
-
- [ {L_RS_CLEAR_USER} ]
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
{L_RS_POWER_DETAILS}
47 |
48 |
49 |
50 | - {L_RS_POWER_DETAIL_AGE}:
- {FOR_USER_AGE}
51 | - {L_RS_POWER_DETAIL_POSTS}:
- {FOR_NUMBER_OF_POSTS}
52 | - {L_RS_POWER_DETAIL_REPUTAION}:
- {FOR_REPUTATION}
53 | - {L_RS_POWER_DETAIL_WARNINGS}:
- {FOR_WARNINGS}
54 | - {L_RS_POWER_DETAIL_BANS}:
- {FOR_BANS}
55 | - {L_RS_POWER_DETAIL_MIN}:
- {MINIMUM_VOTING_POWER}
56 | - {L_RS_POWER_DETAIL_MAX}:
- {MAXIMUM_VOTING_POWER}
57 |
58 | - {L_RS_GROUP_POWER}:
- {GROUP_VOTING_POWER}
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
{L_RS_STATS}
67 |
68 |
69 |
70 | | |
71 | {L_RS_POSITIVE} |
72 | {L_RS_NEGATIVE} |
73 |
74 |
75 | | {L_RS_WEEK} |
76 | {POSITIVE_WEEK} |
77 | {NEGATIVE_WEEK} |
78 |
79 |
80 | | {L_RS_MONTH} |
81 | {POSITIVE_MONTH} |
82 | {NEGATIVE_MONTH} |
83 |
84 |
85 | | {L_RS_6MONTHS} |
86 | {POSITIVE_6MONTHS} |
87 | {NEGATIVE_6MONTHS} |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 | {reputation.AVATAR}
130 |
131 |

132 |
133 |
134 |
135 |
136 |
{L_DELETE}
137 |
{reputation.POINTS}
138 |
{reputation.USERNAME} » {reputation.TIME}
139 |
150 |
151 |
155 |
156 |
157 |
158 |
159 |
160 |
161 | {L_RS_EMPTY_DATA}
162 |
163 |
164 |
165 |
166 |
167 |
185 |
186 |
187 |
188 |
189 |
190 |
--------------------------------------------------------------------------------
/notification/type/rate_post_positive.php:
--------------------------------------------------------------------------------
1 | 'pico.reputation.notification',
46 | 'lang' => 'NOTIFICATION_TYPE_REPUTATION',
47 | 'group' => 'NOTIFICATION_GROUP_MISCELLANEOUS',
48 | );
49 |
50 | /**
51 | * Is this type available to the current user (defines whether or not it will be shown in the UCP Edit notification options)
52 | *
53 | * @return bool True/False whether or not this is available to the user
54 | */
55 | public function is_available()
56 | {
57 | return true;
58 | }
59 |
60 | /**
61 | * Get the id of the notification
62 | *
63 | * @param array $data The data for the reputation
64 | */
65 | public static function get_item_id($data)
66 | {
67 | return (int) $data['reputation_id'];
68 | }
69 |
70 | /**
71 | * Get the id of the parent
72 | *
73 | * @param array $data The data for the reputation
74 | */
75 | public static function get_item_parent_id($data)
76 | {
77 | return 0;
78 | }
79 |
80 | /**
81 | * Find the users who will receive notifications
82 | *
83 | * @param array $data The type specific data for the updated
84 | * @param array $options Options for finding users for notification
85 | *
86 | * @return array
87 | */
88 | public function find_users_for_notification($data, $options = array())
89 | {
90 | $options = array_merge(array(
91 | 'ignore_users' => array(),
92 | ), $options);
93 | $users = array((int) $data['user_id_to']);
94 |
95 | $notify_users = $this->check_user_notification_options($users, $options);
96 |
97 | // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
98 | $sql = 'SELECT n.*
99 | FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
100 | WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
101 | AND n.item_parent_id = ' . (int) self::get_item_parent_id($data) . '
102 | AND n.notification_read = 0
103 | AND nt.notification_type_id = n.notification_type_id
104 | AND nt.notification_type_enabled = 1';
105 | $result = $this->db->sql_query($sql);
106 | while ($row = $this->db->sql_fetchrow($result))
107 | {
108 | $row_data = unserialize($row['notification_data']);
109 |
110 | // Compare post id
111 | if ($row_data['post_id'] == $data['post_id'])
112 | {
113 | // Do not create a new notification
114 | unset($notify_users[$row['user_id']]);
115 |
116 | $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row);
117 | $update_voting_users = $notification->add_voting_users($data);
118 | if (!empty($update_voting_users))
119 | {
120 | $sql = 'UPDATE ' . $this->notifications_table . '
121 | SET ' . $this->db->sql_build_array('UPDATE', $update_voting_users) . '
122 | WHERE notification_id = ' . $row['notification_id'];
123 | $this->db->sql_query($sql);
124 | }
125 | }
126 | }
127 | $this->db->sql_freeresult($result);
128 |
129 | return $notify_users;
130 | }
131 |
132 | /**
133 | * Users needed to query before this notification can be displayed
134 | *
135 | * @return array Array of user_ids
136 | */
137 | public function users_to_query()
138 | {
139 | $voting_users = $this->get_data('voting_users');
140 |
141 | $users = array(
142 | $this->get_data('user_id_from'),
143 | );
144 |
145 | if (is_array($voting_users))
146 | {
147 | foreach ($voting_users as $voting_user)
148 | {
149 | $users[] = $voting_user['user_id_from'];
150 | }
151 | }
152 |
153 | return $users;
154 | }
155 |
156 | /**
157 | * Get the user's avatar
158 | */
159 | public function get_avatar()
160 | {
161 | return $this->user_loader->get_avatar($this->get_data('user_id_from'));
162 | }
163 |
164 | /**
165 | * Get the HTML formatted title of this notification
166 | *
167 | * @return string
168 | */
169 | public function get_title()
170 | {
171 | $voting_users = $this->get_data('voting_users');
172 | $usernames = array();
173 |
174 | if (!is_array($voting_users))
175 | {
176 | $voting_users = array();
177 | }
178 |
179 | $voting_users = array_merge(array(array(
180 | 'user_id_from' => $this->get_data('user_id_from'),
181 | )), $voting_users);
182 |
183 | $voting_users_cnt = sizeof($voting_users);
184 | $voting_users = $this->trim_user_ary($voting_users);
185 | $trimmed_voting_users_cnt = $voting_users_cnt - sizeof($voting_users);
186 |
187 | foreach ($voting_users as $voting_user)
188 | {
189 | $usernames[] = $this->user_loader->get_username($voting_user['user_id_from'], 'no_profile');
190 | }
191 |
192 | if ($trimmed_voting_users_cnt > 20)
193 | {
194 | $usernames[] = $this->user->lang('NOTIFICATION_MANY_OTHERS');
195 | }
196 | else if ($trimmed_voting_users_cnt)
197 | {
198 | $usernames[] = $this->user->lang('NOTIFICATION_X_OTHERS', $trimmed_voting_users_cnt);
199 | }
200 |
201 | return $this->user->lang(
202 | $this->language_key,
203 | phpbb_generate_string_list($usernames, $this->user),
204 | $trimmed_voting_users_cnt
205 | );
206 | }
207 |
208 | /**
209 | * Get the HTML formatted reference of the notification
210 | *
211 | * @return string
212 | */
213 | public function get_reference()
214 | {
215 | return $this->user->lang(
216 | 'NOTIFICATION_REFERENCE',
217 | censor_text($this->get_data('post_subject'))
218 | );
219 | }
220 |
221 | /**
222 | * Get the url to this item
223 | *
224 | * @return string URL
225 | */
226 | public function get_url()
227 | {
228 | return append_sid($this->phpbb_root_path . 'viewtopic.' . $this->php_ext, "p={$this->get_data('post_id')}#p{$this->get_data('post_id')}");
229 | }
230 |
231 | /**
232 | * Trim the user array passed down to 3 users if the array contains
233 | * more than 4 users.
234 | *
235 | * @param array $users Array of users
236 | * @return array Trimmed array of user_ids
237 | */
238 | public function trim_user_ary($users)
239 | {
240 | if (sizeof($users) > 4)
241 | {
242 | array_splice($users, 3);
243 | }
244 | return $users;
245 | }
246 |
247 | /**
248 | * Get email template
249 | *
250 | * @return string|bool
251 | */
252 | public function get_email_template()
253 | {
254 | return false;
255 | }
256 |
257 | /**
258 | * Get email template variables
259 | *
260 | * @return array
261 | */
262 | public function get_email_template_variables()
263 | {
264 | return array();
265 | }
266 |
267 | /**
268 | * Function for preparing the data for insertion in an SQL query
269 | * (The service handles insertion)
270 | *
271 | * @param array $data The data for the reputation
272 | * @param array $pre_create_data Data from pre_create_insert_array()
273 | *
274 | * @return array Array of data ready to be inserted into the database
275 | */
276 | public function create_insert_array($data, $pre_create_data = array())
277 | {
278 | $this->set_data('user_id_from', $data['user_id_from']);
279 | $this->set_data('post_id', $data['post_id']);
280 | $this->set_data('post_subject', $data['post_subject']);
281 |
282 | return parent::create_insert_array($data, $pre_create_data);
283 | }
284 |
285 | /**
286 | * Add voting users to the notification
287 | *
288 | * @param mixed $user
289 | */
290 | public function add_voting_users($user)
291 | {
292 | if ($this->get_data('user_id_from') == $user['user_id_from'])
293 | {
294 | return array();
295 | }
296 |
297 | $voting_users = $this->get_data('voting_users');
298 |
299 | $voting_users = ($voting_users === null) ? array() : $voting_users;
300 |
301 | if (sizeof($voting_users) > 25)
302 | {
303 | return array();
304 | }
305 |
306 | foreach ($voting_users as $voting_user)
307 | {
308 | if ($voting_user['user_id_from'] == $user['user_id_from'])
309 | {
310 | return array();
311 | }
312 | }
313 |
314 | $voting_users[] = array(
315 | 'user_id_from' => $user['user_id_from'],
316 | );
317 |
318 | $this->set_data('voting_users', $voting_users);
319 |
320 | $serialized_data = serialize($this->get_data(false));
321 |
322 | if (utf8_strlen($serialized_data) >= 4000)
323 | {
324 | return array();
325 | }
326 |
327 | return array('notification_data' => $serialized_data);
328 | }
329 | }
330 |
--------------------------------------------------------------------------------
/notification/type/rate_user.php:
--------------------------------------------------------------------------------
1 | user_loader = $user_loader;
44 | $this->db = $db;
45 | $this->cache = $cache;
46 | $this->user = $user;
47 | $this->auth = $auth;
48 | $this->config = $config;
49 | $this->helper = $helper;
50 | $this->phpbb_root_path = $phpbb_root_path;
51 | $this->php_ext = $php_ext;
52 | $this->notification_types_table = $notification_types_table;
53 | $this->notifications_table = $notifications_table;
54 | $this->user_notifications_table = $user_notifications_table;
55 | }
56 |
57 | /**
58 | * Get notification type name
59 | *
60 | * @return string
61 | */
62 | public function get_type()
63 | {
64 | return 'pico.reputation.notification.type.rate_user';
65 | }
66 |
67 | /**
68 | * Language key used to output the text
69 | *
70 | * @var string
71 | */
72 | protected $language_key = 'NOTIFICATION_RATE_USER';
73 |
74 | /**
75 | * Notification option data (for outputting to the user)
76 | *
77 | * @var bool|array False if the service should use it's default data
78 | * Array of data (including keys 'id', 'lang', and 'group')
79 | */
80 | public static $notification_option = array(
81 | 'id' => 'pico.reputation.notification',
82 | 'lang' => 'NOTIFICATION_TYPE_REPUTATION',
83 | 'group' => 'NOTIFICATION_GROUP_MISCELLANEOUS',
84 | );
85 |
86 | /**
87 | * Is this type available to the current user (defines whether or not it will be shown in the UCP Edit notification options)
88 | *
89 | * @return bool True/False whether or not this is available to the user
90 | */
91 | public function is_available()
92 | {
93 | return true;
94 | }
95 |
96 | /**
97 | * Get the id of the notification
98 | *
99 | * @param array $data The data for the reputation
100 | */
101 | public static function get_item_id($data)
102 | {
103 | return (int) $data['reputation_id'];
104 | }
105 |
106 | /**
107 | * Get the id of the parent
108 | *
109 | * @param array $data The data for the reputation
110 | */
111 | public static function get_item_parent_id($data)
112 | {
113 | return 0;
114 | }
115 |
116 | /**
117 | * Find the users who will receive notifications
118 | *
119 | * @param array $data The type specific data for the updated
120 | * @param array $options Options for finding users for notification
121 | *
122 | * @return array
123 | */
124 | public function find_users_for_notification($data, $options = array())
125 | {
126 | $options = array_merge(array(
127 | 'ignore_users' => array(),
128 | ), $options);
129 | $users = array((int) $data['user_id_to']);
130 |
131 | $notify_users = $this->check_user_notification_options($users, $options);
132 |
133 | // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
134 | $sql = 'SELECT n.*
135 | FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
136 | WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
137 | AND n.item_parent_id = ' . (int) self::get_item_parent_id($data) . '
138 | AND n.notification_read = 0
139 | AND n.user_id = ' . $data['user_id_to'] . '
140 | AND nt.notification_type_id = n.notification_type_id
141 | AND nt.notification_type_enabled = 1';
142 | $result = $this->db->sql_query($sql);
143 | while ($row = $this->db->sql_fetchrow($result))
144 | {
145 | $row_data = unserialize($row['notification_data']);
146 |
147 | // Do not create a new notification
148 | unset($notify_users[$row['user_id']]);
149 |
150 | $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row);
151 | $update_responders = $notification->add_voting_users($data);
152 | if (!empty($update_responders))
153 | {
154 | $sql = 'UPDATE ' . $this->notifications_table . '
155 | SET ' . $this->db->sql_build_array('UPDATE', $update_responders) . '
156 | WHERE notification_id = ' . $row['notification_id'];
157 | $this->db->sql_query($sql);
158 | }
159 | }
160 | $this->db->sql_freeresult($result);
161 |
162 | return $notify_users;
163 | }
164 |
165 | /**
166 | * Users needed to query before this notification can be displayed
167 | *
168 | * @return array Array of user_ids
169 | */
170 | public function users_to_query()
171 | {
172 | $voting_users = $this->get_data('voting_users');
173 |
174 | $users = array(
175 | $this->get_data('user_id_from'),
176 | );
177 |
178 | if (is_array($voting_users))
179 | {
180 | foreach ($voting_users as $voting_user)
181 | {
182 | $users[] = $voting_user['user_id_from'];
183 | }
184 | }
185 |
186 | return $users;
187 | }
188 |
189 | /**
190 | * Get the user's avatar
191 | */
192 | public function get_avatar()
193 | {
194 | return $this->user_loader->get_avatar($this->get_data('user_id_from'));
195 | }
196 |
197 | /**
198 | * Get the HTML formatted title of this notification
199 | *
200 | * @return string
201 | */
202 | public function get_title()
203 | {
204 | $voting_users = $this->get_data('voting_users');
205 | $usernames = array();
206 |
207 | if (!is_array($voting_users))
208 | {
209 | $voting_users = array();
210 | }
211 |
212 | $voting_users = array_merge(array(array(
213 | 'user_id_from' => $this->get_data('user_id_from'),
214 | )), $voting_users);
215 |
216 | $voting_users_cnt = sizeof($voting_users);
217 | $voting_users = $this->trim_user_ary($voting_users);
218 | $trimmed_voting_users_cnt = $voting_users_cnt - sizeof($voting_users);
219 |
220 | foreach ($voting_users as $voting_user)
221 | {
222 | $usernames[] = $this->user_loader->get_username($voting_user['user_id_from'], 'no_profile');
223 | }
224 |
225 | if ($trimmed_voting_users_cnt > 20)
226 | {
227 | $usernames[] = $this->user->lang('NOTIFICATION_MANY_OTHERS');
228 | }
229 | else if ($trimmed_voting_users_cnt)
230 | {
231 | $usernames[] = $this->user->lang('NOTIFICATION_X_OTHERS', $trimmed_voting_users_cnt);
232 | }
233 |
234 | return $this->user->lang(
235 | $this->language_key,
236 | phpbb_generate_string_list($usernames, $this->user),
237 | $trimmed_voting_users_cnt
238 | );
239 | }
240 |
241 | /**
242 | * Get the url to this item
243 | *
244 | * @return string URL
245 | */
246 | public function get_url()
247 | {
248 | return $this->helper->route('reputation_details_controller', array('uid' => $this->user->data['user_id']));
249 | }
250 |
251 | /**
252 | * Trim the user array passed down to 3 users if the array contains
253 | * more than 4 users.
254 | *
255 | * @param array $users Array of users
256 | * @return array Trimmed array of user_ids
257 | */
258 | public function trim_user_ary($users)
259 | {
260 | if (sizeof($users) > 4)
261 | {
262 | array_splice($users, 3);
263 | }
264 | return $users;
265 | }
266 |
267 | /**
268 | * Get email template
269 | *
270 | * @return string|bool
271 | */
272 | public function get_email_template()
273 | {
274 | return false;
275 | }
276 |
277 | /**
278 | * Get email template variables
279 | *
280 | * @return array
281 | */
282 | public function get_email_template_variables()
283 | {
284 | return array();
285 | }
286 |
287 | /**
288 | * Function for preparing the data for insertion in an SQL query
289 | * (The service handles insertion)
290 | *
291 | * @param array $data The data for the reputation
292 | * @param array $pre_create_data Data from pre_create_insert_array()
293 | *
294 | * @return array Array of data ready to be inserted into the database
295 | */
296 | public function create_insert_array($data, $pre_create_data = array())
297 | {
298 | $this->set_data('user_id_from', $data['user_id_from']);
299 |
300 | return parent::create_insert_array($data, $pre_create_data);
301 | }
302 |
303 | /**
304 | * Add voting users to the notification
305 | *
306 | * @param mixed $user
307 | */
308 | public function add_voting_users($user)
309 | {
310 | if ($this->get_data('user_id_from') == $user['user_id_from'])
311 | {
312 | return array();
313 | }
314 |
315 | $voting_users = $this->get_data('voting_users');
316 |
317 | $voting_users = ($voting_users === null) ? array() : $voting_users;
318 |
319 | if (sizeof($voting_users) > 25)
320 | {
321 | return array();
322 | }
323 |
324 | foreach ($voting_users as $voting_user)
325 | {
326 | if ($voting_user['user_id_from'] == $user['user_id_from'])
327 | {
328 | return array();
329 | }
330 | }
331 |
332 | $voting_users[] = array(
333 | 'user_id_from' => $user['user_id_from'],
334 | );
335 |
336 | $this->set_data('voting_users', $voting_users);
337 |
338 | $serialized_data = serialize($this->get_data(false));
339 |
340 | if (utf8_strlen($serialized_data) >= 4000)
341 | {
342 | return array();
343 | }
344 |
345 | return array('notification_data' => $serialized_data);
346 | }
347 | }
348 |
--------------------------------------------------------------------------------
/styles/prosilver/template/reputation.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @package Reputation System
3 | * @copyright (c) 2014 Pico
4 | * @license http://opensource.org/licenses/gpl-license.php GNU Public License
5 | */
6 | var reputation = {};
7 | reputation.requestSent = false;
8 |
9 | (function ($) { // Avoid conflicts with other libraries
10 |
11 | /*$(document).ready(function() {
12 | //TO-DO Highlighting and hiding post
13 | $('.positive').each(function() {
14 | $(this).parents('.post').addClass("hidden");
15 | });
16 | });*/
17 |
18 | // Close reputation popup
19 | $('body').click(function() {
20 | if (!reputation.requestSent) {
21 | $("#reputation-popup").fadeOut('fast');
22 | }
23 | });
24 |
25 | // Stop propagation
26 | $('#reputation-popup').click(function(e) {
27 | e.stopPropagation();
28 | });
29 |
30 | // Rating user
31 | $('#rate-user').click(function(event) {
32 | reputation.show_popup(this.href, event, 'user', $(this).attr('data-referer'));
33 | });
34 |
35 | // Rating post - positive
36 | $('a.rate-good-icon').click(function(event) {
37 | reputation.show_popup(this.href, event, 'post', $(this).attr('data-referer'));
38 | });
39 |
40 | // Rating post - negative
41 | $('a.rate-bad-icon').click(function(event) {
42 | reputation.show_popup(this.href, event, 'post', $(this).attr('data-referer'));
43 | });
44 |
45 | // Display post reputation details
46 | $('a.post-reputation').click(function(event) {
47 | reputation.show_popup(this.href, event, 'details', $(this).attr('data-referer'));
48 | });
49 |
50 | // Display user reputation details
51 | $('.user-reputation a').click(function(event) {
52 | reputation.show_popup(this.href, event, 'details', $(this).attr('data-referer'));
53 | });
54 |
55 | // Save vote
56 | $('#reputation-popup').on("click", '.button1', function(event) {
57 | event.stopPropagation();
58 | event.preventDefault();
59 |
60 | reputation.submit_action($('#reputation-popup > form').attr('action'), $('#reputation-popup > form').attr('data-rate'));
61 | });
62 |
63 | // Cancel rating
64 | $('#reputation-popup').on("click", '.button2', function(event) {
65 | event.stopPropagation();
66 | event.preventDefault();
67 |
68 | $('#reputation-popup').fadeOut('fast').queue(function() {
69 | $(this).empty();
70 | $(this).dequeue();
71 | });
72 | });
73 |
74 | // Sort reputation by
75 | $('#reputation-popup').on("click", 'a.sort_order', function(event) {
76 | event.stopPropagation();
77 | event.preventDefault();
78 |
79 | reputation.sort_order_by(this.href, $('.footer-popup').attr('data-referer'));
80 | });
81 |
82 | // Delete reputation
83 | $('#reputation-popup').on("click", '.reputation-delete', function(event) {
84 | event.stopPropagation();
85 | event.preventDefault();
86 |
87 | var confirmation = $('a.reputation-delete').attr('data-lang-confirm');
88 |
89 | if (confirm(confirmation)) {
90 | reputation.submit_action(this.href, 'delete');
91 | }
92 | });
93 |
94 | // Clear reputation
95 | $('#reputation-popup').on("click", '.clear-reputation', function(event) {
96 | event.stopPropagation();
97 | event.preventDefault();
98 |
99 | var confirmation = $('a.clear-reputation').attr('data-lang-confirm');
100 |
101 | if (confirm(confirmation)) {
102 | reputation.submit_action(this.href, 'clear');
103 | }
104 | });
105 |
106 | /**
107 | * Show the reputation popup with proper data
108 | */
109 | reputation.show_popup = function(href, event, mode, ref) {
110 | event.stopPropagation();
111 | event.preventDefault();
112 |
113 | if (!reputation.requestSent) {
114 | reputation.requestSent = true;
115 |
116 | $.ajax({
117 | url: href,
118 | data: ref,
119 | dataType: 'html',
120 | beforeSend: function() {
121 | $('#reputation-popup').hide().empty().removeClass('small-popup normal-popup');
122 | },
123 | success: function(data) {
124 | // Fix - do not display the empty popup when comment and reputation power are disabled
125 | if (data.substr(0,1) != '{') {
126 | $('#reputation-popup').append(data).fadeIn('fast');
127 | }
128 |
129 | switch(mode) {
130 | case 'details':
131 | $('#reputation-popup').addClass('normal-popup');
132 | targetleft = ($(window).width() - $('#reputation-popup').outerWidth()) / 2;
133 | targettop = ($(window).height() - $('#reputation-popup').outerHeight()) / 2;
134 | break;
135 |
136 | default:
137 | $('#reputation-popup').addClass('small-popup');
138 | // Center popup relative to clicked coordinate
139 | targetleft = event.pageX - $('#reputation-popup').outerWidth() / 2;
140 | // Popup can not be too close or behind the right border of the screen
141 | targetleft = Math.min (targetleft, $(document).width() - 20 - $('#reputation-popup').outerWidth());
142 | targetleft = Math.max (targetleft, 20);
143 | targettop = event.pageY + 10;
144 | break;
145 | }
146 |
147 | $('#reputation-popup').css({'top': targettop + 'px', 'left': targetleft + 'px'});
148 |
149 | // It's JSON! Probably an error. Lets clean the reputation popup and show the error there
150 | if (data.substr(0,1) == '{') {
151 | reputation.response(jQuery.parseJSON(data), mode);
152 | }
153 | },
154 | complete: function() {
155 | reputation.requestSent = false;
156 | }
157 | });
158 | }
159 | }
160 |
161 | /**
162 | * Submit reputation action
163 | */
164 | reputation.submit_action = function(href, mode) {
165 | switch(mode) {
166 | case 'post':
167 | case 'user':
168 | data = $('#reputation-popup form').serialize();
169 | break;
170 |
171 | default:
172 | data = '';
173 | break;
174 | }
175 |
176 | $.ajax({
177 | url: href,
178 | data: data,
179 | dataType: 'json',
180 | type: 'POST',
181 | success: function(r) {
182 | reputation.response(r, mode);
183 | }
184 | });
185 | }
186 |
187 | /**
188 | * Reputation response
189 | */
190 | reputation.response = function(data, mode) {
191 | // If there is an error, show it
192 | if (data.error_msg) {
193 | $('#reputation-popup').empty().append('
' + data.error_msg + '
').fadeIn();
194 | }
195 | // If there is a comment error, show it
196 | else if (data.comment_error) {
197 | $('.error').detach();
198 | $('.comment').append('
' + data.comment_error + '
');
199 | }
200 | // Otherwise modify the board outlook
201 | else {
202 | switch (mode) {
203 | case 'post':
204 | var post_id = data.post_id;
205 | var poster_id = data.poster_id;
206 |
207 | $('#reputation-popup').empty().append('
' + data.success_msg + '
').delay(500).fadeOut('fast').queue(function() {
208 | $('#profile-' + poster_id + ' span').text(data.user_reputation);
209 | $('#p' + post_id + ' .post-reputation span').text(data.post_reputation);
210 | $('#p' + post_id + ' .post-reputation').removeClass('neutral negative positive').addClass(data.reputation_class);
211 | $('#p' + post_id + ' .rate-good-icon').removeClass('rated_good rated_bad').addClass(data.reputation_vote);
212 | $('#p' + post_id + ' .rate-bad-icon').removeClass('rated_good rated_bad').addClass(data.reputation_vote);
213 | $(this).empty().dequeue();
214 | });
215 | break;
216 |
217 | case 'user':
218 | $('#reputation-popup').empty().append('
' + data.success_msg + '
').delay(500).fadeOut('fast').queue(function() {
219 | $('#user-reputation').html(data.user_reputation);
220 | $(this).empty().dequeue();
221 | });
222 | break;
223 |
224 | case 'delete':
225 | var post_id = data.post_id;
226 | var poster_id = data.poster_id;
227 | var rid = data.rid;
228 |
229 | $('#r' + rid).hide('fast', function() {
230 | $('#r' + rid).detach();
231 | if ($('.reputation-list').length == 0) {
232 | $('#reputation-popup').fadeOut('fast').empty();
233 | }
234 | });
235 | $('#profile-' + poster_id + ' span').text(data.user_reputation);
236 | $('#p' + post_id + ' .post-reputation span').text(data.post_reputation);
237 | $('#p' + post_id + ' .post-reputation').removeClass('neutral negative positive').addClass(data.reputation_class);
238 |
239 | if (data.own_vote) {
240 | $('#p' + post_id + ' .rate-good-icon').removeClass('rated_good rated_bad');
241 | $('#p' + post_id + ' .rate-bad-icon').removeClass('rated_good rated_bad');
242 | }
243 | break;
244 |
245 | case 'clear':
246 | if (data.clear_post) {
247 | var post_id = data.post_id;
248 | var poster_id = data.poster_id;
249 |
250 | $('.reputation-list').slideUp(function() {
251 | $('#reputation-popup').fadeOut('fast').empty().delay(300).queue(function() {
252 | $('#profile-' + poster_id + ' span').text(data.user_reputation);
253 | $('#p' + post_id + ' .post-reputation span').text(data.post_reputation);
254 | $('#p' + post_id + ' .post-reputation').removeClass('neutral negative positive').addClass(data.reputation_class);
255 | $('#p' + post_id + ' .rate-good-icon').removeClass('rated_good rated_bad');
256 | $('#p' + post_id + ' .rate-bad-icon').removeClass('rated_good rated_bad');
257 | }).dequeue();
258 | });
259 |
260 | }
261 | else if (data.clear_user) {
262 | var post_ids = data.post_ids;
263 | var poster_id = data.poster_id;
264 |
265 | $('.reputation-list').slideUp(function() {
266 | $('#reputation-popup').fadeOut('fast').empty().delay(300).queue(function() {
267 | $('#profile-' + poster_id + ' span').text(data.user_reputation);
268 |
269 | $.each(post_ids, function(i, post_id) {
270 | $('#p' + post_id + ' .post-reputation span').text(data.post_reputation);
271 | $('#p' + post_id + ' .post-reputation').removeClass('neutral negative positive').addClass(data.reputation_class);
272 | $('#p' + post_id + ' .rate-good-icon').removeClass('rated_good rated_bad');
273 | $('#p' + post_id + ' .rate-bad-icon').removeClass('rated_good rated_bad');
274 | });
275 | }).dequeue();
276 | });
277 | }
278 | break;
279 | }
280 | }
281 | }
282 |
283 | /**
284 | * Sort reputations
285 | */
286 | reputation.sort_order_by = function(href, ref) {
287 | $.ajax({
288 | url: href,
289 | data: ref,
290 | dataType: 'html',
291 | success: function(s) {
292 | $('#reputation-popup').empty().append(s);
293 | }
294 | });
295 | }
296 |
297 | })(jQuery); // Avoid conflicts with other libraries
298 |
--------------------------------------------------------------------------------
/language/en/reputation_acp.php:
--------------------------------------------------------------------------------
1 | 'Here you can configure Reputation System’s settings. They are divided into groups.',
42 | 'ACP_REPUTATION_RATE_EXPLAIN' => 'Here you can award additional reputation points to any users.',
43 |
44 | 'RS_ENABLE' => 'Enable Reputation System',
45 |
46 | 'RS_SYNC' => 'Synchronise Reputation System',
47 | 'RS_SYNC_EXPLAIN' => 'You can synchronise reputation points after a mass removal of posts/topics/users, changing reputation settings, changing post authors, conversions from others systems. This may take a while. You will be notified when the process is completed.
Warning! All reputation points that do not match the reputation settings will be deleted during synchronization . It is recommended to make backup of the reputation table (DB) before synchronisation.',
48 | 'RS_SYNC_REPUTATION_CONFIRM' => 'Are you sure you wish to synchronise reputations?',
49 |
50 | 'RS_TRUNCATE' => 'Clear Reputation System',
51 | 'RS_TRUNCATE_EXPLAIN' => 'This procedure completely removes all data.
Action is not reversible!',
52 | 'RS_TRUNCATE_CONFIRM' => 'Are you sure you wish to clear Reputation System?',
53 | 'RS_TRUNCATE_DONE' => 'Reputations were cleared.',
54 |
55 | 'REPUTATION_SETTINGS_CHANGED' => '
Altered Reputation System settings',
56 |
57 | // Setting legend
58 | 'ACP_RS_MAIN' => 'General',
59 | 'ACP_RS_DISPLAY' => 'Display settings',
60 | 'ACP_RS_POSTS_RATING' => 'Post rating',
61 | 'ACP_RS_USERS_RATING' => 'User rating',
62 | 'ACP_RS_COMMENT' => 'Comments',
63 | 'ACP_RS_POWER' => 'Reputation power',
64 | 'ACP_RS_TOPLIST' => 'Toplist',
65 |
66 | // General
67 | 'RS_NEGATIVE_POINT' => 'Allow negative points',
68 | 'RS_NEGATIVE_POINT_EXPLAIN' => 'When disabled users can not give negative points.',
69 | 'RS_MIN_REP_NEGATIVE' => 'Minimum reputation for negative voting',
70 | 'RS_MIN_REP_NEGATIVE_EXPLAIN' => 'How much reputation is required to give negative points. Setting the value to 0 disables this behaviour.',
71 | 'RS_WARNING' => 'Enable warnings',
72 | 'RS_WARNING_EXPLAIN' => 'Users with proper permissions can give negative points when warning users.',
73 | 'RS_WARNING_MAX_POWER' => 'Maximum reputation power for warnings',
74 | 'RS_WARNING_MAX_POWER_EXPLAIN' => 'Maximum reputation power allowed for warnings.',
75 | 'RS_MIN_POINT' => 'Minimum points',
76 | 'RS_MIN_POINT_EXPLAIN' => 'Limits the minimum reputation points a user can receive. Setting the value to 0 disables this behaviour.',
77 | 'RS_MAX_POINT' => 'Maximum points',
78 | 'RS_MAX_POINT_EXPLAIN' => 'Limits the maximum reputation points a user can receive. Setting the value to 0 disables this behaviour.',
79 | 'RS_PREVENT_OVERRATING' => 'Prevent overrating',
80 | 'RS_PREVENT_OVERRATING_EXPLAIN' => 'Block users from rating the same user.
Example: if user A has more than 10 reputation entries and 85% of them come from user B, user B can not rate that user until his votes ratio is higher than 85%.
To disable this feature set one or both values to 0.',
81 | 'RS_PREVENT_NUM' => 'Total reputation entries of user A is equal to or higher than',
82 | 'RS_PREVENT_PERC' => '
and ratio of user B votes is equal to or higher than',
83 | 'RS_PER_PAGE' => 'Reputations per page',
84 | 'RS_PER_PAGE_EXPLAIN' => 'How many rows should we display in tables of reputation points?',
85 | 'RS_DISPLAY_AVATAR' => 'Display avatars',
86 | 'RS_POINT_TYPE' => 'Method for displaying points',
87 | 'RS_POINT_TYPE_EXPLAIN' => 'Viewing reputation points can be displayed as either the exact value of reputation points a user gave or as an image showing a plus or minus for positive or negative points. The Image method is useful if you set up reputation points so that one rating always equals to one point.',
88 | 'RS_POINT_VALUE' => 'Value',
89 | 'RS_POINT_IMG' => 'Image',
90 |
91 | // Post rating
92 | 'RS_POST_RATING' => 'Enable post rating',
93 | 'RS_POST_RATING_EXPLAIN' => 'Allow users to rate other user posts.
On each forums management page you can enable or disable reputations.',
94 | 'RS_ALLOW_REPUTATION_BUTTON' => 'Submit and enable Reputation System in all forums',
95 | 'RS_ANTISPAM' => 'Anti-Spam',
96 | 'RS_ANTISPAM_EXPLAIN' => 'Block users from rating any more posts after they have rated the defined number of posts within the defined number of hours. To disable this feature set one or both values to 0.',
97 | 'RS_POSTS' => 'Number of rated posts',
98 | 'RS_HOURS' => 'in the last hours',
99 | 'RS_ANTISPAM_METHOD' => 'Anti-Spam check method',
100 | 'RS_ANTISPAM_METHOD_EXPLAIN' => 'Method for checking Anti-Spam. “Same user” method checks reputation given to the same user. “All users” method checks reputation regardless of who received points.',
101 | 'RS_SAME_USER' => 'Same user',
102 | 'RS_ALL_USERS' => 'All users',
103 |
104 | // User rating
105 | 'RS_USER_RATING' => 'Allow rating of users from their profile page',
106 | 'RS_USER_RATING_GAP' => 'Voting gap',
107 | 'RS_USER_RATING_GAP_EXPLAIN' => 'Time period a user must wait before they can give another rating to a user they have already rated. Setting the value to 0 disables this behaviour and users can rate other users once each.',
108 |
109 | // Comments
110 | 'RS_ENABLE_COMMENT' => 'Enable comments',
111 | 'RS_ENABLE_COMMENT_EXPLAIN' => 'When enabled, users will be able to add a personal comment with their rating.',
112 | 'RS_FORCE_COMMENT' => 'Force user to enter comment',
113 | 'RS_FORCE_COMMENT_EXPLAIN' => 'Users will be required to add a comment with their rating.',
114 | 'RS_COMMENT_NO' => 'No',
115 | 'RS_COMMENT_BOTH' => 'Both user and post ratings',
116 | 'RS_COMMENT_POST' => 'Only post ratings',
117 | 'RS_COMMENT_USER' => 'Only user ratings',
118 | 'RS_COMMEN_LENGTH' => 'Comment length',
119 | 'RS_COMMEN_LENGTH_EXPLAIN' => 'The number of characters allowed within a comment. Set to 0 for unlimited characters.',
120 |
121 | // Reputation power
122 | 'RS_ENABLE_POWER' => 'Enable reputation power',
123 | 'RS_ENABLE_POWER_EXPLAIN' => 'Reputation power is something that users earn and spend on voting. New users have low power, active and veteran users gain more power. The more power you have the more you can vote during a specified period of time and the more influence you can have on the rating of another user or post.
Users can choose during voting how much power they will spend on a vote, giving more points to interesting posts.',
124 | 'RS_POWER_RENEWAL' => 'Power renewal time',
125 | 'RS_POWER_RENEWAL_EXPLAIN' => 'This controls how users can spend earned power.
If you set this option, users must wait for the given time interval before they can vote again. The more reputation power a user has, the more points they can spend in the set time.
Setting the value to 0 disables this behaviour and users can vote without waiting.',
126 | 'RS_MIN_POWER' => 'Starting/Minimum reputation power',
127 | 'RS_MIN_POWER_EXPLAIN' => 'This is how much reputation power newly registered users, banned users and users with low reputation or other criteria have. Users can’t go lower than this minimum voting power.
Allowed 0-10. Recommended 1.',
128 | 'RS_MAX_POWER' => 'Maximum power spending per vote',
129 | 'RS_MAX_POWER_EXPLAIN' => 'Maximum amount of power that a user can spend per vote. Even if a user has millions of points, they’ll still be limited by this maximum number when voting.
Users will select this from dropdown menu: 1 to X
Allowed 1-20. Recommended: 3.',
130 | 'RS_POWER_EXPLAIN' => 'Reputation power explanation',
131 | 'RS_POWER_EXPLAIN_EXPLAIN' => 'Explain how reputation power is calculated to users.',
132 | 'RS_TOTAL_POSTS' => 'Gain power with number of posts',
133 | 'RS_TOTAL_POSTS_EXPLAIN' => 'User will gain 1 reputation power every X number of posts set here.',
134 | 'RS_MEMBERSHIP_DAYS' => 'Gain power with length of the user’s membership',
135 | 'RS_MEMBERSHIP_DAYS_EXPLAIN' => 'User will gain 1 reputation power every X number of days set here',
136 | 'RS_POWER_REP_POINT' => 'Gain power with the user’s reputation',
137 | 'RS_POWER_REP_POINT_EXPLAIN' => 'User will gain 1 reputation power every X number of reputation points they earn set here.',
138 | 'RS_LOSE_POWER_WARN' => 'Lose power with warnings',
139 | 'RS_LOSE_POWER_WARN_EXPLAIN' => 'Each warning decreases reputation power by this amount of points. Warnings expire in accordance with the settings in General -> Board Configuration -> Board settings',
140 |
141 | // Toplist
142 | 'RS_ENABLE_TOPLIST' => 'Enable Toplist',
143 | 'RS_ENABLE_TOPLIST_EXPLAIN' => 'Display a list of users with the most reputation points on the index page.',
144 | 'RS_TOPLIST_DIRECTION' => 'Direction of list',
145 | 'RS_TOPLIST_DIRECTION_EXPLAIN' => 'Display the users in the list in a horizontal or vertical direction.',
146 | 'RS_TL_HORIZONTAL' => 'Horizontal',
147 | 'RS_TL_VERTICAL' => 'Vertical',
148 | 'RS_TOPLIST_NUM' => 'Number of Users to Display',
149 | 'RS_TOPLIST_NUM_EXPLAIN' => 'Number of users displayed on the toplist.',
150 |
151 | // Rate module
152 | 'POINTS_INVALID' => 'Points field has to contain only numbers.',
153 | 'RS_VOTE_SAVED' => 'Your vote has been saved successfully',
154 | ));
155 |
--------------------------------------------------------------------------------
/controller/action_controller.php:
--------------------------------------------------------------------------------
1 | auth = $auth;
67 | $this->db = $db;
68 | $this->helper = $helper;
69 | $this->request = $request;
70 | $this->user = $user;
71 | $this->reputation_helper = $reputation_helper;
72 | $this->reputation_manager = $reputation_manager;
73 | $this->reputations_table = $reputations_table;
74 | $this->reputation_types_table = $reputation_types_table;
75 | $this->root_path = $root_path;
76 | $this->php_ext = $php_ext;
77 | }
78 |
79 | /**
80 | * Delete reputation page/action
81 | *
82 | * @param int $rid Reputation ID taken from the URL
83 | * @return null
84 | * @access public
85 | */
86 | public function delete($rid)
87 | {
88 | $this->user->add_lang_ext('pico/reputation', 'reputation_system');
89 | $is_ajax = $this->request->is_ajax();
90 | $submit = false;
91 |
92 | $post_type_id = (int) $this->reputation_manager->get_reputation_type_id('post');
93 |
94 | $sql_array = array(
95 | 'SELECT' => 'r.*, rt.reputation_type_name, p.post_id, uf.username AS username_from, ut.username AS username_to',
96 | 'FROM' => array(
97 | $this->reputations_table => 'r',
98 | $this->reputation_types_table => 'rt',
99 | ),
100 | 'LEFT_JOIN' => array(
101 | array(
102 | 'FROM' => array(POSTS_TABLE => 'p'),
103 | 'ON' => 'p.post_id = r.reputation_item_id
104 | AND r.reputation_type_id = ' . $post_type_id,
105 | ),
106 | array(
107 | 'FROM' => array(USERS_TABLE => 'uf'),
108 | 'ON' => 'r.user_id_from = uf.user_id ',
109 | ),
110 | array(
111 | 'FROM' => array(USERS_TABLE => 'ut'),
112 | 'ON' => 'r.user_id_to = ut.user_id ',
113 | ),
114 | ),
115 | 'WHERE' => 'r.reputation_id = ' . $rid,
116 | );
117 | $sql = $this->db->sql_build_query('SELECT', $sql_array);
118 | $result = $this->db->sql_query($sql);
119 | $row = $this->db->sql_fetchrow($result);
120 | $this->db->sql_freeresult($result);
121 |
122 | //We couldn't find this reputation. May be it was deleted meanwhile?
123 | if (empty($row))
124 | {
125 | $message = $this->user->lang('RS_NO_REPUTATION');
126 | $json_data = array(
127 | 'error_msg' => $message,
128 | );
129 | $redirect = append_sid("{$this->root_path}index.$this->php_ext");
130 | $redirect_text = 'RETURN_INDEX';
131 |
132 | $this->reputation_manager->response($message, $json_data, $redirect, $redirect_text, $is_ajax);
133 | }
134 |
135 | if ($this->request->is_set_post('cancel'))
136 | {
137 | redirect($this->helper->route('reputation_details_controller', array('uid' => $row['user_id_to'])));
138 | }
139 |
140 | if ($this->auth->acl_gets('m_rs_moderate') || (($row['user_id_from'] == $this->user->data['user_id']) && $this->auth->acl_get('u_rs_delete')))
141 | {
142 | if ($is_ajax)
143 | {
144 | $submit = true;
145 | }
146 | else
147 | {
148 | $s_hidden_fields = build_hidden_fields(array(
149 | 'r' => $rid,
150 | ));
151 |
152 | if (confirm_box(true))
153 | {
154 | $submit = true;
155 | }
156 | else
157 | {
158 | confirm_box(false, $this->user->lang('RS_REPUTATION_DELETE_CONFIRM'), $s_hidden_fields);
159 | }
160 | }
161 | }
162 | else
163 | {
164 | $message = $this->user->lang('RS_USER_CANNOT_DELETE');
165 | $json_data = array(
166 | 'error_msg' => $message,
167 | );
168 | $redirect = $this->helper->route('reputation_details_controller', array('uid' => $row['user_id_to']));
169 | $redirect_text = 'RETURN_PAGE';
170 |
171 | $this->reputation_manager->response($message, $json_data, $redirect, $redirect_text, $is_ajax);
172 | }
173 |
174 | if ($submit)
175 | {
176 | try
177 | {
178 | $this->reputation_manager->delete_reputation($row);
179 | }
180 | catch (\pico\reputation\exception\base $e)
181 | {
182 | // Catch exception
183 | trigger_error($e->get_message($this->user));
184 | }
185 |
186 | $user_reputation = $this->reputation_manager->get_user_reputation($row['user_id_to']);
187 |
188 | $message = $this->user->lang('RS_POINTS_DELETED');
189 | $json_data = array(
190 | 'rid' => $rid,
191 | 'user_reputation' => $user_reputation,
192 | );
193 |
194 | if (isset($row['post_id']))
195 | {
196 | $post_reputation = $this->reputation_manager->get_post_reputation($row['post_id']);
197 |
198 | $json_data = array_merge($json_data, array(
199 | 'poster_id' => $row['user_id_to'],
200 | 'post_id' => $row['post_id'],
201 | 'post_reputation' => $post_reputation,
202 | 'reputation_class' => $this->reputation_helper->reputation_class($post_reputation),
203 | 'own_vote' => ($row['user_id_from'] == $this->user->data['user_id']) ? true : false,
204 | ));
205 | }
206 |
207 | $redirect = $this->helper->route('reputation_details_controller', array('uid' => $row['user_id_to']));
208 | $redirect_text = 'RETURN_PAGE';
209 |
210 | $this->reputation_manager->response($message, $json_data, $redirect, $redirect_text, $is_ajax);
211 | }
212 | }
213 |
214 | /**
215 | * Clear post reputation
216 | *
217 | * @param int $post_id Post ID
218 | * @return null
219 | * @access public
220 | */
221 | public function clear_post($post_id)
222 | {
223 | $this->user->add_lang_ext('pico/reputation', 'reputation_system');
224 | $is_ajax = $this->request->is_ajax();
225 | $submit = false;
226 | $post_type_id = (int) $this->reputation_manager->get_reputation_type_id('post');
227 |
228 | $sql_array = array(
229 | 'SELECT' => 'r.*, p.post_subject, p.post_reputation, ut.username AS username_to',
230 | 'FROM' => array(
231 | $this->reputations_table => 'r',
232 | POSTS_TABLE => 'p',
233 | ),
234 | 'LEFT_JOIN' => array(
235 | array(
236 | 'FROM' => array(USERS_TABLE => 'ut'),
237 | 'ON' => 'r.user_id_to = ut.user_id ',
238 | ),
239 | ),
240 | 'WHERE' => 'r.reputation_item_id = ' . $post_id . '
241 | AND r.reputation_type_id = ' . $post_type_id . '
242 | AND p.post_id = r.reputation_item_id',
243 | );
244 | $sql = $this->db->sql_build_query('SELECT', $sql_array);
245 | $result = $this->db->sql_query($sql);
246 | $row = $this->db->sql_fetchrow($result);
247 | $this->db->sql_freeresult($result);
248 |
249 | //We couldn't find this reputation. May be it was deleted meanwhile?
250 | if (empty($row))
251 | {
252 | $message = $this->user->lang('RS_NO_REPUTATION');
253 | $json_data = array(
254 | 'error_msg' => $message,
255 | );
256 | $redirect = append_sid("{$this->root_path}index.$this->php_ext");
257 | $redirect_text = 'RETURN_INDEX';
258 |
259 | $this->reputation_manager->response($message, $json_data, $redirect, $redirect_text, $is_ajax);
260 | }
261 |
262 | $redirect = $this->helper->route('reputation_post_details_controller', array('post_id' => $post_id));
263 |
264 | if ($this->request->is_set_post('cancel'))
265 | {
266 | redirect($redirect);
267 | }
268 |
269 | $redirect_text = 'RETURN_PAGE';
270 |
271 | if ($this->auth->acl_gets('m_rs_moderate'))
272 | {
273 | if ($is_ajax)
274 | {
275 | $submit = true;
276 | }
277 | else
278 | {
279 | $s_hidden_fields = build_hidden_fields(array(
280 | 'p' => $post_id,
281 | ));
282 |
283 | if (confirm_box(true))
284 | {
285 | $submit = true;
286 | }
287 | else
288 | {
289 | confirm_box(false, $this->user->lang('RS_CLEAR_POST_CONFIRM'), $s_hidden_fields);
290 | }
291 | }
292 | }
293 | else
294 | {
295 | $message = $this->user->lang('RS_USER_CANNOT_DELETE');
296 | $json_data = array(
297 | 'error_msg' => $message,
298 | );
299 |
300 | $this->reputation_manager->response($message, $json_data, $redirect, $redirect_text, $is_ajax);
301 | }
302 |
303 | if ($submit)
304 | {
305 | try
306 | {
307 | $this->reputation_manager->clear_post_reputation($post_id, $row);
308 | }
309 | catch (\pico\reputation\exception\base $e)
310 | {
311 | // Catch exception
312 | trigger_error($e->get_message($this->user));
313 | }
314 |
315 | $message = $this->user->lang('RS_CLEARED_POST');
316 | $json_data = array(
317 | 'clear_post' => true,
318 | 'post_id' => $post_id,
319 | 'poster_id' => $row['user_id_to'],
320 | 'user_reputation' => $this->reputation_manager->get_user_reputation($row['user_id_to']),
321 | 'post_reputation' => 0,
322 | 'reputation_class' => 'neutral',
323 | );
324 |
325 | $this->reputation_manager->response($message, $json_data, $redirect, $redirect_text, $is_ajax);
326 | }
327 | }
328 |
329 | /**
330 | * Clear user reputation
331 | *
332 | * @param int $uid User ID
333 | * @return null
334 | * @access public
335 | */
336 | public function clear_user($uid)
337 | {
338 | $this->user->add_lang_ext('pico/reputation', 'reputation_system');
339 | $is_ajax = $this->request->is_ajax();
340 | $submit = false;
341 |
342 | $sql_array = array(
343 | 'SELECT' => 'r.*, ut.username AS username_to',
344 | 'FROM' => array(
345 | $this->reputations_table => 'r',
346 | ),
347 | 'LEFT_JOIN' => array(
348 | array(
349 | 'FROM' => array(USERS_TABLE => 'ut'),
350 | 'ON' => 'r.user_id_to = ut.user_id ',
351 | ),
352 | ),
353 | 'WHERE' => 'r.user_id_to = ' . $uid
354 | );
355 | $sql = $this->db->sql_build_query('SELECT', $sql_array);
356 | $result = $this->db->sql_query($sql);
357 | $row = $this->db->sql_fetchrow($result);
358 | $this->db->sql_freeresult($result);
359 |
360 | //We couldn't find this reputation. May be it was deleted meanwhile?
361 | if (empty($row))
362 | {
363 | $message = $this->user->lang('RS_NO_REPUTATION');
364 | $json_data = array(
365 | 'error_msg' => $message,
366 | );
367 | $redirect = append_sid("{$this->root_path}index.$this->php_ext");
368 | $redirect_text = 'RETURN_INDEX';
369 |
370 | $this->reputation_manager->response($message, $json_data, $redirect, $redirect_text, $is_ajax);
371 | }
372 |
373 | $redirect = $this->helper->route('reputation_details_controller', array('uid' => $uid));
374 |
375 | if ($this->request->is_set_post('cancel'))
376 | {
377 | redirect($redirect);
378 | }
379 |
380 | $post_ids = array();
381 | $post_type_id = (int) $this->reputation_manager->get_reputation_type_id('post');
382 |
383 | $sql = 'SELECT reputation_item_id
384 | FROM ' . $this->reputations_table . "
385 | WHERE user_id_to = {$uid}
386 | AND reputation_type_id = {$post_type_id}
387 | GROUP BY reputation_item_id";
388 | $result = $this->db->sql_query($sql);
389 |
390 | while ($post_row = $this->db->sql_fetchrow($result))
391 | {
392 | $post_ids[] = $post_row['reputation_item_id'];
393 | }
394 | $this->db->sql_freeresult($result);
395 |
396 | $redirect_text = 'RETURN_PAGE';
397 |
398 | if ($this->auth->acl_gets('m_rs_moderate'))
399 | {
400 | if ($is_ajax)
401 | {
402 | $submit = true;
403 | }
404 | else
405 | {
406 | $s_hidden_fields = build_hidden_fields(array(
407 | 'u' => $uid,
408 | ));
409 |
410 | if (confirm_box(true))
411 | {
412 | $submit = true;
413 | }
414 | else
415 | {
416 | confirm_box(false, $this->user->lang('RS_CLEAR_POST_CONFIRM'), $s_hidden_fields);
417 | }
418 | }
419 | }
420 | else
421 | {
422 | $message = $this->user->lang('RS_USER_CANNOT_DELETE');
423 | $json_data = array(
424 | 'error_msg' => $message,
425 | );
426 |
427 | $this->reputation_manager->response($message, $json_data, $redirect, $redirect_text, $is_ajax);
428 | }
429 |
430 | if ($submit)
431 | {
432 | try
433 | {
434 | $this->reputation_manager->clear_user_reputation($uid, $row, $post_ids);
435 | }
436 | catch (\pico\reputation\exception\base $e)
437 | {
438 | // Catch exception
439 | trigger_error($e->get_message($this->user));
440 | }
441 |
442 | $message = $this->user->lang('RS_CLEARED_USER');
443 | $json_data = array(
444 | 'clear_user' => true,
445 | 'post_ids' => $post_ids,
446 | 'poster_id' => $uid,
447 | 'user_reputation' => 0,
448 | 'post_reputation' => 0,
449 | 'reputation_class' => 'neutral',
450 | );
451 |
452 | $this->reputation_manager->response($message, $json_data, $redirect, $redirect_text, $is_ajax);
453 | }
454 | }
455 | }
456 |
--------------------------------------------------------------------------------
/core/reputation_manager.php:
--------------------------------------------------------------------------------
1 | auth = $auth;
80 | $this->cache = $cache;
81 | $this->config = $config;
82 | $this->db = $db;
83 | $this->log = $log;
84 | $this->notification_manager = $notification_manager;
85 | $this->template = $template;
86 | $this->user = $user;
87 | $this->reputations_table = $reputations_table;
88 | $this->reputation_types_table = $reputation_types_table;
89 | $this->root_path = $root_path;
90 | $this->php_ext = $php_ext;
91 | }
92 |
93 | /**
94 | * Get the reputation types
95 | *
96 | * @return array Reputation types
97 | * @access public
98 | */
99 | public function get_reputation_types()
100 | {
101 | $reputation_type_ids = $this->cache->get('reputation_type_ids');
102 |
103 | if ($reputation_type_ids === false)
104 | {
105 | $reputation_type_ids = array();
106 |
107 | $sql = 'SELECT *
108 | FROM ' . $this->reputation_types_table;
109 | $result = $this->db->sql_query($sql);
110 | while ($row = $this->db->sql_fetchrow($result))
111 | {
112 | $reputation_type_ids[(int) $row['reputation_type_id']] = (string) $row['reputation_type_name'];
113 | }
114 | $this->db->sql_freeresult($result);
115 |
116 | $this->cache->put('reputation_type_ids', $reputation_type_ids);
117 | }
118 |
119 | return $reputation_type_ids;
120 | }
121 |
122 | /**
123 | * Get reputation type id from string
124 | *
125 | * @param string $type_string
126 | * @return int $type_id
127 | * @access public
128 | */
129 | public function get_reputation_type_id($type_string)
130 | {
131 | $types = $this->get_reputation_types();
132 |
133 | $type_id = array_search($type_string, $types);
134 |
135 | if (empty($type_id))
136 | {
137 | throw new \pico\reputation\exception\invalid_argument(array('reputation_type', 'INVALID_TYPE'));
138 | }
139 |
140 | return $type_id;
141 | }
142 |
143 | /**
144 | * The main function for recording reputation vote.
145 | *
146 | * @param array $data Reputation data
147 | * @access public
148 | * @return null
149 | */
150 | public function store_reputation($data)
151 | {
152 | $data['reputation_time'] = time();
153 |
154 | $fields = array(
155 | 'user_id_from' => 'integer',
156 | 'user_id_to' => 'integer',
157 | 'reputation_time' => 'integer',
158 | 'reputation_type' => 'string',
159 | 'reputation_item_id' => 'integer',
160 | 'reputation_points' => 'integer',
161 | 'reputation_comment' => 'string',
162 | );
163 |
164 | foreach ($fields as $field => $type)
165 | {
166 | if (!isset($data[$field]))
167 | {
168 | throw new \pico\reputation\exception\invalid_argument(array($field, 'FIELD_MISSING'));
169 | }
170 |
171 | $value = $data[$field];
172 |
173 | settype($value, $type);
174 |
175 | $data[$field] = $value;
176 | }
177 |
178 | // Get reputation type id
179 | $data['reputation_type_id'] = $this->get_reputation_type_id($data['reputation_type']);
180 |
181 | // Unset reputation type - it is not stored in DB
182 | unset($data['reputation_type']);
183 |
184 | $validate_unsigned = array(
185 | 'user_id_from',
186 | 'user_id_to',
187 | 'reputation_time',
188 | 'reputation_type_id',
189 | 'reputation_item_id',
190 | );
191 |
192 | foreach ($validate_unsigned as $field)
193 | {
194 | if ($data[$field] < 0)
195 | {
196 | throw new \pico\reputation\exception\out_of_bounds($field);
197 | }
198 | }
199 |
200 | // Save reputation vote
201 | $sql = 'INSERT INTO ' . $this->reputations_table . ' ' . $this->db->sql_build_array('INSERT', $data);
202 | $this->db->sql_query($sql);
203 |
204 | unset($this->reputation_id);
205 | $this->reputation_id = $this->db->sql_nextid();
206 |
207 | // Update post reputation
208 | if ($data['reputation_type_id'] == $this->get_reputation_type_id('post'))
209 | {
210 | $sql = 'UPDATE ' . POSTS_TABLE . "
211 | SET post_reputation = post_reputation + {$data['reputation_points']}
212 | WHERE post_id = {$data['reputation_item_id']}";
213 | $this->db->sql_query($sql);
214 | }
215 |
216 | // Update user reputation
217 | $sql = 'UPDATE ' . USERS_TABLE . "
218 | SET user_reputation = user_reputation + {$data['reputation_points']}
219 | WHERE user_id = {$data['user_id_to']}";
220 | $this->db->sql_query($sql);
221 |
222 | // Check max/min user points
223 | if ($this->config['rs_max_point'] || $this->config['rs_min_point'])
224 | {
225 | $this->check_max_min($data['user_id_to']);
226 | }
227 | }
228 |
229 | /**
230 | * Check user reputation
231 | *
232 | * If it is higher than allowed, decrease it to maximum.
233 | * If it is lower than allowed, increase it to minimum.
234 | *
235 | * @param int $user_id User ID
236 | * @access public
237 | * @return null
238 | */
239 | private function check_max_min($user_id)
240 | {
241 | $sql = 'SELECT SUM(reputation_points) AS points
242 | FROM ' . $this->reputations_table . '
243 | WHERE user_id_to = ' . (int) $user_id;
244 | $result = $this->db->sql_query($sql);
245 | $points = $this->db->sql_fetchfield('points');
246 | $this->db->sql_freeresult($result);
247 |
248 | // Maximum user reputation
249 | if (($points > $this->config['rs_max_point']) && $this->config['rs_max_point'])
250 | {
251 | $sql = 'UPDATE ' . USERS_TABLE . "
252 | SET user_reputation = {$this->config['rs_max_point']}
253 | WHERE user_id = $user_id";
254 | $this->db->sql_query($sql);
255 | }
256 |
257 | // Minimum user reputation
258 | if (($points < $this->config['rs_min_point']) && $this->config['rs_min_point'])
259 | {
260 | $sql = 'UPDATE ' . USERS_TABLE . "
261 | SET user_reputation = {$this->config['rs_min_point']}
262 | WHERE user_id = $user_id";
263 | $this->db->sql_query($sql);
264 | }
265 | }
266 |
267 | /**
268 | * Notify user about reputation
269 | *
270 | * @param string $notification_type_name Notification type name
271 | * @param array $data Notification data
272 | * @access public
273 | * @return null
274 | */
275 | public function add_notification($notification_type_name, $data)
276 | {
277 | $data = array_merge(
278 | array('reputation_id' => $this->reputation_id),
279 | $data
280 | );
281 | $this->notification_manager->add_notifications($notification_type_name, $data);
282 | }
283 |
284 | /**
285 | * Response method for displaying reputation messages
286 | *
287 | * @param string $message_lang Message user lang
288 | * @param array $json_data Json data for ajax request
289 | * @param string $redirect_link Redirect link
290 | * @param string $redirect_text Redirect text
291 | * @param bool $is_ajax Ajax request
292 | * @access public
293 | * @return string
294 | */
295 | public function response($message_lang, $json_data, $redirect_link, $redirect_text, $is_ajax = false)
296 | {
297 | $redirect = $redirect_link;
298 |
299 | meta_refresh(3, $redirect);
300 |
301 | $message = $message_lang;
302 |
303 | if ($is_ajax)
304 | {
305 | $json_response = new \phpbb\json_response();
306 | $json_response->send($json_data);
307 | }
308 |
309 | $message .= '
' . $this->user->lang($redirect_text, '
', '');
310 | trigger_error($message);
311 | }
312 |
313 | /**
314 | * Return post reputation
315 | *
316 | * @param int $post_id Post ID
317 | * @access public
318 | * @return int post reputation
319 | */
320 | public function get_post_reputation($post_id)
321 | {
322 | $sql = 'SELECT post_reputation
323 | FROM ' . POSTS_TABLE . "
324 | WHERE post_id = $post_id";
325 | $result = $this->db->sql_query($sql);
326 | $row = $this->db->sql_fetchrow($result);
327 | $this->db->sql_freeresult($result);
328 |
329 | return $row['post_reputation'];
330 | }
331 |
332 | /**
333 | * Return user reputation
334 | *
335 | * @param int $user_id User ID
336 | * @access public
337 | * @return int user reputation
338 | */
339 | public function get_user_reputation($user_id)
340 | {
341 | $sql = 'SELECT user_reputation
342 | FROM ' . USERS_TABLE . "
343 | WHERE user_id = $user_id";
344 | $result = $this->db->sql_query($sql);
345 | $row = $this->db->sql_fetchrow($result);
346 | $this->db->sql_freeresult($result);
347 |
348 | return $row['user_reputation'];
349 | }
350 |
351 | /**
352 | * Prevent overrating one user by another user
353 | *
354 | * @param int $user_id User ID
355 | * @access public
356 | * @return bool
357 | */
358 | public function prevent_rating($user_id)
359 | {
360 | if (!$this->config['rs_prevent_num'] || !$this->config['rs_prevent_perc'])
361 | {
362 | return false;
363 | }
364 |
365 | $total_reps = $same_user = 0;
366 |
367 | $post_type = (int) $this->get_reputation_type_id('post');
368 | $user_type = (int) $this->get_reputation_type_id('user');
369 |
370 | $sql = 'SELECT user_id_from
371 | FROM ' . $this->reputations_table . "
372 | WHERE user_id_to = {$user_id}
373 | AND (reputation_type_id = {$post_type} OR reputation_type_id = {$user_type})";
374 | $result = $this->db->sql_query($sql);
375 |
376 | while ($row = $this->db->sql_fetchrow($result))
377 | {
378 | $total_reps++;
379 |
380 | if ($row['user_id_from'] == $this->user->data['user_id'])
381 | {
382 | $same_user++;
383 | }
384 | }
385 | $this->db->sql_freeresult($result);
386 |
387 | if (($total_reps >= $this->config['rs_prevent_num']) && ($same_user / $total_reps * 100 >= $this->config['rs_prevent_perc']))
388 | {
389 | return true;
390 | }
391 |
392 | return false;
393 | }
394 |
395 | /**
396 | * Generet post URL
397 | *
398 | * @param array $row Array with data
399 | * @access public
400 | * @return null
401 | */
402 | public function generate_post_link($row)
403 | {
404 | $post_subject = $post_url = '';
405 |
406 | // Post was deleted
407 | if (!isset($row['post_subject']) && !isset($row['post_id']))
408 | {
409 | $post_subject = $this->user->lang('RS_POST_DELETE');
410 | }
411 |
412 | // Post exists
413 | if (isset($row['post_id']))
414 | {
415 | // Check forum read permission
416 | if ($this->auth->acl_get('f_read', $row['forum_id']))
417 | {
418 | $post_subject = $row['post_subject'] . ' [#p' . $row['post_id'] . ']';
419 | $post_url = append_sid("{$this->root_path}viewtopic.$this->php_ext", 'f=' . $row['forum_id'] . '&p=' . $row['post_id'] . '#p' . $row['post_id']);
420 | }
421 | }
422 |
423 | $this->template->assign_block_vars('reputation.post', array(
424 | 'POST_SUBJECT' => $post_subject,
425 | 'U_POST' => $post_url,
426 | 'S_POST' => $row['reputation_type_id'] == $this->get_reputation_type_id('post'),
427 | ));
428 | }
429 |
430 | /**
431 | * Delete single reputation
432 | *
433 | * @param array $data Reputation data
434 | * @access public
435 | * @return null
436 | */
437 | public function delete_reputation($data)
438 | {
439 | // Required fields
440 | $fields = array(
441 | 'user_id_from',
442 | 'user_id_to',
443 | 'reputation_item_id',
444 | 'reputation_points',
445 | 'reputation_type_name',
446 | );
447 |
448 | foreach ($fields as $field)
449 | {
450 | if (!isset($data[$field]))
451 | {
452 | throw new \pico\reputation\exception\invalid_argument(array($field, 'FIELD_MISSING'));
453 | }
454 | }
455 |
456 | if ($data['reputation_type_id'] == $this->get_reputation_type_id('post'))
457 | {
458 | $sql = 'UPDATE ' . POSTS_TABLE . "
459 | SET post_reputation = post_reputation - {$data['reputation_points']}
460 | WHERE post_id = {$data['reputation_item_id']}";
461 | $this->db->sql_query($sql);
462 | }
463 |
464 | $sql = 'DELETE FROM ' . $this->reputations_table . "
465 | WHERE reputation_id = {$data['reputation_id']}";
466 | $this->db->sql_query($sql);
467 |
468 | $sql = 'UPDATE ' . USERS_TABLE . "
469 | SET user_reputation = user_reputation - {$data['reputation_points']}
470 | WHERE user_id = {$data['user_id_to']}";
471 | $this->db->sql_query($sql);
472 |
473 | // Check max/min points
474 | if ($this->config['rs_max_point'] || $this->config['rs_min_point'])
475 | {
476 | $this->check_max_min($data['user_id_to']);
477 | }
478 |
479 | $this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_REPUTATION_DELETED', false, array(
480 | 'user_id_from' => (isset($data['username_from'])) ? $data['username_from'] : $data['user_id_from'],
481 | 'user_id_to' => (isset($data['username_to'])) ? $data['username_to'] : $data['user_id_to'],
482 | 'points' => $data['reputation_points'],
483 | 'type_name' => $data['reputation_type_name'],
484 | 'item_id' => $data['reputation_item_id'],
485 | ));
486 | }
487 |
488 | /**
489 | * Clear post reputation
490 | *
491 | * @param int $post_id Post id
492 | * @param array $data Reputation data
493 | * @access public
494 | * @return null
495 | */
496 | public function clear_post_reputation($post_id, $data)
497 | {
498 | // Required fields
499 | $fields = array(
500 | 'user_id_to',
501 | 'reputation_item_id',
502 | 'reputation_type_id',
503 | 'post_reputation',
504 | );
505 |
506 | foreach ($fields as $field)
507 | {
508 | if (!isset($data[$field]))
509 | {
510 | throw new \pico\reputation\exception\invalid_argument(array($field, 'FIELD_MISSING'));
511 | }
512 | }
513 |
514 | $sql = 'UPDATE ' . POSTS_TABLE . "
515 | SET post_reputation = 0
516 | WHERE post_id = {$post_id}";
517 | $this->db->sql_query($sql);
518 |
519 | $sql = 'UPDATE ' . USERS_TABLE . "
520 | SET user_reputation = user_reputation - {$data['post_reputation']}
521 | WHERE user_id = {$data['user_id_to']}";
522 | $this->db->sql_query($sql);
523 |
524 | // Check max/min points
525 | if ($this->config['rs_max_point'] || $this->config['rs_min_point'])
526 | {
527 | $this->check_max_min($data['user_id_to']);
528 | }
529 |
530 | $sql = 'DELETE FROM ' . $this->reputations_table . "
531 | WHERE reputation_item_id = {$post_id}
532 | AND reputation_type_id = {$data['reputation_type_id']}";
533 | $this->db->sql_query($sql);
534 |
535 | $this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_POST_REPUTATION_CLEARED', false, array(
536 | 'user_id_to' => (isset($data['username_to'])) ? $data['username_to'] : $data['user_id_to'],
537 | 'post_subject' => (isset($data['post_subject'])) ? $data['post_subject'] : $data['reputation_item_id'],
538 | ));
539 | }
540 |
541 | /**
542 | * Clear user reputation
543 | *
544 | * @param int $user_id User id
545 | * @param array $data Reputation data
546 | * @param arrat $post_ids Post IDs
547 | * @access public
548 | * @return null
549 | */
550 | public function clear_user_reputation($user_id, $data, $post_ids)
551 | {
552 | // Required fields
553 | $fields = array(
554 | 'user_id_to',
555 | 'reputation_item_id',
556 | );
557 |
558 | foreach ($fields as $field)
559 | {
560 | if (!isset($data[$field]))
561 | {
562 | throw new \pico\reputation\exception\invalid_argument(array($field, 'FIELD_MISSING'));
563 | }
564 | }
565 |
566 | $sql = 'UPDATE ' . USERS_TABLE . "
567 | SET user_reputation = 0
568 | WHERE user_id = {$user_id}";
569 | $this->db->sql_query($sql);
570 |
571 | $sql = 'UPDATE ' . POSTS_TABLE . '
572 | SET post_reputation = 0
573 | WHERE ' . $this->db->sql_in_set('post_id', $post_ids, false, true);
574 | $this->db->sql_query($sql);
575 |
576 | $sql = 'DELETE FROM ' . $this->reputations_table . "
577 | WHERE user_id_to = {$user_id}";
578 | $this->db->sql_query($sql);
579 |
580 | $this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_USER_REPUTATION_CLEARED', false, array(
581 | 'user_id_to' => (isset($data['username_to'])) ? $data['username_to'] : $data['user_id_to'],
582 | ));
583 | }
584 | }
585 |
--------------------------------------------------------------------------------