diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 746e0d9..54df5bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,21 +49,3 @@ jobs: run: | composer exec phpunit -- tests/ if: matrix.target == 'phpunit' - - build-container: - runs-on: ubuntu-latest - permissions: - security-events: write - pull-requests: write - steps: - - uses: actions/checkout@v6 - - - name: Build container - uses: infrabits/ci-pack@main - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - image: ghcr.io/${{ github.repository }}:${{ github.sha }} - use_builder: latest - buildpack: heroku/php - publish_image: false - runtime_release: ${{ github.sha }} diff --git a/src/Wikipedia/Api.php b/src/Wikipedia/Api.php index 963f2f3..a7412f7 100644 --- a/src/Wikipedia/Api.php +++ b/src/Wikipedia/Api.php @@ -115,7 +115,7 @@ public function recentchanges($count = 10, $namespace = null, $dir = 'older', $t '|flags|timestamp|title|ids|sizes&format=json&rclimit=' . $count . $append ); $x = $this->http->unserialize($x); - return $x['query']['recentchanges']; + return $x['query']['recentchanges'] ?? []; } /** @@ -158,7 +158,7 @@ public function search($search, $limit = 10, $offset = 0, $namespace = 0, $what urlencode($search) . $append ); $x = $this->http->unserialize($x); - return $x['query']['search']; + return $x['query']['search'] ?? []; } /** @@ -213,7 +213,7 @@ public function logs( 'title|type|user|timestamp|comment|details' . $append ); $x = $this->http->unserialize($x); - return $x['query']['logevents']; + return $x['query']['logevents'] ?? []; } /** @@ -241,13 +241,9 @@ public function usercontribs($user, $count = 50, &$continue = null, $dir = 'olde urlencode($user) . '&uclimit=' . urlencode($count) . '&ucdir=' . urlencode($dir) . $append ); $x = $this->http->unserialize($x); - if (array_key_exists('ucstart', $x['query-continue']['usercontribs'])) { - $continue = $x['query-continue']['usercontribs']['ucstart']; - } else { - $continue = null; - } + $continue = $x['query-continue']['usercontribs']['ucstart'] ?? null; - return $x['query']['usercontribs']; + return $x['query']['usercontribs'] ?? []; } /** @@ -278,12 +274,12 @@ public function users($start = null, $limit = 1, $group = null, $requirestart = 'blockinfo|editcount|registration|groups&aulimit=' . urlencode($limit) . $append ); $x = $this->http->unserialize($x); - $continue = $x['query-continue']['allusers']['aufrom']; - if (($requirestart == true) and ($x['query']['allusers'][0]['name'] != $start)) { + $continue = $x['query-continue']['allusers']['aufrom'] ?? null; + if ($requirestart == true && ($x['query']['allusers'][0]['name'] ?? null) != $start) { return false; } - return $x['query']['allusers']; + return $x['query']['allusers'] ?? []; } /** @@ -311,9 +307,9 @@ public function categorymembers($category, $count = 500, &$continue = null) ); $x = $this->http->unserialize($x); - $continue = $x['query-continue']['categorymembers']['cmcontinue']; + $continue = $x['query-continue']['categorymembers']['cmcontinue'] ?? null; - return $x['query']['categorymembers']; + return $x['query']['categorymembers'] ?? []; } /** @@ -352,9 +348,9 @@ public function listcategories(&$start = null, $limit = 50, $dir = 'ascending', ); $x = $this->http->unserialize($x); - $start = $x['query-continue']['allcategories']['acfrom']; + $start = $x['query-continue']['allcategories']['acfrom'] ?? null; - return $x['query']['allcategories']; + return $x['query']['allcategories'] ?? []; } /** @@ -398,7 +394,7 @@ public function backlinks($page, $count = 500, &$continue = null, $filter = null $continue = null; } - return $x['query']['backlinks']; + return $x['query']['backlinks'] ?? []; } /** @@ -436,7 +432,7 @@ public function embeddedin($page, $count = 500, &$continue = null) $continue = null; } - return $x['query']['embeddedin']; + return $x['query']['embeddedin'] ?? []; } /** @@ -475,7 +471,7 @@ public function listprefix($prefix, $namespace = 0, $count = 500, &$continue = n $continue = null; } - return $x['query']['allpages']; + return $x['query']['allpages'] ?? []; } /** @@ -539,10 +535,10 @@ public function edit( $x = $this->http->post($this->apiurl, $params); $x = $this->http->unserialize($x); - if ($x['edit']['result'] == 'Success') { + if (isset($x['edit']['result']) && $x['edit']['result'] == 'Success') { return true; } - if ($x['error']['code'] == 'badtoken') { + if (isset($x['error']['code']) && $x['error']['code'] == 'badtoken') { if ($this->login($this->user, $this->pass, $this->assert_auth)) { return $this->edit($page, $data, $summary, $minor, $bot, $wpStarttime, $wpEdittime, $checkrun); } else { @@ -574,7 +570,7 @@ public function gettoken($title) ); $x = $this->http->unserialize($x); - return $x['query']['tokens']['csrftoken']; + return $x['query']['tokens']['csrftoken'] ?? null; } /** @@ -588,7 +584,7 @@ public function getLoginToken() '&action=query&meta=tokens&type=login'); $x = $this->http->unserialize($x); - return $x['query']['tokens']['logintoken']; + return $x['query']['tokens']['logintoken'] ?? null; } @@ -613,7 +609,7 @@ public function login($user, $pass, $assert_auth = true) $x = $this->http->unserialize($x); - return $x['login']['result'] == 'Success'; + return isset($x['login']['result']) && $x['login']['result'] == 'Success'; } /** @@ -630,11 +626,15 @@ public function loggedin() '?action=query&meta=userinfo&format=json'); $x = $this->http->unserialize($x); + if (!isset($x['query']['userinfo'])) { + return false; + } + if (!$this->user) { return !array_key_exists('anon', $x['query']['userinfo']); } - return $x['query']['userinfo']['name'] === $this->user; + return ($x['query']['userinfo']['name'] ?? null) === $this->user; } /** @@ -693,7 +693,7 @@ public function rollback($title, $user, $reason, $token = null, $checkrun = true $x = $this->http->get($this->apiurl . '?action=query&meta=tokens&type=rollback&format=json'); $x = $this->http->unserialize($x); - $token = $x['query']['tokens']['rollbacktoken']; + $token = $x['query']['tokens']['rollbacktoken'] ?? null; $params = array( 'action' => 'rollback', @@ -792,9 +792,12 @@ public function revisions( } } + if (!isset($x['query']['pages']) || !is_array($x['query']['pages'])) { + return []; + } foreach (array_values($x['query']['pages']) as $data) { - return $data['revisions']; + return $data['revisions'] ?? []; } - return array(); + return []; } } diff --git a/src/Wikipedia/Http.php b/src/Wikipedia/Http.php index 913bd1c..a864a45 100644 --- a/src/Wikipedia/Http.php +++ b/src/Wikipedia/Http.php @@ -142,15 +142,20 @@ public function unserialize($response) $response = json_decode($response, true); + if (!is_array($response)) { + if ($this->logger !== null) { + $this->logger->error('Failed to decode API response'); + } + return []; + } + if ($this->logger !== null) { - // Handle errors if (array_key_exists('error', $response)) { $caller = (new \Exception())->getTrace()[1]['function']; $this->logger->error($caller . ' API Error: ' . var_export($response['error'], true)); } - // Handle warnings if (array_key_exists('warnings', $response)) { $caller = (new \Exception())->getTrace()[1]['function']; $this->logger->warning($caller . ' API Warnings: ' . diff --git a/src/Wikipedia/Query.php b/src/Wikipedia/Query.php index 8c8a0ca..e650007 100644 --- a/src/Wikipedia/Query.php +++ b/src/Wikipedia/Query.php @@ -62,7 +62,7 @@ public function getpage($page) $this->checkurl(); $ret = $this->api->revisions($page, 1, 'older', true, null, true, false, false); - if (is_array($ret) && array_key_exists(0, $ret) && array_key_exists('*', $ret[0]['slots']['main'])) { + if (is_array($ret) && isset($ret[0]['slots']['main']['*'])) { return $ret[0]['slots']['main']['*']; } }