diff --git a/.distignore b/.distignore index 84519f65..c4f986f7 100755 --- a/.distignore +++ b/.distignore @@ -23,11 +23,11 @@ behat.yml bitbucket-pipelines.yml bin .circleci/config.yml -# composer.json +composer.json composer.lock dependencies.yml Gruntfile.js -# package.json +package.json package-lock.json phpunit.xml phpunit.xml.dist diff --git a/forms-bridge/addons/gsheets/class-gsheets-addon.php b/forms-bridge/addons/gsheets/class-gsheets-addon.php index eafc1859..16937aa3 100644 --- a/forms-bridge/addons/gsheets/class-gsheets-addon.php +++ b/forms-bridge/addons/gsheets/class-gsheets-addon.php @@ -1,8 +1,14 @@ addon === 'gsheets' ) { + if ( 'gsheets' === $bridge->addon ) { return false; } @@ -85,7 +95,7 @@ public function ping( $backend ) { $parsed = wp_parse_url( $backend->base_url ); $host = $parsed['host'] ?? ''; - if ( $host !== 'sheets.googleapis.com' ) { + if ( 'sheets.googleapis.com' !== $host ) { return false; } diff --git a/forms-bridge/addons/gsheets/class-gsheets-form-bridge.php b/forms-bridge/addons/gsheets/class-gsheets-form-bridge.php index 0b216cff..00048077 100644 --- a/forms-bridge/addons/gsheets/class-gsheets-form-bridge.php +++ b/forms-bridge/addons/gsheets/class-gsheets-form-bridge.php @@ -1,4 +1,9 @@ tab ); @@ -29,12 +48,15 @@ private function value_range( $values ) { $len = strlen( $abc ); $columns = array(); - for ( $row = 0; $row < count( $values ); $row++ ) { + + $rows = count( $values ); + for ( $row = 0; $row < $rows; $row++ ) { $rowcols = array(); - $i = -1; - for ( $col = 0; $col < count( $values[ $row ] ); $col++ ) { - if ( $col > 0 && $col % $len === 0 ) { + $i = -1; + $cols = count( $values[ $row ] ); + for ( $col = 0; $col < $cols; $col++ ) { + if ( $col > 0 && 0 === $col % $len ) { ++$i; } @@ -57,6 +79,13 @@ private function value_range( $values ) { return $range; } + /** + * Fetches the first row of the sheet and return it as an array of headers / columns. + * + * @param Backend|null $backend Bridge backend instance. + * + * @return array + */ public function get_headers( $backend = null ) { if ( ! $this->is_valid ) { return new WP_Error( 'invalid_bridge' ); @@ -77,6 +106,15 @@ public function get_headers( $backend = null ) { return $response['data']['values'][0] ?? array(); } + /** + * Creates a new sheet on the document. + * + * @param integer $index Position of the new sheet in the sheets list. + * @param string $title Sheet title. + * @param Backend $backend Bridge backend instance. + * + * @return array|WP_Error Sheet data or creation error. + */ private function add_sheet( $index, $title, $backend ) { $response = $backend->post( $this->endpoint . ':batchUpdate', @@ -108,6 +146,13 @@ private function add_sheet( $index, $title, $backend ) { return $response['data']; } + /** + * Request for the list of sheets of the document. + * + * @param Backend $backend Bridge backend instance. + * + * @return array|WP_Error + */ private function get_sheets( $backend ) { $response = $backend->get( $this->endpoint ); @@ -124,6 +169,7 @@ private function get_sheets( $backend ) { } /** + * Sends the payload to the backend. * * @param array $payload Submission data. * @param array $attachments Submission's attached files. Will be ignored. @@ -152,7 +198,7 @@ public function submit( $payload = array(), $attachments = array() ) { $endpoint = $this->endpoint . '/values/' . rawurlencode( $this->tab ); $method = $this->method; - if ( $method === 'POST' || $method === 'PUT' ) { + if ( 'POST' === $method || 'PUT' === $method ) { $endpoint .= '!A1:Z:append/?valueInputOption=USER_ENTERED'; $headers = $this->get_headers( $backend ); @@ -216,6 +262,14 @@ private static function flatten_payload( $payload, $path = '' ) { return $flat; } + /** + * Returns array values as a flat vector of play key values. + * + * @param mixed $value Payload value. + * @param string $path Hierarchical path to the value. + * + * @return mixed + */ private static function flatten_value( $value, $path = '' ) { if ( ! is_array( $value ) ) { return $value; diff --git a/forms-bridge/addons/gsheets/hooks.php b/forms-bridge/addons/gsheets/hooks.php index 35d7c754..58f0b689 100644 --- a/forms-bridge/addons/gsheets/hooks.php +++ b/forms-bridge/addons/gsheets/hooks.php @@ -1,4 +1,9 @@ 'Basic', ), array( - 'ref' => '#credential', - 'name' => 'client_id', - 'label' => __( 'User login', 'forms-bridge' ), - 'description' => __( - 'Either, a user name or email', - 'forms-bridge' - ), - 'type' => 'text', - 'required' => true, + 'ref' => '#credential', + 'name' => 'client_id', + 'label' => __( 'User login', 'forms-bridge' ), + 'type' => 'text', + 'required' => true, ), array( 'ref' => '#credential', diff --git a/forms-bridge/deps/http b/forms-bridge/deps/http index 71466126..25fbd7d0 160000 --- a/forms-bridge/deps/http +++ b/forms-bridge/deps/http @@ -1 +1 @@ -Subproject commit 7146612614c8657ebf4d6c5b6fbf91d38d01250d +Subproject commit 25fbd7d0aabcefd3b7db9b50709920d55dd5d058 diff --git a/forms-bridge/deps/plugin b/forms-bridge/deps/plugin index cfbbf34c..bccdde34 160000 --- a/forms-bridge/deps/plugin +++ b/forms-bridge/deps/plugin @@ -1 +1 @@ -Subproject commit cfbbf34c2b5490f6e21e99d814bb89e87ddd7d26 +Subproject commit bccdde34a97aca13a5118e9e08222d0dd0a17129 diff --git a/src/components/Credential/AuthorizeButton.jsx b/src/components/Credential/AuthorizeButton.jsx index 74679b04..54ac47bd 100644 --- a/src/components/Credential/AuthorizeButton.jsx +++ b/src/components/Credential/AuthorizeButton.jsx @@ -3,6 +3,7 @@ import { useError } from "../../providers/Error"; import { useFetchSettings } from "../../providers/Settings"; import { restUrl } from "../../lib/utils"; +const { useMemo } = wp.element; const { Button } = wp.components; const apiFetch = wp.apiFetch; const { __ } = wp.i18n; @@ -13,6 +14,21 @@ export default function AuthorizeButton({ addon, data }) { const fetchSettings = useFetchSettings(); + const authorized = useMemo(() => { + if (!(data.access_token && data.expires_at)) return false; + + if (data.refresh_token) { + return true; + } + + let expirationDate = new Date(data.expires_at); + if (expirationDate.getFullYear() === 1970) { + expirationDate = new Date(data.expires_at * 1000); + } + + return Date.now() < expirationDate.getTime(); + }, [data.access_token, data.expires_at]); + const revoke = () => { setLoading(true); @@ -65,7 +81,7 @@ export default function AuthorizeButton({ addon, data }) { .finally(() => setLoading(false)); }; - if (data.refresh_token) { + if (authorized) { return (