PluginProbe ʕ •ᴥ•ʔ
Elementor Website Builder – more than just a page builder / 3.8.0-beta2
Elementor Website Builder – more than just a page builder v3.8.0-beta2
4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.22.0-dev1 4.0.0-beta3 3.22.0-dev2 4.0.0-beta4 3.22.0-dev3 4.0.0-beta5 3.22.0-dev4 4.0.0-dev1 3.22.0-dev5 4.0.0-dev2 3.22.0-dev6 4.0.0-dev3 3.22.1 4.0.0-dev4 3.22.2 4.0.0-dev5 3.22.3 4.0.1 3.23.0 4.0.2 3.23.0-beta1 3.23.0-beta2 3.23.0-beta3 3.23.0-beta4 3.23.0-beta5 3.23.0-beta6 3.23.0-dev1 3.23.0-dev2 3.23.0-dev3 3.23.0-dev4 3.23.0-dev5 3.23.0-dev6 3.23.1 3.23.2 3.23.3 3.23.4 3.24.0 3.24.0-beta1 3.24.0-beta2 3.24.0-beta3 3.24.0-dev1 3.24.0-dev2 3.24.0-dev3 3.24.1 3.24.2 3.24.3 3.24.4 3.24.5 3.24.6 3.24.7 3.24.8 3.25.0 3.25.0-beta1 3.25.0-beta2 3.25.0-beta3 3.25.0-dev1 3.25.0-dev2 3.25.0-dev3 3.25.1 3.25.10 3.25.11 3.25.2 3.25.3 3.25.4 3.25.5 3.25.6 3.25.7 3.25.8 3.25.9 3.26.0 3.26.0-beta1 3.26.0-beta2 3.26.0-beta3 3.26.0-beta4 3.26.0-beta5 3.26.0-dev1 3.26.0-dev2 3.26.0-dev3 3.26.0-dev4 3.26.0-dev5 3.26.1 3.26.2 3.26.3 3.26.4 3.26.5 3.27.0 3.27.0-beta1 3.27.0-beta2 3.27.0-dev1 3.27.0-dev2 3.27.1 3.27.2 3.27.3 3.27.4 3.27.5 3.27.6 3.27.7 3.28.0 3.28.0-beta1 3.28.0-beta2 3.28.0-beta3 3.28.0-dev1 3.28.0-dev2 3.28.0-dev3 3.28.1 3.28.2 3.28.3 3.28.4 3.29.0 3.29.0-beta1 trunk 3.29.0-beta2 3.0.0 3.29.0-beta3 3.0.1 3.29.0-beta4 3.0.10 3.29.0-dev1 3.0.11 3.29.0-dev2 3.0.12 3.29.0-dev3 3.0.13 3.29.0-dev4 3.0.14 3.29.1 3.0.15 3.29.2 3.0.16 3.3.0 3.0.2 3.3.1 3.0.3 3.30.0 3.0.4 3.30.0-beta1 3.0.5 3.30.0-beta2 3.0.6 3.30.0-beta3 3.0.7 3.30.0-dev1 3.0.8 3.30.0-dev2 3.0.8.1 3.30.0-dev3 3.0.9 3.30.1 3.1.0 3.30.2 3.1.0-beta1 3.30.3 3.1.0-beta2 3.30.4 3.1.0-beta3 3.31.0 3.1.0-beta4 3.31.0-beta1 3.1.0-dev1 3.31.0-beta2 3.1.0-dev2 3.31.0-dev1 3.1.0-dev3 3.31.0-dev2 3.1.1 3.31.1 3.1.2 3.31.2 3.1.3 3.31.3 3.1.4 3.31.4 3.10.0 3.31.5 3.10.0-dev1 3.32.0 3.10.1 3.32.0-beta1 3.10.2 3.32.0-beta2 3.11.0 3.32.0-beta3 3.11.0-beta1 3.32.0-dev1 3.11.0-beta2 3.32.0-dev2 3.11.0-beta3 3.32.0-dev3 3.11.0-dev1 3.32.1 3.11.0-dev2 3.32.2 3.11.0-dev3 3.32.3 3.11.1 3.32.4 3.11.2 3.32.5 3.11.3 3.33.0 3.11.4 3.33.0-beta1 3.11.5 3.33.0-beta2 3.12.0 3.33.0-beta3 3.12.1 3.33.0-beta4 3.12.2 3.33.0-dev1 3.13.0 3.33.0-dev2 3.13.0-beta1 3.33.0-dev3 3.13.0-beta2 3.33.0-dev4 3.13.0-beta3 3.33.1 3.13.0-dev3 3.33.2 3.13.0-dev4 3.33.3 3.13.1 3.33.4 3.13.2 3.33.5 3.13.3 3.33.6 3.13.4 3.34.0 3.14.0 3.34.0-beta1 3.14.0-beta1 3.34.0-beta2 3.14.0-beta2 3.34.0-beta3 3.14.0-beta3 3.34.0-dev1 3.14.0-beta4 3.34.0-dev2 3.14.0-beta5 3.34.1 3.14.1 3.34.2 3.15.0 3.34.3 3.15.1 3.34.4 3.15.2 3.35.0 3.15.3 3.35.0-beta1 3.16.0 3.35.0-beta2 3.16.0-beta3 3.35.0-beta3 3.16.0-beta4 3.35.0-beta4 3.16.0-dev1 3.35.0-dev1 3.16.0-dev2 3.35.0-dev2 3.16.1 3.35.0-dev3 3.16.2 3.35.0-dev4 3.16.3 3.35.1 3.16.4 3.35.2 3.16.5 3.35.3 3.16.6 3.35.4 3.17.0 3.35.5 3.17.0-dev2 3.35.6 3.17.0-dev3 3.35.7 3.17.0-dev4 3.35.8 3.17.1 3.35.9 3.17.2 3.4.0 3.17.3 3.4.0-dev7 3.18.0 3.4.0-dev8 3.18.0-beta1 3.4.0-dev9 3.18.0-beta2 3.4.1 3.18.0-beta3 3.4.2 3.18.0-beta4 3.4.3 3.18.0-dev1 3.4.4 3.18.1 3.4.5 3.18.2 3.4.6 3.18.3 3.4.7 3.19.0 3.4.8 3.19.0-beta1 3.5.0 3.19.0-beta2 3.5.0-beta1 3.19.0-beta3 3.5.0-beta2 3.19.0-beta4 3.5.0-beta3 3.19.0-beta5 3.5.0-beta4 3.19.0-beta6 3.5.0-beta5 3.19.0-dev1 3.5.0-beta7 3.19.0-dev2 3.5.0-beta8 3.19.0-dev3 3.5.0-dev8 3.19.0-dev4 3.5.0-dev9 3.19.0-dev5 3.5.1 3.19.0-dev6 3.5.2 3.19.1 3.5.3 3.19.2 3.5.4 3.19.3 3.5.5 3.19.4 3.5.6 3.2.0 3.6.0 3.2.1 3.6.0-beta1 3.2.2 3.6.0-beta2 3.2.3 3.6.0-beta3 3.2.4 3.6.0-beta4 3.2.5 3.6.0-beta5 3.20.0 3.6.0-dev1 3.20.0-beta1 3.6.0-dev10 3.20.0-beta2 3.6.1 3.20.0-beta3 3.6.2 3.20.0-beta4 3.6.3 3.20.0-dev1 3.6.4 3.20.0-dev2 3.6.5 3.20.0-dev3 3.6.6 3.20.0-dev4 3.6.7 3.20.1 3.6.8 3.20.2 3.7.0 3.20.3 3.7.0-beta1 3.20.4 3.7.0-beta2 3.21.0 3.7.0-beta3 3.21.0-beta1 3.7.0-beta4 3.21.0-beta2 3.7.0-dev1 3.21.0-beta3 3.7.1 3.21.0-dev1 3.7.2 3.21.0-dev2 3.7.3 3.21.0-dev3 3.7.4 3.21.1 3.7.5 3.21.2 3.7.6 3.21.3 3.7.7 3.21.4 3.7.8 3.21.5 3.8.0 3.21.6 3.8.0-beta1 3.21.7 3.8.0-beta2 3.21.8 3.8.0-beta3 3.22.0 3.8.1 3.22.0-beta1 3.9.0 3.22.0-beta2 3.9.1 3.22.0-beta3 3.9.2 3.22.0-beta4 4.0.0 3.22.0-beta5 4.0.0-beta1 3.22.0-beta6 4.0.0-beta2
elementor / modules / landing-pages / module.php
elementor / modules / landing-pages Last commit date
admin-menu-items 3 years ago documents 4 years ago module.php 3 years ago
module.php
525 lines
1 <?php
2 namespace Elementor\Modules\LandingPages;
3
4 use Elementor\Core\Admin\Menu\Admin_Menu_Manager;
5 use Elementor\Core\Admin\Menu\Main as MainMenu;
6 use Elementor\Core\Base\Module as BaseModule;
7 use Elementor\Core\Documents_Manager;
8 use Elementor\Core\Experiments\Manager as Experiments_Manager;
9 use Elementor\Modules\LandingPages\Documents\Landing_Page;
10 use Elementor\Modules\LandingPages\AdminMenuItems\Landing_Pages_Menu_Item;
11 use Elementor\Modules\LandingPages\AdminMenuItems\Landing_Pages_Empty_View_Menu_Item;
12 use Elementor\Modules\LandingPages\Module as Landing_Pages_Module;
13 use Elementor\Plugin;
14 use Elementor\TemplateLibrary\Source_Local;
15
16 if ( ! defined( 'ABSPATH' ) ) {
17 exit; // Exit if accessed directly.
18 }
19
20 class Module extends BaseModule {
21
22 const DOCUMENT_TYPE = 'landing-page';
23 const CPT = 'e-landing-page';
24 const ADMIN_PAGE_SLUG = 'edit.php?post_type=' . self::CPT;
25
26 private $posts;
27 private $trashed_posts;
28 private $new_lp_url;
29 private $permalink_structure;
30
31 public function get_name() {
32 return 'landing-pages';
33 }
34
35 /**
36 * Get Experimental Data
37 *
38 * Implementation of this method makes the module an experiment.
39 *
40 * @since 3.1.0
41 *
42 * @return array
43 */
44 public static function get_experimental_data() {
45 return [
46 'name' => 'landing-pages',
47 'title' => esc_html__( 'Landing Pages', 'elementor' ),
48 'description' => esc_html__( 'Adds a new Elementor content type that allows creating beautiful landing pages instantly in a streamlined workflow.', 'elementor' ),
49 'release_status' => Experiments_Manager::RELEASE_STATUS_STABLE,
50 'default' => Experiments_Manager::STATE_ACTIVE,
51 'new_site' => [
52 'default_active' => true,
53 'minimum_installation_version' => '3.1.0-beta',
54 ],
55 ];
56 }
57
58 /**
59 * Get Trashed Landing Pages Posts
60 *
61 * Returns the posts property of a WP_Query run for Landing Pages with post_status of 'trash'.
62 *
63 * @since 3.1.0
64 *
65 * @return array trashed posts
66 */
67 private function get_trashed_landing_page_posts() {
68 if ( $this->trashed_posts ) {
69 return $this->trashed_posts;
70 }
71
72 // `'posts_per_page' => 1` is because this is only used as an indicator to whether there are any trashed landing pages.
73 $trashed_posts_query = new \WP_Query( [
74 'no_found_rows' => true,
75 'post_type' => self::CPT,
76 'post_status' => 'trash',
77 'posts_per_page' => 1,
78 'meta_key' => '_elementor_template_type',
79 'meta_value' => self::DOCUMENT_TYPE,
80 ] );
81
82 $this->trashed_posts = $trashed_posts_query->posts;
83
84 return $this->trashed_posts;
85 }
86
87 /**
88 * Get Landing Pages Posts
89 *
90 * Returns the posts property of a WP_Query run for posts with the Landing Pages CPT.
91 *
92 * @since 3.1.0
93 *
94 * @return array posts
95 */
96 private function get_landing_page_posts() {
97 if ( $this->posts ) {
98 return $this->posts;
99 }
100
101 // `'posts_per_page' => 1` is because this is only used as an indicator to whether there are any landing pages.
102 $posts_query = new \WP_Query( [
103 'no_found_rows' => true,
104 'post_type' => self::CPT,
105 'post_status' => 'any',
106 'posts_per_page' => 1,
107 'meta_key' => '_elementor_template_type',
108 'meta_value' => self::DOCUMENT_TYPE,
109 ] );
110
111 $this->posts = $posts_query->posts;
112
113 return $this->posts;
114 }
115
116 /**
117 * Is Elementor Landing Page.
118 *
119 * Check whether the post is an Elementor Landing Page.
120 *
121 * @since 3.1.0
122 * @access public
123 *
124 * @param \WP_Post $post Post Object
125 *
126 * @return bool Whether the post was built with Elementor.
127 */
128 public function is_elementor_landing_page( $post ) {
129 return self::CPT === $post->post_type;
130 }
131
132 private function get_menu_args() {
133 $posts = $this->get_landing_page_posts();
134
135 // If there are no Landing Pages, show the "Create Your First Landing Page" page.
136 // If there are, show the pages table.
137 if ( ! empty( $posts ) ) {
138 $menu_slug = self::ADMIN_PAGE_SLUG;
139 $function = null;
140 } else {
141 $menu_slug = self::CPT;
142 $function = [ $this, 'print_empty_landing_pages_page' ];
143 }
144
145 return [
146 'menu_slug' => $menu_slug,
147 'function' => $function,
148 ];
149 }
150
151 private function register_admin_menu( MainMenu $menu ) {
152 $landing_pages_title = esc_html__( 'Landing Pages', 'elementor' );
153
154 $menu_args = array_merge( $this->get_menu_args(), [
155 'page_title' => $landing_pages_title,
156 'menu_title' => $landing_pages_title,
157 'index' => 20,
158 ] );
159
160 $menu->add_submenu( $menu_args );
161 }
162
163 /**
164 * Add Submenu Page
165 *
166 * Adds the 'Landing Pages' submenu item to the 'Templates' menu item.
167 *
168 * @since 3.1.0
169 */
170 private function register_admin_menu_legacy( Admin_Menu_Manager $admin_menu ) {
171 $menu_args = $this->get_menu_args();
172
173 $slug = $menu_args['menu_slug'];
174 $function = $menu_args['function'];
175
176 if ( is_callable( $function ) ) {
177 $admin_menu->register( $slug, new Landing_Pages_Empty_View_Menu_Item( $function ) );
178 } else {
179 $admin_menu->register( $slug, new Landing_Pages_Menu_Item() );
180 }
181 }
182
183 /**
184 * Get 'Add New' Landing Page URL
185 *
186 * Retrieves the custom URL for the admin dashboard's 'Add New' button in the Landing Pages admin screen. This URL
187 * creates a new Landing Pages and directly opens the Elementor Editor with the Template Library modal open on the
188 * Landing Pages tab.
189 *
190 * @since 3.1.0
191 *
192 * @return string
193 */
194 private function get_add_new_landing_page_url() {
195 if ( ! $this->new_lp_url ) {
196 $this->new_lp_url = Plugin::$instance->documents->get_create_new_post_url( self::CPT, self::DOCUMENT_TYPE ) . '#library';
197 }
198 return $this->new_lp_url;
199 }
200
201 /**
202 * Get Empty Landing Pages Page
203 *
204 * Prints the HTML content of the page that is displayed when there are no existing landing pages in the DB.
205 * Added as the callback to add_submenu_page.
206 *
207 * @since 3.1.0
208 */
209 public function print_empty_landing_pages_page() {
210 $template_sources = Plugin::$instance->templates_manager->get_registered_sources();
211 $source_local = $template_sources['local'];
212 $trashed_posts = $this->get_trashed_landing_page_posts();
213
214 ?>
215 <div class="e-landing-pages-empty">
216 <?php
217 /** @var Source_Local $source_local */
218 $source_local->print_blank_state_template( esc_html__( 'Landing Page', 'elementor' ), $this->get_add_new_landing_page_url(), esc_html__( 'Build Effective Landing Pages for your business\' marketing campaigns.', 'elementor' ) );
219
220 if ( ! empty( $trashed_posts ) ) : ?>
221 <div class="e-trashed-items">
222 <?php
223 printf(
224 /* translators: %1$s Link open tag, %2$s: Link close tag. */
225 esc_html__( 'Or view %1$sTrashed Items%1$s', 'elementor' ),
226 '<a href="' . esc_url( admin_url( 'edit.php?post_status=trash&post_type=' . self::CPT ) ) . '">',
227 '</a>'
228 );
229 ?>
230 </div>
231 <?php endif; ?>
232 </div>
233 <?php
234 }
235
236 /**
237 * Is Current Admin Page Edit LP
238 *
239 * Checks whether the current page is a native WordPress edit page for a landing page.
240 */
241 private function is_landing_page_admin_edit() {
242 $screen = get_current_screen();
243
244 if ( 'post' === $screen->base ) {
245 return $this->is_elementor_landing_page( get_post() );
246 }
247
248 return false;
249 }
250
251 /**
252 * Admin Localize Settings
253 *
254 * Enables adding properties to the globally available elementorAdmin.config JS object in the Admin Dashboard.
255 * Runs on the 'elementor/admin/localize_settings' filter.
256 *
257 * @since 3.1.0
258 *
259 * @param $settings
260 * @return array|null
261 */
262 private function admin_localize_settings( $settings ) {
263 $additional_settings = [
264 'urls' => [
265 'addNewLandingPageUrl' => $this->get_add_new_landing_page_url(),
266 ],
267 'landingPages' => [
268 'landingPagesHasPages' => [] !== $this->get_landing_page_posts(),
269 'isLandingPageAdminEdit' => $this->is_landing_page_admin_edit(),
270 ],
271 ];
272
273 return array_replace_recursive( $settings, $additional_settings );
274 }
275
276 /**
277 * Register Landing Pages CPT
278 *
279 * @since 3.1.0
280 */
281 private function register_landing_page_cpt() {
282 $labels = [
283 'name' => esc_html__( 'Landing Pages', 'elementor' ),
284 'singular_name' => esc_html__( 'Landing Page', 'elementor' ),
285 'add_new' => esc_html__( 'Add New', 'elementor' ),
286 'add_new_item' => esc_html__( 'Add New Landing Page', 'elementor' ),
287 'edit_item' => esc_html__( 'Edit Landing Page', 'elementor' ),
288 'new_item' => esc_html__( 'New Landing Page', 'elementor' ),
289 'all_items' => esc_html__( 'All Landing Pages', 'elementor' ),
290 'view_item' => esc_html__( 'View Landing Page', 'elementor' ),
291 'search_items' => esc_html__( 'Search Landing Pages', 'elementor' ),
292 'not_found' => esc_html__( 'No landing pages found', 'elementor' ),
293 'not_found_in_trash' => esc_html__( 'No landing pages found in trash', 'elementor' ),
294 'parent_item_colon' => '',
295 'menu_name' => esc_html__( 'Landing Pages', 'elementor' ),
296 ];
297
298 $args = [
299 'labels' => $labels,
300 'public' => true,
301 'show_in_menu' => 'edit.php?post_type=elementor_library&tabs_group=library',
302 'capability_type' => 'page',
303 'taxonomies' => [ Source_Local::TAXONOMY_TYPE_SLUG ],
304 'supports' => [ 'title', 'editor', 'comments', 'revisions', 'trackbacks', 'author', 'excerpt', 'page-attributes', 'thumbnail', 'custom-fields', 'post-formats', 'elementor' ],
305 ];
306
307 register_post_type( self::CPT, $args );
308 }
309
310 /**
311 * Remove Post Type Slug
312 *
313 * Landing Pages are supposed to act exactly like pages. This includes their URLs being directly under the site's
314 * domain name. Since "Landing Pages" is a CPT, WordPress automatically adds the landing page slug as a prefix to
315 * it's posts' permalinks. This method checks if the post's post type is Landing Pages, and if it is, it removes
316 * the CPT slug from the requested post URL.
317 *
318 * Runs on the 'post_type_link' filter.
319 *
320 * @since 3.1.0
321 *
322 * @param $post_link
323 * @param $post
324 * @param $leavename
325 * @return string|string[]
326 */
327 private function remove_post_type_slug( $post_link, $post, $leavename ) {
328 // Only try to modify the permalink if the post is a Landing Page.
329 if ( self::CPT !== $post->post_type || 'publish' !== $post->post_status ) {
330 return $post_link;
331 }
332
333 // Any slug prefixes need to be removed from the post link.
334 return get_home_url() . '/' . $post->post_name . '/';
335 }
336
337 /**
338 * Adjust Landing Page Query
339 *
340 * Since Landing Pages are a CPT but should act like pages, the WP_Query that is used to fetch the page from the
341 * database needs to be adjusted. This method adds the Landing Pages CPT to the list of queried post types, to
342 * make sure the database query finds the correct Landing Page to display.
343 * Runs on the 'pre_get_posts' action.
344 *
345 * @since 3.1.0
346 *
347 * @param \WP_Query $query
348 */
349 private function adjust_landing_page_query( \WP_Query $query ) {
350 // Only handle actual pages.
351 if (
352 ! $query->is_main_query()
353 // If the query is not for a page.
354 || ! isset( $query->query['page'] )
355 // If the query is for a static home/blog page.
356 || is_home()
357 // If the post type comes already set, the main query is probably a custom one made by another plugin.
358 // In this case we do not want to intervene in order to not cause a conflict.
359 || isset( $query->query['post_type'] )
360 ) {
361 return;
362 }
363
364 // Create the post types property as an array and include the landing pages CPT in it.
365 $query_post_types = [ 'post', 'page', self::CPT ];
366
367 // Since WordPress determined this is supposed to be a page, we'll pre-set the post_type query arg to make sure
368 // it includes the Landing Page CPT, so when the query is parsed, our CPT will be a legitimate match to the
369 // Landing Page's permalink (that is directly under the domain, without a CPT slug prefix). In some cases,
370 // The 'name' property will be set, and in others it is the 'pagename', so we have to cover both cases.
371 if ( ! empty( $query->query['name'] ) ) {
372 $query->set( 'post_type', $query_post_types );
373 } elseif ( ! empty( $query->query['pagename'] ) && false === strpos( $query->query['pagename'], '/' ) ) {
374 $query->set( 'post_type', $query_post_types );
375
376 // We also need to set the name query var since redirect_guess_404_permalink() relies on it.
377 add_filter( 'pre_redirect_guess_404_permalink', function( $value ) use ( $query ) {
378 set_query_var( 'name', $query->query['pagename'] );
379
380 return $value;
381 } );
382 }
383 }
384
385 /**
386 * Handle 404
387 *
388 * This method runs after a page is not found in the database, but before a page is returned as a 404.
389 * These cases are handled in this filter callback, that runs on the 'pre_handle_404' filter.
390 *
391 * In some cases (such as when a site uses custom permalink structures), WordPress's WP_Query does not identify a
392 * Landing Page's URL as a post belonging to the Landing Page CPT. Some cases are handled successfully by the
393 * adjust_landing_page_query() method, but some are not and still trigger a 404 process. This method handles such
394 * cases by overriding the $wp_query global to fetch the correct landing page post entry.
395 *
396 * For example, since Landing Pages slugs come directly after the site domain name, WP_Query might parse the post
397 * as a category page. Since there is no category matching the slug, it triggers a 404 process. In this case, we
398 * run a query for a Landing Page post with the passed slug ($query->query['category_name']. If a Landing Page
399 * with the passed slug is found, we override the global $wp_query with the new, correct query.
400 *
401 * @param $current_value
402 * @param $query
403 * @return false
404 */
405 private function handle_404( $current_value, $query ) {
406 global $wp_query;
407
408 // If another plugin/theme already used this filter, exit here to avoid conflicts.
409 if ( $current_value ) {
410 return $current_value;
411 }
412
413 if (
414 // Make sure we only intervene in the main query.
415 ! $query->is_main_query()
416 // If a post was found, this is not a 404 case, so do not intervene.
417 || ! empty( $query->posts )
418 // This filter is only meant to deal with wrong queries where the only query var is 'category_name'.
419 // If there is no 'category_name' query var, do not intervene.
420 || empty( $query->query['category_name'] )
421 // If the query is for a real taxonomy (determined by it including a table to search in, such as the
422 // wp_term_relationships table), do not intervene.
423 || ! empty( $query->tax_query->table_aliases )
424 ) {
425 return false;
426 }
427
428 // Search for a Landing Page with the same name passed as the 'category name'.
429 $possible_new_query = new \WP_Query( [
430 'no_found_rows' => true,
431 'post_type' => self::CPT,
432 'name' => $query->query['category_name'],
433 ] );
434
435 // Only if such a Landing Page is found, override the query to fetch the correct page.
436 if ( ! empty( $possible_new_query->posts ) ) {
437 $wp_query = $possible_new_query; //phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
438 }
439
440 return false;
441 }
442
443 public function __construct() {
444 $this->permalink_structure = get_option( 'permalink_structure' );
445
446 $this->register_landing_page_cpt();
447
448 // If there is a permalink structure set to the site, run the hooks that modify the Landing Pages permalinks to
449 // match WordPress' native 'Pages' post type.
450 if ( '' !== $this->permalink_structure ) {
451 // Landing Pages' post link needs to be modified to be identical to the pages permalink structure. This
452 // needs to happen in both the admin and the front end, since post links are also used in the admin pages.
453 add_filter( 'post_type_link', function( $post_link, $post, $leavename ) {
454 return $this->remove_post_type_slug( $post_link, $post, $leavename );
455 }, 10, 3 );
456
457 // The query itself only has to be manipulated when pages are viewed in the front end.
458 if ( ! is_admin() || wp_doing_ajax() ) {
459 add_action( 'pre_get_posts', function ( $query ) {
460 $this->adjust_landing_page_query( $query );
461 } );
462
463 // Handle cases where visiting a Landing Page's URL returns 404.
464 add_filter( 'pre_handle_404', function ( $value, $query ) {
465 return $this->handle_404( $value, $query );
466 }, 10, 2 );
467 }
468 }
469
470 add_action( 'elementor/documents/register', function( Documents_Manager $documents_manager ) {
471 $documents_manager->register_document_type( self::DOCUMENT_TYPE, Landing_Page::get_class_full_name() );
472 } );
473
474 if ( Plugin::$instance->experiments->is_feature_active( 'admin_menu_rearrangement' ) ) {
475 add_action( 'elementor/admin/menu_registered/elementor', function( MainMenu $menu ) {
476 $this->register_admin_menu( $menu );
477 } );
478 } else {
479 add_action( 'elementor/admin/menu/register', function( Admin_Menu_Manager $admin_menu ) {
480 $this->register_admin_menu_legacy( $admin_menu );
481 }, Source_Local::ADMIN_MENU_PRIORITY + 20 );
482 }
483
484 // Add the custom 'Add New' link for Landing Pages into Elementor's admin config.
485 add_action( 'elementor/admin/localize_settings', function( array $settings ) {
486 return $this->admin_localize_settings( $settings );
487 } );
488
489 add_filter( 'elementor/template_library/sources/local/register_taxonomy_cpts', function( array $cpts ) {
490 $cpts[] = self::CPT;
491
492 return $cpts;
493 } );
494
495 // In the Landing Pages Admin Table page - Overwrite Template type column header title.
496 add_action( 'manage_' . Landing_Pages_Module::CPT . '_posts_columns', function( $posts_columns ) {
497 /** @var Source_Local $source_local */
498 $source_local = Plugin::$instance->templates_manager->get_source( 'local' );
499
500 return $source_local->admin_columns_headers( $posts_columns );
501 } );
502
503 // In the Landing Pages Admin Table page - Overwrite Template type column row values.
504 add_action( 'manage_' . Landing_Pages_Module::CPT . '_posts_custom_column', function( $column_name, $post_id ) {
505 /** @var Landing_Page $document */
506 $document = Plugin::$instance->documents->get( $post_id );
507
508 $document->admin_columns_content( $column_name );
509 }, 10, 2 );
510
511 // Overwrite the Admin Bar's 'New +' Landing Page URL with the link that creates the new LP in Elementor
512 // with the Template Library modal open.
513 add_action( 'admin_bar_menu', function( $admin_bar ) {
514 // Get the Landing Page menu node.
515 $new_landing_page_node = $admin_bar->get_node( 'new-e-landing-page' );
516
517 if ( $new_landing_page_node ) {
518 $new_landing_page_node->href = $this->get_add_new_landing_page_url();
519
520 $admin_bar->add_node( $new_landing_page_node );
521 }
522 }, 100 );
523 }
524 }
525