1 | <?php |
||
2 | define( 'YOURLS_ADMIN', true ); |
||
3 | require_once( dirname( __DIR__ ).'/includes/load-yourls.php' ); |
||
4 | yourls_maybe_require_auth(); |
||
5 | |||
6 | // Variables |
||
7 | $table_url = YOURLS_DB_TABLE_URL; |
||
8 | $search_sentence = $search_text = $url = $keyword = ''; |
||
9 | /* $where will collect additional SQL arguments: |
||
10 | * $where['sql'] will concatenate SQL clauses: $where['sql'] .= ' AND something = :value '; |
||
11 | * $where['binds'] will hold the (name => value) placeholder pairs: $where['binds']['value'] = $value; |
||
12 | */ |
||
13 | $where = array('sql' => '', 'binds' => array()); |
||
14 | $date_filter = $date_first = $date_second = ''; |
||
15 | $base_page = yourls_admin_url( 'index.php' ); |
||
16 | |||
17 | // Default SQL behavior |
||
18 | $search_in_text = yourls__( 'URL' ); |
||
19 | $search_in = 'all'; |
||
20 | $sort_by_text = yourls__( 'Short URL' ); |
||
21 | $sort_by = 'timestamp'; |
||
22 | $sort_order = 'desc'; |
||
23 | $page = ( isset( $_GET['page'] ) ? intval($_GET['page']) : 1 ); |
||
24 | $search = yourls_get_search_text(); |
||
25 | $perpage = ( isset( $_GET['perpage'] ) && intval( $_GET['perpage'] ) ? intval($_GET['perpage']) : yourls_apply_filter( 'admin_view_per_page', 15 ) ); |
||
26 | $click_limit = ( isset( $_GET['click_limit'] ) && $_GET['click_limit'] !== '' ) ? intval( $_GET['click_limit'] ) : '' ; |
||
27 | if ( $click_limit !== '' ) { |
||
28 | $click_filter = ( isset( $_GET['click_filter'] ) && $_GET['click_filter'] == 'more' ? 'more' : 'less' ) ; |
||
0 ignored issues
–
show
Coding Style
introduced
by
Loading history...
|
|||
29 | $click_moreless = ( $click_filter == 'more' ? '>' : '<' ); |
||
0 ignored issues
–
show
|
|||
30 | $where['sql'] = " AND clicks $click_moreless :click_limit"; |
||
31 | $where['binds']['click_limit'] = $click_limit; |
||
32 | } else { |
||
33 | $click_filter = ''; |
||
34 | } |
||
35 | |||
36 | // Searching |
||
37 | if( !empty( $search ) && !empty( $_GET['search_in'] ) ) { |
||
38 | switch( $_GET['search_in'] ) { |
||
39 | case 'all': |
||
40 | $search_in_text = yourls__( 'All fields' ); |
||
41 | $search_in = 'all'; |
||
42 | break; |
||
43 | case 'keyword': |
||
44 | $search_in_text = yourls__( 'Short URL' ); |
||
45 | $search_in = 'keyword'; |
||
46 | break; |
||
0 ignored issues
–
show
|
|||
47 | case 'url': |
||
48 | $search_in_text = yourls__( 'URL' ); |
||
49 | $search_in = 'url'; |
||
50 | break; |
||
0 ignored issues
–
show
|
|||
51 | case 'title': |
||
52 | $search_in_text = yourls__( 'Title' ); |
||
53 | $search_in = 'title'; |
||
54 | break; |
||
0 ignored issues
–
show
|
|||
55 | case 'ip': |
||
56 | $search_in_text = yourls__( 'IP Address' ); |
||
57 | $search_in = 'ip'; |
||
58 | break; |
||
0 ignored issues
–
show
|
|||
59 | } |
||
60 | $search_sentence = yourls_s( 'Searching for <strong>%1$s</strong> in <strong>%2$s</strong>.', yourls_esc_html( $search ), yourls_esc_html( $search_in_text ) ); |
||
0 ignored issues
–
show
|
|||
61 | $search_text = $search; |
||
62 | $search = str_replace( '*', '%', '*' . $search . '*' ); |
||
63 | if( $search_in == 'all' ) { |
||
64 | $where['sql'] .= ' AND CONCAT_WS("",`keyword`,`url`,`title`,`ip`) LIKE (:search)'; |
||
65 | $where['binds']['search'] = $search; |
||
66 | // Search across all fields. The resulting SQL will be something like: |
||
67 | // SELECT * FROM `yourls_url` WHERE CONCAT_WS('',`keyword`,`url`,`title`,`ip`) LIKE ("%ozh%") |
||
68 | // CONCAT_WS because CONCAT('foo', 'bar', NULL) = NULL. NULL wins. Not sure if values can be NULL now or in the future, so better safe. |
||
69 | // TODO: pay attention to this bit when the DB schema changes |
||
70 | } else { |
||
71 | $where['sql'] .= " AND `$search_in` LIKE (:search)"; |
||
72 | $where['binds']['search'] = $search; |
||
73 | } |
||
74 | } |
||
75 | |||
76 | // Time span |
||
77 | if( !empty( $_GET['date_filter'] ) ) { |
||
78 | switch( $_GET['date_filter'] ) { |
||
79 | case 'before': |
||
80 | $date_filter = 'before'; |
||
81 | if( isset( $_GET['date_first'] ) && yourls_sanitize_date( $_GET['date_first'] ) ) { |
||
82 | $date_first = yourls_sanitize_date( $_GET['date_first'] ); |
||
83 | $date_first_sql = yourls_sanitize_date_for_sql( $_GET['date_first'] ); |
||
84 | $where['sql'] .= ' AND `timestamp` < :date_first_sql'; |
||
85 | $where['binds']['date_first_sql'] = $date_first_sql; |
||
86 | } |
||
87 | break; |
||
0 ignored issues
–
show
|
|||
88 | case 'after': |
||
89 | $date_filter = 'after'; |
||
90 | if( isset( $_GET['date_first'] ) && yourls_sanitize_date( $_GET['date_first'] ) ) { |
||
91 | $date_first_sql = yourls_sanitize_date_for_sql( $_GET['date_first'] ); |
||
92 | $date_first = yourls_sanitize_date( $_GET['date_first'] ); |
||
93 | $where['sql'] .= ' AND `timestamp` > :date_first_sql'; |
||
94 | $where['binds']['date_first_sql'] = $date_first_sql; |
||
95 | } |
||
96 | break; |
||
0 ignored issues
–
show
|
|||
97 | case 'between': |
||
98 | $date_filter = 'between'; |
||
99 | if( isset( $_GET['date_first'] ) && isset( $_GET['date_second'] ) && yourls_sanitize_date( $_GET['date_first'] ) && yourls_sanitize_date( $_GET['date_second'] ) ) { |
||
0 ignored issues
–
show
|
|||
100 | $date_first_sql = yourls_sanitize_date_for_sql( $_GET['date_first'] ); |
||
101 | $date_second_sql = yourls_sanitize_date_for_sql( $_GET['date_second'] ); |
||
102 | $date_first = yourls_sanitize_date( $_GET['date_first'] ); |
||
103 | $date_second = yourls_sanitize_date( $_GET['date_second'] ); |
||
104 | $where['sql'] .= ' AND `timestamp` BETWEEN :date_first_sql AND :date_second_sql'; |
||
105 | $where['binds']['date_first_sql'] = $date_first_sql; |
||
106 | $where['binds']['date_second_sql'] = $date_second_sql; |
||
107 | } |
||
108 | break; |
||
0 ignored issues
–
show
|
|||
109 | } |
||
110 | } |
||
111 | |||
112 | // Sorting |
||
113 | if( !empty( $_GET['sort_by'] ) || !empty( $_GET['sort_order'] ) ) { |
||
114 | switch( $_GET['sort_by'] ) { |
||
115 | case 'keyword': |
||
116 | $sort_by_text = yourls__( 'Short URL' ); |
||
117 | $sort_by = 'keyword'; |
||
118 | break; |
||
0 ignored issues
–
show
|
|||
119 | case 'url': |
||
120 | $sort_by_text = yourls__( 'URL' ); |
||
121 | $sort_by = 'url'; |
||
122 | break; |
||
0 ignored issues
–
show
|
|||
123 | case 'title': |
||
124 | $sort_by_text = yourls__( 'Title' ); |
||
125 | $sort_by = 'title'; |
||
126 | break; |
||
127 | case 'timestamp': |
||
128 | $sort_by_text = yourls__( 'Date' ); |
||
129 | $sort_by = 'timestamp'; |
||
130 | break; |
||
0 ignored issues
–
show
|
|||
131 | case 'ip': |
||
132 | $sort_by_text = yourls__( 'IP Address' ); |
||
133 | $sort_by = 'ip'; |
||
134 | break; |
||
0 ignored issues
–
show
|
|||
135 | case 'clicks': |
||
136 | $sort_by_text = yourls__( 'Clicks' ); |
||
137 | $sort_by = 'clicks'; |
||
138 | break; |
||
0 ignored issues
–
show
|
|||
139 | } |
||
140 | switch( $_GET['sort_order'] ) { |
||
141 | case 'asc': |
||
142 | $sort_order = 'asc'; |
||
143 | break; |
||
0 ignored issues
–
show
|
|||
144 | case 'desc': |
||
145 | $sort_order = 'desc'; |
||
146 | break; |
||
0 ignored issues
–
show
|
|||
147 | } |
||
148 | } |
||
149 | |||
150 | // Get URLs Count for current filter, total links in DB & total clicks |
||
151 | list( $total_urls, $total_clicks ) = array_values( yourls_get_db_stats() ); |
||
152 | if ( !empty($where['sql']) ) { |
||
153 | list( $total_items, $total_items_clicks ) = array_values( yourls_get_db_stats( $where ) ); |
||
154 | } else { |
||
155 | $total_items = $total_urls; |
||
156 | $total_items_clicks = false; |
||
157 | } |
||
158 | |||
159 | // This is a bookmarklet |
||
160 | if ( isset( $_GET['u'] ) or isset( $_GET['up'] ) ) { |
||
161 | $is_bookmark = true; |
||
162 | yourls_do_action( 'bookmarklet' ); |
||
163 | |||
164 | // No sanitization needed here: everything happens in yourls_add_new_link() |
||
165 | if( isset( $_GET['u'] ) ) { |
||
166 | // Old school bookmarklet: ?u=<url> |
||
167 | $url = urldecode( $_GET['u'] ); |
||
168 | } else { |
||
169 | // New style bookmarklet: ?up=<url protocol>&us=<url slashes>&ur=<url rest> |
||
170 | $url = urldecode( $_GET['up'] . $_GET['us'] . $_GET['ur'] ); |
||
171 | } |
||
172 | $keyword = ( isset( $_GET['k'] ) ? ( $_GET['k'] ) : '' ); |
||
173 | $title = ( isset( $_GET['t'] ) ? ( $_GET['t'] ) : '' ); |
||
174 | $return = yourls_add_new_link( $url, $keyword, $title ); |
||
175 | |||
176 | // If fails because keyword already exist, retry with no keyword |
||
177 | if ( isset( $return['status'] ) && $return['status'] == 'fail' && isset( $return['code'] ) && $return['code'] == 'error:keyword' ) { |
||
0 ignored issues
–
show
|
|||
178 | $msg = $return['message']; |
||
179 | $return = yourls_add_new_link( $url, '' ); |
||
180 | $return['message'] .= ' ('.$msg.')'; |
||
181 | } |
||
182 | |||
183 | // Stop here if bookmarklet with a JSON callback function |
||
184 | if( isset( $_GET['jsonp'] ) && $_GET['jsonp'] == 'yourls' ) { |
||
0 ignored issues
–
show
|
|||
185 | $short = $return['shorturl'] ? $return['shorturl'] : ''; |
||
186 | $message = $return['message']; |
||
187 | yourls_content_type_header( 'application/javascript' ); |
||
188 | echo yourls_apply_filter( 'bookmarklet_jsonp', "yourls_callback({'short_url':'$short','message':'$message'});" ); |
||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $short instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
As per coding-style, please use concatenation or
sprintf for the variable $message instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
|
|||
189 | |||
190 | die(); |
||
191 | } |
||
192 | |||
193 | // Now use the URL that has been sanitized and returned by yourls_add_new_link() |
||
194 | $url = $return['url']['url']; |
||
195 | $where['sql'] .= ' AND `url` LIKE :url '; |
||
196 | $where['binds']['url'] = $url; |
||
197 | |||
198 | $page = $total_pages = $perpage = 1; |
||
199 | $offset = 0; |
||
200 | |||
201 | $text = ( isset( $_GET['s'] ) ? stripslashes( $_GET['s'] ) : '' ); |
||
202 | |||
203 | // Sharing with social bookmarklets |
||
204 | if( !empty($_GET['share']) ) { |
||
205 | yourls_do_action( 'pre_share_redirect' ); |
||
206 | switch ( $_GET['share'] ) { |
||
207 | case 'twitter': |
||
208 | // share with Twitter |
||
209 | $destination = sprintf( "https://twitter.com/intent/tweet?url=%s&text=%s", urlencode( $return['shorturl'] ), urlencode( $title ) ); |
||
210 | yourls_redirect( $destination, 303 ); |
||
211 | |||
212 | // Deal with the case when redirection failed: |
||
213 | $return['status'] = 'error'; |
||
214 | $return['errorCode'] = 400; |
||
215 | $return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Twitter' ); |
||
216 | break; |
||
217 | |||
218 | case 'facebook': |
||
219 | // share with Facebook |
||
220 | $destination = sprintf( "https://www.facebook.com/sharer/sharer.php?u=%s&t=%s", urlencode( $return['shorturl'] ), urlencode( $title ) ); |
||
221 | yourls_redirect( $destination, 303 ); |
||
222 | |||
223 | // Deal with the case when redirection failed: |
||
224 | $return['status'] = 'error'; |
||
225 | $return['errorCode'] = 400; |
||
226 | $return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Facebook' ); |
||
227 | break; |
||
228 | |||
229 | case 'tumblr': |
||
230 | // share with Tumblr |
||
231 | $destination = sprintf( "https://www.tumblr.com/share?v=3&u=%s&t=%s&s=%s", urlencode( $return['shorturl'] ), urlencode( $title ), urlencode( $text ) ); |
||
232 | yourls_redirect( $destination, 303 ); |
||
233 | |||
234 | // Deal with the case when redirection failed: |
||
235 | $return['status'] = 'error'; |
||
236 | $return['errorCode'] = 400; |
||
237 | $return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Tumblr' ); |
||
238 | break; |
||
239 | |||
240 | default: |
||
241 | // Is there a custom registered social bookmark? |
||
242 | yourls_do_action( 'share_redirect_' . $_GET['share'], $return ); |
||
243 | |||
244 | // Still here? That was an unknown 'share' method, then. |
||
245 | $return['status'] = 'error'; |
||
246 | $return['errorCode'] = 400; |
||
247 | $return['message'] = yourls__( 'Unknown "Share" bookmarklet' ); |
||
248 | break; |
||
249 | } |
||
250 | } |
||
251 | |||
252 | // This is not a bookmarklet |
||
253 | } else { |
||
254 | $is_bookmark = false; |
||
255 | |||
256 | // Checking $page, $offset, $perpage |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
56% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them.
Loading history...
|
|||
257 | if( empty($page) || $page == 0 ) { |
||
0 ignored issues
–
show
|
|||
258 | $page = 1; |
||
259 | } |
||
260 | if( empty($offset) ) { |
||
261 | $offset = 0; |
||
262 | } |
||
263 | if( empty($perpage) || $perpage == 0) { |
||
0 ignored issues
–
show
|
|||
264 | $perpage = 50; |
||
265 | } |
||
266 | |||
267 | // Determine $offset |
||
268 | $offset = ( $page-1 ) * $perpage; |
||
269 | |||
270 | // Determine Max Number Of Items To Display On Page |
||
271 | if( ( $offset + $perpage ) > $total_items ) { |
||
272 | $max_on_page = $total_items; |
||
273 | } else { |
||
274 | $max_on_page = ( $offset + $perpage ); |
||
275 | } |
||
276 | |||
277 | // Determine Number Of Items To Display On Page |
||
278 | if ( ( $offset + 1 ) > $total_items ) { |
||
279 | $display_on_page = $total_items; |
||
280 | } else { |
||
281 | $display_on_page = ( $offset + 1 ); |
||
282 | } |
||
283 | |||
284 | // Determing Total Amount Of Pages |
||
285 | $total_pages = ceil( $total_items / $perpage ); |
||
286 | } |
||
287 | |||
288 | |||
289 | // Begin output of the page |
||
290 | $context = ( $is_bookmark ? 'bookmark' : 'index' ); |
||
291 | yourls_html_head( $context ); |
||
292 | yourls_html_logo(); |
||
293 | yourls_html_menu() ; |
||
0 ignored issues
–
show
|
|||
294 | |||
295 | yourls_do_action( 'admin_page_before_content' ); |
||
296 | |||
297 | if ( !$is_bookmark ) { ?> |
||
298 | <p><?php echo $search_sentence; ?></p> |
||
299 | <p><?php |
||
0 ignored issues
–
show
|
|||
300 | printf( yourls__( 'Display <strong>%1$s</strong> to <strong class="increment">%2$s</strong> of <strong class="increment">%3$s</strong> URLs' ), $display_on_page, $max_on_page, $total_items ); |
||
0 ignored issues
–
show
|
|||
301 | if( $total_items_clicks !== false ) |
||
302 | echo ", " . sprintf( yourls_n( 'counting <strong>1</strong> click', 'counting <strong>%s</strong> clicks', $total_items_clicks ), yourls_number_format_i18n( $total_items_clicks ) ); |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
The string literal
, does not require double quotes, as per coding-style, please use single quotes.
PHP provides two ways to mark string literals. Either with single quotes String literals in single quotes on the other hand are evaluated very literally and the only two
characters that needs escaping in the literal are the single quote itself ( Double quoted string literals may contain other variables or more complex escape sequences. <?php
$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";
print $doubleQuoted;
will print an indented: If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear. For more information on PHP string literals and available escape sequences see the PHP core documentation.
Loading history...
|
|||
303 | ?>.</p> |
||
304 | <?php } ?> |
||
305 | <p id="overall_tracking"><?php printf( yourls__( 'Overall, tracking <strong class="increment">%1$s</strong> links, <strong>%2$s</strong> clicks, and counting!' ), yourls_number_format_i18n( $total_urls ), yourls_number_format_i18n( $total_clicks ) ); ?></p> |
||
306 | <?php |
||
307 | |||
0 ignored issues
–
show
|
|||
308 | yourls_do_action( 'admin_page_before_form' ); |
||
309 | |||
310 | yourls_html_addnew(); |
||
311 | |||
312 | // If bookmarklet, add message. Otherwise, hide hidden share box. |
||
313 | if ( !$is_bookmark ) { |
||
314 | yourls_share_box( '', '', '', '', '', '', true ); |
||
315 | } else { |
||
316 | echo '<script type="text/javascript">$(document).ready(function(){ |
||
317 | feedback( "' . $return['message'] . '", "'. $return['status'] .'"); |
||
318 | init_clipboard(); |
||
319 | });</script>'; |
||
320 | } |
||
321 | |||
322 | yourls_do_action( 'admin_page_before_table' ); |
||
323 | |||
324 | yourls_table_head(); |
||
325 | |||
326 | if ( !$is_bookmark ) { |
||
327 | $params = array( |
||
328 | 'search' => $search, |
||
329 | 'search_text' => $search_text, |
||
330 | 'search_in' => $search_in, |
||
331 | 'sort_by' => $sort_by, |
||
332 | 'sort_order' => $sort_order, |
||
333 | 'page' => $page, |
||
334 | 'perpage' => $perpage, |
||
335 | 'click_filter' => $click_filter, |
||
336 | 'click_limit' => $click_limit, |
||
337 | 'total_pages' => $total_pages, |
||
338 | 'date_filter' => $date_filter, |
||
339 | 'date_first' => $date_first, |
||
340 | 'date_second' => $date_second, |
||
341 | ); |
||
0 ignored issues
–
show
|
|||
342 | yourls_html_tfooter( $params ); |
||
343 | } |
||
344 | |||
345 | yourls_table_tbody_start(); |
||
346 | |||
347 | // Main Query |
||
348 | $where = yourls_apply_filter( 'admin_list_where', $where ); |
||
349 | $url_results = $ydb->fetchObjects( "SELECT * FROM `$table_url` WHERE 1=1 ${where['sql']} ORDER BY `$sort_by` $sort_order LIMIT $offset, $perpage;", $where['binds'] ); |
||
350 | $found_rows = false; |
||
351 | if( $url_results ) { |
||
352 | $found_rows = true; |
||
353 | foreach( $url_results as $url_result ) { |
||
354 | $keyword = yourls_sanitize_keyword($url_result->keyword); |
||
355 | $timestamp = strtotime( $url_result->timestamp ); |
||
356 | $url = stripslashes( $url_result->url ); |
||
357 | $ip = $url_result->ip; |
||
358 | $title = $url_result->title ? $url_result->title : ''; |
||
359 | $clicks = $url_result->clicks; |
||
360 | |||
361 | echo yourls_table_add_row( $keyword, $url, $title, $ip, $clicks, $timestamp ); |
||
362 | } |
||
363 | } |
||
364 | |||
365 | $display = $found_rows ? 'display:none' : ''; |
||
366 | echo '<tr id="nourl_found" style="'.$display.'"><td colspan="6">' . yourls__('No URL') . '</td></tr>'; |
||
0 ignored issues
–
show
|
|||
367 | |||
368 | yourls_table_tbody_end(); |
||
369 | |||
370 | yourls_table_end(); |
||
371 | |||
372 | yourls_do_action( 'admin_page_after_table' ); |
||
373 | |||
374 | if ( $is_bookmark ) |
||
375 | yourls_share_box( $url, $return['shorturl'], $title, $text ); |
||
376 | ?> |
||
377 | |||
378 | <?php yourls_html_footer( ); ?> |
||
379 |