Completed
Pull Request — master (#2282)
by ྅༻ Ǭɀħ
01:46
created

functions-html.php ➔ yourls_html_footer()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 27
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 23
nc 4
nop 1
dl 0
loc 27
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Display <h1> header and logo
5
 *
6
 */
7
function yourls_html_logo() {
8
	yourls_do_action( 'pre_html_logo' );
9
	?>
10
	<header role="banner">
11
	<h1>
12
		<a href="<?php echo yourls_admin_url( 'index.php' ) ?>" title="YOURLS"><span>YOURLS</span>: <span>Y</span>our <span>O</span>wn <span>URL</span> <span>S</span>hortener<br/>
13
		<img src="<?php yourls_site_url(); ?>/images/yourls-logo.png" alt="YOURLS" title="YOURLS" border="0" style="border: 0px;" /></a>
14
	</h1>
15
	</header>
16
	<?php
17
	yourls_do_action( 'html_logo' );
18
}
19
20
/**
21
 * Display HTML head and <body> tag
22
 *
23
 * @param string $context Context of the page (stats, index, infos, ...)
24
 * @param string $title HTML title of the page
25
 */
26
function yourls_html_head( $context = 'index', $title = '' ) {
27
28
	yourls_do_action( 'pre_html_head', $context, $title );
29
30
	// All components to false, except when specified true
31
	$share = $insert = $tablesorter = $tabs = $cal = $charts = false;
32
33
	// Load components as needed
34
	switch ( $context ) {
35
		case 'infos':
36
			$share = $tabs = $charts = true;
37
			break;
38
39
		case 'bookmark':
40
			$share = $insert = $tablesorter = true;
41
			break;
42
43
		case 'index':
44
			$insert = $tablesorter = $cal = $share = true;
45
			break;
46
47
		case 'plugins':
48
		case 'tools':
49
			$tablesorter = true;
50
			break;
51
52
		case 'install':
53
		case 'login':
54
		case 'new':
55
		case 'upgrade':
56
			break;
57
	}
58
59
	// Force no cache for all admin pages
60
	if( yourls_is_admin() && !headers_sent() ) {
61
		header( 'Expires: Thu, 23 Mar 1972 07:00:00 GMT' );
62
		header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
63
		header( 'Cache-Control: no-cache, must-revalidate, max-age=0' );
64
		header( 'Pragma: no-cache' );
65
		yourls_content_type_header( yourls_apply_filter( 'html_head_content-type', 'text/html' ) );
66
		yourls_do_action( 'admin_headers', $context, $title );
67
	}
68
69
	// Store page context
70
	yourls_set_html_context($context);
71
72
	// Body class
73
	$bodyclass = yourls_apply_filter( 'bodyclass', '' );
74
	$bodyclass .= ( yourls_is_mobile_device() ? 'mobile' : 'desktop' );
75
76
	// Page title
77
	$_title = 'YOURLS &mdash; Your Own URL Shortener | ' . yourls_link();
78
	$title = $title ? $title . " &laquo; " . $_title : $_title;
79
	$title = yourls_apply_filter( 'html_title', $title, $context );
80
81
	?>
82
<!DOCTYPE html>
83
<html <?php yourls_html_language_attributes(); ?>>
84
<head>
85
	<title><?php echo $title ?></title>
86
	<meta http-equiv="Content-Type" content="<?php echo yourls_apply_filter( 'html_head_meta_content-type', 'text/html; charset=utf-8' ); ?>" />
87
	<meta name="generator" content="YOURLS <?php echo YOURLS_VERSION ?>" />
88
	<meta name="description" content="YOURLS &raquo; Your Own URL Shortener' | <?php yourls_site_url(); ?>" />
89
	<meta name="referrer" content="always" />
90
	<?php yourls_do_action('html_head_meta', $context); ?>
91
	<link rel="shortcut icon" href="<?php yourls_favicon(); ?>" />
92
	<script src="<?php yourls_site_url(); ?>/js/jquery-2.2.4.min.js?v=<?php echo YOURLS_VERSION; ?>" type="text/javascript"></script>
93
	<script src="<?php yourls_site_url(); ?>/js/common.js?v=<?php echo YOURLS_VERSION; ?>" type="text/javascript"></script>
94
	<script src="<?php yourls_site_url(); ?>/js/jquery.notifybar.js?v=<?php echo YOURLS_VERSION; ?>" type="text/javascript"></script>
95
	<link rel="stylesheet" href="<?php yourls_site_url(); ?>/css/style.css?v=<?php echo YOURLS_VERSION; ?>" type="text/css" media="screen" />
96 View Code Duplication
	<?php if ( $tabs ) { ?>
0 ignored issues
show
Duplication introduced by LeoColomb
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...
97
		<link rel="stylesheet" href="<?php yourls_site_url(); ?>/css/infos.css?v=<?php echo YOURLS_VERSION; ?>" type="text/css" media="screen" />
98
		<script src="<?php yourls_site_url(); ?>/js/infos.js?v=<?php echo YOURLS_VERSION; ?>" type="text/javascript"></script>
99
	<?php } ?>
100 View Code Duplication
	<?php if ( $tablesorter ) { ?>
0 ignored issues
show
Duplication introduced by LeoColomb
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...
101
		<link rel="stylesheet" href="<?php yourls_site_url(); ?>/css/tablesorter.css?v=<?php echo YOURLS_VERSION; ?>" type="text/css" media="screen" />
102
		<script src="<?php yourls_site_url(); ?>/js/jquery.tablesorter.min.js?v=<?php echo YOURLS_VERSION; ?>" type="text/javascript"></script>
103
	<?php } ?>
104
	<?php if ( $insert ) { ?>
105
		<script src="<?php yourls_site_url(); ?>/js/insert.js?v=<?php echo YOURLS_VERSION; ?>" type="text/javascript"></script>
106
	<?php } ?>
107
	<?php if ( $share ) { ?>
108
		<link rel="stylesheet" href="<?php yourls_site_url(); ?>/css/share.css?v=<?php echo YOURLS_VERSION; ?>" type="text/css" media="screen" />
109
		<script src="<?php yourls_site_url(); ?>/js/share.js?v=<?php echo YOURLS_VERSION; ?>" type="text/javascript"></script>
110
		<script src="<?php yourls_site_url(); ?>/js/clipboard.min.js?v=<?php echo YOURLS_VERSION; ?>" type="text/javascript"></script>
111
	<?php } ?>
112 View Code Duplication
	<?php if ( $cal ) { ?>
0 ignored issues
show
Duplication introduced by LeoColomb
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...
113
		<link rel="stylesheet" href="<?php yourls_site_url(); ?>/css/cal.css?v=<?php echo YOURLS_VERSION; ?>" type="text/css" media="screen" />
114
		<?php yourls_l10n_calendar_strings(); ?>
115
		<script src="<?php yourls_site_url(); ?>/js/jquery.cal.js?v=<?php echo YOURLS_VERSION; ?>" type="text/javascript"></script>
116
	<?php } ?>
117
	<?php if ( $charts ) { ?>
118
			<script type="text/javascript" src="https://www.google.com/jsapi"></script>
119
			<script type="text/javascript">
120
					 google.load('visualization', '1.0', {'packages':['corechart', 'geochart']});
121
			</script>
122
	<?php } ?>
123
	<script type="text/javascript">
124
	//<![CDATA[
125
		var ajaxurl  = '<?php echo yourls_admin_url( 'admin-ajax.php' ); ?>';
126
	//]]>
127
	</script>
128
	<?php yourls_do_action( 'html_head', $context ); ?>
129
</head>
130
<body class="<?php echo $context; ?> <?php echo $bodyclass; ?>">
131
<div id="wrap">
132
	<?php
133
}
134
135
/**
136
 * Display HTML footer (including closing body & html tags)
137
 *
138
 * Function yourls_die() will call this function with the optional param set to false: most likely, if we're using yourls_die(),
139
 * there's a problem, so don't maybe add to it by sending another SQL query
140
 *
141
 * @param  bool $can_query  If set to false, will not try to send another query to DB server
142
 * @return void
143
 */
144
function yourls_html_footer($can_query = true) {
145
    if($can_query) {
146
        $num_queries = yourls_get_num_queries();
147
        $num_queries = sprintf( yourls_n( '1 query', '%s queries', $num_queries ), $num_queries );
148
    } else {
149
        $num_queries = '';
150
    }
151
152
	?>
153
	</div><?php // wrap ?>
154
	<footer id="footer" role="contentinfo"><p>
155
		<?php
156
		$footer  = yourls_s( 'Powered by %s', '<a href="http://yourls.org/" title="YOURLS">YOURLS</a> v ' . YOURLS_VERSION );
157
		$footer .= ' &ndash; '.$num_queries;
158
		echo yourls_apply_filter( 'html_footer_text', $footer );
159
		?>
160
	</p></footer>
161
	<?php if( defined( 'YOURLS_DEBUG' ) && YOURLS_DEBUG == true ) {
0 ignored issues
show
Coding Style Best Practice introduced by LeoColomb
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
162
		echo '<div style="text-align:left"><pre>';
163
		echo join( "\n", yourls_get_debug_log() );
164
		echo '</div>';
165
	} ?>
166
	<?php yourls_do_action( 'html_footer', yourls_get_html_context() ); ?>
167
	</body>
168
	</html>
169
	<?php
170
}
171
172
/**
173
 * Display "Add new URL" box
174
 *
175
 * @param string $url URL to prefill the input with
176
 * @param string $keyword Keyword to prefill the input with
177
 */
178
function yourls_html_addnew( $url = '', $keyword = '' ) {
179
	?>
180
	<main role="main">
181
	<div id="new_url">
182
		<div>
183
			<form id="new_url_form" action="" method="get">
184
				<div><strong><?php yourls_e( 'Enter the URL' ); ?></strong>:<input type="text" id="add-url" name="url" value="<?php echo $url; ?>" class="text" size="80" placeholder="http://" />
185
				<?php yourls_e( 'Optional '); ?> : <strong><?php yourls_e('Custom short URL'); ?></strong>:<input type="text" id="add-keyword" name="keyword" value="<?php echo $keyword; ?>" class="text" size="8" />
186
				<?php yourls_nonce_field( 'add_url', 'nonce-add' ); ?>
187
				<input type="button" id="add-button" name="add-button" value="<?php yourls_e( 'Shorten The URL' ); ?>" class="button" onclick="add_link();" /></div>
188
			</form>
189
			<div id="feedback" style="display:none"></div>
190
		</div>
191
		<?php yourls_do_action( 'html_addnew' ); ?>
192
	</div>
193
	<?php
194
}
195
196
/**
197
 * Display main table's footer
198
 *
199
 * The $param array is defined in /admin/index.php, check the yourls_html_tfooter() call
200
 *
201
 * @param array $params Array of all required parameters
202
 * @return string Result
203
 */
204
function yourls_html_tfooter( $params = array() ) {
205
    // Manually extract all parameters from the array. We prefer doing it this way, over using extract(),
206
    // to make things clearer and more explicit about what var is used.
207
    $search       = $params['search'];
0 ignored issues
show
Unused Code introduced by ozh
$search is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
208
    $search_text  = $params['search_text'];
209
    $search_in    = $params['search_in'];
210
    $sort_by      = $params['sort_by'];
211
    $sort_order   = $params['sort_order'];
212
    $page         = $params['page'];
213
    $perpage      = $params['perpage'];
214
    $click_filter = $params['click_filter'];
215
    $click_limit  = $params['click_limit'];
216
    $total_pages  = $params['total_pages'];
217
    $date_filter  = $params['date_filter'];
218
    $date_first   = $params['date_first'];
219
    $date_second  = $params['date_second'];
220
221
	?>
222
	<tfoot>
223
		<tr>
224
			<th colspan="6">
225
			<div id="filter_form">
226
				<form action="" method="get">
227
					<div id="filter_options">
228
						<?php
229
230
						// First search control: text to search
231
						$_input = '<input type="text" name="search" class="text" size="12" value="' . yourls_esc_attr( $search_text ) . '" />';
232
						$_options = array(
233
                            'all'     => yourls__( 'All fields' ),
234
							'keyword' => yourls__( 'Short URL' ),
235
							'url'     => yourls__( 'URL' ),
236
							'title'   => yourls__( 'Title' ),
237
							'ip'      => yourls__( 'IP' ),
238
						);
239
						$_select = yourls_html_select( 'search_in', $_options, $search_in );
240
						/* //translators: "Search for <input field with text to search> in <select dropdown with URL, title...>" */
241
						yourls_se( 'Search for %1$s in %2$s', $_input , $_select );
242
						echo "&ndash;\n";
243
244
						// Second search control: order by
245
						$_options = array(
246
							'keyword'      => yourls__( 'Short URL' ),
247
							'url'          => yourls__( 'URL' ),
248
							'timestamp'    => yourls__( 'Date' ),
249
							'ip'           => yourls__( 'IP' ),
250
							'clicks'       => yourls__( 'Clicks' ),
251
						);
252
						$_select = yourls_html_select( 'sort_by', $_options, $sort_by );
253
						$sort_order = isset( $sort_order ) ? $sort_order : 'desc' ;
254
						$_options = array(
255
							'asc'  => yourls__( 'Ascending' ),
256
							'desc' => yourls__( 'Descending' ),
257
						);
258
						$_select2 = yourls_html_select( 'sort_order', $_options, $sort_order );
259
						/* //translators: "Order by <criteria dropdown (date, clicks...)> in <order dropdown (Descending or Ascending)>" */
260
						yourls_se( 'Order by %1$s %2$s', $_select , $_select2 );
261
						echo "&ndash;\n";
262
263
						// Third search control: Show XX rows
264
						/* //translators: "Show <text field> rows" */
265
						yourls_se( 'Show %s rows',  '<input type="text" name="perpage" class="text" size="2" value="' . $perpage . '" />' );
266
						echo "<br/>\n";
267
268
						// Fourth search control: Show links with more than XX clicks
269
						$_options = array(
270
							'more' => yourls__( 'more' ),
271
							'less' => yourls__( 'less' ),
272
						);
273
						$_select = yourls_html_select( 'click_filter', $_options, $click_filter );
274
						$_input  = '<input type="text" name="click_limit" class="text" size="4" value="' . $click_limit . '" /> ';
275
						/* //translators: "Show links with <more/less> than <text field> clicks" */
276
						yourls_se( 'Show links with %1$s than %2$s clicks', $_select, $_input );
277
						echo "<br/>\n";
278
279
						// Fifth search control: Show links created before/after/between ...
280
						$_options = array(
281
							'before'  => yourls__('before'),
282
							'after'   => yourls__('after'),
283
							'between' => yourls__('between'),
284
						);
285
						$_select = yourls_html_select( 'date_filter', $_options, $date_filter );
286
						$_input  = '<input type="text" name="date_first" id="date_first" class="text" size="12" value="' . $date_first . '" />';
287
						$_and    = '<span id="date_and"' . ( $date_filter === 'between' ? ' style="display:inline"' : '' ) . '> &amp; </span>';
288
						$_input2 = '<input type="text" name="date_second" id="date_second" class="text" size="12" value="' . $date_second . '"' . ( $date_filter === 'between' ? ' style="display:inline"' : '' ) . '/>';
289
						/* //translators: "Show links created <before/after/between> <date input> <"and" if applicable> <date input if applicable>" */
290
						yourls_se( 'Show links created %1$s %2$s %3$s %4$s', $_select, $_input, $_and, $_input2 );
291
						?>
292
293
						<div id="filter_buttons">
294
							<input type="submit" id="submit-sort" value="<?php yourls_e('Search'); ?>" class="button primary" />
295
							&nbsp;
296
							<input type="button" id="submit-clear-filter" value="<?php yourls_e('Clear'); ?>" class="button" onclick="window.parent.location.href = 'index.php'" />
297
						</div>
298
299
					</div>
300
				</form>
301
			</div>
302
303
			<?php
304
			// Remove empty keys from the $params array so it doesn't clutter the pagination links
305
			$params = array_filter( $params, 'yourls_return_if_not_empty_string' ); // remove empty keys
306
307
			if( isset( $search_text ) ) {
308
				$params['search'] = $search_text;
309
				unset( $params['search_text'] );
310
			}
311
			?>
312
313
			<div id="pagination">
314
				<span class="navigation">
315
				<?php if( $total_pages > 1 ) { ?>
316
					<span class="nav_total"><?php echo sprintf( yourls_n( '1 page', '%s pages', $total_pages ), $total_pages ); ?></span>
317
					<?php
318
					$base_page = yourls_admin_url( 'index.php' );
319
					// Pagination offsets: min( max ( zomg! ) );
320
					$p_start = max(  min( $total_pages - 4, $page - 2 ), 1 );
321
					$p_end = min( max( 5, $page + 2 ), $total_pages );
322
					if( $p_start >= 2 ) {
323
						$link = yourls_add_query_arg( array_merge( $params, array( 'page' => 1 ) ), $base_page );
324
						echo '<span class="nav_link nav_first"><a href="' . $link . '" title="' . yourls_esc_attr__('Go to First Page') . '">' . yourls__( '&laquo; First' ) . '</a></span>';
325
						echo '<span class="nav_link nav_prev"></span>';
326
					}
327
					for( $i = $p_start ; $i <= $p_end; $i++ ) {
328
						if( $i == $page ) {
329
							echo "<span class='nav_link nav_current'>$i</span>";
330 View Code Duplication
						} else {
0 ignored issues
show
Duplication introduced by LeoColomb
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...
331
							$link = yourls_add_query_arg( array_merge( $params, array( 'page' => $i ) ), $base_page );
332
							echo '<span class="nav_link nav_goto"><a href="' . $link . '" title="' . sprintf( yourls_esc_attr( 'Page %s' ), $i ) .'">'.$i.'</a></span>';
333
						}
334
					}
335 View Code Duplication
					if( ( $p_end ) < $total_pages ) {
0 ignored issues
show
Duplication introduced by LeoColomb
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...
336
						$link = yourls_add_query_arg( array_merge( $params, array( 'page' => $total_pages ) ), $base_page );
337
						echo '<span class="nav_link nav_next"></span>';
338
						echo '<span class="nav_link nav_last"><a href="' . $link . '" title="' . yourls_esc_attr__('Go to Last Page') . '">' . yourls__( 'Last &raquo;' ) . '</a></span>';
339
					}
340
					?>
341
				<?php } ?>
342
				</span>
343
			</div>
344
			</th>
345
		</tr>
346
		<?php yourls_do_action( 'html_tfooter' ); ?>
347
	</tfoot>
348
	<?php
349
}
350
351
/**
352
 * Return a select box
353
 *
354
 * @since 1.6
355
 *
356
 * @param string $name HTML 'name' (also use as the HTML 'id')
357
 * @param array $options array of 'value' => 'Text displayed'
358
 * @param string $selected optional 'value' from the $options array that will be highlighted
359
 * @param boolean $display false (default) to return, true to echo
360
 * @return string HTML content of the select element
361
 */
362
function yourls_html_select( $name, $options, $selected = '', $display = false ) {
363
	$html = "<select name='$name' id='$name' size='1'>\n";
364
	foreach( $options as $value => $text ) {
365
		$html .= "<option value='$value' ";
366
		$html .= $selected == $value ? ' selected="selected"' : '';
367
		$html .= ">$text</option>\n";
368
	}
369
	$html .= "</select>\n";
370
	$html  = yourls_apply_filter( 'html_select', $html, $name, $options, $selected, $display );
371
	if( $display )
372
		echo $html;
373
	return $html;
374
}
375
376
/**
377
 * Display the Quick Share box
378
 *
379
 */
380
function yourls_share_box( $longurl, $shorturl, $title = '', $text='', $shortlink_title = '', $share_title = '', $hidden = false ) {
381
	if ( $shortlink_title == '' )
382
		$shortlink_title = '<h2>' . yourls__( 'Your short link' ) . '</h2>';
383
	if ( $share_title == '' )
384
		$share_title = '<h2>' . yourls__( 'Quick Share' ) . '</h2>';
385
386
	// Allow plugins to short-circuit the whole function
387
	$pre = yourls_apply_filter( 'shunt_share_box', false );
388
	if ( false !== $pre )
389
		return $pre;
390
391
	$text   = ( $text ? '"'.$text.'" ' : '' );
392
	$title  = ( $title ? "$title " : '' );
393
	$share  = yourls_esc_textarea( $title.$text.$shorturl );
394
	$count  = 140 - strlen( $share );
395
	$hidden = ( $hidden ? 'style="display:none;"' : '' );
396
397
	// Allow plugins to filter all data
398
	$data = compact( 'longurl', 'shorturl', 'title', 'text', 'shortlink_title', 'share_title', 'share', 'count', 'hidden' );
399
	$data = yourls_apply_filter( 'share_box_data', $data );
400
	extract( $data );
401
402
	$_share = rawurlencode( $share );
403
	$_url   = rawurlencode( $shorturl );
404
	?>
405
406
	<div id="shareboxes" <?php echo $hidden; ?>>
407
408
		<?php yourls_do_action( 'shareboxes_before', $longurl, $shorturl, $title, $text ); ?>
409
410
		<div id="copybox" class="share">
411
		<?php echo $shortlink_title; ?>
412
			<p><input id="copylink" class="text" size="32" value="<?php echo yourls_esc_url( $shorturl ); ?>" /></p>
413
			<p><small><?php yourls_e( 'Long link' ); ?>: <a id="origlink" href="<?php echo yourls_esc_url( $longurl ); ?>"><?php echo yourls_esc_url( $longurl ); ?></a></small>
414
			<?php if( yourls_do_log_redirect() ) { ?>
415
			<br/><small><?php yourls_e( 'Stats' ); ?>: <a id="statlink" href="<?php echo yourls_esc_url( $shorturl ); ?>+"><?php echo yourls_esc_url( $shorturl ); ?>+</a></small>
416
			<input type="hidden" id="titlelink" value="<?php echo yourls_esc_attr( $title ); ?>" />
417
			<?php } ?>
418
			</p>
419
		</div>
420
421
		<?php yourls_do_action( 'shareboxes_middle', $longurl, $shorturl, $title, $text ); ?>
422
423
		<div id="sharebox" class="share">
424
			<?php echo $share_title; ?>
425
			<div id="tweet">
426
				<span id="charcount" class="hide-if-no-js"><?php echo $count; ?></span>
427
				<textarea id="tweet_body"><?php echo $share; ?></textarea>
428
			</div>
429
			<p id="share_links"><?php yourls_e( 'Share with' ); ?>
430
				<a id="share_tw" href="http://twitter.com/home?status=<?php echo $_share; ?>" title="<?php yourls_e( 'Tweet this!' ); ?>" onclick="share('tw');return false">Twitter</a>
431
				<a id="share_fb" href="http://www.facebook.com/share.php?u=<?php echo $_url; ?>" title="<?php yourls_e( 'Share on Facebook' ); ?>" onclick="share('fb');return false;">Facebook</a>
432
				<?php
433
				yourls_do_action( 'share_links', $longurl, $shorturl, $title, $text );
434
				// Note: on the main admin page, there are no parameters passed to the sharebox when it's drawn.
435
				?>
436
			</p>
437
		</div>
438
439
		<?php yourls_do_action( 'shareboxes_after', $longurl, $shorturl, $title, $text ); ?>
440
441
	</div>
442
443
	<?php
444
}
445
446
/**
447
 * Die die die
448
 *
449
 */
450
function yourls_die( $message = '', $title = '', $header_code = 200 ) {
451
    yourls_do_action( 'pre_yourls_die', $message, $title, $header_code );
452
453
	yourls_status_header( $header_code );
454
455
	if( !yourls_did_action( 'html_head' ) ) {
456
		yourls_html_head();
457
		yourls_html_logo();
458
	}
459
	echo yourls_apply_filter( 'die_title', "<h2>$title</h2>" );
460
	echo yourls_apply_filter( 'die_message', "<p>$message</p>" );
461
    // Hook into 'yourls_die' to add more elements or messages to that page
462
	yourls_do_action( 'yourls_die' );
463
	if( !yourls_did_action( 'html_footer' ) ) {
464
		yourls_html_footer(false);
465
	}
466
	die();
467
}
468
469
/**
470
 * Return an "Edit" row for the main table
471
 *
472
 * @param string $keyword Keyword to edit
473
 * @return string HTML of the edit row
474
 */
475
function yourls_table_edit_row( $keyword ) {
476
	$keyword = yourls_sanitize_string( $keyword );
477
	$id = yourls_string2htmlid( $keyword ); // used as HTML #id
478
	$url = yourls_get_keyword_longurl( $keyword );
479
	$title = htmlspecialchars( yourls_get_keyword_title( $keyword ) );
480
	$safe_url = yourls_esc_attr( rawurldecode( $url ) );
481
	$safe_title = yourls_esc_attr( $title );
482
483
    // Make strings sprintf() safe: '%' -> '%%'
484
    $safe_url = str_replace( '%', '%%', $safe_url );
485
    $safe_title = str_replace( '%', '%%', $safe_title );
486
487
	$www = yourls_link();
488
489
	$nonce = yourls_create_nonce( 'edit-save_'.$id );
490
491
	if( $url ) {
492
		$return = <<<RETURN
493
<tr id="edit-$id" class="edit-row"><td colspan="5" class="edit-row"><strong>%s</strong>:<input type="text" id="edit-url-$id" name="edit-url-$id" value="$safe_url" class="text" size="70" /><br/><strong>%s</strong>: $www<input type="text" id="edit-keyword-$id" name="edit-keyword-$id" value="$keyword" class="text" size="10" /><br/><strong>%s</strong>: <input type="text" id="edit-title-$id" name="edit-title-$id" value="$safe_title" class="text" size="60" /></td><td colspan="1"><input type="button" id="edit-submit-$id" name="edit-submit-$id" value="%s" title="%s" class="button" onclick="edit_link_save('$id');" />&nbsp;<input type="button" id="edit-close-$id" name="edit-close-$id" value="%s" title="%s" class="button" onclick="edit_link_hide('$id');" /><input type="hidden" id="old_keyword_$id" value="$keyword"/><input type="hidden" id="nonce_$id" value="$nonce"/></td></tr>
494
RETURN;
495
		$return = sprintf( $return, yourls__( 'Long URL' ), yourls__( 'Short URL' ), yourls__( 'Title' ), yourls__( 'Save' ), yourls__( 'Save new values' ), yourls__( 'Cancel' ), yourls__( 'Cancel editing' ) );
496
	} else {
497
		$return = '<tr class="edit-row notfound"><td colspan="6" class="edit-row notfound">' . yourls__( 'Error, URL not found' ) . '</td></tr>';
498
	}
499
500
	$return = yourls_apply_filter( 'table_edit_row', $return, $keyword, $url, $title );
501
502
	return $return;
503
}
504
505
/**
506
 * Return an "Add" row for the main table
507
 *
508
 * @return string HTML of the edit row
509
 */
510
function yourls_table_add_row( $keyword, $url, $title = '', $ip, $clicks, $timestamp ) {
511
	$keyword  = yourls_sanitize_string( $keyword );
512
	$id       = yourls_string2htmlid( $keyword ); // used as HTML #id
513
	$shorturl = yourls_link( $keyword );
514
515
	$statlink = yourls_statlink( $keyword );
516
517
	$delete_link = yourls_nonce_url( 'delete-link_'.$id,
518
		yourls_add_query_arg( array( 'id' => $id, 'action' => 'delete', 'keyword' => $keyword ), yourls_admin_url( 'admin-ajax.php' ) )
0 ignored issues
show
Documentation introduced by LeoColomb
yourls_add_query_arg(arr..._url('admin-ajax.php')) is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
519
	);
520
521
	$edit_link = yourls_nonce_url( 'edit-link_'.$id,
522
		yourls_add_query_arg( array( 'id' => $id, 'action' => 'edit', 'keyword' => $keyword ), yourls_admin_url( 'admin-ajax.php' ) )
0 ignored issues
show
Documentation introduced by LeoColomb
yourls_add_query_arg(arr..._url('admin-ajax.php')) is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
523
	);
524
525
	// Action link buttons: the array
526
	$actions = array(
527
		'stats' => array(
528
			'href'    => $statlink,
529
			'id'      => "statlink-$id",
530
			'title'   => yourls_esc_attr__( 'Stats' ),
531
			'anchor'  => yourls__( 'Stats' ),
532
		),
533
		'share' => array(
534
			'href'    => '',
535
			'id'      => "share-button-$id",
536
			'title'   => yourls_esc_attr__( 'Share' ),
537
			'anchor'  => yourls__( 'Share' ),
538
			'onclick' => "toggle_share('$id');return false;",
539
		),
540
		'edit' => array(
541
			'href'    => $edit_link,
542
			'id'      => "edit-button-$id",
543
			'title'   => yourls_esc_attr__( 'Edit' ),
544
			'anchor'  => yourls__( 'Edit' ),
545
			'onclick' => "edit_link_display('$id');return false;",
546
		),
547
		'delete' => array(
548
			'href'    => $delete_link,
549
			'id'      => "delete-button-$id",
550
			'title'   => yourls_esc_attr__( 'Delete' ),
551
			'anchor'  => yourls__( 'Delete' ),
552
			'onclick' => "remove_link('$id');return false;",
553
		)
554
	);
555
	$actions = yourls_apply_filter( 'table_add_row_action_array', $actions );
556
557
	// Action link buttons: the HTML
558
	$action_links = '';
559
	foreach( $actions as $key => $action ) {
560
		$onclick = isset( $action['onclick'] ) ? 'onclick="' . $action['onclick'] . '"' : '' ;
561
		$action_links .= sprintf( '<a href="%s" id="%s" title="%s" class="%s" %s>%s</a>',
562
			$action['href'], $action['id'], $action['title'], 'button button_'.$key, $onclick, $action['anchor']
563
		);
564
	}
565
	$action_links = yourls_apply_filter( 'action_links', $action_links, $keyword, $url, $ip, $clicks, $timestamp );
566
567
	if( ! $title )
568
		$title = $url;
569
570
	$protocol_warning = '';
571
	if( ! in_array( yourls_get_protocol( $url ) , array( 'http://', 'https://' ) ) )
572
		$protocol_warning = yourls_apply_filter( 'add_row_protocol_warning', '<span class="warning" title="' . yourls__( 'Not a common link' ) . '">&#9733;</span>' );
573
574
	// Row cells: the array
575
	$cells = array(
576
		'keyword' => array(
577
			'template'      => '<a href="%shorturl%">%keyword_html%</a>',
578
			'shorturl'      => yourls_esc_url( $shorturl ),
579
			'keyword_html'  => yourls_esc_html( $keyword ),
580
		),
581
		'url' => array(
582
			'template'      => '<a href="%long_url%" title="%title_attr%">%title_html%</a><br/><small>%warning%<a href="%long_url%">%long_url_html%</a></small>',
583
			'long_url'      => yourls_esc_url( $url ),
584
			'title_attr'    => yourls_esc_attr( $title ),
585
			'title_html'    => yourls_esc_html( yourls_trim_long_string( $title ) ),
586
			'long_url_html' => yourls_esc_html( yourls_trim_long_string( $url ) ),
587
			'warning'       => $protocol_warning,
588
		),
589
		'timestamp' => array(
590
			'template' => '%date%',
591
			'date'     => date( 'M d, Y H:i', $timestamp +( YOURLS_HOURS_OFFSET * 3600 ) ),
592
		),
593
		'ip' => array(
594
			'template' => '%ip%',
595
			'ip'       => $ip,
596
		),
597
		'clicks' => array(
598
			'template' => '%clicks%',
599
			'clicks'   => yourls_number_format_i18n( $clicks, 0, '', '' ),
0 ignored issues
show
Unused Code introduced by LeoColomb
The call to yourls_number_format_i18n() has too many arguments starting with ''.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
600
		),
601
		'actions' => array(
602
			'template' => '%actions% <input type="hidden" id="keyword_%id%" value="%keyword%"/>',
603
			'actions'  => $action_links,
604
			'id'       => $id,
605
			'keyword'  => $keyword,
606
		),
607
	);
608
	$cells = yourls_apply_filter( 'table_add_row_cell_array', $cells, $keyword, $url, $title, $ip, $clicks, $timestamp );
609
610
	// Row cells: the HTML. Replace every %stuff% in 'template' with 'stuff' value.
611
	$row = "<tr id=\"id-$id\">";
612
	foreach( $cells as $cell_id => $elements ) {
613
		$callback = new yourls_table_add_row_callback( $elements );
614
		$row .= sprintf( '<td class="%s" id="%s">', $cell_id, $cell_id . '-' . $id );
615
		$row .= preg_replace_callback( '/%([^%]+)?%/', array( $callback, 'callback' ), $elements['template'] );
616
		// For the record, in PHP 5.3+ we don't need to introduce a class in order to pass additional parameters
617
		// to the callback function. Instead, we would have used the 'use' keyword :
618
		// $row .= preg_replace_callback( '/%([^%]+)?%/', function( $match ) use ( $elements ) { return $elements[ $match[1] ]; }, $elements['template'] );
619
620
		$row .= '</td>';
621
	}
622
	$row .= "</tr>";
623
	$row  = yourls_apply_filter( 'table_add_row', $row, $keyword, $url, $title, $ip, $clicks, $timestamp );
624
625
	return $row;
626
}
627
628
/**
629
 * Callback class for yourls_table_add_row
630
 *
631
 * See comment about PHP 5.3+ in yourls_table_add_row()
632
 *
633
 * @since 1.7
634
 */
635
class yourls_table_add_row_callback {
636
    private $elements;
637
638
    function __construct($elements) {
0 ignored issues
show
Best Practice introduced by ozh
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
639
		$this->elements = $elements;
640
	}
641
642
    function callback( $matches ) {
0 ignored issues
show
Best Practice introduced by ozh
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
643
		return $this->elements[ $matches[1] ];
644
    }
645
}
646
647
648
/**
649
 * Echo the main table head
650
 *
651
 */
652
function yourls_table_head() {
653
	$start = '<table id="main_table" class="tblSorter" cellpadding="0" cellspacing="1"><thead><tr>'."\n";
654
	echo yourls_apply_filter( 'table_head_start', $start );
655
656
	$cells = yourls_apply_filter( 'table_head_cells', array(
657
		'shorturl' => yourls__( 'Short URL' ),
658
		'longurl'  => yourls__( 'Original URL' ),
659
		'date'     => yourls__( 'Date' ),
660
		'ip'       => yourls__( 'IP' ),
661
		'clicks'   => yourls__( 'Clicks' ),
662
		'actions'  => yourls__( 'Actions' )
663
	) );
664
	foreach( $cells as $k => $v ) {
665
		echo "<th id='main_table_head_$k'>$v</th>\n";
666
	}
667
668
	$end = "</tr></thead>\n";
669
	echo yourls_apply_filter( 'table_head_end', $end );
670
}
671
672
/**
673
 * Echo the tbody start tag
674
 *
675
 */
676
function yourls_table_tbody_start() {
677
	echo yourls_apply_filter( 'table_tbody_start', '<tbody>' );
678
}
679
680
/**
681
 * Echo the tbody end tag
682
 *
683
 */
684
function yourls_table_tbody_end() {
685
	echo yourls_apply_filter( 'table_tbody_end', '</tbody>' );
686
}
687
688
/**
689
 * Echo the table start tag
690
 *
691
 */
692
function yourls_table_end() {
693
	echo yourls_apply_filter( 'table_end', '</table></main>' );
694
}
695
696
/**
697
 * Echo HTML tag for a link
698
 *
699
 */
700
function yourls_html_link( $href, $title = '', $element = '' ) {
701
	if( !$title )
702
		$title = $href;
703
	if( $element )
704
		$element = sprintf( 'id="%s"', yourls_esc_attr( $element ) );
705
	$link = sprintf( '<a href="%s" %s>%s</a>', yourls_esc_url( $href ), $element, yourls_esc_html( $title ) );
706
	echo yourls_apply_filter( 'html_link', $link );
707
}
708
709
/**
710
 * Display the login screen. Nothing past this point.
711
 *
712
 */
713
function yourls_login_screen( $error_msg = '' ) {
714
	yourls_html_head( 'login' );
715
716
	$action = ( isset( $_GET['action'] ) && $_GET['action'] == 'logout' ? '?' : '' );
717
718
	yourls_html_logo();
719
	?>
720
	<div id="login">
721
		<form method="post" action="<?php echo $action; ?>"> <?php // reset any QUERY parameters ?>
722
			<?php
723
				if( !empty( $error_msg ) ) {
724
					echo '<p class="error">'.$error_msg.'</p>';
725
				}
726
			?>
727
			<p>
728
				<label for="username"><?php yourls_e( 'Username' ); ?></label><br />
729
				<input type="text" id="username" name="username" size="30" class="text" />
730
			</p>
731
			<p>
732
				<label for="password"><?php yourls_e( 'Password' ); ?></label><br />
733
				<input type="password" id="password" name="password" size="30" class="text" />
734
			</p>
735
			<p style="text-align: right;">
736
				<input type="submit" id="submit" name="submit" value="<?php yourls_e( 'Login' ); ?>" class="button" />
737
			</p>
738
		</form>
739
		<script type="text/javascript">$('#username').focus();</script>
740
	</div>
741
	<?php
742
	yourls_html_footer();
743
	die();
744
}
745
746
/**
747
 * Display the admin menu
748
 *
749
 */
750
function yourls_html_menu() {
751
752
	// Build menu links
753
	if( defined( 'YOURLS_USER' ) ) {
754
		$logout_link = yourls_apply_filter( 'logout_link', sprintf( yourls__('Hello <strong>%s</strong>'), YOURLS_USER ) . ' (<a href="' . yourls_admin_url() . '?action=logout" title="' . yourls_esc_attr__( 'Logout' ) . '">' . yourls__( 'Logout' ) . '</a>)' );
755
	} else {
756
		$logout_link = yourls_apply_filter( 'logout_link', '' );
757
	}
758
	$help_link   = yourls_apply_filter( 'help_link',   '<a href="' . yourls_site_url( false ) .'/readme.html">' . yourls__( 'Help' ) . '</a>' );
759
760
	$admin_links    = array();
761
	$admin_sublinks = array();
762
763
	$admin_links['admin'] = array(
764
		'url'    => yourls_admin_url( 'index.php' ),
765
		'title'  => yourls__( 'Go to the admin interface' ),
766
		'anchor' => yourls__( 'Admin interface' )
767
	);
768
769
	if( yourls_is_admin() ) {
770
		$admin_links['tools'] = array(
771
			'url'    => yourls_admin_url( 'tools.php' ),
772
			'anchor' => yourls__( 'Tools' )
773
		);
774
		$admin_links['plugins'] = array(
775
			'url'    => yourls_admin_url( 'plugins.php' ),
776
			'anchor' => yourls__( 'Manage Plugins' )
777
		);
778
		$admin_sublinks['plugins'] = yourls_list_plugin_admin_pages();
779
	}
780
781
	$admin_links    = yourls_apply_filter( 'admin_links',    $admin_links );
782
	$admin_sublinks = yourls_apply_filter( 'admin_sublinks', $admin_sublinks );
783
784
	// Now output menu
785
	echo '<nav role="navigation"><ul id="admin_menu">'."\n";
786
	if ( yourls_is_private() && !empty( $logout_link ) )
787
		echo '<li id="admin_menu_logout_link">' . $logout_link .'</li>';
788
789
	foreach( (array)$admin_links as $link => $ar ) {
790 View Code Duplication
		if( isset( $ar['url'] ) ) {
0 ignored issues
show
Duplication introduced by LeoColomb
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...
791
			$anchor = isset( $ar['anchor'] ) ? $ar['anchor'] : $link;
792
			$title  = isset( $ar['title'] ) ? 'title="' . $ar['title'] . '"' : '';
793
			printf( '<li id="admin_menu_%s_link" class="admin_menu_toplevel"><a href="%s" %s>%s</a>', $link, $ar['url'], $title, $anchor );
794
		}
795
		// Output submenu if any. TODO: clean up, too many code duplicated here
796
		if( isset( $admin_sublinks[$link] ) ) {
797
			echo "<ul>\n";
798
			foreach( $admin_sublinks[$link] as $link => $ar ) {
799 View Code Duplication
				if( isset( $ar['url'] ) ) {
0 ignored issues
show
Duplication introduced by LeoColomb
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...
800
					$anchor = isset( $ar['anchor'] ) ? $ar['anchor'] : $link;
801
					$title  = isset( $ar['title'] ) ? 'title="' . $ar['title'] . '"' : '';
802
					printf( '<li id="admin_menu_%s_link" class="admin_menu_sublevel admin_menu_sublevel_%s"><a href="%s" %s>%s</a>', $link, $link, $ar['url'], $title, $anchor );
803
				}
804
			}
805
			echo "</ul>\n";
806
		}
807
	}
808
809
	if ( isset( $help_link ) )
810
		echo '<li id="admin_menu_help_link">' . $help_link .'</li>';
811
812
	yourls_do_action( 'admin_menu' );
813
	echo "</ul></nav>\n";
814
	yourls_do_action( 'admin_notices' );
815
	yourls_do_action( 'admin_notice' ); // because I never remember if it's 'notices' or 'notice'
816
	/*
817
	To display a notice:
818
	$message = "<div>OMG, dude, I mean!</div>" );
819
	yourls_add_action( 'admin_notices', create_function( '', "echo '$message';" ) );
820
	*/
821
}
822
823
/**
824
 * Wrapper function to display admin notices
825
 *
826
 */
827
function yourls_add_notice( $message, $style = 'notice' ) {
828
	// Escape single quotes in $message to avoid breaking the anonymous function
829
	$message = yourls_notice_box( strtr( $message, array( "'" => "\'" ) ), $style );
830
	yourls_add_action( 'admin_notices', create_function( '', "echo '$message';" ) );
831
}
832
833
/**
834
 * Return a formatted notice
835
 *
836
 */
837
function yourls_notice_box( $message, $style = 'notice' ) {
838
	return <<<HTML
839
	<div class="$style">
840
	<p>$message</p>
841
	</div>
842
HTML;
843
}
844
845
/**
846
 * Display a page
847
 *
848
 */
849
function yourls_page( $page ) {
850
	$include = YOURLS_ABSPATH . "/pages/$page.php";
851
	if( !file_exists( $include ) ) {
852
		yourls_die( "Page '$page' not found", 'Not found', 404 );
853
	}
854
	yourls_do_action( 'pre_page', $page );
855
	include_once( $include );
856
	yourls_do_action( 'post_page', $page );
857
	die();
858
}
859
860
/**
861
 * Display the language attributes for the HTML tag.
862
 *
863
 * Builds up a set of html attributes containing the text direction and language
864
 * information for the page. Stolen from WP.
865
 *
866
 * @since 1.6
867
 */
868
function yourls_html_language_attributes() {
869
	$attributes = array();
870
	$output = '';
0 ignored issues
show
Unused Code introduced by LeoColomb
$output is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
871
872
	$attributes[] = ( yourls_is_rtl() ? 'dir="rtl"' : 'dir="ltr"' );
873
874
	$doctype = yourls_apply_filter( 'html_language_attributes_doctype', 'html' );
875
	// Experimental: get HTML lang from locale. Should work. Convert fr_FR -> fr-FR
876
	if ( $lang = str_replace( '_', '-', yourls_get_locale() ) ) {
877
		if( $doctype == 'xhtml' ) {
878
			$attributes[] = "xml:lang=\"$lang\"";
879
		} else {
880
			$attributes[] = "lang=\"$lang\"";
881
		}
882
	}
883
884
	$output = implode( ' ', $attributes );
885
	$output = yourls_apply_filter( 'html_language_attributes', $output );
886
	echo $output;
887
}
888
889
/**
890
 * Output translated strings used by the Javascript calendar
891
 *
892
 * @since 1.6
893
 */
894
function yourls_l10n_calendar_strings() {
895
	echo "\n<script>\n";
896
	echo "var l10n_cal_month = " . json_encode( array_values( yourls_l10n_months() ) ) . ";\n";
897
	echo "var l10n_cal_days = " . json_encode( array_values( yourls_l10n_weekday_initial() ) ) . ";\n";
898
	echo "var l10n_cal_today = \"" . yourls_esc_js( yourls__( 'Today' ) ) . "\";\n";
899
	echo "var l10n_cal_close = \"" . yourls_esc_js( yourls__( 'Close' ) ) . "\";\n";
900
	echo "</script>\n";
901
902
	// Dummy returns, to initialize l10n strings used in the calendar
903
	yourls__( 'Today' );
904
	yourls__( 'Close' );
905
}
906
907
908
/**
909
 * Display a notice if there is a newer version of YOURLS available
910
 *
911
 * @since 1.7
912
 */
913
function yourls_new_core_version_notice() {
914
915
	$checks = yourls_get_option( 'core_version_checks' );
916
917
	if( isset( $checks->last_result->latest ) AND version_compare( $checks->last_result->latest, YOURLS_VERSION, '>' ) ) {
918
		$msg = yourls_s( '<a href="%s">YOURLS version %s</a> is available. Please update!', 'http://yourls.org/download', $checks->last_result->latest );
919
		yourls_add_notice( $msg );
920
	}
921
}
922
923
/**
924
 * Send a filerable content type header
925
 *
926
 * @since 1.7
927
 * @param string $type content type ('text/html', 'application/json', ...)
928
 * @return bool whether header was sent
929
 */
930
function yourls_content_type_header( $type ) {
931
    yourls_do_action( 'content_type_header', $type );
932
	if( !headers_sent() ) {
933
		$charset = yourls_apply_filter( 'content_type_header_charset', 'utf-8' );
934
		header( "Content-Type: $type; charset=$charset" );
935
		return true;
936
	}
937
	return false;
938
}
939
940
/**
941
 * Get search text from query string variables search_protocol, search_slashes and search
942
 *
943
 * Some servers don't like query strings containing "(ht|f)tp(s)://". A javascript bit
944
 * explodes the search text into protocol, slashes and the rest (see JS function
945
 * split_search_text_before_search()) and this function glues pieces back together
946
 * See issue https://github.com/YOURLS/YOURLS/issues/1576
947
 *
948
 * @since 1.7
949
 * @return string Search string
950
 */
951
function yourls_get_search_text() {
952
	$search = '';
953
	if( isset( $_GET['search_protocol'] ) )
954
		$search .= $_GET['search_protocol'];
955
	if( isset( $_GET['search_slashes'] ) )
956
		$search .= $_GET['search_slashes'];
957
	if( isset( $_GET['search'] ) )
958
		$search .= $_GET['search'];
959
960
	return htmlspecialchars( trim( $search ) );
961
}
962
963
/**
964
 * Display or return HTML for a bookmarklet link
965
 *
966
 * @since 1.7.1
967
 * @param string $href    bookmarklet link (presumably minified code with "javascript:" scheme)
968
 * @param string $anchor  link anchor
969
 * @param bool   $echo    true to display, false to return the HTML
970
 * @return string         the HTML for a bookmarklet link
971
 */
972
function yourls_bookmarklet_link( $href, $anchor, $echo = true ) {
973
    $alert = yourls_esc_attr__( 'Drag to your toolbar!' );
974
    $link = <<<LINK
975
    <a href="$href" class="bookmarklet" onclick="alert('$alert');return false;">$anchor</a>
976
LINK;
977
978
    if( $echo )
979
        echo $link;
980
    return $link;
981
}
982
983
/**
984
 * Set HTML context (stats, index, infos, ...)
985
 *
986
 * @since  1.7.3
987
 * @param  string  $context
988
 * @return void
989
 */
990
function yourls_set_html_context($context) {
991
    global $ydb;
992
    $ydb->set_html_context($context);
993
}
994
995
/**
996
 * Get HTML context (stats, index, infos, ...)
997
 *
998
 * @since  1.7.3
999
 * @return string
1000
 */
1001
function yourls_get_html_context() {
1002
    global $ydb;
1003
    $ydb->get_html_context();
1004
}
1005
1006