1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Check if we have PDO installed, returns bool |
5
|
|
|
* |
6
|
|
|
* @since 1.7.3 |
7
|
|
|
* @return bool |
8
|
|
|
*/ |
9
|
|
|
function yourls_check_PDO() { |
10
|
|
|
return extension_loaded('pdo'); |
11
|
|
|
} |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* Check if server has MySQL 5.0+ |
15
|
|
|
* |
16
|
|
|
*/ |
17
|
|
|
function yourls_check_database_version() { |
18
|
6 |
|
return ( version_compare( '5.0', yourls_get_database_version() ) <= 0 ); |
19
|
|
|
} |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* Get DB version |
23
|
|
|
* |
24
|
|
|
* @since 1.7 |
25
|
|
|
* @return string sanitized DB version |
26
|
|
|
*/ |
27
|
|
|
function yourls_get_database_version() { |
28
|
|
|
// Allow plugins to short-circuit the whole function |
29
|
6 |
|
$pre = yourls_apply_filter( 'shunt_get_database_version', false ); |
30
|
6 |
|
if ( false !== $pre ) { |
31
|
|
|
return $pre; |
32
|
|
|
} |
|
|
|
|
33
|
|
|
|
34
|
6 |
|
return yourls_sanitize_version(yourls_get_db()->mysql_version()); |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Check if PHP > 5.6 |
39
|
|
|
* |
40
|
|
|
*/ |
41
|
|
|
function yourls_check_php_version() { |
42
|
1 |
|
return version_compare( PHP_VERSION, '5.6.0', '>=' ); |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Check if server is an Apache |
47
|
|
|
* |
48
|
|
|
*/ |
49
|
|
|
function yourls_is_apache() { |
50
|
3 |
|
if( !array_key_exists( 'SERVER_SOFTWARE', $_SERVER ) ) |
51
|
|
|
return false; |
52
|
|
|
return ( |
53
|
3 |
|
strpos( $_SERVER['SERVER_SOFTWARE'], 'Apache' ) !== false |
54
|
3 |
|
|| strpos( $_SERVER['SERVER_SOFTWARE'], 'LiteSpeed' ) !== false |
55
|
|
|
); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* Check if server is running IIS |
60
|
|
|
* |
61
|
|
|
*/ |
62
|
|
|
function yourls_is_iis() { |
63
|
3 |
|
return ( array_key_exists( 'SERVER_SOFTWARE', $_SERVER ) ? ( strpos( $_SERVER['SERVER_SOFTWARE'], 'IIS' ) !== false ) : false ); |
|
|
|
|
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* Create .htaccess or web.config. Returns boolean |
69
|
|
|
* |
70
|
|
|
*/ |
71
|
|
|
function yourls_create_htaccess() { |
72
|
3 |
|
$host = parse_url( yourls_get_yourls_site() ); |
73
|
3 |
|
$path = ( isset( $host['path'] ) ? $host['path'] : '' ); |
74
|
|
|
|
75
|
3 |
|
if ( yourls_is_iis() ) { |
76
|
|
|
// Prepare content for a web.config file |
77
|
|
|
$content = array( |
78
|
1 |
|
'<?'.'xml version="1.0" encoding="UTF-8"?>', |
|
|
|
|
79
|
1 |
|
'<configuration>', |
|
|
|
|
80
|
1 |
|
' <system.webServer>', |
|
|
|
|
81
|
1 |
|
' <security>', |
|
|
|
|
82
|
1 |
|
' <requestFiltering allowDoubleEscaping="true" />', |
|
|
|
|
83
|
1 |
|
' </security>', |
|
|
|
|
84
|
1 |
|
' <rewrite>', |
|
|
|
|
85
|
1 |
|
' <rules>', |
|
|
|
|
86
|
1 |
|
' <rule name="YOURLS" stopProcessing="true">', |
|
|
|
|
87
|
1 |
|
' <match url="^(.*)$" ignoreCase="false" />', |
|
|
|
|
88
|
1 |
|
' <conditions>', |
|
|
|
|
89
|
1 |
|
' <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />', |
|
|
|
|
90
|
1 |
|
' <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />', |
|
|
|
|
91
|
1 |
|
' </conditions>', |
|
|
|
|
92
|
1 |
|
' <action type="Rewrite" url="'.$path.'/yourls-loader.php" appendQueryString="true" />', |
|
|
|
|
93
|
1 |
|
' </rule>', |
|
|
|
|
94
|
1 |
|
' </rules>', |
|
|
|
|
95
|
1 |
|
' </rewrite>', |
|
|
|
|
96
|
1 |
|
' </system.webServer>', |
|
|
|
|
97
|
1 |
|
'</configuration>', |
|
|
|
|
98
|
|
|
); |
|
|
|
|
99
|
|
|
|
100
|
1 |
|
$filename = YOURLS_ABSPATH.'/web.config'; |
101
|
1 |
|
$marker = 'none'; |
102
|
|
|
|
103
|
|
|
} else { |
104
|
|
|
// Prepare content for a .htaccess file |
105
|
|
|
$content = array( |
106
|
2 |
|
'<IfModule mod_rewrite.c>', |
|
|
|
|
107
|
2 |
|
'RewriteEngine On', |
|
|
|
|
108
|
2 |
|
'RewriteBase '.$path.'/', |
|
|
|
|
109
|
2 |
|
'RewriteCond %{REQUEST_FILENAME} !-f', |
|
|
|
|
110
|
2 |
|
'RewriteCond %{REQUEST_FILENAME} !-d', |
|
|
|
|
111
|
2 |
|
'RewriteRule ^.*$ '.$path.'/yourls-loader.php [L]', |
|
|
|
|
112
|
2 |
|
'</IfModule>', |
|
|
|
|
113
|
|
|
); |
|
|
|
|
114
|
|
|
|
115
|
2 |
|
$filename = YOURLS_ABSPATH.'/.htaccess'; |
116
|
2 |
|
$marker = 'YOURLS'; |
117
|
|
|
|
118
|
|
|
} |
119
|
|
|
|
120
|
3 |
|
return ( yourls_insert_with_markers( $filename, $marker, $content ) ); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* Insert text into a file between BEGIN/END markers, return bool. Stolen from WP |
125
|
|
|
* |
126
|
|
|
* Inserts an array of strings into a file (eg .htaccess ), placing it between |
127
|
|
|
* BEGIN and END markers. Replaces existing marked info. Retains surrounding |
128
|
|
|
* data. Creates file if none exists. |
129
|
|
|
* |
130
|
|
|
* @since 1.3 |
131
|
|
|
* |
132
|
|
|
* @param string $filename |
133
|
|
|
* @param string $marker |
134
|
|
|
* @param array $insertion |
135
|
|
|
* @return bool True on write success, false on failure. |
136
|
|
|
*/ |
137
|
|
|
function yourls_insert_with_markers( $filename, $marker, $insertion ) { |
138
|
8 |
|
if ( !file_exists( $filename ) || is_writeable( $filename ) ) { |
139
|
8 |
|
if ( !file_exists( $filename ) ) { |
140
|
4 |
|
$markerdata = ''; |
141
|
|
|
} else { |
142
|
4 |
|
$markerdata = explode( "\n", implode( '', file( $filename ) ) ); |
|
|
|
|
143
|
|
|
} |
144
|
|
|
|
145
|
8 |
|
if ( !$f = @fopen( $filename, 'w' ) ) |
|
|
|
|
146
|
|
|
return false; |
147
|
|
|
|
148
|
8 |
|
$foundit = false; |
149
|
8 |
|
if ( $markerdata ) { |
150
|
4 |
|
$state = true; |
151
|
4 |
|
foreach ( $markerdata as $n => $markerline ) { |
152
|
4 |
|
if ( strpos( $markerline, '# BEGIN ' . $marker ) !== false ) |
153
|
2 |
|
$state = false; |
154
|
4 |
|
if ( $state ) { |
155
|
4 |
|
if ( $n + 1 < count( $markerdata ) ) |
156
|
3 |
|
fwrite( $f, "{$markerline}\n" ); |
|
|
|
|
157
|
|
|
else |
158
|
4 |
|
fwrite( $f, "{$markerline}" ); |
|
|
|
|
159
|
|
|
} |
160
|
4 |
|
if ( strpos( $markerline, '# END ' . $marker ) !== false ) { |
161
|
2 |
|
if ( $marker != 'none' ) |
|
|
|
|
162
|
2 |
|
fwrite( $f, "# BEGIN {$marker}\n" ); |
|
|
|
|
163
|
2 |
|
if ( is_array( $insertion ) ) |
164
|
2 |
|
foreach ( $insertion as $insertline ) |
165
|
2 |
|
fwrite( $f, "{$insertline}\n" ); |
|
|
|
|
166
|
2 |
|
if ( $marker != 'none' ) |
|
|
|
|
167
|
2 |
|
fwrite( $f, "# END {$marker}\n" ); |
|
|
|
|
168
|
2 |
|
$state = true; |
169
|
2 |
|
$foundit = true; |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
} |
173
|
8 |
|
if ( !$foundit ) { |
174
|
6 |
|
if ( $marker != 'none' ) |
|
|
|
|
175
|
5 |
|
fwrite( $f, "\n\n# BEGIN {$marker}\n" ); |
|
|
|
|
176
|
6 |
|
foreach ( $insertion as $insertline ) |
177
|
6 |
|
fwrite( $f, "{$insertline}\n" ); |
|
|
|
|
178
|
6 |
|
if ( $marker != 'none' ) |
|
|
|
|
179
|
5 |
|
fwrite( $f, "# END {$marker}\n\n" ); |
|
|
|
|
180
|
|
|
} |
181
|
8 |
|
fclose( $f ); |
182
|
8 |
|
return true; |
183
|
|
|
} else { |
184
|
|
|
return false; |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Create MySQL tables. Return array( 'success' => array of success strings, 'errors' => array of error strings ) |
|
|
|
|
190
|
|
|
* |
191
|
|
|
* @since 1.3 |
192
|
|
|
* @return array An array like array( 'success' => array of success strings, 'errors' => array of error strings ) |
|
|
|
|
193
|
|
|
*/ |
194
|
|
|
function yourls_create_sql_tables() { |
195
|
|
|
// Allow plugins (most likely a custom db.php layer in user dir) to short-circuit the whole function |
|
|
|
|
196
|
1 |
|
$pre = yourls_apply_filter( 'shunt_yourls_create_sql_tables', null ); |
|
|
|
|
197
|
|
|
// your filter function should return an array of ( 'success' => $success_msg, 'error' => $error_msg ), see below |
|
|
|
|
198
|
1 |
|
if ( null !== $pre ) { |
|
|
|
|
199
|
|
|
return $pre; |
200
|
|
|
} |
201
|
|
|
|
202
|
1 |
|
$ydb = yourls_get_db(); |
203
|
|
|
|
204
|
1 |
|
$error_msg = array(); |
205
|
1 |
|
$success_msg = array(); |
206
|
|
|
|
207
|
|
|
// Create Table Query |
208
|
1 |
|
$create_tables = array(); |
209
|
1 |
|
$create_tables[YOURLS_DB_TABLE_URL] = |
210
|
|
|
'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_URL.'` ('. |
211
|
|
|
'`keyword` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT "",'. |
212
|
|
|
'`url` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,'. |
213
|
|
|
'`title` text COLLATE utf8mb4_unicode_ci DEFAULT NULL,'. |
214
|
|
|
'`timestamp` timestamp NOT NULL DEFAULT current_timestamp(),'. |
215
|
|
|
'`ip` varchar(41) COLLATE utf8mb4_unicode_ci NOT NULL,'. |
216
|
|
|
'`clicks` int(10) unsigned NOT NULL,'. |
217
|
|
|
'PRIMARY KEY (`keyword`),'. |
218
|
|
|
'KEY `ip` (`ip`),'. |
219
|
|
|
'KEY `timestamp` (`timestamp`)'. |
220
|
|
|
') DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;'; |
221
|
|
|
|
222
|
1 |
|
$create_tables[YOURLS_DB_TABLE_OPTIONS] = |
223
|
|
|
'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_OPTIONS.'` ('. |
224
|
|
|
'`option_id` bigint(20) unsigned NOT NULL auto_increment,'. |
225
|
|
|
'`option_name` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL default "",'. |
226
|
|
|
'`option_value` longtext COLLATE utf8mb4_unicode_ci NOT NULL,'. |
227
|
|
|
'PRIMARY KEY (`option_id`,`option_name`),'. |
228
|
|
|
'KEY `option_name` (`option_name`)'. |
229
|
|
|
') AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;'; |
230
|
|
|
|
231
|
1 |
|
$create_tables[YOURLS_DB_TABLE_LOG] = |
232
|
|
|
'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_LOG.'` ('. |
233
|
|
|
'`click_id` int(11) NOT NULL auto_increment,'. |
234
|
|
|
'`click_time` datetime NOT NULL,'. |
235
|
|
|
'`shorturl` varchar(100) BINARY NOT NULL,'. |
236
|
|
|
'`referrer` varchar(200) NOT NULL,'. |
237
|
|
|
'`user_agent` varchar(255) NOT NULL,'. |
238
|
|
|
'`ip_address` varchar(41) NOT NULL,'. |
239
|
|
|
'`country_code` char(2) NOT NULL,'. |
240
|
|
|
'PRIMARY KEY (`click_id`),'. |
241
|
|
|
'KEY `shorturl` (`shorturl`)'. |
242
|
|
|
') AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;'; |
243
|
|
|
|
244
|
|
|
|
245
|
1 |
|
$create_table_count = 0; |
246
|
|
|
|
247
|
1 |
|
yourls_debug_mode(true); |
248
|
|
|
|
249
|
|
|
// Create tables |
250
|
1 |
|
foreach ( $create_tables as $table_name => $table_query ) { |
251
|
1 |
|
$ydb->perform( $table_query ); |
252
|
1 |
|
$create_success = $ydb->fetchAffected( "SHOW TABLES LIKE '$table_name'" ); |
|
|
|
|
253
|
1 |
|
if( $create_success ) { |
254
|
1 |
|
$create_table_count++; |
255
|
1 |
|
$success_msg[] = yourls_s( "Table '%s' created.", $table_name ); |
256
|
|
|
} else { |
257
|
|
|
$error_msg[] = yourls_s( "Error creating table '%s'.", $table_name ); |
258
|
|
|
} |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
// Initializes the option table |
262
|
1 |
|
if( !yourls_initialize_options() ) |
263
|
1 |
|
$error_msg[] = yourls__( 'Could not initialize options' ); |
264
|
|
|
|
265
|
|
|
// Insert sample links |
266
|
1 |
|
if( !yourls_insert_sample_links() ) |
267
|
1 |
|
$error_msg[] = yourls__( 'Could not insert sample short URLs' ); |
268
|
|
|
|
269
|
|
|
// Check results of operations |
270
|
1 |
|
if ( sizeof( $create_tables ) == $create_table_count ) { |
|
|
|
|
271
|
1 |
|
$success_msg[] = yourls__( 'YOURLS tables successfully created.' ); |
272
|
|
|
} else { |
273
|
|
|
$error_msg[] = yourls__( 'Error creating YOURLS tables.' ); |
274
|
|
|
} |
275
|
|
|
|
276
|
1 |
|
return array( 'success' => $success_msg, 'error' => $error_msg ); |
|
|
|
|
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
/** |
280
|
|
|
* Initializes the option table |
281
|
|
|
* |
282
|
|
|
* Each yourls_update_option() returns either true on success (option updated) or false on failure (new value == old value, or |
|
|
|
|
283
|
|
|
* for some reason it could not save to DB). |
284
|
|
|
* Since true & true & true = 1, we cast it to boolean type to return true (or false) |
285
|
|
|
* |
286
|
|
|
* @since 1.7 |
287
|
|
|
* @return bool |
288
|
|
|
*/ |
289
|
|
|
function yourls_initialize_options() { |
290
|
|
|
return ( bool ) ( |
291
|
2 |
|
yourls_update_option( 'version', YOURLS_VERSION ) |
|
|
|
|
292
|
2 |
|
& yourls_update_option( 'db_version', YOURLS_DB_VERSION ) |
293
|
2 |
|
& yourls_update_option( 'next_id', 1 ) |
294
|
2 |
|
& yourls_update_option( 'active_plugins', array() ) |
295
|
|
|
); |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
/** |
299
|
|
|
* Populates the URL table with a few sample links |
300
|
|
|
* |
301
|
|
|
* @since 1.7 |
302
|
|
|
* @return bool |
303
|
|
|
*/ |
304
|
|
|
function yourls_insert_sample_links() { |
305
|
2 |
|
$link1 = yourls_add_new_link( 'http://blog.yourls.org/', 'yourlsblog', 'YOURLS\' Blog' ); |
306
|
2 |
|
$link2 = yourls_add_new_link( 'http://yourls.org/', 'yourls', 'YOURLS: Your Own URL Shortener' ); |
|
|
|
|
307
|
2 |
|
$link3 = yourls_add_new_link( 'http://ozh.org/', 'ozh', 'ozh.org' ); |
308
|
|
|
return ( bool ) ( |
309
|
2 |
|
$link1['status'] == 'success' |
|
|
|
|
310
|
2 |
|
& $link2['status'] == 'success' |
311
|
2 |
|
& $link3['status'] == 'success' |
312
|
|
|
); |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
|
316
|
|
|
/** |
317
|
|
|
* Toggle maintenance mode. Inspired from WP. Returns true for success, false otherwise |
318
|
|
|
* |
319
|
|
|
*/ |
320
|
|
|
function yourls_maintenance_mode( $maintenance = true ) { |
321
|
|
|
|
322
|
|
|
$file = YOURLS_ABSPATH . '/.maintenance' ; |
|
|
|
|
323
|
|
|
|
324
|
|
|
// Turn maintenance mode on : create .maintenance file |
325
|
|
|
if ( (bool)$maintenance ) { |
326
|
|
|
if ( ! ( $fp = @fopen( $file, 'w' ) ) ) |
|
|
|
|
327
|
|
|
return false; |
328
|
|
|
|
329
|
|
|
$maintenance_string = '<?php $maintenance_start = ' . time() . '; ?>'; |
330
|
|
|
@fwrite( $fp, $maintenance_string ); |
|
|
|
|
331
|
|
|
@fclose( $fp ); |
|
|
|
|
332
|
|
|
@chmod( $file, 0644 ); // Read and write for owner, read for everybody else |
|
|
|
|
333
|
|
|
|
334
|
|
|
// Not sure why the fwrite would fail if the fopen worked... Just in case |
335
|
|
|
return( is_readable( $file ) ); |
336
|
|
|
|
337
|
|
|
// Turn maintenance mode off : delete the .maintenance file |
338
|
|
|
} else { |
339
|
|
|
return @unlink($file); |
340
|
|
|
} |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
|