asimlqt / php-google-spreadsheet-client

A PHP library for accessing and manipulating Google Spreadsheets
Other
543 stars 154 forks source link

Bug: Delete enty in iteration (for/foreach) works incorrect on second and next deletions #124

Closed MaxZhuravlev closed 8 years ago

MaxZhuravlev commented 8 years ago

Test: Create such spreadsheet image

Run code that should delete rows with "Delete" text:

        ...
        $entries=$listFeed->getEntries();
        foreach ($entries as $entry) {
            $values = $entry->getValues();
            if($values['numberordelete']=='Delete'){
                $entry->delete();
            }
        }

Result: image

First "delete me" row deleted correctly. Second and further deletions/editings are all displaced! Deleting wrong rows!

Also in same situations in long lists, if you try to delete last row, google will return error 400.

Workaround which works for me:

        ...
        $entries=$listFeed->getEntries();
        $iReal=0;
        for($i=0;$i<count($entries);$i++){
            $entry=$entries[$i];
            $values = $entry->getValues();
            if($values['numberordelete']=='Delete'){
                $entries[$iReal]->delete(); $iReal--;
            }
            $iReal++;
        }

Result of testing this workaround on same spreadsheet: image

GustavoA23 commented 8 years ago

Unfortunately this work around doesnt really apply to my situation. Even testing on a new blank sheet it returns a 400 error, and it seems to be related to the DefaultServiceRequest.

PHP Fatal error:  Uncaught exception 'Google\Spreadsheet\Exception' with message 'Error in Google Request' in /var/www/html/vendor/asimlqt/php-google-spreadsheet-client/src/Google/Spreadsheet/DefaultServiceRequest.php:286
Stack trace:
#0 /var/www/html/vendor/asimlqt/php-google-spreadsheet-client/src/Google/Spreadsheet/DefaultServiceRequest.php(181): Google\Spreadsheet\DefaultServiceRequest->execute(Resource id #94)
#1 /var/www/html/vendor/asimlqt/php-google-spreadsheet-client/src/Google/Spreadsheet/ListFeed.php(89): Google\Spreadsheet\DefaultServiceRequest->post('https://spreads...', '<entry xmlns="h...')
#2 /var/www/html/textLoggerAlpha.php(257): Google\Spreadsheet\ListFeed->insert(Array)
#3 /var/www/html/textLoggerAlpha.php(164): batch(841, 1500)
#4 {main}
  thrown in /var/www/html/vendor/asimlqt/php-google-spreadsheet-client/src/Google/Spreadsheet/DefaultServiceRequest.php on line 286
asimlqt commented 8 years ago

@MaxZhuravlev Thanks for raising this. I can confirm this is definitely a bug and is not to do with this library. It's a bug in the Spreadsheet API which Google need to fix. I have submitted a ticket so we'll just have to wait for their response.

https://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=4382

As temporary workaround in your situation you can just loop over the entries in reverse order:

foreach (array_reverse($worksheet->getListFeed()->getEntries()) as $entry) {
    $values = $entry->getValues();
    if ($values["numberordelete"] === "Delete") {
        $entry->delete();
    }
}
DenoBY commented 8 years ago

@asimlqt Why use array_reverse?

asimlqt commented 8 years ago

@DenoBY Have you read the bug report I posted for this issue? There's a link in my previous comment.

Apparently Google don't think this is a bug and are not going to fix it so 'm closing this issue.

DenoBY commented 8 years ago

@asimlqt Thank