]> CyberLeo.Net >> Repos - Github/YOURLS.git/blob - includes/functions-upgrade.php
Add plain API format
[Github/YOURLS.git] / includes / functions-upgrade.php
1 <?php
2
3 /**
4  * Upgrade YOURLS and DB schema
5  *
6  */
7 function yourls_upgrade( $step, $oldver, $newver, $oldsql, $newsql ) {
8         // special case for 1.3: the upgrade is a multi step procedure
9         if( $oldsql == 100 ) {
10                 yourls_upgrade_to_14( $step );
11         }
12         
13         // other upgrades which are done in a single pass
14         switch( $step ) {
15         
16         case 1:
17         case 2:
18                 if( $oldsql < 210 )
19                         yourls_upgrade_to_141();
20                         
21                 if( $oldsql < 220 )
22                         yourls_upgrade_to_143();
23                 
24                 if( $oldsql < 250 )
25                         yourls_upgrade_to_15();
26                         
27                 if( $oldsql < 482 )
28                         yourls_upgrade_482();
29                 
30                 yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=3" ) );
31
32                 break;
33                 
34         case 3:
35                 // Update options to reflect latest version
36                 yourls_update_option( 'version', YOURLS_VERSION );
37                 yourls_update_option( 'db_version', YOURLS_DB_VERSION );
38                 break;
39         }
40 }
41
42 /**
43  * Upgrade r482
44  *
45  */
46 function yourls_upgrade_482() {
47         // Change URL title charset to UTF8
48         global $ydb;
49         $table_url = YOURLS_DB_TABLE_URL;
50         $sql = "ALTER TABLE `$table_url` CHANGE `title` `title` TEXT CHARACTER SET utf8;";
51         $ydb->query( $sql );
52         echo "<p>Updating table structure. Please wait...</p>";
53 }
54
55 /************************** 1.4.3 -> 1.5 **************************/
56
57 /**
58  * Main func for upgrade from 1.4.3 to 1.5
59  *
60  */
61 function yourls_upgrade_to_15( ) {
62         // Create empty 'active_plugins' entry in the option if needed
63         if( yourls_get_option( 'active_plugins' ) === false )
64                 yourls_add_option( 'active_plugins', array() );
65         echo "<p>Enabling the plugin API. Please wait...</p>";
66         
67         // Alter URL table to store titles
68         global $ydb;
69         $table_url = YOURLS_DB_TABLE_URL;
70         $sql = "ALTER TABLE `$table_url` ADD `title` TEXT AFTER `url`;";
71         $ydb->query( $sql );
72         echo "<p>Updating table structure. Please wait...</p>";
73         
74         // Update .htaccess
75         yourls_create_htaccess();
76         echo "<p>Updating .htaccess file. Please wait...</p>";
77 }
78
79 /************************** 1.4.1 -> 1.4.3 **************************/
80
81 /**
82  * Main func for upgrade from 1.4.1 to 1.4.3
83  *
84  */
85 function yourls_upgrade_to_143( ) {
86         // Check if we have 'keyword' (borked install) or 'shorturl' (ok install)
87         global $ydb;
88         $table_log = YOURLS_DB_TABLE_LOG;
89         $sql = "SHOW COLUMNS FROM `$table_log`";
90         $cols = $ydb->get_results( $sql );
91         if ( $cols[2]->Field == 'keyword' ) {
92                 $sql = "ALTER TABLE `$table_log` CHANGE `keyword` `shorturl` VARCHAR( 200 ) BINARY;";
93                 $ydb->query( $sql );
94         }
95         echo "<p>Structure of existing tables updated. Please wait...</p>";
96 }
97
98 /************************** 1.4 -> 1.4.1 **************************/
99
100 /**
101  * Main func for upgrade from 1.4 to 1.4.1
102  *
103  */
104 function yourls_upgrade_to_141( ) {
105         // Kill old cookies from 1.3 and prior
106         setcookie('yourls_username', null, time() - 3600 );
107         setcookie('yourls_password', null, time() - 3600 );
108         // alter table URL
109         yourls_alter_url_table_to_141();
110         // recreate the htaccess file if needed
111         yourls_create_htaccess();
112 }
113
114 /**
115  * Alter table URL to 1.4.1
116  *
117  */
118 function yourls_alter_url_table_to_141() {
119         global $ydb;
120         $table_url = YOURLS_DB_TABLE_URL;
121         $alter = "ALTER TABLE `$table_url` CHANGE `keyword` `keyword` VARCHAR( 200 ) BINARY, CHANGE `url` `url` TEXT BINARY ";
122         $ydb->query( $alter );
123         echo "<p>Structure of existing tables updated. Please wait...</p>";
124 }
125
126
127 /************************** 1.3 -> 1.4 **************************/
128
129 /**
130  * Main func for upgrade from 1.3-RC1 to 1.4
131  *
132  */
133 function yourls_upgrade_to_14( $step ) {
134         
135         switch( $step ) {
136         case 1:
137                 // create table log & table options
138                 // update table url structure
139                 // update .htaccess
140                 yourls_create_tables_for_14(); // no value returned, assuming it went OK
141                 yourls_alter_url_table_to_14(); // no value returned, assuming it went OK
142                 $clean = yourls_clean_htaccess_for_14(); // returns bool
143                 $create = yourls_create_htaccess(); // returns bool
144                 if ( !$create )
145                         echo "<p class='warning'>Please create your <tt>.htaccess</tt> file (I could not do it for you). Please refer to <a href='http://yourls.org/htaccess'>http://yourls.org/htaccess</a>.";
146                 yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=2&oldver=1.3&newver=1.4&oldsql=100&newsql=200" ), $create );
147                 break;
148                 
149         case 2:
150                 // convert each link in table url
151                 yourls_update_table_to_14();
152                 break;
153         
154         case 3:
155                 // update table url structure part 2: recreate indexes
156                 yourls_alter_url_table_to_14_part_two();
157                 // update version & db_version & next_id in the option table
158                 // attempt to drop YOURLS_DB_TABLE_NEXTDEC
159                 yourls_update_options_to_14();
160                 // Now upgrade to 1.4.1
161                 yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=1&oldver=1.4&newver=1.4.1&oldsql=200&newsql=210" ) );
162                 break;
163         }
164 }
165
166 /**
167  * Update options to reflect new version
168  *
169  */
170 function yourls_update_options_to_14() {
171         yourls_update_option( 'version', '1.4' );
172         yourls_update_option( 'db_version', '200' );
173         
174         if( defined('YOURLS_DB_TABLE_NEXTDEC') ) {
175                 global $ydb;
176                 $table = YOURLS_DB_TABLE_NEXTDEC;
177                 $next_id = $ydb->get_var("SELECT `next_id` FROM `$table`");
178                 yourls_update_option( 'next_id', $next_id );
179                 @$ydb->query( "DROP TABLE `$table`" );
180         } else {
181                 yourls_update_option( 'next_id', 1 ); // In case someone mistakenly deleted the next_id constant or table too early
182         }
183 }
184
185 /**
186  * Create new tables for YOURLS 1.4: options & log
187  *
188  */
189 function yourls_create_tables_for_14() {
190         global $ydb;
191
192         $queries = array();
193
194         $queries[YOURLS_DB_TABLE_OPTIONS] = 
195                 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_OPTIONS.'` ('.
196                 '`option_id` int(11) unsigned NOT NULL auto_increment,'.
197                 '`option_name` varchar(64) NOT NULL default "",'.
198                 '`option_value` longtext NOT NULL,'.
199                 'PRIMARY KEY (`option_id`,`option_name`),'.
200                 'KEY `option_name` (`option_name`)'.
201                 ');';
202                 
203         $queries[YOURLS_DB_TABLE_LOG] = 
204                 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_LOG.'` ('.
205                 '`click_id` int(11) NOT NULL auto_increment,'.
206                 '`click_time` datetime NOT NULL,'.
207                 '`shorturl` varchar(200) NOT NULL,'.
208                 '`referrer` varchar(200) NOT NULL,'.
209                 '`user_agent` varchar(255) NOT NULL,'.
210                 '`ip_address` varchar(41) NOT NULL,'.
211                 '`country_code` char(2) NOT NULL,'.
212                 'PRIMARY KEY (`click_id`),'.
213                 'KEY `shorturl` (`shorturl`)'.
214                 ');';
215         
216         foreach( $queries as $query ) {
217                 $ydb->query( $query ); // There's no result to be returned to check if table was created (except making another query to check table existence, which we'll avoid)
218         }
219         
220         echo "<p>New tables created. Please wait...</p>";
221
222 }
223
224 /**
225  * Alter table structure, part 1 (change schema, drop index)
226  *
227  */
228 function yourls_alter_url_table_to_14() {
229         global $ydb;
230         $table = YOURLS_DB_TABLE_URL;
231
232         $alters = array();
233         $results = array();
234         $alters[] = "ALTER TABLE `$table` CHANGE `id` `keyword` VARCHAR( 200 ) NOT NULL";
235         $alters[] = "ALTER TABLE `$table` CHANGE `url` `url` TEXT NOT NULL";
236         $alters[] = "ALTER TABLE `$table` DROP PRIMARY KEY";
237         
238         foreach ( $alters as $query ) {
239                 $ydb->query( $query );
240         }
241         
242         echo "<p>Structure of existing tables updated. Please wait...</p>";
243 }
244
245 /**
246  * Alter table structure, part 2 (recreate indexes after the table is up to date)
247  *
248  */
249 function yourls_alter_url_table_to_14_part_two() {
250         global $ydb;
251         $table = YOURLS_DB_TABLE_URL;
252         
253         $alters = array();
254         $alters[] = "ALTER TABLE `$table` ADD PRIMARY KEY ( `keyword` )";
255         $alters[] = "ALTER TABLE `$table` ADD INDEX ( `ip` )";
256         $alters[] = "ALTER TABLE `$table` ADD INDEX ( `timestamp` )";
257         
258         foreach ( $alters as $query ) {
259                 $ydb->query( $query );
260         }
261
262         echo "<p>New table index created</p>";
263 }
264
265 /**
266  * Convert each link from 1.3 (id) to 1.4 (keyword) structure
267  *
268  */
269 function yourls_update_table_to_14() {
270         global $ydb;
271         $table = YOURLS_DB_TABLE_URL;
272
273         // Modify each link to reflect new structure
274         $chunk = 45;
275         $from = isset($_GET['from']) ? intval( $_GET['from'] ) : 0 ;
276         $total = yourls_get_db_stats();
277         $total = $total['total_links'];
278         
279         $sql = "SELECT `keyword`,`url` FROM `$table` WHERE 1=1 ORDER BY `url` ASC LIMIT $from, $chunk ;";
280         
281         $rows = $ydb->get_results($sql);
282         
283         $count = 0;
284         $queries = 0;
285         foreach( $rows as $row ) {
286                 $keyword = $row->keyword;
287                 $url = $row->url;
288                 $newkeyword = yourls_int2string( $keyword );
289                 $ydb->query("UPDATE `$table` SET `keyword` = '$newkeyword' WHERE `url` = '$url';");
290                 if( $ydb->result === true ) {
291                         $queries++;
292                 } else {
293                         echo "<p>Huho... Could not update rown with url='$url', from keyword '$keyword' to keyword '$newkeyword'</p>"; // Find what went wrong :/
294                 }
295                 $count++;
296         }
297         
298         // All done for this chunk of queries, did it all go as expected?
299         $success = true;
300         if( $count != $queries ) {
301                 $success = false;
302                 $num = $count - $queries;
303                 echo "<p>$num error(s) occured while updating the URL table :(</p>";
304         }
305         
306         if ( $count == $chunk ) {
307                 // there are probably other rows to convert
308                 $from = $from + $chunk;
309                 $remain = $total - $from;
310                 echo "<p>Converted $chunk database rows ($remain remaining). Continuing... Please do not close this window until it's finished!</p>";
311                 yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=2&oldver=1.3&newver=1.4&oldsql=100&newsql=200&from=$from" ), $success );
312         } else {
313                 // All done
314                 echo '<p>All rows converted! Please wait...</p>';
315                 yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=3&oldver=1.3&newver=1.4&oldsql=100&newsql=200" ), $success );
316         }
317         
318 }
319
320 /**
321  * Clean .htaccess as it existed before 1.4. Returns boolean
322  *
323  */
324 function yourls_clean_htaccess_for_14() {
325         $filename = YOURLS_ABSPATH.'/.htaccess';
326         
327         $result = false;
328         if( is_writeable( $filename ) ) {
329                 $contents = implode( '', file( $filename ) );
330                 // remove "ShortURL" block
331                 $contents = preg_replace( '/# BEGIN ShortURL.*# END ShortURL/s', '', $contents );
332                 // comment out deprecated RewriteRule
333                 $find = 'RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L]';
334                 $replace = "# You can safely remove this 5 lines block -- it's no longer used in YOURLS\n".
335                                 "# $find";
336                 $contents = str_replace( $find, $replace, $contents );
337                 
338                 // Write cleaned file
339                 $f = fopen( $filename, 'w' );
340                 fwrite( $f, $contents );
341                 fclose( $f );
342                 
343                 $result = true;
344         }
345
346         return $result;
347 }
348