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