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