How to recover an old installation with Softaculous

Yesterday I had some time and will to update my TikiWiki installation, that I created in 2008, with version 2 something. When I checked it yesterday, I discovered that the current version is 8.3 !! So I thought: OK, let’s do it!

Unfortunately, a lot of time converts to a lot of changes, so it’s been probably more trouble than needed if I had been keeping TikiWiki up to date along time. Not only the version of the application had changed, but also other basic setups of my hosting provider, including cpanel version and softaculous version. I tried it anyway, using Softaculous updater, but it failed. So I went for my backup.

Fortunately, I made a backup before proceeding, and I’ve been able to restore it by now. Really I made two, for good measure, and that was “lucky” because I needed both. So I’m going to suggest you the same. Do both a database backup (I used cpanel, but anything that can export SQL does the job) and an installation backup (with Softactulous).

 

Softaculous backs up an installation, but the zip does not appear in the backups page.

This is something I was worried about since I got it. Soon after backing up something, Softaculous shows a progress bar and finally a success page that informs you that you will find that backup in the backups page. You navigate there and the zip does not appear !! I made a brand new backup, but I got the same: no zip in the backups page, just the message “You do not have any backups”.

The workaround is to

  1. remove the old installation completely if it’s still there
  2. create a fresh one at the old directory and with the old database name (dummy installation) BUT input your current email address for receiving the installation details
  3. get the number that appears at the end of the backup URL: let’s say it’s 5
  4. access your site with a file manager
  5. enter the softaculous_backups folder
  6. locate the zip file of the backup: you’ll discover it was properly created, with a name like “tiki.0.2012-02-04_19-50-44.zip”
  7. rename it to “tiki.5.2012-02-04_19-50-44.zip”
  8. refresh the backups page
Now you’ll see the zip in the backups page, and you will be able to restore it from there.

Softaculous restores an installation, but the database is empty.

So you restore it, go to the application page and you get a connection error. You check with the file manager and see the application file structure in the old directory, then you check with phpMyAdmin and see the database, but it’s completely empty !! The problem here was that the dummy installation created a database with the old name and the old user name BUT with a new user password.

The workaround is to

  1. import the database backup with phpMyAdmin
  2. edit the database configuration file in the application folder, such that the password is the one sent to your email address

Now you’ll see the application page as it was at backup time, and you’ll be able to go on from there.

 

I’m now going to find a way to export my old wiki content from the old installation and import it back into a new one. Wish me luck.

 

How to fix a preg_match bug

This is the second time I try to fix the preg_match bug with a number 50887. The first time I tried it, less than two months ago, my solution was buggy too, and for this reason I have unpublished it.

There are many different scenarios that I didn’t take into account, but almost all of them were related to How to count expected matches of a PHP regular expression. The rest were essentially the same: I thought that the preg_match bug was affecting just the last optional match. Later I found instead that it affects really all the matches at the end, any number of them, be they optional or not. Due to this little misunderstanding I had to rewrite a big portion of the function.

{[ .fix | 1.hilite(=php=) ]}

For the function ando_preg_count_groups(…) see the post How to count expected matches of a PHP regular expression.

Minimal Tests

The following tests are based on $regex = ‘(?J:(?Mon|Fri|Sun)(?:day)?|(?Tue)(?:sday)?|(?Wed)(?:nesday)?|(?Thu)(?:rsday)?|(?Sat)(?:urday)?)’;

.

Test 1a

{[ .test-1a-program | 1.hilite(=php=) ]}

In the next comparison we see the same result, and it really is, because
the count of expected matches equals the count of returned matches.
Array
(
    [0] => Saturday
    [DN] => Sat
    [1] => 
    [2] => 
    [3] => 
    [4] => 
    [5] => Sat
)
Array
(
    [0] => Saturday
    [DN] => Sat
    [1] => 
    [2] => 
    [3] => 
    [4] => 
    [5] => Sat
)
Test 1b

{[ .test-1b-program | 1.hilite(=php=) ]}

In the next comparison we see above that the bug applies to all the matches at the end,
and below that my fix correctly returns all expected matches, including the empty ones.
Array
(
    [0] => Tuesday
    [DN] => Tue
    [1] => 
    [2] => Tue
)
Array
(
    [0] => Tuesday
    [DN] => Tue
    [1] => 
    [2] => Tue
    [3] => 
    [4] => 
    [5] => 
)
Test 1c

{[ .test-1c-program | 1.hilite(=php=) ]}

In the next comparison we see above the bug at its extreme,
and below that my fix works as well as in the other cases.
Array
(
    [0] => 
)
Array
(
    [0] => 
    [DN] => 
    [1] => 
    [2] => 
    [3] => 
    [4] => 
    [5] => 
)

The following tests are based on $regex = ‘(?|Saturday|Sun(day)?)’;.

Test 2a

{[ .test-2a-program | 1.hilite(=php=) ]}

Array
(
    [0] => Sun
)
Array
(
    [0] => Sun
    [1] => 
)
Test 2b

{[ .test-2b-program | 1.hilite(=php=) ]}

Array
(
    [0] => Sunday
    [1] => day
)
Array
(
    [0] => Sunday
    [1] => day
)
Test 2c

{[ .test-2c-program | 1.hilite(=php=) ]}

Array
(
    [0] => Saturday
)
Array
(
    [0] => Saturday
    [1] => 
)

The following tests are based on $regex = ‘(?|(Sat)ur(day)|Sun(day)?)’;.

Test 3a

{[ .test-2a-program | 1.hilite(=php=) ]}

Array
(
    [0] => Sun
)
Array
(
    [0] => Sun
    [1] => 
    [2] => 
)
Test 3b

{[ .test-2b-program | 1.hilite(=php=) ]}

Array
(
    [0] => Sunday
    [1] => day
)
Array
(
    [0] => Sunday
    [1] => day
    [2] => 
)
Test 3c

{[ .test-2c-program | 1.hilite(=php=) ]}

Array
(
    [0] => Saturday
    [1] => Sat
    [2] => day
)
Array
(
    [0] => Saturday
    [1] => Sat
    [2] => day
)

How to fix a preg_match bug

I wanted to parse the host of a URL with a regular expression to get its third level domain {[.pattern | 1.hilite(=php=)]}

Let’s test the general case with http://www.dnr.state.oh.us/ {[.example-1 | 1.hilite(=php=)]}

array(2) {
  [0]=>
  string(19) "www.dnr.state.oh.us"
  [1]=>
  string(5) "state"
}

Pretty good. And now let’s test the edge case with http://google.com/ {[.example-2 | 1.hilite(=php=)]}

array(1) {
  [0]=>
  string(10) "google.com"
}

WTF, where is my empty submatch? Since when an optional submatch is not a submatch if it’s empty?

I googled it and found that there is already a filed bug. The chosen resolution has been won’t fix!! They say for backward compatibility, but I cannot imagine how fixing it would break anything older.

  • If I expect 3 submatches from my pattern, but I get 2, then I know (for the bug) that the missing submatch is the last one and it’s an empty string. So I add it myself to the submatches array. Would a programmer do anything different to fix this bug?
  • If the bug is globally fixed, it means that my old code will always get 3 submatches from that pattern. So my individual fix won’t get triggered, and having the last submatch the same value (empty string) as the one my fix would have added, I won’t have any issue, except a bit of (stale) unused code.
To cleanly fix it myself once and for all, I’ve written a wrapper ando_preg_match that has the same signature and the expected results.
EDIT: There were some bugs in my own fix to the preg_match bug. For the code, please see the new post.

In the edge case I get now

array(2) {
  [0]=>
  string(10) "google.com"
  [1]=>
  string(0) ""
}

Unfortunately the wrapper is more complex than I like, but PHP allows regular expressions with named groups and they require a lot of additional code. Anyway I’ve been able to do it all in a single function that can be easily dropped in any project.

Here is a test with a pattern with named groups, just in case you were wondering what it looks like {[.example-3 | 1.hilite(=php=)]}

array(3) {
  [0]=>
  string(10) "google.com"
  ["subdomain"]=>
  string(0) ""
  [1]=>
  string(0) ""
}

Actually, this last example allows me to show that my wrapper is really returning the expected result. In fact, just by adding a last non-empty group to the previous pattern, the original and buggy preg_match will work just fine {[.example-4 | 1.hilite(=php=)]}

array(4) {
  [0]=>
  string(10) "google.com"
  ["subdomain"]=>
  string(0) ""
  [1]=>
  string(0) ""
  [2]=>
  string(10) "google.com"
}

Of course you’ll get the same result using the wrapper.