These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
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 | $where = $search_sentence = $search_text = $url = $keyword = ''; |
||
9 | $date_filter = $date_first = $date_second = ''; |
||
10 | $base_page = yourls_admin_url( 'index.php' ); |
||
11 | |||
12 | // Default SQL behavior |
||
13 | $search_in_text = yourls__( 'URL' ); |
||
14 | $search_in = 'all'; |
||
15 | $sort_by_text = yourls__( 'Short URL' ); |
||
16 | $sort_by = 'timestamp'; |
||
17 | $sort_order = 'desc'; |
||
18 | $page = ( isset( $_GET['page'] ) ? intval($_GET['page']) : 1 ); |
||
19 | $search = yourls_get_search_text(); |
||
20 | $perpage = ( isset( $_GET['perpage'] ) && intval( $_GET['perpage'] ) ? intval($_GET['perpage']) : yourls_apply_filter( 'admin_view_per_page', 15 ) ); |
||
21 | $click_limit = ( isset( $_GET['click_limit'] ) && $_GET['click_limit'] !== '' ) ? intval( $_GET['click_limit'] ) : '' ; |
||
22 | if ( $click_limit !== '' ) { |
||
23 | $click_filter = ( isset( $_GET['click_filter'] ) && $_GET['click_filter'] == 'more' ? 'more' : 'less' ) ; |
||
24 | $click_moreless = ( $click_filter == 'more' ? '>' : '<' ); |
||
25 | $where = " AND clicks $click_moreless $click_limit"; |
||
26 | } else { |
||
27 | $click_filter = ''; |
||
28 | } |
||
29 | |||
30 | // Searching |
||
31 | if( !empty( $search ) && !empty( $_GET['search_in'] ) ) { |
||
32 | View Code Duplication | switch( $_GET['search_in'] ) { |
|
0 ignored issues
–
show
|
|||
33 | case 'all': |
||
34 | $search_in_text = yourls__( 'All fields' ); |
||
35 | $search_in = 'all'; |
||
36 | break; |
||
37 | case 'keyword': |
||
38 | $search_in_text = yourls__( 'Short URL' ); |
||
39 | $search_in = 'keyword'; |
||
40 | break; |
||
41 | case 'url': |
||
42 | $search_in_text = yourls__( 'URL' ); |
||
43 | $search_in = 'url'; |
||
44 | break; |
||
45 | case 'title': |
||
46 | $search_in_text = yourls__( 'Title' ); |
||
47 | $search_in = 'title'; |
||
48 | break; |
||
49 | case 'ip': |
||
50 | $search_in_text = yourls__( 'IP Address' ); |
||
51 | $search_in = 'ip'; |
||
52 | break; |
||
53 | } |
||
54 | $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 ) ); |
||
55 | $search_text = $search; |
||
56 | $search = str_replace( '*', '%', '*' . yourls_escape( $search ) . '*' ); |
||
57 | if( $search_in == 'all' ) { |
||
58 | $where .= " AND CONCAT_WS('',`keyword`,`url`,`title`,`ip`) LIKE ('$search')"; |
||
59 | // Search across all fields. The resulting SQL will be something like: |
||
60 | // SELECT * FROM `yourls_url` WHERE CONCAT_WS('',`keyword`,`url`,`title`,`ip`) LIKE ("%ozh%") |
||
61 | // 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. |
||
62 | // TODO: pay attention to this bit when the DB schema changes |
||
63 | } else { |
||
64 | $where .= " AND `$search_in` LIKE ('$search')"; |
||
65 | } |
||
66 | } |
||
67 | |||
68 | // Time span |
||
69 | if( !empty( $_GET['date_filter'] ) ) { |
||
70 | switch( $_GET['date_filter'] ) { |
||
71 | View Code Duplication | case 'before': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
72 | $date_filter = 'before'; |
||
73 | if( isset( $_GET['date_first'] ) && yourls_sanitize_date( $_GET['date_first'] ) ) { |
||
74 | $date_first = yourls_sanitize_date( $_GET['date_first'] ); |
||
75 | $date_first_sql = yourls_sanitize_date_for_sql( $_GET['date_first'] ); |
||
76 | $where .= " AND `timestamp` < '$date_first_sql'"; |
||
77 | } |
||
78 | break; |
||
79 | View Code Duplication | case 'after': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
80 | $date_filter = 'after'; |
||
81 | if( isset( $_GET['date_first'] ) && yourls_sanitize_date( $_GET['date_first'] ) ) { |
||
82 | $date_first_sql = yourls_sanitize_date_for_sql( $_GET['date_first'] ); |
||
83 | $date_first = yourls_sanitize_date( $_GET['date_first'] ); |
||
84 | $where .= " AND `timestamp` > '$date_first_sql'"; |
||
85 | } |
||
86 | break; |
||
87 | case 'between': |
||
88 | $date_filter = 'between'; |
||
89 | if( isset( $_GET['date_first'] ) && isset( $_GET['date_second'] ) && yourls_sanitize_date( $_GET['date_first'] ) && yourls_sanitize_date( $_GET['date_second'] ) ) { |
||
90 | $date_first_sql = yourls_sanitize_date_for_sql( $_GET['date_first'] ); |
||
91 | $date_second_sql = yourls_sanitize_date_for_sql( $_GET['date_second'] ); |
||
92 | $date_first = yourls_sanitize_date( $_GET['date_first'] ); |
||
93 | $date_second = yourls_sanitize_date( $_GET['date_second'] ); |
||
94 | $where .= " AND `timestamp` BETWEEN '$date_first_sql' AND '$date_second_sql'"; |
||
95 | } |
||
96 | break; |
||
97 | } |
||
98 | } |
||
99 | |||
100 | // Sorting |
||
101 | if( !empty( $_GET['sort_by'] ) || !empty( $_GET['sort_order'] ) ) { |
||
102 | View Code Duplication | switch( $_GET['sort_by'] ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
103 | case 'keyword': |
||
104 | $sort_by_text = yourls__( 'Short URL' ); |
||
105 | $sort_by = 'keyword'; |
||
106 | break; |
||
107 | case 'url': |
||
108 | $sort_by_text = yourls__( 'URL' ); |
||
109 | $sort_by = 'url'; |
||
110 | break; |
||
111 | case 'timestamp': |
||
112 | $sort_by_text = yourls__( 'Date' ); |
||
113 | $sort_by = 'timestamp'; |
||
114 | break; |
||
115 | case 'ip': |
||
116 | $sort_by_text = yourls__( 'IP Address' ); |
||
117 | $sort_by = 'ip'; |
||
118 | break; |
||
119 | case 'clicks': |
||
120 | $sort_by_text = yourls__( 'Clicks' ); |
||
121 | $sort_by = 'clicks'; |
||
122 | break; |
||
123 | } |
||
124 | switch( $_GET['sort_order'] ) { |
||
125 | case 'asc': |
||
126 | $sort_order = 'asc'; |
||
127 | break; |
||
128 | case 'desc': |
||
129 | $sort_order = 'desc'; |
||
130 | break; |
||
131 | } |
||
132 | } |
||
133 | |||
134 | // Get URLs Count for current filter, total links in DB & total clicks |
||
135 | list( $total_urls, $total_clicks ) = array_values( yourls_get_db_stats() ); |
||
136 | if ( $where ) { |
||
137 | list( $total_items, $total_items_clicks ) = array_values( yourls_get_db_stats( $where ) ); |
||
138 | } else { |
||
139 | $total_items = $total_urls; |
||
140 | $total_items_clicks = false; |
||
141 | } |
||
142 | |||
143 | // This is a bookmarklet |
||
144 | if ( isset( $_GET['u'] ) or isset( $_GET['up'] ) ) { |
||
145 | $is_bookmark = true; |
||
146 | yourls_do_action( 'bookmarklet' ); |
||
147 | |||
148 | // No sanitization needed here: everything happens in yourls_add_new_link() |
||
149 | if( isset( $_GET['u'] ) ) { |
||
150 | // Old school bookmarklet: ?u=<url> |
||
151 | $url = rawurldecode( $_GET['u'] ); |
||
152 | } else { |
||
153 | // New style bookmarklet: ?up=<url protocol>&us=<url slashes>&ur=<url rest> |
||
154 | $url = rawurldecode( $_GET['up'] . $_GET['us'] . $_GET['ur'] ); |
||
155 | } |
||
156 | $keyword = ( isset( $_GET['k'] ) ? ( $_GET['k'] ) : '' ); |
||
157 | $title = ( isset( $_GET['t'] ) ? ( $_GET['t'] ) : '' ); |
||
158 | $return = yourls_add_new_link( $url, $keyword, $title ); |
||
159 | |||
160 | // If fails because keyword already exist, retry with no keyword |
||
161 | if ( isset( $return['status'] ) && $return['status'] == 'fail' && isset( $return['code'] ) && $return['code'] == 'error:keyword' ) { |
||
162 | $msg = $return['message']; |
||
163 | $return = yourls_add_new_link( $url, '', $ydb ); |
||
164 | $return['message'] .= ' ('.$msg.')'; |
||
165 | } |
||
166 | |||
167 | // Stop here if bookmarklet with a JSON callback function |
||
168 | if( isset( $_GET['jsonp'] ) && $_GET['jsonp'] == 'yourls' ) { |
||
169 | $short = $return['shorturl'] ? $return['shorturl'] : ''; |
||
170 | $message = $return['message']; |
||
171 | yourls_content_type_header( 'application/javascript' ); |
||
172 | echo yourls_apply_filter( 'bookmarklet_jsonp', "yourls_callback({'short_url':'$short','message':'$message'});" ); |
||
173 | |||
174 | die(); |
||
175 | } |
||
176 | |||
177 | // Now use the URL that has been sanitized and returned by yourls_add_new_link() |
||
178 | $url = $return['url']['url']; |
||
179 | $where = sprintf( " AND `url` LIKE '%s' ", yourls_escape( $url ) ); |
||
180 | |||
181 | $page = $total_pages = $perpage = 1; |
||
182 | $offset = 0; |
||
183 | |||
184 | $text = ( isset( $_GET['s'] ) ? stripslashes( $_GET['s'] ) : '' ); |
||
185 | |||
186 | // Sharing with social bookmarklets |
||
187 | if( !empty($_GET['share']) ) { |
||
188 | yourls_do_action( 'pre_share_redirect' ); |
||
189 | switch ( $_GET['share'] ) { |
||
190 | View Code Duplication | case 'twitter': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
191 | // share with Twitter |
||
192 | $destination = sprintf( "https://twitter.com/intent/tweet?url=%s&text=%s", urlencode( $return['shorturl'] ), urlencode( $title ) ); |
||
193 | yourls_redirect( $destination, 303 ); |
||
194 | |||
195 | // Deal with the case when redirection failed: |
||
196 | $return['status'] = 'error'; |
||
197 | $return['errorCode'] = 400; |
||
198 | $return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Twitter' ); |
||
199 | break; |
||
200 | |||
201 | View Code Duplication | case 'facebook': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
202 | // share with Facebook |
||
203 | $destination = sprintf( "https://www.facebook.com/sharer/sharer.php?u=%s&t=%s", urlencode( $return['shorturl'] ), urlencode( $title ) ); |
||
204 | yourls_redirect( $destination, 303 ); |
||
205 | |||
206 | // Deal with the case when redirection failed: |
||
207 | $return['status'] = 'error'; |
||
208 | $return['errorCode'] = 400; |
||
209 | $return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Facebook' ); |
||
210 | break; |
||
211 | |||
212 | View Code Duplication | case 'tumblr': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
213 | // share with Tumblr |
||
214 | $destination = sprintf( "https://www.tumblr.com/share?v=3&u=%s&t=%s&s=%s", urlencode( $return['shorturl'] ), urlencode( $title ), urlencode( $text ) ); |
||
215 | yourls_redirect( $destination, 303 ); |
||
216 | |||
217 | // Deal with the case when redirection failed: |
||
218 | $return['status'] = 'error'; |
||
219 | $return['errorCode'] = 400; |
||
220 | $return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Tumblr' ); |
||
221 | break; |
||
222 | |||
223 | default: |
||
224 | // Is there a custom registered social bookmark? |
||
225 | yourls_do_action( 'share_redirect_' . $_GET['share'], $return ); |
||
226 | |||
227 | // Still here? That was an unknown 'share' method, then. |
||
228 | $return['status'] = 'error'; |
||
229 | $return['errorCode'] = 400; |
||
230 | $return['message'] = yourls__( 'Unknown "Share" bookmarklet' ); |
||
231 | break; |
||
232 | } |
||
233 | } |
||
234 | |||
235 | // This is not a bookmarklet |
||
236 | } else { |
||
237 | $is_bookmark = false; |
||
238 | |||
239 | // Checking $page, $offset, $perpage |
||
240 | if( empty($page) || $page == 0 ) { |
||
241 | $page = 1; |
||
242 | } |
||
243 | if( empty($offset) ) { |
||
244 | $offset = 0; |
||
245 | } |
||
246 | if( empty($perpage) || $perpage == 0) { |
||
247 | $perpage = 50; |
||
248 | } |
||
249 | |||
250 | // Determine $offset |
||
251 | $offset = ( $page-1 ) * $perpage; |
||
252 | |||
253 | // Determine Max Number Of Items To Display On Page |
||
254 | if( ( $offset + $perpage ) > $total_items ) { |
||
255 | $max_on_page = $total_items; |
||
256 | } else { |
||
257 | $max_on_page = ( $offset + $perpage ); |
||
258 | } |
||
259 | |||
260 | // Determine Number Of Items To Display On Page |
||
261 | if ( ( $offset + 1 ) > $total_items ) { |
||
262 | $display_on_page = $total_items; |
||
263 | } else { |
||
264 | $display_on_page = ( $offset + 1 ); |
||
265 | } |
||
266 | |||
267 | // Determing Total Amount Of Pages |
||
268 | $total_pages = ceil( $total_items / $perpage ); |
||
269 | } |
||
270 | |||
271 | |||
272 | // Begin output of the page |
||
273 | $context = ( $is_bookmark ? 'bookmark' : 'index' ); |
||
274 | yourls_html_head( $context ); |
||
275 | yourls_html_logo(); |
||
276 | yourls_html_menu() ; |
||
277 | |||
278 | yourls_do_action( 'admin_page_before_content' ); |
||
279 | |||
280 | if ( !$is_bookmark ) { ?> |
||
281 | <p><?php echo $search_sentence; ?></p> |
||
282 | <p><?php |
||
283 | 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 ); |
||
284 | if( $total_items_clicks !== false ) |
||
285 | echo ", " . sprintf( yourls_n( 'counting <strong>1</strong> click', 'counting <strong>%s</strong> clicks', $total_items_clicks ), yourls_number_format_i18n( $total_items_clicks ) ); |
||
286 | ?>.</p> |
||
287 | <?php } ?> |
||
288 | <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> |
||
289 | <?php |
||
290 | |||
291 | yourls_do_action( 'admin_page_before_form' ); |
||
292 | |||
293 | yourls_html_addnew(); |
||
294 | |||
295 | // If bookmarklet, add message. Otherwise, hide hidden share box. |
||
296 | if ( !$is_bookmark ) { |
||
297 | yourls_share_box( '', '', '', '', '', '', true ); |
||
298 | } else { |
||
299 | echo '<script type="text/javascript">$(document).ready(function(){ |
||
300 | feedback( "' . $return['message'] . '", "'. $return['status'] .'"); |
||
301 | init_clipboard(); |
||
302 | });</script>'; |
||
303 | } |
||
304 | |||
305 | yourls_do_action( 'admin_page_before_table' ); |
||
306 | |||
307 | yourls_table_head(); |
||
308 | |||
309 | if ( !$is_bookmark ) { |
||
310 | $params = array( |
||
311 | 'search' => $search, |
||
312 | 'search_text' => $search_text, |
||
313 | 'search_in' => $search_in, |
||
314 | 'sort_by' => $sort_by, |
||
315 | 'sort_order' => $sort_order, |
||
316 | 'page' => $page, |
||
317 | 'perpage' => $perpage, |
||
318 | 'click_filter' => $click_filter, |
||
319 | 'click_limit' => $click_limit, |
||
320 | 'total_pages' => $total_pages, |
||
321 | 'date_filter' => $date_filter, |
||
322 | 'date_first' => $date_first, |
||
323 | 'date_second' => $date_second, |
||
324 | ); |
||
325 | yourls_html_tfooter( $params ); |
||
326 | } |
||
327 | |||
328 | yourls_table_tbody_start(); |
||
329 | |||
330 | // Main Query |
||
331 | $where = yourls_apply_filter( 'admin_list_where', $where ); |
||
332 | $url_results = $ydb->get_results( "SELECT * FROM `$table_url` WHERE 1=1 $where ORDER BY `$sort_by` $sort_order LIMIT $offset, $perpage;" ); |
||
333 | $found_rows = false; |
||
334 | if( $url_results ) { |
||
335 | $found_rows = true; |
||
336 | foreach( $url_results as $url_result ) { |
||
337 | $keyword = yourls_sanitize_string( $url_result->keyword ); |
||
338 | $timestamp = strtotime( $url_result->timestamp ); |
||
339 | $url = stripslashes( $url_result->url ); |
||
340 | $ip = $url_result->ip; |
||
341 | $title = $url_result->title ? $url_result->title : ''; |
||
342 | $clicks = $url_result->clicks; |
||
343 | |||
344 | echo yourls_table_add_row( $keyword, $url, $title, $ip, $clicks, $timestamp ); |
||
345 | } |
||
346 | } |
||
347 | |||
348 | $display = $found_rows ? 'display:none' : ''; |
||
349 | echo '<tr id="nourl_found" style="'.$display.'"><td colspan="6">' . yourls__('No URL') . '</td></tr>'; |
||
350 | |||
351 | yourls_table_tbody_end(); |
||
352 | |||
353 | yourls_table_end(); |
||
354 | |||
355 | yourls_do_action( 'admin_page_after_table' ); |
||
356 | |||
357 | if ( $is_bookmark ) |
||
358 | yourls_share_box( $url, $return['shorturl'], $title, $text ); |
||
359 | ?> |
||
360 | |||
361 | <?php yourls_html_footer( ); ?> |
||
362 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.