From 68b27342cfd4091c2cb47c9c5ee66a0b079a998b Mon Sep 17 00:00:00 2001 From: Vlad Date: Wed, 11 Sep 2024 14:50:11 -0400 Subject: [PATCH] Implement opening Single & Edit Entry fields in lightbox --- future/includes/class-gv-plugin.php | 1 + ...ass-gravityview-lightbox-entry-request.php | 50 +++ .../class-gravityview-lightbox-entry.php | 287 ++++++++++++++++++ 3 files changed, 338 insertions(+) create mode 100644 includes/extensions/lightbox-entry/class-gravityview-lightbox-entry-request.php create mode 100644 includes/extensions/lightbox-entry/class-gravityview-lightbox-entry.php diff --git a/future/includes/class-gv-plugin.php b/future/includes/class-gv-plugin.php index b9223def2..6ff888d95 100644 --- a/future/includes/class-gv-plugin.php +++ b/future/includes/class-gv-plugin.php @@ -226,6 +226,7 @@ public function include_legacy_core() { include_once $this->dir( 'includes/extensions/duplicate-entry/class-duplicate-entry.php' ); include_once $this->dir( 'includes/extensions/entry-notes/class-gravityview-field-notes.php' ); include_once $this->dir( 'includes/extensions/lightbox/class-gravityview-lightbox.php' ); + include_once $this->dir( 'includes/extensions/lightbox-entry/class-gravityview-lightbox-entry.php' ); // Load WordPress Widgets include_once $this->dir( 'includes/wordpress-widgets/register-wordpress-widgets.php' ); diff --git a/includes/extensions/lightbox-entry/class-gravityview-lightbox-entry-request.php b/includes/extensions/lightbox-entry/class-gravityview-lightbox-entry-request.php new file mode 100644 index 000000000..8ee0ccf7f --- /dev/null +++ b/includes/extensions/lightbox-entry/class-gravityview-lightbox-entry-request.php @@ -0,0 +1,50 @@ +entry = $entry; + $this->view = $view; + + add_filter( 'gravityview_go_back_url', '__return_null' ); + add_filter( 'gravityview/entry_link/add_query_args', '__return_false' ); + + parent::__construct(); + } + + /** + * {@inheritDoc} + * + * @since TBD + */ + public function is_entry( $form_id = 0 ) { + return $this->entry; + } + + /** + * {@inheritDoc} + * + * @since TBD + */ + public function is_view( $return_view = true ) { + return $return_view ? $this->view : true; + } + + /** + * {@inheritDoc} + * + * @since TBD + */ + public function is_renderable(): bool { + return true; + } +} diff --git a/includes/extensions/lightbox-entry/class-gravityview-lightbox-entry.php b/includes/extensions/lightbox-entry/class-gravityview-lightbox-entry.php new file mode 100644 index 000000000..01f711b14 --- /dev/null +++ b/includes/extensions/lightbox-entry/class-gravityview-lightbox-entry.php @@ -0,0 +1,287 @@ + explode( '/v', self::REST_NAMESPACE )[0], + 'version' => explode( '/v', self::REST_NAMESPACE )[1], + 'endpoint' => sprintf( + 'view/%s/entry/%s', + '(?P[0-9]+)', + '(?P[0-9]+)' ), + 'methods' => [ 'GET', 'POST' ], + 'callback' => [ $this, 'render_entry' ], + 'permission_callback' => '__return_true', // WP will handle the nonce and Entry_Renderer::render() will take care of permissions. + ]; + + return $routes; + } + + /** + * Modify attributes for the single or entry link to open in a lightbox. + * + * @used-by `gravityview_field_entry_link` filter. + * + * @since TBD + * + * @param string $link The entry link (HTML markup). + * @param string $href The entry link URL. + * @param array $entry The entry data. + * @param array $field_settings The Link to Single Entry field settings. + * + * @return string + */ + public function modify_entry_link( $link, $href, $entry, $field_settings ) { + $view = GravityView_View::getInstance(); + $href = self::REST_NAMESPACE . "/view/{$view->getViewId()}/entry/{$entry['id']}"; + $is_rest = $href === ltrim( $_REQUEST['rest_route'] ?? '', '/' ); + $is_edit_entry = 'edit_link' === $field_settings['id']; + + if ( ! (int) ( $field_settings['lightbox'] ?? 0 ) && ! $is_rest ) { + return $link; + } + + $args = [ + '_wpnonce' => wp_create_nonce( 'wp_rest' ), + ]; + + if ( $is_edit_entry ) { + $args['edit'] = wp_create_nonce( GravityView_Edit_Entry::get_nonce_key( $view->view_id, $view->form_id, $entry['id'] ) ); + } + + $href = add_query_arg( + $args, + rest_url( $href ), + ); + + $atts = [ + 'class' => ( $link_atts['class'] ?? '' ) . ' gravityview-fancybox', + 'rel' => 'nofollow', + 'data-type' => 'iframe', + 'data-fancybox' => $view->getCurrentField()['UID'], + ]; + + return gravityview_get_link( + $href, + $is_edit_entry ? $field_settings['edit_link'] : $field_settings['entry_link_text'], + $is_rest ? [] : $atts // Do not add the attributes if the link is being rendered in the REST context. + ); + } + + /** + * Renders the single or edit entry view. + * + * @used-by `gk/foundation/rest/routes` filter. + * + * @since TBD + * + * @param GravityView_Lightbox_Entry_Request $request The request object. + * + * @return void + */ + public function render_entry( $request ) { + $view_id = $request->get_param( 'view_id' ) ?? 0; + $entry_id = $request->get_param( 'entry_id' ) ?? 0; + + $view = View::by_id( $view_id ); + $entry = GF_Entry::by_id( $entry_id ); + $form = GVCommon::get_form( $entry['form_id'] ?? 0 ); + $is_edit = $request->get_param( 'edit' ) ?? null; + $is_delete = $request->get_param( 'delete' ) ?? null; + + if ( ! $view || ! $entry || ! $form ) { + gravityview()->log->error( "Unable to find View ID {$view_id} and/or entry ID {$entry_id}." ); + + return; + } + + $view_data = GravityView_View_Data::getInstance(); + $view_data->add_view( $view->ID ); + + if ( $is_edit && wp_verify_nonce( $is_edit, GravityView_Edit_Entry::get_nonce_key( $view->ID, $form['id'], $entry->ID ) ) ) { + add_filter( 'gravityview/edit_entry/verify_nonce', '__return_true' ); + } + + ob_start(); + + if ( $is_delete ) { + add_filter( 'wp_redirect', '__return_false' ); + do_action( 'wp' ); // Entry deletion hooks to the `wp` action. + + $redirect_url = $view->settings->get( 'delete_redirect_url', '' ); + $reload_page = GravityView_Delete_Entry::REDIRECT_TO_MULTIPLE_ENTRIES_VALUE === (int) $view->settings->get( 'delete_redirect', GravityView_Delete_Entry::REDIRECT_TO_MULTIPLE_ENTRIES_VALUE ); + + ?> + + 'text/html' ] ); + } + + GravityView_frontend::getInstance()->setGvOutputData( $view_data ); + GravityView_frontend::getInstance()->add_scripts_and_styles(); + + $title = do_shortcode( + GravityView_API::replace_variables( + $view->settings->get( 'single_title', '' ), + $form, + $entry + ) + ); + + $entry_renderer = $is_edit ? new Edit_Entry_Renderer() : new Entry_Renderer(); + + $content = $entry_renderer->render( + $entry, + $view, + new GravityView_Lightbox_Entry_Request( $view, $entry ) + ); + + ?> + + + <?php echo $title; ?> + + + + + + + + + + + + + + + + 'text/html' ] ); + } + + /** + * Enqueues View editor script that handles the lightbox entry settings. + * + * @since TBD + * + * @param array $scripts The registered scripts. + * + * @return void + */ + public function enqueue_view_editor_script( $scripts ) { + global $post; + + if ( ! $post instanceof WP_Post && 'gravityview' !== $post->post_type && 'edit' !== $post->filter ) { + return $scripts; + } + + $scripts[] = [ + 'script' => << [ 'jquery' ], + ]; + + return $scripts; + } +} + +new GravityView_Lightbox_Entry();